Solved Indestructible Items - Lava

Discussion in 'Plugin Development' started by NathanWolf, Jan 3, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    NathanWolf

    Searching seems to suggest this is impossible, but does anyone know any tricks to making a dropped item indestructible?

    I'm specifically having a problem with lava. I can prevent an Item from despawning, I can prevent most damage (fire, explosions)- but if the item falls in lava, it seems to be impossible to prevent it from being destroyed.

    Am I missing anything?
     
  2. Offline

    Jogy34

    If you wanted to go into NMS you could create your own item entities which aren't affected by lava. That might be kinda difficult to sync in depending on what you're doing with them though.
     
    NathanWolf likes this.
  3. Offline

    JRL1004

    NathanWolf There is a way using NMS I am looking into for you. It turns out that in Minecraft all entities has the option of being 100% invulnerable. This is stored as an NBTTagCompound. As of right now, I am looking into the code to force an entity into immortality.
     
  4. Offline

    Jogy34


    Oh yeah. In the top most NBTTag you would just set "Invulnerable" to true.
     
    NathanWolf likes this.
  5. Offline

    JRL1004

    There is a method ("e") in EntityItem that uses an NBTTagCompound to set an entity as being invulnerable. I am not sure if this helps you but if it does then at least I did something.
     
    NathanWolf likes this.
  6. Offline

    sgavster

    I'd like to know also, seems nice to do :p
     
  7. Offline

    JRL1004

    Jogy34 sgavster If either of you can tell me how to get a value from a class using reflection that would be nice. I have tried to use Field _f = net.minecraft.<otherstuff>.class.getDeclaringField("invulnerable") [since that is the name of the variable] but after getting the field I have been unable to set it back. I feel as if I am doing something wrong :/
     
  8. Offline

    NathanWolf

    JRL1004 Jogy34 Thanks guys! That's awesome! Exactly what I was looking for.

    Here are the classes I use to do this: InventoryUtils and NMSUtils

    And the relevant bits of code here, using reflection for your pleasure:

    Code:java
    1. protected static Object getHandle(org.bukkit.entity.Entity entity) {
    2. Object handle = null;
    3. try {
    4. Method handleMethod = entity.getClass().getMethod("getHandle");
    5. handle = handleMethod.invoke(entity);
    6. } catch (Throwable ex) {
    7. ex.printStackTrace();
    8. }
    9. return handle;
    10. }
    11.  
    12. public static void setInvulnerable(Entity entity) {
    13. try {
    14. Object handle = getHandle(entity);
    15. Field invulnerableField = class_Entity.getDeclaredField("invulnerable");
    16. invulnerableField.setAccessible(true);
    17. invulnerableField.set(handle, true);
    18. } catch (Exception ex) {
    19. ex.printStackTrace();
    20. }
    21. }


    I put this in a handler for ItemSpawnEvent, and it does exactly what I want. No more losing my wand when I die in lava!

    Thanks very much :D

    EDIT: I left out the parts of code where I get class_Entity, but it's the sort of boilerplate NMS "get a class from the CB version#" trickery I'm sure you've seen before.
     
    sgavster likes this.
  9. Offline

    Jogy34

    Why are you using reflection to use the getHandle() method, it's public:


    Nevermind, you're trying to make it version independent, which you really shouldn't do but whatever.
     
  10. Offline

    NathanWolf


    I know it's not strictly safe, but generally I just try to avoid using anything obfuscated. I figure things like "getHandle" and "invulnerable" aren't going to change their meaning anytime soon.

    I had to abandon plugin development for a few years due to a job change- I don't like the idea of my plugins having a self-destruct timer on them. :)
     
Thread Status:
Not open for further replies.

Share This Page