#item entity health
1 messages · Page 1 of 1 (latest)
Yes
Alright so follow this; https://blog.jeff-media.com/nms-use-mojang-mappings-for-your-spigot-plugins/
And simply replace 1.18.2 with 1.19 everywhere
Hello alex 🙂
hi :3 I should update that I guess
Slightly offtopic but the expansion works now after your update
also I saw your comment about it being hard to find if CombatLogX killed a player. I'll see what I can do about that
Thanks
Did you solve everything or do you need help with reading the health?
Well I have never used build tools and I don't have git I need to figure out all that before
BuildTools does everything for you
Download the jar and run java -jar BuildTools.jar --rev 1.19 --remapped
That's it
Git bash is optional
where do I have to run that ? in the plugin folder ?
in the folder with the BuildTools jar
I recommend just making a new folder for that
Did you add everything to your pom?
I'm confused on what I should add, does this replace the spigot that I already have ?
Thanks a lot
Ok looks like my pom is working
what do I have to do to get the nms version of the item entity ?
((CraftItem)item).getHandle();
gives you an NMS entity
where "item" is a bukkit Item
oh nms entities don't have health either
that's crazy to think that all entities have armor slots
but not all have health
how does that make sense
@cursive mulch can you help me please ?
Well not quite
There's a method to get armor slots but it returns an empty list by default
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
health field in ItemEntity
Item item = null; //Bukkit Item Entity
ItemEntity nmsItem = (ItemEntity) ((CraftItem) item).getHandle();
try {
Field privateField = ItemEntity.class.getDeclaredField("health");
privateField.setAccessible(true);
int health = privateField.getInt(nmsItem); //get
privateField.setInt(nmsItem, health); //set
} catch(NoSuchFieldException | IllegalAccessException e) {
//TODO Handle
}
@forest prism
You can store that field somewhere so it doesn't do a look up each time
why do you need the "health" of an item anyway?
java.lang.NoClassDefFoundError: org/bukkit/craftbukkit/v1_19_R1/entity/CraftItem
I want to detect when an item is destroyed
How are you building your jar?
EntityDamageItem
EntityType.DROPPED_ITEM
no need to check any "health" or sth
what's that
entity death event is only called for living entities
and entity damage event is what i'm using but it's called each time the item takes damage not when it dies
so I want to check if damage > health in entitydamageevent
yes
but need health in it
@EventHandler
public void dragonEggDestroyed(EntityDamageEvent event) {
if(event.getEntity() instanceof Item) {
Item item = (Item) event.getEntity();
if(item.getItemStack().getType()==Material.DRAGON_EGG) {
Entity ci = ((CraftItem)item).getHandle();
try {
Field f = Entity.class.getDeclaredField("health");
f.setAccessible(true);
int health = f.getInt(ci);
if(health<=event.getDamage()) {
Bukkit.broadcastMessage("§cDragon egg destroyed.");
}
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}```
That's my code @hollow wadi
hm using the API you could check it a tick later
@EventHandler
public void onDamage(EntityDamageEvent event) {
if(event.getEntityType() == EntityType.DROPPED_ITEM) {
Bukkit.getScheduler().runTask(this, () -> {
if(event.getEntity().isDead()) {
Bukkit.broadcastMessage("Dropped item died: " + event.getEntity());
}
});
}
}
I did that
but for some reasons it's called twice on certain damage types @hollow wadi
if you throw it in fire you will get dropped item died message twice
hm that is weird. yeah then you'll have to use that reflection stuff
and be sure to cache the field instead of getting it every time
I think it's because items can take damage several times in a single tick
very ugly solution:
private final Set<Entity> trackedEntities = new HashSet<>();
@EventHandler
public void onDamage(EntityDamageEvent event) {
if(event.getEntityType() == EntityType.DROPPED_ITEM) {
if(trackedEntities.contains(event.getEntity())) {
return;
}
trackedEntities.add(event.getEntity());
Bukkit.getScheduler().runTask(this, () -> {
if(event.getEntity().isDead()) {
Bukkit.broadcastMessage("Dropped item died: " + event.getEntity());
}
trackedEntities.remove(event.getEntity());
});
}
}
^^ this is probably better than messing around with reflection
I thought about that then thought it was ugly and wanted a better solution
but now that I see how complicated it is
it seems good
thanks a lot
also what does Bukkit.getScheduler().runTask does
how often does it run that and when does it stop
oh it's just like runtasklater(this, () -> {}, 1); ?
yes
Thanks