IceMetalPunk Posted December 14, 2015 Share Posted December 14, 2015 I've implemented a custom damage type ("electricity") by simply creating a new public static DamageSource in my main mod class. It works fine with my custom electricity-damaging blocks, but I'd also like the direct damage from a lightning strike to be considered electricity damage. (This way, if the 5 instant damage from a bolt kills a player, it says they were electrocuted instead of burned.) I don't have any experience with modifying base classes; how would I go about overriding the onStruckByLightning() method for the base entity class so that all entities that don't override it themselves will have this proper electricity behavior? Quote Whatever Minecraft needs, it is most likely not yet another tool tier. Link to comment Share on other sites More sharing options...
Jedispencer21 Posted December 14, 2015 Share Posted December 14, 2015 You could try using LivingHurtEvent then checking if the event.source equals DamageSource#lightningBolt, then cancel the event, then you could use event.entity.attackEntityFrom(yourdamagesource, amount) Quote Link to comment Share on other sites More sharing options...
IceMetalPunk Posted December 14, 2015 Author Share Posted December 14, 2015 I'm pretty sure there's no lightningBolt damage source; it just uses the inFire damage source. But I've been looking into event listeners (I've never used them; I'm very new to modding), and I think that is the right way to go. I've found there's an EntityStruckByLightning event; I'm going to try and use that to make this work. The only thing I'm unsure about is mod compatibility; canceling getting struck by lightening could cause issues with other mods, I'd think. Hopefully, if I copy the usual code and just change the damage source, it won't be too much of a problem... *EDIT* And already I've run into another problem. The default lightning-strike code increments the private member "fire". I don't have access to that variable inside the event listener, and there doesn't seem to be any method to get the current value of "fire", so it's not even possible to use setFire() to do the incrementation (even if I could, setFire() takes an int and multiplies it by 20, so I couldn't add 1 even then). How would I replicate the onStruckByLightning code in an event listener if I have this problem? Quote Whatever Minecraft needs, it is most likely not yet another tool tier. Link to comment Share on other sites More sharing options...
jabelar Posted December 14, 2015 Share Posted December 14, 2015 I'm pretty sure there's no lightningBolt damage source; it just uses the inFire damage source. In 1.8 they added a lightingBolt damage source. So doing this mod would be much easier in 1.8 because as diesieben07 mentions then you could just handle the living hurt event and check for that damage source. I think in 1.7.10 you might get the most control by actually replacing the vanilla lightning bolt entity with your own, but that might require a lot of coding (or at least copying). You're also right that it is bad that the fire field in Entity doesn't have a getter function (someone should submit a PR for this), while it does have a setter function. As diesieben07 mentions you should probably use reflection, but theoretically since there is a setter function you could create your own field to keep track of what it should be and call the setter function. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/ Link to comment Share on other sites More sharing options...
IceMetalPunk Posted December 14, 2015 Author Share Posted December 14, 2015 Sadly, the setFire() method doesn't work as you'd expect; it doesn't allow you to increase the value of the member, only decrease it. And in the case of lightning, the value needs to be increased, so I can't use the setter that comes with the Entity class. I'm looking into reflection, but I'm not quite sure I understand how it works. Looking online at some examples, I tried this code to change the fire field from private to public, but I ended up getting a NoSuchField exception for "fire", even though Entity#fire is definitely a member: /* Reflection to change private members to public for access */ try { // Get Entity#fire field and make it accessible Field fireField=Entity.class.getField("fire"); fireField.setAccessible(true); // Make modifiers accessible Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); // Change the modifiers on the fire field to make it public and not private. try { modifiersField.setInt(fireField, (fireField.getModifiers() & ~Modifier.PRIVATE) | Modifier.PUBLIC); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } Am I not understanding something about how reflection works? Quote Whatever Minecraft needs, it is most likely not yet another tool tier. Link to comment Share on other sites More sharing options...
RANKSHANK Posted December 14, 2015 Share Posted December 14, 2015 Oh boy if there wasn't enough help needed before, there will be soon Field fireField=Entity.class.getField("fire"); Fire is a private field and therefore is only accessible with Class.getDeclaredField(String) Also note that when the code is recompiled it'll stop working since the field names are reverted to their obfuscated variants. Secondly you need an object to grab local variables from. You need an entity and then you need to invoke the set(Object targetInstance, Object newValue) method with your now accessible field. And that's about it. I'm not following why you need to change the burntime on entities struck by lightning though Quote I think its my java of the variables. Link to comment Share on other sites More sharing options...
IceMetalPunk Posted December 14, 2015 Author Share Posted December 14, 2015 Oh boy if there wasn't enough help needed before, there will be soon Field fireField=Entity.class.getField("fire"); Fire is a private field and therefore is only accessible with Class.getDeclaredField(String) Also note that when the code is recompiled it'll stop working since the field names are reverted to their obfuscated variants. Secondly you need an object to grab local variables from. You need an entity and then you need to invoke the set(Object targetInstance, Object newValue) method with your now accessible field. And that's about it. I'm not following why you need to change the burntime on entities struck by lightning though Ah, sorry, as I said, I have absolutely zero experience with reflection in any language >_< I need to change the burntime because lightning does that already. I want everything to be exactly like the vanilla lightning, except with the DamageSource coming from my custom electricity type instead of fire damage. So I've had to cancel the entire event and replace it with my own, as there doesn't seem to be a way to simply change that source (if there is, please let me know; it'd be much easier). So I've managed to make everything error-free, but I can't seem to test it to see if it works. I have this test code that should summon a lightning bolt at the player's position when a block is right-clicked: @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float px, float py, float pz) { world.addWeatherEffect(new EntityLightningBolt(world, px, py, pz)); return true; } When I right-click it, I get the sky flashing and sound effects, but the lightning bolt itself doesn't appear. Quote Whatever Minecraft needs, it is most likely not yet another tool tier. Link to comment Share on other sites More sharing options...
IceMetalPunk Posted December 16, 2015 Author Share Posted December 16, 2015 So, I've tried many nuances of the above code, even trying to spawn lightning bolts in directly with World#spawnEntityInWorld, but nothing seems to work. I always get the proper flashing sky and sound effect, but the lightning bolt itself never appears at all. Is there something more I need to do besides just adding to the weather effects list in order to get lightning? Quote Whatever Minecraft needs, it is most likely not yet another tool tier. Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.