Jump to content

Ernio

Forge Modder
  • Posts

    2638
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by Ernio

  1. As long as registration methods are called in mod's preInit, I can't argue with the fact that it will work.

     

    As to what I would comment here:

     

    1. While ModelLoader is not @SideOnly, it actually is for client use only and I personally would place it in client only class (or client proxy) or at least call it from one (client proxy). :)

     

    2. You already made up your mind, why keep asking? If it works, it works (doesn't mean it is any better than any other thing you could write and most certainly it isn't clearer this way).

     

    3. This is probably the worst: :P

    if(INspecial == 0)
                    this.item.setCreativeTab(Main.modCreativeTab);
    

    Just do ModItemsEnum.this_is_test.item.setSomeThing(stuff) from preInit.

     

    4. Oh wait, it (above) isn't - From now on, instead of doing Items.ITEM, you will have to do Items.LONG_ENUM_NAME.getItem() in EVERY damn place in your code... great!

    Aside from that - writing such systems for simple stuff is retarded - anything out of ordinary will still require writing few more lines of code. :P

     

    My piece on this. 8)

  2. I was thinking if there is or could be a way of getting list of classes loaded by mod.

    Every time a mod is loaded, there would be event fired with some Collection<Class> allowing other mods to for example read annotations on them.

    Or you know - one-to-one event-class firing.

     

    There is obviously order of loading mods so those loaded later might not catch those loaded before them, but this can be solved by either dependency or simply by making snapshot of mod's Collection<Class> and firing event for it at the very end (so when all mods are loaded).

     

    Well, I am open to suggestions as to how this could be made without such event (listing classes on load) or expecting other feedback.

     

    In other news - Forge (mod's) class loader allows to load more classes in runtime (am I the only one doing it?), so if it were for me - make event fire even then (not just in mod inits).

  3. I believe you don't fully understand how data should be stored on players. Well - I might be wrong, but worth asking :)

     

    Saving data to player data files is different from assigning data to player when he is online.

     

    It would help us help you if you would describe your end goal and what you want to store.

  4. If you want your mod to be "universal" (keep it in one .jar), this is step by step on how I'd do it:

     

    Events part:

    1. Create DedicatedServerEvents.class. Mark it with @SideOnly(Side.SERVER).

    2. @SubscribeEvent to PlayerLoggedInEvent in class above.

    3. Register class above from ServerProxy (call during preInit).

    4. At this point whenever mod is ran on dedicated server (so ServerProxy is fired), you will be firing event for all players that log in on this server.

     

    Dedicated part:

    1. In ServerProxy load (during preInit) your data from files (using forge config or configs of your design).

    2. Place loaded data in @SideOnly(Side.SERVER) static storage - it could be for example Map<Block, Double> for block hardness or other ways for different values.

    3. Use loaded data to change vanilla values. In mod's init (ServerProxy) call Block#setHardness and other methods you want and use data you loaded from config.

    4. At this point whenever mod is ran on dedicated server (so ServerProxy is fired), you will be modifying vanilla properties with stuff loaded from configs while storing this data in static maps. @SideOnly also prevents those classes/fields from existing on Client.jar, so there is that.

     

    Syncing stuff:

    1. Create SimpleNetworkWrapper and proper IMessages (remember about thread safety).

    2. In PlayerLoggedInEvent send data from server's static maps to client (serialize them into something and deserialize on receiving client).

    3. On receiver client modify proper Blocks by puling them from registry by names (So e.g: in your packet you send arrays of stuff like: "modid:blockname"=5.0D).

     

    This should work assuming vanilla allows such hot-modifications to hardness values.

     

    Note that similar effects (for only some of block properties) can be achieved with HarvestSpeed (or whetever the name was) and some other events.

     

    BIG NOTE: Mind EVERY word I wrote - each one of them is important as they directly describe possible design approach.

     

    Questions?

  5. Are you sure you setup your workspace correctly?

    gradlew setupDecompWorkspace

    gradlew eclipse

    I have no knowledge of such bug and I've been modding (and coding other stuff) for years using Eclipse.

     

    Can't offer much help, you could lookup your build path and make sure it is setup correctly, but commands mentioned above do that for you so I don't see a point. Maybe get new eclipse?

  6. I don't really know the issue, but I have hints - not all of them might still be a thing (they were in about 1.8, maybe earlier).

     

    Hurt animation (red) doesn't mean entity was damaged - it means it's health went down on client.

    What is worth mentioning is that it also means that if you change maxHealth - it will reflect on health (to lower), thus, you will get hurt animation.

    So the questions one may ask here:

    * Was entity damaged on server, on client or both?

    * Does entity have less health than max - on which sides?

    * Is max health same on both sides?

    * What damaged entity?

     

    Since you have your own entity - you could override some methods and check what caused damage. You could also use events like EntityJoinedWorldEvent to check max health stats and LivingHurtEvent or other events (ConstructingEvent?)

     

    The issue might not even be in entity itself - are you using something that could cause such issue? Events? World? Other entities? How do you spawn your entity?

    Looking from 1.10 source, I don't see obvious error.

  7. I will just throw in my piece: Don't touch 1.5. I personally wouldn't even touch anything below 1.7.10. It's all for nothing. Will take more time to delete and replace with new code than write from scratch (well unless mod features some big piece of code that doesn't rely on minecraft code).

     

    In that case - for quick lookup you can go with stuff like JD-GUI or for full decomp - with BON2 (which may not work for 1.5, idk tho).

  8. No.

     

    There are always 2 sides. There is one Entity for each side.

    Client + Integrated (also integrated LAN)

    Client + Dedicated (or other non-integrated, like outside LAN).

     

    EntityPlayer is a special Entity where Client thread uses AbstractClientPlayer (for EntityPlayer you control, Minecraft#thePlayer, it's EntityPlayerSP), server thread uses EntityPlayerMP.

    So to answer your question - "if (player instanceof EntityPlayerMP)" is almost same check as "if (!World#isRemote)" - where remote means that code is ran on client (so negative is server). you can sue Entity#worldObj to check logical side.

    More here: http://mcforge.readthedocs.io/en/latest/concepts/sides/

     

    Now - you shouldn't create mods that are physical-side specific (meaning they work differently on dedic and integrated). It will get messy for a novice. If you are planning on writing sided mods you should be writing two mods such as one for ONLY dedic, and one for ONLY client.

    Otherwise you should write universal mod (and for real - dedic and integrated is the same thing, so it's easier this way).

     

    To solve your problem in best possible way - please describe the goal you are after, including on what side what should happen. Some of code/events are reserved for specific sides so it's important to state end-goal (like e.g: checking if server is dedic looks different for server and different for client that connects to it).

  9. Okay, well - look: What you described is just an idea, now as to designing it to work properly - I can tell you that aside from rotating hitbox (I haven't checked that one so idk), everything you need it pretty much doable with just Forge.

     

    As far as RenderPlayerAPI goes - I am absolutely sure that there is noone who will help you there more than SmartMoving's source (but to understand it you will need to spend some time on in-depth reading/understanding source).

     

    Note: As mentioned - Forge allows you to edit entity's data, hitboxes and rendering. RenderPlayerAPI is just an API - it is literally layer over what forge might be able to do and provides more compatibility (not functionality). If you want to go for simple - go with Forge. If you want to somehow get along with other RenderPlayerAPI mods - use that.

     

    Now to actual things:

    1. Minecraft threads (sides), COMPLETE understanding.

    2. Forge events (usage).

    3. Rendering and client events, partialTicks, client-only classes.

    4. Rendering with GL and models + whole vanilla Render.class system.

    5. @Capability (storing player states).

    6. SimpleNetworkWrapper (network designs)

    7. Network-related events (tracking, dynamic syncing).

    8. Understanding hitboxes AABB and OBB if you want (idk if they are possible to implement without ASM, there was a thread about it).

    9. Some other stuff such as NBT (saving data) and overall vanilla/forge systems + pretty advanced math (rotating and doing stuff like animation properly).

     

    Do tell me - how much do you think you are prepared (considering mentioned above required knowledge)?

     

    What do you know nothing about? What you are not sure you know enough?

  10. What I mean is that you rely on player to "tell" you when stuff happens.

    Chunks can be loaded by non-players, can be forced to load and basically anything in world can happen when there is 0 players online.

    This is also what I meant by saying this is not syncing issue, but tracking server changes.

    Still tho - chunk loaders are out of my expertise since 1.6, so I am useless here, cheers! 8)

  11. I am not here with straight answer, just wondering about some stuff.

     

    I don't know THAT much about stuff you do in your prev post (tbh - only chunks part), but I think I know enough to say - drop this approach.

    That is unless I am not really seeing what you are trying to do - I will call upon my prev post and say that this way you won't be able to catch all block changes (hell, you will be probably in lesser half if not less).

     

    I'd personally make worlds copy each other by using same chunks (or rather "connected" chunks), like I think d7 suggested.

     

    EDIT:

    As for replacing chunk loaders - you could probably do that from world load event, I am not sure if vanilla's chunk loader is already being used there.

  12. Intro:

    Minecraft runs on 2 (+2 network) threads (http://mcforge.readthedocs.org/en/latest/concepts/sides/), you want to do stuff on client (bot?).

    Each thread tick 20 times, 1tick = 50ms.

    Aside from partialTicks (rendering only), this is "planck time" (smallest) in Minecraft world.

     

    What to do?

    Make scheduler.

    1. @SubscribeEvent to ClientTickEvent.

    - Check for event.phase (pick one).

    2. Create static Queue or List or whatever (its important it's elements are ordered by inserting).

    - You will be throwing "commands" to that list.

    - Those "commands" will be calls to execute specific key.

    3. Make ClientTickEvent execute one command at time from top of ordered list above every few ticks.

    - 10 ticks = 0.5sec like you want.

    - You want to do:

    int ticks;
    Queue commands;
    ClientTickEvent
    {
        if (ticks % 10 && !commands.isEmpty)
        {
           commands.getFromTop().call();
           commands.removeFromTop();
        }
        ++ticks;
    }
    

    4. Throw "commands" from wherever you want (client thread) into queue.

  13. You mean this?

    7327f54360.png

    Not quite. I don't want to list unread threads (while I am not saying it isn't useful af), but open all of them (new, visible on current page, so you don't get e.g 200 tabs at once) in new tabs in browser. So instead of scrolling through dozens of new threads and clicking "open in new tab" for each of them, one could push one button and have them on plate, ready-to-read.

    It's pretty easy to write, but I guess this request was indeed a bit too lazy of me. :P

     

    Sounds like something for a browser extension to me.

    I think I also hear it.

     

  14. Have you looked into EntityCow source? Without looking I am pretty sure code responsible for filling bucket with milk is in onInteract (or similar name) method. If it's not in entity, it might also be located in ItemBucket (again - something along interaction).

    Override it, and do almost same thing but differently.

  15. Okay, I need to ask - what packets have anything to do with block changes. Packets are used to sync sides, not to listen to changes (even if you would listen to packet that says "this block changed" - it doesn't mean the packet would be sent with every change, thus - you miss out on changes).

     

    Question here is not a matter of syncing - it's a matter of detecting change on one of sides (probably server because server saves world).

    Now - Forge doesn't provide event for ALL block changes, it only gives you few hooks such as BlockBreak and PlaceBlock which are called in very specific circumstances (mining/building/explosions) - so again - not all of them.

     

    Firing change block event (if such would exist) from #setBlockState would be not only expensive (not really biggest problem), but wouldn't really solve issue either - why? Because world data (blocks) can and is modified from many other places, including external (e.g: other mods).

     

    So the answer to thread: No, it's impossible to track ALL block changes in world.

     

    More: There is solution to this - its a core-mod. But WAIT! Don't write one (we don't need another core-mod/api)! I strongly belive SpongeAPI has such event (and MANY more) - if you don't know what that is - basically server-sided API (core-mod) that can be installed on top of forge (using all forge systems), an extension that replaced old dead-bukkit.

  16. 1st I will just note: Look at event callbacks. Pre and Post is called exactly at start and end of rendering. If you do something in Pre, it won't really do much to vanilla code since vanilla will render rest on its own.

     

    So one could ask - why such events even exist if they don't allow shit? Well - they do! And yes - almost anything rendering-related has close to zero compatibility (without special APIs) and thus - you basically replace whole thing.

     

    So where am I going with it?

    If you would want to render bracelet, cape, hat or some fire and sparkles - hell yeah, do it in Pre or Post!

    If you need anything that is supposed to manipulate vanilla part of rendering - aside from GL calls like scaling, translating and rotating whole model - you usually can't. Solution? It's always - cancel rendering in Pre and re-render with modified code.

    How to make modified code? Extend e.g: RenderPlayer and edit it to your needs, initialize it in some static field and call doRender() from Pre after event.setCanceled(true); - vanilla is gone, your rendering kicks in.

    You need player specific stuff? Use @Capabilities and make Render class honour your per-player data.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.