}
var comp = _entities.GetComponent<GhostComponent>(ghost);
- ghostSystem.SetCanReturnToBody(comp, canReturn);
+ ghostSystem.SetCanReturnToBody((ghost, comp), canReturn);
}
}
if (mind.Comp.TimeOfDeath.HasValue)
{
- SetTimeOfDeath(ghost, mind.Comp.TimeOfDeath!.Value, ghostComponent);
+ SetTimeOfDeath((ghost, ghostComponent), mind.Comp.TimeOfDeath!.Value);
}
- SetCanReturnToBody(ghostComponent, canReturn);
+ SetCanReturnToBody((ghost, ghostComponent), canReturn);
if (canReturn)
_minds.Visit(mind.Owner, ghost, mind.Comp);
{
TransferTo(mindId, visiting, mind: mind);
if (TryComp(visiting, out GhostComponent? ghostComp))
- _ghosts.SetCanReturnToBody(ghostComp, false);
+ _ghosts.SetCanReturnToBody((visiting, ghostComp), false);
return;
}
entity = Spawn(GameTicker.ObserverPrototypeName, position);
component = EnsureComp<MindContainerComponent>(entity.Value);
var ghostComponent = Comp<GhostComponent>(entity.Value);
- _ghosts.SetCanReturnToBody(ghostComponent, false);
+ _ghosts.SetCanReturnToBody((entity.Value, ghostComponent), false);
}
var oldEntity = mind.OwnedEntity;
namespace Content.Shared.Ghost;
+/// <summary>
+/// Represents an observer ghost.
+/// Handles limiting interactions, using ghost abilities, ghost visibility, and ghost warping.
+/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedGhostSystem))]
[AutoGenerateComponentState(true), AutoGenerateComponentPause]
public sealed partial class GhostComponent : Component
// End actions
- [ViewVariables(VVAccess.ReadWrite), DataField, AutoPausedField]
+ /// <summary>
+ /// Time at which the player died and created this ghost.
+ /// Used to determine votekick eligibility.
+ /// </summary>
+ /// <remarks>
+ /// May not reflect actual time of death if this entity has been paused,
+ /// but will give an accurate length of time <i>since</i> death.
+ /// </remarks>
+ [DataField, AutoPausedField]
public TimeSpan TimeOfDeath = TimeSpan.Zero;
- [DataField("booRadius"), ViewVariables(VVAccess.ReadWrite)]
+ /// <summary>
+ /// Range of the Boo action.
+ /// </summary>
+ [DataField]
public float BooRadius = 3;
- [DataField("booMaxTargets"), ViewVariables(VVAccess.ReadWrite)]
+ /// <summary>
+ /// Maximum number of entities that can affected by the Boo action.
+ /// </summary>
+ [DataField]
public int BooMaxTargets = 3;
- // TODO: instead of this funny stuff just give it access and update in system dirtying when needed
- [ViewVariables(VVAccess.ReadWrite)]
- public bool CanGhostInteract
- {
- get => _canGhostInteract;
- set
- {
- if (_canGhostInteract == value) return;
- _canGhostInteract = value;
- Dirty();
- }
- }
-
+ /// <summary>
+ /// Is this ghost allowed to interact with entities?
+ /// </summary>
+ /// <remarks>
+ /// Used to allow admins ghosts to interact with the world.
+ /// Changed by <see cref="SharedGhostSystem.SetCanGhostInteract"/>.
+ /// </remarks>
[DataField("canInteract"), AutoNetworkedField]
- private bool _canGhostInteract;
+ public bool CanGhostInteract;
/// <summary>
- /// Changed by <see cref="SharedGhostSystem.SetCanReturnToBody"/>
+ /// Is this ghost player allowed to return to their original body?
/// </summary>
- // TODO MIRROR change this to use friend classes when thats merged
- [ViewVariables(VVAccess.ReadWrite)]
- public bool CanReturnToBody
- {
- get => _canReturnToBody;
- set
- {
- if (_canReturnToBody == value) return;
- _canReturnToBody = value;
- Dirty();
- }
- }
+ /// <remarks>
+ /// Changed by <see cref="SharedGhostSystem.SetCanReturnToBody"/>.
+ /// </remarks>
+ [DataField, AutoNetworkedField]
+ public bool CanReturnToBody;
/// <summary>
/// Ghost color
/// <remarks>Used to allow admins to change ghost colors. Should be removed if the capability to edit existing sprite colors is ever added back.</remarks>
[DataField, AutoNetworkedField]
public Color Color = Color.White;
-
- [DataField("canReturnToBody"), AutoNetworkedField]
- private bool _canReturnToBody;
}
public sealed partial class ToggleFoVActionEvent : InstantActionEvent { }
args.Cancel();
}
- public void SetTimeOfDeath(EntityUid uid, TimeSpan value, GhostComponent? component)
+ /// <summary>
+ /// Sets the ghost's time of death.
+ /// </summary>
+ public void SetTimeOfDeath(Entity<GhostComponent?> entity, TimeSpan value)
{
- if (!Resolve(uid, ref component))
+ if (!Resolve(entity, ref entity.Comp))
return;
- component.TimeOfDeath = value;
+ if (entity.Comp.TimeOfDeath == value)
+ return;
+
+ entity.Comp.TimeOfDeath = value;
+ Dirty(entity);
}
- public void SetCanReturnToBody(EntityUid uid, bool value, GhostComponent? component = null)
+ [Obsolete("Use the Entity<GhostComponent?> overload")]
+ public void SetTimeOfDeath(EntityUid uid, TimeSpan value, GhostComponent? component)
{
- if (!Resolve(uid, ref component))
+ SetTimeOfDeath((uid, component), value);
+ }
+
+ /// <summary>
+ /// Sets whether or not the ghost player is allowed to return to their original body.
+ /// </summary>
+ public void SetCanReturnToBody(Entity<GhostComponent?> entity, bool value)
+ {
+ if (!Resolve(entity, ref entity.Comp))
+ return;
+
+ if (entity.Comp.CanReturnToBody == value)
return;
- component.CanReturnToBody = value;
+ entity.Comp.CanReturnToBody = value;
+ Dirty(entity);
}
+ [Obsolete("Use the Entity<GhostComponent?> overload")]
+ public void SetCanReturnToBody(EntityUid uid, bool value, GhostComponent? component = null)
+ {
+ SetCanReturnToBody((uid, component), value);
+ }
+
+ [Obsolete("Use the Entity<GhostComponent?> overload")]
public void SetCanReturnToBody(GhostComponent component, bool value)
{
- component.CanReturnToBody = value;
+ SetCanReturnToBody((component.Owner, component), value);
+ }
+
+
+ /// <summary>
+ /// Sets whether the ghost is allowed to interact with other entities.
+ /// </summary>
+ public void SetCanGhostInteract(Entity<GhostComponent?> entity, bool value)
+ {
+ if (!Resolve(entity, ref entity.Comp))
+ return;
+
+ if (entity.Comp.CanGhostInteract == value)
+ return;
+
+ entity.Comp.CanGhostInteract = value;
+ Dirty(entity);
}
}