Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Everything posted by coolAlias

  1. LivingHurtEvent is not completely reliable because other mods can subscribe to it and modify the amount - you can try to make sure your handler is the last one called by setting its priority to LOWEST, but that is no guarantee - other mods may have done the same. Even if you are last, you still must account for armor and potion effects, both of which are handled after the event is finished (see Entity#damageEntity). One solution would be to flag the entity as struck by the sword, also saving a reference to the sword-wielder and the damaged entity's current health; then, in the following tick compare the damaged entity's current health to its health at the time it was struck. The con to this approach is that if something else damaged the entity in the same tick for more damage, the sword-wielder would recover more health than he should, or possibly the entity even regenerated some health and the sword-wielder recovers less or nothing at all. Another solution is to write a method replicating the logic from #damageEntity (and the methods that it calls) - this will give you a way to pretty much guarantee that you get the correct amount so long as there isn't a handler called after yours that does something to the damage amount. In both cases you are taking a (small) chance. Yet another solution would be to change your mechanic - rather than basing the amount healed on the damage inflicted, have it as an AttributeModifier or Enchantment like effect where upon inflicting any damage at all, the attacker heals a set amount per attribute point, e.g. each point gives 1 heart of healing, so vampire attribute / enchantment at level 3 gives (3 x 2.0) or 3 hearts (6 hp) of healing. Just a thought.
  2. A tab is simply an element that you click and then draw something different. This tutorial covers that kind of stuff in a fair amount of depth and is still very useful despite being for 1.6.4. The concepts are all still relevant.
  3. FontRenderer#FONT_HEIGHT gives you the height of the current font.
  4. He means when you instantiate / initialize your Block class, you should call that method, but it would be easier to simply put whatever code you want automatically run into the abstract class' constructor: However, since you are talking about CLIENT-side only stuff (model registration), you can't do either of what we have shown you. Instead, your best bet is probably to make an interface like this one, implement it in your InBetween class (and any other of your Block classes that have a custom state map), and then use Reflection or some other tactic to iterate over your blocks from your ClientProxy during the appropriate FML init event and call that method for each one that implements that interface. The advantage of doing it that way is it encapsulates the Block's logic all in its own class, so it is easier to maintain, but you may be served just as well by doing it the old-fashioned way and simply calling the ModelLoader method manually for each of your blocks that requires it - it's very simple that way and, unless you have LOTS of blocks that require it, also much faster to do (and fewer lines of code).
  5. To clarify, you don't need to include the armor calculation for things like evasion - that was a bad example, since it is a binary (all or nothing) type of protection. It is useful, however, for things like resistances, e.g. 50% resistance to slashing - well, okay, that takes you to half damage, but now you have to account for the player's armor and potion effects in order to decide if you want to cancel the LivingAttackEvent. You're not changing the damage at this point, nor are you re-posting the event yet again, just deciding if you want to completely negate it to avoid the hurt animation. If there is any damage remaining, you let it all go through to the LivingHurtEvent which then does the same resistance calculations less the armor and potion calculations - those happen during the actual Entity#damageEntity method. Increasing the damage amount during LivingHurtEvent is also fine, e.g. to simulate an armor type that is weak against the damage type, like you mentioned above.
  6. I highly advise NOT doing that unless there is absolutely no other way, the reason being that the whole point of the Forge events is mod inter-compatibility, and directly damaging an entity will break that contract and circumvent any number of other mods' damage handlers. Canceling and reposting an event is fine, but usually you can get by with a simple adjustment to the damage amount in the LivingHurtEvent - it is a publicly mutable field of the event class for a reason. Now, if you are talking about the LivingAttackEvent, that'd be the perfect time to cancel and repost with a new DamageSource, e.g. Piercing, Slashing, Bludgeoning, etc. based on the weapon capability / type. At that point, you wouldn't even care about the armor calculations or other resistances as those would be handled in the hurt event.
  7. It gets applied after, which is why I made this method - however, that neat little trick of creating a class in a vanilla package (even though it's still in YOUR mod's folder) doesn't seem to work anymore, see this post. Unless someone knows how to get that to work, your options are either Reflection e.g. to make the method(s) publicly accessible, or to copy/paste those methods (which likely will still require Reflection to make private fields etc. accessible). One thing you may want to think about: if your protection is going to completely nullify the damage received, doing so in LivingHurtEvent still results in the 'hurt' animation / getting knocked back, at least it used to, so you may also want to check in LivingAttackEvent - note that you cannot alter the damage in the attack event, only cancel it or allow it, but it is useful if something gives complete immunity (e.g. evasion).
  8. Caused by: java.lang.ClassCastException: com.gwater.decorationmod.container.ContainerCrate cannot be cast to net.minecraft.client.gui.GuiScreen Looks like you are returning your Container as the client-side element, but you should be returning the GUI class. Containers are the server-side element.
  9. So assuming a full block, you have 16 x 16 x 16 = 4096 possible positions for each model, and an unknown number of model parts. Will each model part be indexed somehow, e.g. as a hashmap containing a unique integer key to each model part definition? That's probably your best-case scenario, and it's pretty bad: one integer to store the location and one integer to store the model part for each part of the whole, so if you had a model consisting of 20 parts, the minimum you could send would be 40 integers, with a maximum of 4096 x 2 or 8192 integers per complete model. That's not a trivial amount of data. Now you could try to get fancy and try to figure out parts of models that don't need to be set, e.g. assuming that your 'parts' are actually pixel portions, then if there is a 4 x 4 x 4 cubic section where each face is fully covered with model parts, then you probably don't need to send the inner 3 x 3 x 3 section, but you'd probably need to come up with a fairly efficient algorithm to make it worthwhile. I'm not really understanding your design with respect to how it is supposed to interact with the model system and how, exactly, you expect it to function in terms of the game, so the above is all just speculation on my part. If you explain in more detail, perhaps that will give people more of an idea on how to help you. EDIT: On another note - why aren't you using the JSON model system? People are already accustomed to creating resource packs, and sending a compressed JSON file over the network would be trivial and usually pretty light-weight, though you'd have to figure a way to send textures as well. I don't know... the whole idea sounds like a performance nightmare in the making, but who knows, maybe someone will come up with a brilliant solution?
  10. Ah, I see. Well in that case, that's probably the best you can do - send a giant packet (or several) when the player connects to the server or joins the world, and then keep them updated with new or altered varieties as they come. Will it be slow? Probably, especially as the number of items grows, but that's the price for breaking out of the framework of static model definitions loaded directly from the client computers. I honestly wouldn't worry too much about performance until it becomes an issue, though, as it might never become one.
  11. The server generally shouldn't have anything to do with models - those are really only to render things on the client. Why can't you ship or load the models client-side, like vanilla JSON models do?
  12. Use your custom slot for the slot that should have a max stack size of 1 and return 1 for the Slot#getSlotStackLimit method. However, the vanilla #mergeStackInSlot implementations DO NOT check the slot's stack limit (at least as of 1.8 - maybe it has changed), and also has trouble handling slot limits of 1. Here is an implementation I came up with for #mergeStackInSlot - there are others out there as well that do the same thing. As for the shift-clicking moving items into the wrong slots, that has to do with how you choose to implement #transferStackInSlot - you can find some information about that in this tutorial, though I recommend you skip to the final spoiler section first, as that is the most recent.
  13. People probably do but either, don't know the answer and don't have time, inclination, or ability to research the answer, or they know the answer but haven't had the time to reply. Personally, I fall into the first category since I'm using a work computer without Forge installed
  14. Instead of making client-side methods and calls to them in your Registers class, you need to do so from the ClientProxy as has been mentioned several times. E.g. instead of Registers.addItemRender(args), you should be using Main.proxy.addItemRender(args).
  15. Thanks for the clarification.
  16. What Choonster said, and also clean up your imports: import novaviper.tetracraft.common.item.*; import novaviper.tetracraft.common.lib.*; import novaviper.tetracraft.client.lib.*; That's in your ModItems class - well, guess what? Your ModItems class is common to both server and client, but you are including client.lib.* - if any of those classes are @SideOnly(Side.CLIENT), they will not exist on the server but will still try to load. If you are using Eclipse, press Ctrl-Shift-O to auto-import only the classes that you actually use, rather than using the wildcard import.
  17. Are you sure it wasn't just the break point pausing execution? That's what they do - they pause the program execution without ending the process so that you can examine the state of everything currently on the stack and step through the method calls as they happen. To resume, just press the play/resume button, but if you have a break point in your render code, it will immediately drop you out again the next render tick, so you can toggle the break point off after the first time and then resume.
  18. Put a break point in your render code and run in debug mode. While in debug mode, you can also edit values in your code and the effects thereof will usually be immediately visible in-game, so you can tweak your render code on the fly until you get it working how you want.
  19. Your 'Main' class should have an 'instance' field, e.g.: @Mod(modid = ModInfo.ID, name = ModInfo.NAME, version = ModInfo.VERSION) public class Main { @Mod.Instance(ModInfo.ID) public static Main instance; It doesn't have to be named 'Main', it could be 'YourMod' or whatever, but it is your main class that contains all of the critical mod components. As for 'par6', that is the ID of the GUI screen you wish to open. For my mods, I create a constant for each GUI that I can reference, e.g. MyGuiHandler.GUI_SCREEN_ONE might be 1, and GUI_SCREEN_TWO would be 2, etc. That way your IGuiHandler has some way to determine which Gui and Container to class to return.
  20. Not if you insist on making a client-side only mod.
  21. If DamageSource#getEntity is not null, then you are pretty much guaranteed to be in a fight. Either a mob or player hit you directly, or some sort of projectile struck you. However, you should be aware that many events such as LivingHurtEvent and LivingAttackEvent are typically posted only on the server* - you are only aware of them during single-player because the server is integrated with the client. * Unless you (the client player) triggered the event, e.g. when you attack something LivingAttackEvent will be posted for you on your client as well as on the server, but not necessarily when something attacks you. You can find out by printing to the console during the events and then triggering them in single- and multi-player.
  22. It's possible I've misunderstood what that method does - it may only actually affect the reequip animation and have nothing to do with the block-breaking process, though I am/was pretty sure they were related. I've never had occasion to test while breaking a block, though I have had occasion to override the method So, either that method isn't the right one, or it is currently bugged in 1.9.
  23. That looks fine, so perhaps it's a bug? 1.9 did add 2 hands, after all, so I imagine quite a lot must have changed in the background. You could try following the call hierarchy of #shouldCauseReequipAnimation and see if there is anything amiss.
  24. Show your implementation. There's also always the possibility that it is a bug.
  25. Yes, there should be an Item method called something like #shouldCauseReequipAnimation - the syncing of the NBT to the client is what causes the re-equip animation which in turn interrupts block breaking. Be sure to still return true if the stack has indeed changed.
×
×
  • Create New...

Important Information

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