Add GHOST GANG! (#13734)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -1,18 +1,27 @@
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Follower.Components;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Physics.Pull;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Events;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
|
||||
namespace Content.Shared.Follower;
|
||||
|
||||
public sealed class FollowerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly SharedJointSystem _jointSystem = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -20,6 +29,8 @@ public sealed class FollowerSystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<GetVerbsEvent<AlternativeVerb>>(OnGetAlternativeVerbs);
|
||||
SubscribeLocalEvent<FollowerComponent, MoveInputEvent>(OnFollowerMove);
|
||||
SubscribeLocalEvent<FollowerComponent, PullStartedMessage>(OnPullStarted);
|
||||
SubscribeLocalEvent<FollowerComponent, GotEquippedHandEvent>(OnGotEquippedHand);
|
||||
SubscribeLocalEvent<FollowedComponent, EntityTerminatingEvent>(OnFollowedTerminating);
|
||||
SubscribeLocalEvent<BeforeSaveEvent>(OnBeforeSave);
|
||||
}
|
||||
@@ -44,25 +55,38 @@ public sealed class FollowerSystem : EntitySystem
|
||||
|
||||
private void OnGetAlternativeVerbs(GetVerbsEvent<AlternativeVerb> ev)
|
||||
{
|
||||
if (!HasComp<SharedGhostComponent>(ev.User))
|
||||
return;
|
||||
|
||||
if (ev.User == ev.Target || ev.Target.IsClientSide())
|
||||
return;
|
||||
|
||||
var verb = new AlternativeVerb
|
||||
if (HasComp<SharedGhostComponent>(ev.User))
|
||||
{
|
||||
Priority = 10,
|
||||
Act = (() =>
|
||||
var verb = new AlternativeVerb()
|
||||
{
|
||||
StartFollowingEntity(ev.User, ev.Target);
|
||||
}),
|
||||
Impact = LogImpact.Low,
|
||||
Text = Loc.GetString("verb-follow-text"),
|
||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/open.svg.192dpi.png")),
|
||||
};
|
||||
Priority = 10,
|
||||
Act = () => StartFollowingEntity(ev.User, ev.Target),
|
||||
Impact = LogImpact.Low,
|
||||
Text = Loc.GetString("verb-follow-text"),
|
||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/open.svg.192dpi.png"))
|
||||
};
|
||||
ev.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
ev.Verbs.Add(verb);
|
||||
if (_tagSystem.HasTag(ev.Target, "ForceableFollow"))
|
||||
{
|
||||
if (!ev.CanAccess || !ev.CanInteract)
|
||||
return;
|
||||
|
||||
var verb = new AlternativeVerb
|
||||
{
|
||||
Priority = 10,
|
||||
Act = () => StartFollowingEntity(ev.Target, ev.User),
|
||||
Impact = LogImpact.Low,
|
||||
Text = Loc.GetString("verb-follow-me-text"),
|
||||
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/close.svg.192dpi.png")),
|
||||
};
|
||||
|
||||
ev.Verbs.Add(verb);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFollowerMove(EntityUid uid, FollowerComponent component, ref MoveInputEvent args)
|
||||
@@ -70,6 +94,16 @@ public sealed class FollowerSystem : EntitySystem
|
||||
StopFollowingEntity(uid, component.Following);
|
||||
}
|
||||
|
||||
private void OnPullStarted(EntityUid uid, FollowerComponent component, PullStartedMessage args)
|
||||
{
|
||||
StopFollowingEntity(uid, component.Following);
|
||||
}
|
||||
|
||||
private void OnGotEquippedHand(EntityUid uid, FollowerComponent component, GotEquippedHandEvent args)
|
||||
{
|
||||
StopFollowingEntity(uid, component.Following, deparent:false);
|
||||
}
|
||||
|
||||
// Since we parent our observer to the followed entity, we need to detach
|
||||
// before they get deleted so that we don't get recursively deleted too.
|
||||
private void OnFollowedTerminating(EntityUid uid, FollowedComponent component, ref EntityTerminatingEvent args)
|
||||
@@ -102,24 +136,35 @@ public sealed class FollowerSystem : EntitySystem
|
||||
if (!followedComp.Following.Add(follower))
|
||||
return;
|
||||
|
||||
if (TryComp<JointComponent>(follower, out var joints))
|
||||
_jointSystem.ClearJoints(follower, joints);
|
||||
|
||||
_physicsSystem.SetLinearVelocity(follower, Vector2.Zero);
|
||||
|
||||
var xform = Transform(follower);
|
||||
_transform.SetCoordinates(follower, xform, new EntityCoordinates(entity, Vector2.Zero), Angle.Zero);
|
||||
_containerSystem.AttachParentToContainerOrGrid(xform);
|
||||
|
||||
// If we didn't get to parent's container.
|
||||
if (xform.ParentUid != Transform(xform.ParentUid).ParentUid)
|
||||
{
|
||||
_transform.SetCoordinates(follower, xform, new EntityCoordinates(entity, Vector2.Zero), rotation: Angle.Zero);
|
||||
}
|
||||
|
||||
EnsureComp<OrbitVisualsComponent>(follower);
|
||||
|
||||
var followerEv = new StartedFollowingEntityEvent(entity, follower);
|
||||
var entityEv = new EntityStartedFollowingEvent(entity, follower);
|
||||
|
||||
RaiseLocalEvent(follower, followerEv, true);
|
||||
RaiseLocalEvent(entity, entityEv, false);
|
||||
RaiseLocalEvent(follower, followerEv);
|
||||
RaiseLocalEvent(entity, entityEv);
|
||||
Dirty(followedComp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces an entity to stop following another entity, if it is doing so.
|
||||
/// </summary>
|
||||
public void StopFollowingEntity(EntityUid uid, EntityUid target,
|
||||
FollowedComponent? followed=null)
|
||||
/// <param name="deparent">Should the entity deparent itself</param>
|
||||
public void StopFollowingEntity(EntityUid uid, EntityUid target, FollowedComponent? followed = null, bool deparent = true)
|
||||
{
|
||||
if (!Resolve(target, ref followed, false))
|
||||
return;
|
||||
@@ -130,24 +175,27 @@ public sealed class FollowerSystem : EntitySystem
|
||||
followed.Following.Remove(uid);
|
||||
if (followed.Following.Count == 0)
|
||||
RemComp<FollowedComponent>(target);
|
||||
|
||||
RemComp<FollowerComponent>(uid);
|
||||
|
||||
var xform = Transform(uid);
|
||||
_transform.AttachToGridOrMap(uid, xform);
|
||||
if (xform.MapID == MapId.Nullspace)
|
||||
{
|
||||
QueueDel(uid);
|
||||
return;
|
||||
}
|
||||
|
||||
RemComp<OrbitVisualsComponent>(uid);
|
||||
|
||||
var uidEv = new StoppedFollowingEntityEvent(target, uid);
|
||||
var targetEv = new EntityStoppedFollowingEvent(target, uid);
|
||||
|
||||
RaiseLocalEvent(uid, uidEv, true);
|
||||
RaiseLocalEvent(target, targetEv, false);
|
||||
Dirty(followed);
|
||||
RaiseLocalEvent(uid, uidEv);
|
||||
RaiseLocalEvent(target, targetEv);
|
||||
|
||||
if (!Deleted(uid) && deparent)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
_transform.AttachToGridOrMap(uid, xform);
|
||||
if (xform.MapUid == null)
|
||||
{
|
||||
QueueDel(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user