Fix damage desyncing entity from chest node, making it invisible #3385
No reviewers
Labels
No Label
#P1 CRITICAL
#P2: HIGH
#P3: elevated
#P4 priority: medium
#P6: low
#Review
annoying
API
bug
code quality
combat
commands
compatibility
configurability
contribution inside
controls
core feature
creative mode
delayed for engine release
documentation
duplicate
enhancement
environment
gameplay
graphics
ground content conflict
GUI/HUD
help wanted
incomplete feature
invalid / won't fix
items
looking for contributor
mapgen
meta
mineclone2+
Minecraft >= 1.13
Minecraft >= 1.17
missing feature
mobile
mobs
mod support
model needed
multiplayer
Needs adoption
needs discussion
needs engine change
needs more information
needs research
nodes
non-Minecraft feature
non-mob entities
performance
player
possible close
redstone
release notes
schematics
Skyblock
sounds
Testing / Retest
tools
translation
unconfirmed
mcl5
mcla
Media missing
No Milestone
No project
No Assignees
5 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: VoxeLibre/VoxeLibre#3385
Loading…
Reference in New Issue
No description provided.
Delete Branch "emptyshore/MineClone2:fix-lightning-chests"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Each chest node has an associated entity, which presumably is used for
animation. This makes chests distinctly different from e.g. barrels.
This special behaviour means chest entity (which is NOT the chest node)
can desync from node. This occurs when entity is damaged and destroyed
for example by lightning or anvil, which makes the chest disappear
visually (with the node still persisting).
This patch makes chest entity ignore the damage.
Testing
Method 1, lightning:
Method 2, anvil:
6ef34f1c7d
tocb549473d0
cb549473d0
to765b4b8fbc
Checked TNT still explodes the chest and makes it drop items.
it destroys the entity, and that causes it to disappear. it's not textures. And, when you open it, it recreates the entity. At least, that's how I understand it. @MrRar would know more on it.
What you said sounds right to me.
I wonder why the damage groups are being ignored. That does not seem right. I bet this affects more then chests.
@MrRar @Michieal thanks for looking, will have a look at the damage groups!
Edit: as far as I can see, damage groups don't apply here, they are a higher-level abstraction. They apply to tools, players and mobs and Chest entity isn't one of these (neither is lightning). Kinda similar example is the berry bush which deals dmg directly, just as the lightning:
mcl_util.deal_damage is really rudimentary and low level - it seems to largely just decrease HP, but makes a special case for mobs (n/a here). It also checks for handler on entity, but that isn't used anywhere in the codebase (unless I failed search).
My possibly flawed reasoning behind the change is that the chest entity does not represent the chest (node does), so we really shouldn't let it take damage like this at all. Therefore using a NOP hook seems "correct", but I'm happy to redo the PR :)
765b4b8fbc
to6eaa2ac031
Oh also, anvil does the same (anything doing
mcl_util.deal_damage
on a non-player, non-mob entity will cause this). Also bypasses damage groups.Added animated gif to MineClone2/MineClone2#3389
This PR fixes #3389
You didn't need to make an Issue for the Pull Request. In fact, if you don't know how to set it so that the PR closes the issue, it's really an annoying thing, because then we have to find the orphaned issue.
You can discuss things in the PR, including other "errors" or "bugs found". And, it's best to keep all of the information together in one spot, so that it's at hand for reference.
in fact, you should probably go close the issue, so that everything is here...
Fix lightning desynchronising entity from chest nodeto Fix damage desynchronising entity from chest nodePR as good as an issue, point taken, will close the issue.
6eaa2ac031
to805e6bf674
Fix damage desynchronising entity from chest nodeto Fix damage desyncing entity from chest node, making it invisibleYou're probably mostly done with this, but...
In the code for Item Frames and Signs (both) I created a "clearobjects fix" (the link is here) that might help.
Both are nodes with entities attached... just like chests are. Most... modules that create a node with an entity attached have some way of refreshing the entity (as it is required on load / start) in order for it to display properly.
It looks like the chests was opening them. For signs, it was punching them. Sorry that I did not remember this sooner. If you look in the on_rightclick() you should see a function called "update"-something. That would be the thing to put into the chest entity's on_damage callback. The idea being that every time it takes damage, it resets itself via the update function.
The plot thickens :) Turns out signs are also affected - you can wipe out the text with two lightnings (same technique, just plop a rod next to it, two because lightning has 5 dmg, and I think default entity HP is 10). Writing comes back after punching the sign. Anvil destroys the sign though.
Just tested the following in MC:
Some other notes from the chat:
There is actually two problems bundled together, I think:
This:
Is because on load (the LBM calls this) the entities are recreated but their respective Update functions. (I know this, because I rewrote the sign and the item frames.)
All chests will be affected by this, as well as all other node/entitiy combinations. (Chest, signs, item frames are an example of what I mean by this.)
^ This could be applied to the entity...
This is the callback when the entity "dies"... placing the update function in here would cause it to immediately be "resurrected"... may or may not be called when
/clearobjects
is called.We could, but would explosions still be able to affect chests (as they should) if they're "immortal"?
Yes. Explosions interact with the chest node. When the chest node is removed so will the chest entity.
@emptyshore
Please make mcl_util.deal_damage() do no damage to ObjectRefs that have the immortal damage group. All Minetest mods assume that ObjectRefs with the immortal damage group can't be removed.
As a bonus you could remove the no-op deal_damage callbacks from node entites.
Thanks for working on this!
805e6bf674
tof0d0880e68
f0d0880e68
to0b77396106
Added, but one thing to decide is if we should still call the
deal_damage
handler even if the entity is set to immortal?It's a handler that was added in
ce0148d9a8
and I don't think it has ever been used inside the MCL2 codebase, but it could be used by mods.I've put the "simple" case in, where "immortal" prevents the handler from firing, but I think this could perhaps break some downstream mods that rely on deal_damage? Happy to rewrite so that it checks for the handler's existence before checking for immortality.
Other things: chests, signs and frames already configure the entities to be immortal, so no need for changes there! TNT has it's own separate routine, so still explodes the node-entities fine. Anything else to check for?
0b77396106
tobadc247678
Turns out all mobs are immortal :-) In mcl_mobs/api.txt:
So as a result of this change, fire, anvils, etc no longer damages mobs... uh.
Whoops! I was going to say, I thought that I remembered Iron Golems having "Immortal=1" on them, too. I guess that they do.
Maybe make another armor group? like
non_mob_entity
?I think you should add the immortal armor group check before:
target:set_hp(hp - damage, {_mcl_reason = mcl_reason})
I tested it myself and it seems to work.
Moving it will work, but it feels like a leaky abstraction. If we take a step back,
deal_damage
andget_hp
seem to be intended as simple wrappers to support redirection for the custom mob damage handling (using health instead of core hp). Hijacking it for immortality check might surprise someone down the line :)What is odd to me is that the entity is destroyed even though its armor group is set to immortal. Shouldn't minetest engine not kill it in that case?
I couldn't find the spot where the entity is killed when HP reaches 0 - do you know where to find it? Is it in MT core cpp files somewhere?
I'm not sure what you mean. get_hp gets the Minetest entity HP.
The damage groups are only respected by the default punch handeling and mods that want to respect damage groups.
Minetest automatically removes any entities with HP of 0
I don't know what the purpose of the
if hp > 0 then
check is.The problem is that third party mobs will not be affected by deal_damage() because they are using a custom HP system like MCL2 mobs.
One thing I haven't tested but I bet it would be better than target:set_hp() is target:punch(). I am talking about the code that is commented out in the mob damage area.
The default punch handling respects damage groups including immortal. It can also deal damage to mobs that have a custom HP system.
I don't know why the MCL2 mobs aren't using the punching mechanism.
badc247678
to17a91fc381
17a91fc381
to8d1a926dc9
Can't figure out either why target:punch code is commented out. Maybe it was causing infinite loops if on_punch was calling deal_damage? After cursory search, I don't see any obvious places where this would happen though.
Immortal is kinda special, because it's checked for in minetest I think (but not for entities). I think philosophically (lol) minetest should not wipe out immortal entities - if we agree this is the case, then patching it over in deal_damage would be the right thing to do (updated the PR).
I'll try commenting out the punch code and see what happens - but anyway, I don't think that part is relevant to this PR.
8d1a926dc9
tobdc82b76b5
I've tried out the punch code that's commented out in
mcl_util.deal_damage
, and it seemed to work ok (but unrelated so shouldn't be bundled here). Is anything else I need to do here to make the PR acceptable for fixing disappearing node entities?Well, all that I can say is... things are in there for a reason (or removed for one). That said, the reason could be a work-around for a previous minetest version (that is no longer relevant), because the author didn't know any better, because doing so fixes another problem, or something like "tech-debt"... All of these things exist in the code base. It's our job to find them and fix them so that they work correctly.
In other nodes with attached entities, on_punch() was used to refresh them. Not that any player knows about this. I mean, I didn't until I tracked down what on_punch in signs did, when I made it into an API.
Sometimes it's better to cure the ultimate problem instead of curing the symptom.
Do what you want to do. I am not the ultimate authority.
I think that they are confused / lost as to what the root problem is.
You are the closest to an authority on chests that we have, as the rest of us haven't touched the code. Well, maybe epCode too; but I don't know how busy they are. If you're asking me about it, I can look and say, "Yep! It's a chest alright!" lmao.
I'd say I understand the problem, but I don't know how you want to progress. I've proposed two solutions so far. Am I looking for a third solution? Do you want me to clean something up? Should I be looking for why minetest core does not respect
immortal
in this case (I'm not sure if I am able to fix up upstream though)? Should I be looking for why the on_punch is commented out (which is unrelated and won't fix this?)What's the next step I need to do?
I think there is a wider and more complex problem here, and mobs do need plenty of work. I will be focussing on them in future, and will refer back to this stuff so it isn't forgotten, but I don't know the best way yet. I think it's probably a bit tricky for a first issue though.
I appreciate the context and the investigation into this very strange bug. I have tested and it does work. Thanks for picking it up, emptyshore!