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;
// 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
}
SubscribeLocalEvent<BorgChassisComponent, PowerCellChangedEvent>(OnPowerCellChanged);
SubscribeLocalEvent<BorgChassisComponent, PowerCellSlotEmptyEvent>(OnPowerCellSlotEmpty);
SubscribeLocalEvent<BorgChassisComponent, GetCharactedDeadIcEvent>(OnGetDeadIC);
+ SubscribeLocalEvent<BorgChassisComponent, GetCharacterUnrevivableIcEvent>(OnGetUnrevivableIC);
SubscribeLocalEvent<BorgChassisComponent, ItemToggledEvent>(OnToggled);
SubscribeLocalEvent<BorgBrainComponent, MindAddedMessage>(OnBrainMindAdded);
args.Dead = true;
}
+ private void OnGetUnrevivableIC(EntityUid uid, BorgChassisComponent component, ref GetCharacterUnrevivableIcEvent args)
+ {
+ args.Unrevivable = true;
+ }
+
private void OnToggled(Entity<BorgChassisComponent> ent, ref ItemToggledEvent args)
{
var (uid, comp) = ent;
SubscribeLocalEvent<ZombieComponent, CloningEvent>(OnZombieCloning);
SubscribeLocalEvent<ZombieComponent, TryingToSleepEvent>(OnSleepAttempt);
SubscribeLocalEvent<ZombieComponent, GetCharactedDeadIcEvent>(OnGetCharacterDeadIC);
+ SubscribeLocalEvent<ZombieComponent, GetCharacterUnrevivableIcEvent>(OnGetCharacterUnrevivableIC);
SubscribeLocalEvent<ZombieComponent, MindAddedMessage>(OnMindAdded);
SubscribeLocalEvent<ZombieComponent, MindRemovedMessage>(OnMindRemoved);
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)
return _mobState.IsDead(mind.OwnedEntity.Value, targetMobState);
}
+ /// <summary>
+ /// 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"
+ /// </summary>
+ 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<MobStateComponent>(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)
{
}
return IsCharacterDeadPhysically(mind);
}
+ /// <summary>
+ /// 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".
+ /// </summary>
+ 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);
+ }
+
/// <summary>
/// A string to represent the mind for logging
/// </summary>
/// <param name="Dead"></param>
[ByRefEvent]
public record struct GetCharactedDeadIcEvent(bool? Dead);
+
+/// <summary>
+/// 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.
+/// </summary>
+/// <param name="Unrevivable"></param>
+[ByRefEvent]
+public record struct GetCharacterUnrevivableIcEvent(bool? Unrevivable);