@@ -24,6 +24,7 @@ using Content.Shared.Mobs.Components;
|
|||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
using Content.Shared.Movement.Events;
|
using Content.Shared.Movement.Events;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
|
using Content.Shared.NameModifier.EntitySystems;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Storage.Components;
|
using Content.Shared.Storage.Components;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
@@ -66,6 +67,7 @@ namespace Content.Server.Ghost
|
|||||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly TagSystem _tag = default!;
|
[Dependency] private readonly TagSystem _tag = default!;
|
||||||
|
[Dependency] private readonly NameModifierSystem _nameMod = default!;
|
||||||
|
|
||||||
private EntityQuery<GhostComponent> _ghostQuery;
|
private EntityQuery<GhostComponent> _ghostQuery;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||||
@@ -495,6 +497,10 @@ namespace Content.Server.Ghost
|
|||||||
else
|
else
|
||||||
_minds.TransferTo(mind.Owner, ghost, mind: mind.Comp);
|
_minds.TransferTo(mind.Owner, ghost, mind: mind.Comp);
|
||||||
Log.Debug($"Spawned ghost \"{ToPrettyString(ghost)}\" for {mind.Comp.CharacterName}.");
|
Log.Debug($"Spawned ghost \"{ToPrettyString(ghost)}\" for {mind.Comp.CharacterName}.");
|
||||||
|
|
||||||
|
// we changed the entity name above
|
||||||
|
// we have to call this after the mind has been transferred since some mind roles modify the ghost's name
|
||||||
|
_nameMod.RefreshNameModifiers(ghost);
|
||||||
return ghost;
|
return ghost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,12 @@ namespace Content.Server.Roles;
|
|||||||
/// Added to mind role entities to tag that they are a paradox clone.
|
/// Added to mind role entities to tag that they are a paradox clone.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed partial class ParadoxCloneRoleComponent : BaseMindRoleComponent;
|
public sealed partial class ParadoxCloneRoleComponent : BaseMindRoleComponent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name modifer applied to the player when they turn into a ghost.
|
||||||
|
/// Needed to be able to keep the original and the clone apart in dead chat.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public LocId? NameModifier = "paradox-clone-ghost-name-modifier";
|
||||||
|
}
|
||||||
|
|||||||
32
Content.Server/Roles/ParadoxCloneRoleSystem.cs
Normal file
32
Content.Server/Roles/ParadoxCloneRoleSystem.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Content.Shared.Ghost;
|
||||||
|
using Content.Shared.Mind;
|
||||||
|
using Content.Shared.NameModifier.EntitySystems;
|
||||||
|
using Content.Shared.Roles;
|
||||||
|
|
||||||
|
namespace Content.Server.Roles;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// System responsible for giving a ghost of a paradox clone a name modifier.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ParadoxCloneRoleSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<ParadoxCloneRoleComponent, MindRelayedEvent<RefreshNameModifiersEvent>>(OnRefreshNameModifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRefreshNameModifiers(Entity<ParadoxCloneRoleComponent> ent, ref MindRelayedEvent<RefreshNameModifiersEvent> args)
|
||||||
|
{
|
||||||
|
if (!TryComp<MindRoleComponent>(ent.Owner, out var roleComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// only show for ghosts
|
||||||
|
if (!HasComp<GhostComponent>(roleComp.Mind.Comp.OwnedEntity))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent.Comp.NameModifier != null)
|
||||||
|
args.Args.AddModifier(ent.Comp.NameModifier.Value, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
48
Content.Shared/Mind/SharedMindSystem.Relay.cs
Normal file
48
Content.Shared/Mind/SharedMindSystem.Relay.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using Content.Shared.NameModifier.EntitySystems;
|
||||||
|
using Content.Shared.Mind.Components;
|
||||||
|
|
||||||
|
namespace Content.Shared.Mind;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relays events raised on a mobs body to its mind and mind role entities.
|
||||||
|
/// Useful for events that should be raised both on the body and the mind.
|
||||||
|
/// </summary>
|
||||||
|
public abstract partial class SharedMindSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public void InitializeRelay()
|
||||||
|
{
|
||||||
|
// for name modifiers that depend on certain mind roles
|
||||||
|
SubscribeLocalEvent<MindContainerComponent, RefreshNameModifiersEvent>(RelayRefToMind);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RelayToMind<T>(EntityUid uid, MindContainerComponent component, T args) where T : class
|
||||||
|
{
|
||||||
|
var ev = new MindRelayedEvent<T>(args);
|
||||||
|
|
||||||
|
if (TryGetMind(uid, out var mindId, out var mindComp, component))
|
||||||
|
{
|
||||||
|
RaiseLocalEvent(mindId, ref ev);
|
||||||
|
|
||||||
|
foreach (var role in mindComp.MindRoles)
|
||||||
|
RaiseLocalEvent(role, ref ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RelayRefToMind<T>(EntityUid uid, MindContainerComponent component, ref T args) where T : class
|
||||||
|
{
|
||||||
|
var ev = new MindRelayedEvent<T>(args);
|
||||||
|
|
||||||
|
if (TryGetMind(uid, out var mindId, out var mindComp, component))
|
||||||
|
{
|
||||||
|
RaiseLocalEvent(mindId, ref ev);
|
||||||
|
|
||||||
|
foreach (var role in mindComp.MindRoles)
|
||||||
|
RaiseLocalEvent(role, ref ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
args = ev.Args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct MindRelayedEvent<TEvent>(TEvent Args);
|
||||||
@@ -19,7 +19,7 @@ using Robust.Shared.Utility;
|
|||||||
|
|
||||||
namespace Content.Shared.Mind;
|
namespace Content.Shared.Mind;
|
||||||
|
|
||||||
public abstract class SharedMindSystem : EntitySystem
|
public abstract partial class SharedMindSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
[Dependency] private readonly INetManager _net = default!;
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
@@ -42,6 +42,8 @@ public abstract class SharedMindSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnReset);
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnReset);
|
||||||
SubscribeLocalEvent<MindComponent, ComponentStartup>(OnMindStartup);
|
SubscribeLocalEvent<MindComponent, ComponentStartup>(OnMindStartup);
|
||||||
SubscribeLocalEvent<MindComponent, EntityRenamedEvent>(OnRenamed);
|
SubscribeLocalEvent<MindComponent, EntityRenamedEvent>(OnRenamed);
|
||||||
|
|
||||||
|
InitializeRelay();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ paradox-clone-round-end-agent-name = paradox clone
|
|||||||
objective-issuer-paradox = [color=lightblue]Paradox[/color]
|
objective-issuer-paradox = [color=lightblue]Paradox[/color]
|
||||||
|
|
||||||
paradox-clone-role-greeting = A freak space-time anomaly has teleported you into another reality! Now you have to find your counterpart and kill and replace them. Only one of you two can survive.
|
paradox-clone-role-greeting = A freak space-time anomaly has teleported you into another reality! Now you have to find your counterpart and kill and replace them. Only one of you two can survive.
|
||||||
|
|
||||||
|
paradox-clone-ghost-name-modifier = {$baseName} (clone)
|
||||||
|
|||||||
Reference in New Issue
Block a user