You can now return to a brain. Also, clean up terrible console misuse. (#4092)

* You can now return to a brain. Also, clean up terrible console misuse.

* Get rid of Obsolete attribute on Ghost.Execute
This commit is contained in:
20kdc
2021-06-03 09:03:19 +01:00
committed by GitHub
parent 96d808d9fa
commit 2f821f2bc3
6 changed files with 36 additions and 24 deletions

View File

@@ -7,6 +7,7 @@ using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.Chat; using Content.Server.Interfaces.Chat;
using Content.Server.Interfaces.GameObjects; using Content.Server.Interfaces.GameObjects;
using Content.Server.Interfaces.GameTicking;
using Content.Server.Players; using Content.Server.Players;
using Content.Server.Utility; using Content.Server.Utility;
using Content.Shared.Damage; using Content.Shared.Damage;
@@ -69,8 +70,10 @@ namespace Content.Server.Commands.Chat
return; return;
var chat = IoCManager.Resolve<IChatManager>(); var chat = IoCManager.Resolve<IChatManager>();
var owner = player.ContentData()?.Mind?.OwnedComponent?.Owner; var mind = player.ContentData()?.Mind;
var owner = mind?.OwnedComponent?.Owner;
// This check also proves mind not-null for at the end when the mob is ghosted.
if (owner == null) if (owner == null)
{ {
shell.WriteLine("You don't have a mind!"); shell.WriteLine("You don't have a mind!");
@@ -121,9 +124,9 @@ namespace Content.Server.Commands.Chat
dmgComponent.SetDamage(DamageType.Piercing, 200, owner); dmgComponent.SetDamage(DamageType.Piercing, 200, owner);
// Prevent the player from returning to the body. Yes, this is an ugly hack. // Prevent the player from returning to the body.
var ghost = new Ghost(){CanReturn = false}; // Note that mind cannot be null because otherwise owner would be null.
ghost.Execute(shell, argStr, Array.Empty<string>()); IoCManager.Resolve<IGameTicker>().OnGhostAttempt(mind!, false);
} }
} }
} }

View File

@@ -1,4 +1,5 @@
#nullable enable #nullable enable
using System;
using Content.Server.Administration; using Content.Server.Administration;
using Content.Server.Interfaces.GameTicking; using Content.Server.Interfaces.GameTicking;
using Content.Server.Players; using Content.Server.Players;
@@ -14,7 +15,6 @@ namespace Content.Server.Commands.Observer
public string Command => "ghost"; public string Command => "ghost";
public string Description => "Give up on life and become a ghost."; public string Description => "Give up on life and become a ghost.";
public string Help => "ghost"; public string Help => "ghost";
public bool CanReturn { get; set; } = true;
public void Execute(IConsoleShell shell, string argStr, string[] args) public void Execute(IConsoleShell shell, string argStr, string[] args)
{ {
@@ -32,7 +32,7 @@ namespace Content.Server.Commands.Observer
return; return;
} }
if (!IoCManager.Resolve<IGameTicker>().OnGhostAttempt(mind, CanReturn)) if (!IoCManager.Resolve<IGameTicker>().OnGhostAttempt(mind, true))
{ {
shell?.WriteLine("You can't ghost right now."); shell?.WriteLine("You can't ghost right now.");
return; return;

View File

@@ -2,6 +2,8 @@
using System; using System;
using Content.Server.Commands.Observer; using Content.Server.Commands.Observer;
using Content.Server.GameObjects.Components.Observer; using Content.Server.GameObjects.Components.Observer;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.GameObjects.Components.Body; using Content.Shared.GameObjects.Components.Body;
using Content.Shared.GameObjects.Components.Body.Part; using Content.Shared.GameObjects.Components.Body.Part;
@@ -28,6 +30,7 @@ namespace Content.Server.GameObjects.Components.Body
public class BodyComponent : SharedBodyComponent, IRelayMoveInput, IGhostOnMove public class BodyComponent : SharedBodyComponent, IRelayMoveInput, IGhostOnMove
{ {
private Container _partContainer = default!; private Container _partContainer = default!;
[Dependency] private readonly IGameTicker _gameTicker = default!;
protected override bool CanAddPart(string slotId, IBodyPart part) protected override bool CanAddPart(string slotId, IBodyPart part)
{ {
@@ -92,11 +95,11 @@ namespace Content.Server.GameObjects.Components.Body
void IRelayMoveInput.MoveInputPressed(ICommonSession session) void IRelayMoveInput.MoveInputPressed(ICommonSession session)
{ {
if (Owner.TryGetComponent(out IMobStateComponent? mobState) && if (Owner.TryGetComponent(out IMobStateComponent? mobState) &&
mobState.IsDead()) mobState.IsDead() &&
Owner.TryGetComponent(out MindComponent? mind) &&
mind.HasMind)
{ {
var host = IoCManager.Resolve<IServerConsoleHost>(); _gameTicker.OnGhostAttempt(mind.Mind!, true);
new Ghost().Execute(new ConsoleShell(host, session), string.Empty, Array.Empty<string>());
} }
} }

View File

@@ -1,7 +1,7 @@
#nullable enable #nullable enable
using System; using System;
using Content.Server.Commands.Observer;
using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Mobs;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.GameObjects.Components.Movement; using Content.Shared.GameObjects.Components.Movement;
using Robust.Server.Console; using Robust.Server.Console;
using Robust.Shared.Console; using Robust.Shared.Console;
@@ -17,6 +17,7 @@ namespace Content.Server.GameObjects.Components.Observer
public class GhostOnMoveComponent : Component, IRelayMoveInput, IGhostOnMove public class GhostOnMoveComponent : Component, IRelayMoveInput, IGhostOnMove
{ {
public override string Name => "GhostOnMove"; public override string Name => "GhostOnMove";
[Dependency] private readonly IGameTicker _gameTicker = default!;
[DataField("canReturn")] public bool CanReturn { get; set; } = true; [DataField("canReturn")] public bool CanReturn { get; set; } = true;
@@ -26,8 +27,7 @@ namespace Content.Server.GameObjects.Components.Observer
if (Owner.HasComponent<VisitingMindComponent>()) return; if (Owner.HasComponent<VisitingMindComponent>()) return;
if (!Owner.TryGetComponent(out MindComponent? mind) || !mind.HasMind || mind.Mind!.IsVisitingEntity) return; if (!Owner.TryGetComponent(out MindComponent? mind) || !mind.HasMind || mind.Mind!.IsVisitingEntity) return;
var host = IoCManager.Resolve<IServerConsoleHost>(); _gameTicker.OnGhostAttempt(mind.Mind!, CanReturn);
new Ghost().Execute(new ConsoleShell(host, session), string.Empty, Array.Empty<string>());
} }
} }
} }

View File

@@ -48,15 +48,19 @@ namespace Content.Server.GameTicking
} }
var position = playerEntity?.Transform.Coordinates ?? IoCManager.Resolve<IGameTicker>().GetObserverSpawnPoint(); var position = playerEntity?.Transform.Coordinates ?? IoCManager.Resolve<IGameTicker>().GetObserverSpawnPoint();
var canReturn = false; // Ok, so, this is the master place for the logic for if ghosting is "too cheaty" to allow returning.
// There's no reason at this time to move it to any other place, especially given that the 'side effects required' situations would also have to be moved.
// + If CharacterDeadPhysically applies, we're physically dead. Therefore, ghosting OK, and we can return (this is critical for gibbing)
// Note that we could theoretically be ICly dead and still physically alive and vice versa.
// (For example, a zombie could be dead ICly, but may retain memories and is definitely physically active)
// + If we're in a mob that is critical, and we're supposed to be able to return if possible,
/// we're succumbing - the mob is killed. Therefore, character is dead. Ghosting OK.
// (If the mob survives, that's a bug. Ghosting is kept regardless.)
var canReturn = canReturnGlobal && mind.CharacterDeadPhysically;
if (playerEntity != null && canReturnGlobal && playerEntity.TryGetComponent(out IMobStateComponent? mobState)) if (playerEntity != null && canReturnGlobal && playerEntity.TryGetComponent(out IMobStateComponent? mobState))
{ {
if (mobState.IsDead()) if (mobState.IsCritical())
{
canReturn = true;
}
else if (mobState.IsCritical())
{ {
canReturn = true; canReturn = true;
@@ -66,10 +70,6 @@ namespace Content.Server.GameTicking
damageable.SetDamage(DamageType.Asphyxiation, 200, playerEntity); damageable.SetDamage(DamageType.Asphyxiation, 200, playerEntity);
} }
} }
else
{
canReturn = false;
}
} }
var entityManager = IoCManager.Resolve<IEntityManager>(); var entityManager = IoCManager.Resolve<IEntityManager>();

View File

@@ -114,7 +114,13 @@ namespace Content.Server.Mobs
/// (Maybe you were looking for the action blocker system?) /// (Maybe you were looking for the action blocker system?)
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
public bool CharacterDeadIC public bool CharacterDeadIC => CharacterDeadPhysically;
/// <summary>
/// True if the OwnedEntity of this mind is physically dead.
/// This specific definition, as opposed to CharacterDeadIC, is used to determine if ghosting should allow return.
/// </summary>
[ViewVariables]
public bool CharacterDeadPhysically
{ {
get get
{ {