From 9b5ddb87f542c3e1202f9c26f5ea2016de3c8ce7 Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Tue, 6 May 2025 19:24:26 +0200 Subject: [PATCH] Fix brains, borgs etc not counting as marooned (#37148) * init * comments * comment * no more debug --- .../Systems/KillPersonConditionSystem.cs | 6 +-- Content.Server/Silicons/Borgs/BorgSystem.cs | 6 +++ Content.Server/Zombies/ZombieSystem.cs | 6 +++ Content.Shared/Mind/SharedMindSystem.cs | 47 +++++++++++++++++++ 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/Content.Server/Objectives/Systems/KillPersonConditionSystem.cs b/Content.Server/Objectives/Systems/KillPersonConditionSystem.cs index 012fb80f76..9c8fa0b335 100644 --- a/Content.Server/Objectives/Systems/KillPersonConditionSystem.cs +++ b/Content.Server/Objectives/Systems/KillPersonConditionSystem.cs @@ -39,7 +39,7 @@ public sealed class KillPersonConditionSystem : EntitySystem return 1f; var targetDead = _mind.IsCharacterDeadIc(mind); - var targetOnShuttle = _emergencyShuttle.IsTargetEscaping(mind.OwnedEntity.Value); + var targetMarooned = !_emergencyShuttle.IsTargetEscaping(mind.OwnedEntity.Value) || _mind.IsCharacterUnrevivableIc(mind); if (!_config.GetCVar(CCVars.EmergencyShuttleEnabled) && requireMaroon) { requireDead = true; @@ -55,11 +55,11 @@ public sealed class KillPersonConditionSystem : EntitySystem // If the shuttle hasn't left, give 50% progress if the target isn't on the shuttle as a "almost there!" if (requireMaroon && !_emergencyShuttle.ShuttlesLeft) - return targetOnShuttle ? 0f : 0.5f; + return targetMarooned ? 0.5f : 0f; // If the shuttle has already left, and the target isn't on it, 100% if (requireMaroon && _emergencyShuttle.ShuttlesLeft) - return targetOnShuttle ? 0f : 1f; + return targetMarooned ? 1f : 0f; return 1f; // Good job you did it woohoo } diff --git a/Content.Server/Silicons/Borgs/BorgSystem.cs b/Content.Server/Silicons/Borgs/BorgSystem.cs index 82e247cb0b..7c096f1729 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.cs @@ -72,6 +72,7 @@ public sealed partial class BorgSystem : SharedBorgSystem SubscribeLocalEvent(OnPowerCellChanged); SubscribeLocalEvent(OnPowerCellSlotEmpty); SubscribeLocalEvent(OnGetDeadIC); + SubscribeLocalEvent(OnGetUnrevivableIC); SubscribeLocalEvent(OnToggled); SubscribeLocalEvent(OnBrainMindAdded); @@ -218,6 +219,11 @@ public sealed partial class BorgSystem : SharedBorgSystem args.Dead = true; } + private void OnGetUnrevivableIC(EntityUid uid, BorgChassisComponent component, ref GetCharacterUnrevivableIcEvent args) + { + args.Unrevivable = true; + } + private void OnToggled(Entity ent, ref ItemToggledEvent args) { var (uid, comp) = ent; diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index 054bd0f6ec..8f8dd36ad4 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -66,6 +66,7 @@ namespace Content.Server.Zombies SubscribeLocalEvent(OnZombieCloning); SubscribeLocalEvent(OnSleepAttempt); SubscribeLocalEvent(OnGetCharacterDeadIC); + SubscribeLocalEvent(OnGetCharacterUnrevivableIC); SubscribeLocalEvent(OnMindAdded); SubscribeLocalEvent(OnMindRemoved); @@ -168,6 +169,11 @@ namespace Content.Server.Zombies args.Dead = true; } + private void OnGetCharacterUnrevivableIC(EntityUid uid, ZombieComponent component, ref GetCharacterUnrevivableIcEvent args) + { + args.Unrevivable = true; + } + private void OnStartup(EntityUid uid, ZombieComponent component, ComponentStartup args) { if (component.EmoteSoundsId == null) diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index ab17a4221e..de8d4f0567 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -253,6 +253,24 @@ public abstract partial class SharedMindSystem : EntitySystem return _mobState.IsDead(mind.OwnedEntity.Value, targetMobState); } + /// + /// True if the OwnedEntity of this mind is physically unrevivable. + /// This is mainly to check whether a mind is able to inherit their "original" character again without the need for creating a new one. + /// In cases of being a brain, being borged or a zombie they are "unrevivable" + /// + public bool IsCharacterUnrevivablePhysically(MindComponent mind) + { + if (mind.OwnedEntity == null) + return true; + + // This entity cannot be dead, alive or crit, so it makes sense it cannot be revived to begin with. + if (!HasComp(mind.OwnedEntity)) + return true; + + // Could use checks for the amount of damage they have, but with chemistry you can never tell what damage means someone is truly "unrevivable". + return false; + } + public virtual void Visit(EntityUid mindId, EntityUid entity, MindComponent? mind = null) { } @@ -556,6 +574,27 @@ public abstract partial class SharedMindSystem : EntitySystem return IsCharacterDeadPhysically(mind); } + /// + /// True if this Mind is 'sufficiently unrevivable' IC (Objectives, EndText). + /// Note that this is *IC logic*, it's not necessarily tied to any specific truth. + /// "If administrators decide that zombies are unrevivable, this returns true for zombies." + /// Alternative IsCharacterDeadIC that checks for whether they will be able to inherit their body again. + /// State in which they must be given a new body to "live" (borging, being a brain, etc) should count as "unrevivable". + /// + public bool IsCharacterUnrevivableIc(MindComponent mind) + { + if (mind.OwnedEntity is { } owned) + { + var ev = new GetCharacterUnrevivableIcEvent(null); + RaiseLocalEvent(owned, ref ev); + + if (ev.Unrevivable != null) + return ev.Unrevivable.Value; + } + + return IsCharacterUnrevivablePhysically(mind); + } + /// /// A string to represent the mind for logging /// @@ -602,3 +641,11 @@ public abstract partial class SharedMindSystem : EntitySystem /// [ByRefEvent] public record struct GetCharactedDeadIcEvent(bool? Dead); + +/// +/// Raised on an entity to determine whether or not they are "unrevivable" in IC-logic. +/// Used to check for things such as being borged or a zombie. +/// +/// +[ByRefEvent] +public record struct GetCharacterUnrevivableIcEvent(bool? Unrevivable);