Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded throwables are unembedded when the parent entity is destroyed #32707

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

Centronias
Copy link
Contributor

@Centronias Centronias commented Oct 9, 2024

BUT it only applies to entities which emit a DestructionEventArgs or BeingGibbedEvent when they're destroyed.

About the PR

Tracks projectiles embedded in an object, and un-embeds them when either [] is raised on the object (presently just before they're deleted).

Why / Balance

Fixes #22823

Technical details

  • Added HasProjectilesEmbeddedComponent, which is applied to objects when a projectile is embedded in them
    • this component tracks the EntityUids of the objects that're embedded
  • Split the code that's used to remove embedded objects manually into one function which preserves that functionality, and a new function which reuses 99% of the implementation of that functionality to be able to arbitrarily un-embed objects at will.
    • the un-embedding function now additionally checks that the object is, in fact, embedded in something by looking for itself in its parent's HasProjectilesEmbeddedComponent.
  • Added two event subscriptions to Server's ProjectileSystem which checks an entity for children with EmbeddableProjectile, and uses this shared un-embedding code to unembed them.
    • This is run when an entity with HasProjectilesEmbeddedComponent has either DestructionEventArgs or BeingGibbedEvent raised
  • Tweaks to exactly how we call the embedding code such that embedding (hopefully) happens before destruction
    • Before I added this, I was running into nondeterministic behavior where different objects would survive or not when thrown at water tanks (eg. spear didn't, but plasma spear did -- quite weird)

Known Issues

In general, there're still a ton of cases where an embedded object will be destroyed when its parent id deleted. This is because there're so many cases where entities are just deleted or enqueued for deletion without raising any events to hook in some "pls drop embedded stuff before you die" logic. However, I think a great many of these are relatively violent in-game events (eg. gas canisters exploding due to overpressurization) that it won't be quite so noticeable.
The only solution I can think of for this would be to do some kind of audit of all places where things're deleted and make sure there's some generic "entity is being removed from game due to 'IC' reasons" event so that a hook can be implemented to react to it.
("IC reasons" as opposed to things like particle effects ending, admin deletion, etc.)

Because I only order embedding to occur before Destructible destruction, it's conceivable there's some case where something that'd embed in a body will gib it in the same interaction, and that'll have the same projectile-deleting effect. But, I figure that that's a markedly rarer case that's not worth adding a bunch of additional before: [ ... ] conditions for.
I will leave it to the wisdom of the reviewers.

Media

unembed-all.mp4
Old revision media
LeReusableSpear.mp4

@YotaXP 's mouse-eating case:

eatmousedropsknife.mp4

Requirements

Breaking changes

None? Possibly something coming from the system ordering?
Added public method to ProjectileSystemShared to unembed Entity<EmbeddableProjectileComponent>?

Changelog
🆑

  • fix: Destroying objects with projectiles stuck to them will now leave the projectiles on the ground rather than deleting them.

…e objects are destroyed

BUT it only applies to objects with Destructible or Body (when they're gibbed)
@YotaXP
Copy link

YotaXP commented Oct 9, 2024

Eating a mouse with an embedded item still deletes the item. (This happened in a round recently which is why I thought of it. lol)

Content.Server/Projectiles/ProjectileSystem.cs Outdated Show resolved Hide resolved
Content.Server/Projectiles/ProjectileSystem.cs Outdated Show resolved Hide resolved
- component to track embedded objects on embeddee
- unembed checks for said component on parent
@github-actions github-actions bot added the Status: Needs Review This PR requires new reviews before it can be merged. label Oct 14, 2024
Copy link

@YotaXP YotaXP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't say I'm familiar enough with the codebase at this time to give a proper review (my computer is too potato to even work in it), but I'll do what I can with my general C# knowledge.

Content.Server/Projectiles/ProjectileSystem.cs Outdated Show resolved Hide resolved
Content.Shared/Projectiles/SharedProjectileSystem.cs Outdated Show resolved Hide resolved
@github-actions github-actions bot added the Merge Conflict This PR currently has conflicts that need to be addressed. label Oct 22, 2024
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the Merge Conflict This PR currently has conflicts that need to be addressed. label Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Needs Review This PR requires new reviews before it can be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

embeddable throwables get destroyed when their parent dies
3 participants