]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
[Fix] move ninja objectives into NinjaRole (#15490)
authordeltanedas <39013340+deltanedas@users.noreply.github.com>
Mon, 17 Apr 2023 22:32:05 +0000 (22:32 +0000)
committerGitHub <noreply@github.com>
Mon, 17 Apr 2023 22:32:05 +0000 (16:32 -0600)
Co-authored-by: deltanedas <@deltanedas:kde.org>
15 files changed:
Content.Server/Ninja/NinjaRole.cs [new file with mode: 0644]
Content.Server/Ninja/Systems/NinjaGlovesSystem.cs
Content.Server/Ninja/Systems/NinjaSystem.cs
Content.Server/Ninja/Systems/SpiderChargeSystem.cs
Content.Server/Objectives/Conditions/DoorjackCondition.cs
Content.Server/Objectives/Conditions/DownloadCondition.cs
Content.Server/Objectives/Conditions/SpiderChargeCondition.cs
Content.Server/Objectives/Conditions/SurviveCondition.cs
Content.Server/Objectives/Conditions/TerrorCondition.cs
Content.Server/Objectives/Requirements/NinjaRequirement.cs [new file with mode: 0644]
Content.Server/Traitor/TraitorRole.cs
Content.Shared/Ninja/Components/NinjaComponent.cs
Content.Shared/Ninja/Systems/NinjaGlovesSystem.cs
Content.Shared/Ninja/Systems/NinjaSystem.cs
Resources/Prototypes/Objectives/ninjaObjectives.yml

diff --git a/Content.Server/Ninja/NinjaRole.cs b/Content.Server/Ninja/NinjaRole.cs
new file mode 100644 (file)
index 0000000..80b0f47
--- /dev/null
@@ -0,0 +1,43 @@
+using Content.Server.Traitor;
+using Content.Shared.Roles;
+
+namespace Content.Server.Ninja;
+
+/// <summary>
+/// Stores the ninja's objectives in the mind so if they die the rest of the greentext persists.
+/// </summary>
+public sealed class NinjaRole : TraitorRole
+{
+    public NinjaRole(Mind.Mind mind, AntagPrototype antagPrototype) : base(mind, antagPrototype) { }
+
+    /// <summary>
+    /// Number of doors that have been doorjacked, used for objective
+    /// </summary>
+    [ViewVariables]
+    public int DoorsJacked = 0;
+
+    /// <summary>
+    /// Research nodes that have been downloaded, used for objective
+    /// </summary>
+    // TODO: client doesn't need to know what nodes are downloaded, just how many
+    [ViewVariables]
+    public HashSet<string> DownloadedNodes = new();
+
+    /// <summary>
+    /// Warp point that the spider charge has to target
+    /// </summary>
+    [ViewVariables]
+    public EntityUid? SpiderChargeTarget = null;
+
+    /// <summary>
+    /// Whether the spider charge has been detonated on the target, used for objective
+    /// </summary>
+    [ViewVariables]
+    public bool SpiderChargeDetonated;
+
+    /// <summary>
+    /// Whether the comms console has been hacked, used for objective
+    /// </summary>
+    [ViewVariables]
+    public bool CalledInThreat;
+}
index 0a7fe722ec3226cfe54f8958345f5678e73afbe4..57377da5565e22b232c01f4502e1f7ea69702616 100644 (file)
@@ -1,15 +1,20 @@
 using Content.Server.Communications;
 using Content.Server.DoAfter;
+using Content.Server.Ninja.Systems;
 using Content.Server.Power.Components;
 using Content.Shared.DoAfter;
 using Content.Shared.Interaction.Events;
 using Content.Shared.Ninja.Components;
 using Content.Shared.Ninja.Systems;
+using Content.Shared.Popups;
+using Content.Shared.Research.Components;
 
 namespace Content.Server.Ninja.Systems;
 
 public sealed class NinjaGlovesSystem : SharedNinjaGlovesSystem
 {
+    [Dependency] private readonly new NinjaSystem _ninja = default!;
+
     protected override void OnDrain(EntityUid uid, NinjaDrainComponent comp, InteractionAttemptEvent args)
     {
         if (!GloveCheck(uid, args, out var gloves, out var user, out var target)
@@ -29,8 +34,59 @@ public sealed class NinjaGlovesSystem : SharedNinjaGlovesSystem
         _doAfter.TryStartDoAfter(doAfterArgs);
     }
 
-    protected override bool IsCommsConsole(EntityUid uid)
+    protected override void OnDownloadDoAfter(EntityUid uid, NinjaDownloadComponent comp, DownloadDoAfterEvent args)
+    {
+        if (args.Cancelled || args.Handled)
+            return;
+
+        var user = args.User;
+        var target = args.Target;
+
+        if (!TryComp<NinjaComponent>(user, out var ninja)
+            || !TryComp<TechnologyDatabaseComponent>(target, out var database))
+            return;
+
+        var gained = _ninja.Download(uid, database.TechnologyIds);
+        var str = gained == 0
+            ? Loc.GetString("ninja-download-fail")
+            : Loc.GetString("ninja-download-success", ("count", gained), ("server", target));
+
+        Popups.PopupEntity(str, user, user, PopupType.Medium);
+    }
+
+    protected override void OnTerror(EntityUid uid, NinjaTerrorComponent comp, InteractionAttemptEvent args)
+    {
+        if (!GloveCheck(uid, args, out var gloves, out var user, out var target)
+            || !_ninja.GetNinjaRole(user, out var role)
+            || !HasComp<CommunicationsConsoleComponent>(target))
+            return;
+
+
+        // can only do it once
+        if (role.CalledInThreat)
+        {
+            Popups.PopupEntity(Loc.GetString("ninja-terror-already-called"), user, user);
+            return;
+        }
+
+        var doAfterArgs = new DoAfterArgs(user, comp.TerrorTime, new TerrorDoAfterEvent(), target: target, used: uid, eventTarget: uid)
+        {
+            BreakOnDamage = true,
+            BreakOnUserMove = true,
+            MovementThreshold = 0.5f,
+            CancelDuplicate = false
+        };
+
+        _doAfter.TryStartDoAfter(doAfterArgs);
+        // FIXME: doesnt work, don't show the console popup
+        args.Cancel();
+    }
+
+    protected override void OnTerrorDoAfter(EntityUid uid, NinjaTerrorComponent comp, TerrorDoAfterEvent args)
     {
-        return HasComp<CommunicationsConsoleComponent>(uid);
+        if (args.Cancelled || args.Handled)
+            return;
+
+        _ninja.CallInThreat(args.User);
     }
 }
index 318d1115bd0d440aee6b5ec0bd037b65636538f1..b9812c5be46d4deaf00c8a06d18f749354f55ed1 100644 (file)
@@ -8,12 +8,12 @@ using Content.Server.GameTicking.Rules;
 using Content.Server.GameTicking.Rules.Configurations;
 using Content.Server.Ghost.Roles.Events;
 using Content.Server.Mind.Components;
+using Content.Server.Ninja;
 using Content.Server.Ninja.Components;
 using Content.Server.Objectives;
 using Content.Server.Popups;
 using Content.Server.Power.Components;
 using Content.Server.PowerCell;
-using Content.Server.Traitor;
 using Content.Server.Warps;
 using Content.Shared.Alert;
 using Content.Shared.Doors.Components;
@@ -32,6 +32,7 @@ using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 using System.Diagnostics.CodeAnalysis;
+using System.Linq;
 
 namespace Content.Server.Ninja.Systems;
 
@@ -89,6 +90,49 @@ public sealed class NinjaSystem : SharedNinjaSystem
         GreetNinja(mind);
     }
 
+    /// <summary>
+    /// Download the given set of nodes, returning how many new nodes were downloaded.'
+    /// </summary>
+    public int Download(EntityUid uid, List<string> ids)
+    {
+        if (!GetNinjaRole(uid, out var role))
+            return 0;
+
+        var oldCount = role.DownloadedNodes.Count;
+        role.DownloadedNodes.UnionWith(ids);
+        var newCount = role.DownloadedNodes.Count;
+        return newCount - oldCount;
+    }
+
+    /// <summary>
+    /// Gets a ninja's role using the player's mind
+    /// </summary>
+    public static bool GetNinjaRole(Mind.Mind? mind, [NotNullWhen(true)] out NinjaRole? role)
+    {
+        if (mind == null)
+        {
+            role = null;
+            return false;
+        }
+
+        role = (NinjaRole?) mind.AllRoles
+            .Where(r => r is NinjaRole)
+            .FirstOrDefault();
+        return role != null;
+    }
+
+    /// <summary>
+    /// Gets a ninja's role using the player's entity id
+    /// </summary>
+    public bool GetNinjaRole(EntityUid uid, [NotNullWhen(true)] out NinjaRole? role)
+    {
+        role = null;
+        if (!TryComp<MindComponent>(uid, out var mind))
+            return false;
+
+        return GetNinjaRole(mind.Mind, out role);
+    }
+
     /// <summary>
     /// Returns the space ninja spawn gamerule's config
     /// </summary>
@@ -150,14 +194,17 @@ public sealed class NinjaSystem : SharedNinjaSystem
         return GetNinjaBattery(user, out var battery) && battery.TryUseCharge(charge);
     }
 
-    public override void CallInThreat(NinjaComponent comp)
+    /// <summary>
+    /// Completes the objective, makes announcement and adds rule of a random threat.
+    /// </summary>
+    public void CallInThreat(EntityUid uid)
     {
-        base.CallInThreat(comp);
-
         var config = RuleConfig();
-        if (config.Threats.Count == 0)
+        if (config.Threats.Count == 0 || !GetNinjaRole(uid, out var role) || role.CalledInThreat)
             return;
 
+        role.CalledInThreat = true;
+
         var threat = _random.Pick(config.Threats);
         if (_proto.TryIndex<GameRulePrototype>(threat.Rule, out var rule))
         {
@@ -224,20 +271,6 @@ public sealed class NinjaSystem : SharedNinjaSystem
 
             _implants.ForceImplant(uid, implant, implantComp);
         }
-
-        // choose spider charge detonation point
-        // currently based on warp points, something better could be done (but would likely require mapping work)
-        var warps = new List<EntityUid>();
-        var query = EntityQueryEnumerator<WarpPointComponent>();
-        while (query.MoveNext(out var warpUid, out var warp))
-        {
-            // won't be asked to detonate the nuke disk or singularity
-            if (warp.Location != null && !HasComp<PhysicsComponent>(warpUid))
-                warps.Add(warpUid);
-        }
-
-        if (warps.Count > 0)
-            comp.SpiderChargeTarget = _random.Pick(warps);
     }
 
     private void OnNinjaSpawned(EntityUid uid, NinjaComponent comp, GhostRoleSpawnerUsedEvent args)
@@ -249,17 +282,19 @@ public sealed class NinjaSystem : SharedNinjaSystem
 
     private void OnNinjaMindAdded(EntityUid uid, NinjaComponent comp, MindAddedMessage args)
     {
+        Logger.ErrorS("ninja_testing", "AMONG US 2 RELASED");
         if (TryComp<MindComponent>(uid, out var mind) && mind.Mind != null)
             GreetNinja(mind.Mind);
     }
 
     private void GreetNinja(Mind.Mind mind)
     {
+        Logger.ErrorS("ninja_testing", "GREETING");
         if (!mind.TryGetSession(out var session))
             return;
 
         var config = RuleConfig();
-        var role = new TraitorRole(mind, _proto.Index<AntagPrototype>("SpaceNinja"));
+        var role = new NinjaRole(mind, _proto.Index<AntagPrototype>("SpaceNinja"));
         mind.AddRole(role);
         _traitorRule.Traitors.Add(role);
         foreach (var objective in config.Objectives)
@@ -267,6 +302,21 @@ public sealed class NinjaSystem : SharedNinjaSystem
             AddObjective(mind, objective);
         }
 
+        Logger.ErrorS("ninja_testing", "added role");
+        // choose spider charge detonation point
+        // currently based on warp points, something better could be done (but would likely require mapping work)
+        var warps = new List<EntityUid>();
+        var query = EntityQueryEnumerator<WarpPointComponent>();
+        while (query.MoveNext(out var warpUid, out var warp))
+        {
+            // won't be asked to detonate the nuke disk or singularity
+            if (warp.Location != null && !HasComp<PhysicsComponent>(warpUid))
+                warps.Add(warpUid);
+        }
+
+        if (warps.Count > 0)
+            role.SpiderChargeTarget = _random.Pick(warps);
+
         _audio.PlayGlobal(config.GreetingSound, Filter.Empty().AddPlayer(session), false, AudioParams.Default);
         _chatMan.DispatchServerMessage(session, Loc.GetString("ninja-role-greeting"));
 
@@ -285,8 +335,8 @@ public sealed class NinjaSystem : SharedNinjaSystem
     private void OnDoorEmagged(EntityUid uid, DoorComponent door, ref DoorEmaggedEvent args)
     {
         // make sure it's a ninja doorjacking it
-        if (TryComp<NinjaComponent>(args.UserUid, out var ninja))
-            ninja.DoorsJacked++;
+        if (GetNinjaRole(args.UserUid, out var role))
+            role.DoorsJacked++;
     }
 
     private void UpdateNinja(EntityUid uid, NinjaComponent ninja, float frameTime)
index 94d3fb7911be8267ba16d10dbfe37fd2ec471764..35cad95335c0904270c6967b844aa8cb8b0b9937 100644 (file)
@@ -26,7 +26,7 @@ public sealed class SpiderChargeSystem : EntitySystem
     {
         var user = args.User;
 
-        if (!TryComp<NinjaComponent>(user, out var ninja))
+        if (!_ninja.GetNinjaRole(user, out var role))
         {
             _popups.PopupEntity(Loc.GetString("spider-charge-not-ninja"), user, user);
             args.Handled = true;
@@ -34,17 +34,16 @@ public sealed class SpiderChargeSystem : EntitySystem
         }
 
         // allow planting anywhere if there is no target, which should never happen
-        if (ninja.SpiderChargeTarget != null)
+        if (role.SpiderChargeTarget == null)
+            return;
+
+        // assumes warp point still exists
+        var target = Transform(role.SpiderChargeTarget.Value).MapPosition;
+        var coords = args.ClickLocation.ToMap(EntityManager, _transform);
+        if (!coords.InRange(target, comp.Range))
         {
-            // assumes warp point still exists
-            var target = Transform(ninja.SpiderChargeTarget.Value).MapPosition;
-            var coords = args.ClickLocation.ToMap(EntityManager, _transform);
-            if (!coords.InRange(target, comp.Range))
-            {
-                _popups.PopupEntity(Loc.GetString("spider-charge-too-far"), user, user);
-                args.Handled = true;
-                return;
-            }
+            _popups.PopupEntity(Loc.GetString("spider-charge-too-far"), user, user);
+            args.Handled = true;
         }
     }
 
@@ -55,10 +54,10 @@ public sealed class SpiderChargeSystem : EntitySystem
 
     private void OnExplode(EntityUid uid, SpiderChargeComponent comp, TriggerEvent args)
     {
-        if (comp.Planter == null || !TryComp<NinjaComponent>(comp.Planter, out var ninja))
+        if (comp.Planter == null || !_ninja.GetNinjaRole(comp.Planter.Value, out var role))
             return;
 
         // assumes the target was destroyed, that the charge wasn't moved somehow
-        _ninja.DetonateSpiderCharge(ninja);
+        role.SpiderChargeDetonated = true;
     }
 }
index 335b18f198a907f2cc731649725755ce684b4652..fc46d038364b041ba411c3b9a93b82da393cd333 100644 (file)
@@ -1,5 +1,5 @@
+using Content.Server.Ninja.Systems;
 using Content.Server.Objectives.Interfaces;
-using Content.Shared.Ninja.Components;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
 
@@ -30,16 +30,14 @@ public sealed class DoorjackCondition : IObjectiveCondition
     {
         get
         {
-            var entMan = IoCManager.Resolve<IEntityManager>();
-            if (_mind?.OwnedEntity == null
-                || !entMan.TryGetComponent<NinjaComponent>(_mind.OwnedEntity, out var ninja))
-                return 0f;
-
             // prevent divide-by-zero
             if (_target == 0)
                 return 1f;
 
-            return (float) ninja.DoorsJacked / (float) _target;
+            if (!NinjaSystem.GetNinjaRole(_mind, out var role))
+                return 0f;
+
+            return (float) role.DoorsJacked / (float) _target;
         }
     }
 
index 18948b195581d17a4097a7ccdade24ca012e8b6b..fe71aa05da13eca8d47efdb7270c980fa4d7f05e 100644 (file)
@@ -1,5 +1,5 @@
+using Content.Server.Ninja.Systems;
 using Content.Server.Objectives.Interfaces;
-using Content.Shared.Ninja.Components;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
 
@@ -34,12 +34,10 @@ public sealed class DownloadCondition : IObjectiveCondition
             if (_target == 0)
                 return 1f;
 
-            var entMan = IoCManager.Resolve<IEntityManager>();
-            if (_mind?.OwnedEntity == null
-                || !entMan.TryGetComponent<NinjaComponent>(_mind.OwnedEntity, out var ninja))
+            if (!NinjaSystem.GetNinjaRole(_mind, out var role))
                 return 0f;
 
-            return (float) ninja.DownloadedNodes.Count / (float) _target;
+            return (float) role.DownloadedNodes.Count / (float) _target;
         }
     }
 
index c8ea4897dfecf47ef9ac6dcc546df184f47ee472..5ae9cad3b110676b6a4b665f8918e6c192fff40f 100644 (file)
@@ -1,6 +1,6 @@
+using Content.Server.Ninja.Systems;
 using Content.Server.Objectives.Interfaces;
 using Content.Server.Warps;
-using Content.Shared.Ninja.Components;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
 
@@ -23,12 +23,11 @@ public sealed class SpiderChargeCondition : IObjectiveCondition
         get
         {
             var entMan = IoCManager.Resolve<IEntityManager>();
-            if (_mind?.OwnedEntity == null
-                || !entMan.TryGetComponent<NinjaComponent>(_mind.OwnedEntity, out var ninja)
-                || ninja.SpiderChargeTarget == null
-                || !entMan.TryGetComponent<WarpPointComponent>(ninja.SpiderChargeTarget, out var warp)
+            if (!NinjaSystem.GetNinjaRole(_mind, out var role)
+                || role.SpiderChargeTarget == null
+                || !entMan.TryGetComponent<WarpPointComponent>(role.SpiderChargeTarget, out var warp)
                 || warp.Location == null)
-                // if you are funny and microbomb then press c, you get this
+                // this should never really happen but eh
                 return Loc.GetString("objective-condition-spider-charge-no-target");
 
             return Loc.GetString("objective-condition-spider-charge-title", ("location", warp.Location));
@@ -43,12 +42,10 @@ public sealed class SpiderChargeCondition : IObjectiveCondition
     {
         get
         {
-            var entMan = IoCManager.Resolve<IEntityManager>();
-            if (_mind?.OwnedEntity == null
-                || !entMan.TryGetComponent<NinjaComponent>(_mind.OwnedEntity, out var ninja))
+            if (!NinjaSystem.GetNinjaRole(_mind, out var role))
                 return 0f;
 
-            return ninja.SpiderChargeDetonated ? 1f : 0f;
+            return role.SpiderChargeDetonated ? 1f : 0f;
         }
     }
 
index b4bfe4426dbafb12aa15aa0e7a9c198c31008b16..2641918238dd3bc7a8f603a9ec427ac98fa91e4a 100644 (file)
@@ -1,46 +1,43 @@
 using Content.Server.Objectives.Interfaces;
-using JetBrains.Annotations;
 using Robust.Shared.Utility;
 
-namespace Content.Server.Objectives.Conditions
+namespace Content.Server.Objectives.Conditions;
+
+[DataDefinition]
+public sealed class SurviveCondition : IObjectiveCondition
 {
-    [UsedImplicitly]
-    [DataDefinition]
-    public sealed class SurviveCondition : IObjectiveCondition
-    {
-        private Mind.Mind? _mind;
+    private Mind.Mind? _mind;
 
-        public IObjectiveCondition GetAssigned(Mind.Mind mind)
-        {
-            return new SurviveCondition {_mind = mind};
-        }
+    public IObjectiveCondition GetAssigned(Mind.Mind mind)
+    {
+        return new SurviveCondition {_mind = mind};
+    }
 
-        public string Title => Loc.GetString("objective-condition-survive-title");
+    public string Title => Loc.GetString("objective-condition-survive-title");
 
-        public string Description => Loc.GetString("objective-condition-survive-description");
+    public string Description => Loc.GetString("objective-condition-survive-description");
 
-        public SpriteSpecifier Icon => new SpriteSpecifier.Rsi(new ResourcePath("Clothing/Head/Helmets/spaceninja.rsi"), "icon");
+    public SpriteSpecifier Icon => new SpriteSpecifier.Rsi(new ResourcePath("Clothing/Head/Helmets/spaceninja.rsi"), "icon");
 
-        public float Difficulty => 0.5f;
+    public float Difficulty => 0.5f;
 
-        public float Progress => (_mind?.CharacterDeadIC ?? true) ? 0f : 1f;
+    public float Progress => (_mind?.CharacterDeadIC ?? true) ? 0f : 1f;
 
-        public bool Equals(IObjectiveCondition? other)
-        {
-            return other is SurviveCondition condition && Equals(_mind, condition._mind);
-        }
+    public bool Equals(IObjectiveCondition? other)
+    {
+        return other is SurviveCondition condition && Equals(_mind, condition._mind);
+    }
 
-        public override bool Equals(object? obj)
-        {
-            if (ReferenceEquals(null, obj)) return false;
-            if (ReferenceEquals(this, obj)) return true;
-            if (obj.GetType() != GetType()) return false;
-            return Equals((SurviveCondition) obj);
-        }
+    public override bool Equals(object? obj)
+    {
+        if (ReferenceEquals(null, obj)) return false;
+        if (ReferenceEquals(this, obj)) return true;
+        if (obj.GetType() != GetType()) return false;
+        return Equals((SurviveCondition) obj);
+    }
 
-        public override int GetHashCode()
-        {
-            return (_mind != null ? _mind.GetHashCode() : 0);
-        }
+    public override int GetHashCode()
+    {
+        return (_mind != null ? _mind.GetHashCode() : 0);
     }
 }
index 10f76b6a6e6a068bca861f6005a9b6af1b86628d..89d5f412635637a8251279f2c32317716cf3534c 100644 (file)
@@ -1,5 +1,5 @@
+using Content.Server.Ninja.Systems;
 using Content.Server.Objectives.Interfaces;
-using Content.Shared.Ninja.Components;
 using Robust.Shared.Utility;
 
 namespace Content.Server.Objectives.Conditions;
@@ -24,12 +24,10 @@ public sealed class TerrorCondition : IObjectiveCondition
     {
         get
         {
-            var entMan = IoCManager.Resolve<IEntityManager>();
-            if (_mind?.OwnedEntity == null
-                || !entMan.TryGetComponent<NinjaComponent>(_mind.OwnedEntity, out var ninja))
+            if (!NinjaSystem.GetNinjaRole(_mind, out var role))
                 return 0f;
 
-            return ninja.CalledInThreat ? 1f : 0f;
+            return role.CalledInThreat ? 1f : 0f;
         }
     }
 
diff --git a/Content.Server/Objectives/Requirements/NinjaRequirement.cs b/Content.Server/Objectives/Requirements/NinjaRequirement.cs
new file mode 100644 (file)
index 0000000..e330a7f
--- /dev/null
@@ -0,0 +1,13 @@
+using Content.Server.Objectives.Interfaces;
+using Content.Server.Ninja;
+
+namespace Content.Server.Objectives.Requirements;
+
+[DataDefinition]
+public sealed class NinjaRequirement : IObjectiveRequirement
+{
+    public bool CanBeAssigned(Mind.Mind mind)
+    {
+        return mind.HasRole<NinjaRole>();
+    }
+}
index 4e23122e7d1a9cf00409b2f8b5ecff36fd631491..d7b4d39f30e05dafb8508ec998dc5cb35a58504a 100644 (file)
@@ -4,7 +4,8 @@ using Content.Shared.Roles;
 
 namespace Content.Server.Traitor
 {
-    public sealed class TraitorRole : Role
+    [Virtual]
+    public class TraitorRole : Role
     {
         public AntagPrototype Prototype { get; }
 
index 851be9a5a9e73a2a9d0f89b6efbfad83a2aa4c1d..3036e06b73ad9c64d3787d97c1438fe9e3fce756 100644 (file)
@@ -8,7 +8,6 @@ namespace Content.Shared.Ninja.Components;
 /// Component placed on a mob to make it a space ninja, able to use suit and glove powers.
 /// Contains ids of all ninja equipment.
 /// </summary>
-// TODO: Contains objective related stuff, might want to move it out somehow
 [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
 [Access(typeof(SharedNinjaSystem))]
 public sealed partial class NinjaComponent : Component
@@ -16,6 +15,7 @@ public sealed partial class NinjaComponent : Component
     /// <summary>
     /// Grid entity of the station the ninja was spawned around. Set if spawned naturally by the event.
     /// </summary>
+    [ViewVariables, AutoNetworkedField]
     public EntityUid? StationGrid;
 
     /// <summary>
@@ -35,35 +35,4 @@ public sealed partial class NinjaComponent : Component
     /// </summary>
     [ViewVariables]
     public EntityUid? Katana = null;
-
-    /// <summary>
-    /// Number of doors that have been doorjacked, used for objective
-    /// </summary>
-    [ViewVariables, AutoNetworkedField]
-    public int DoorsJacked = 0;
-
-    /// <summary>
-    /// Research nodes that have been downloaded, used for objective
-    /// </summary>
-    // TODO: client doesn't need to know what nodes are downloaded, just how many
-    [ViewVariables, AutoNetworkedField]
-    public HashSet<string> DownloadedNodes = new();
-
-    /// <summary>
-    /// Warp point that the spider charge has to target
-    /// </summary>
-    [ViewVariables, AutoNetworkedField]
-    public EntityUid? SpiderChargeTarget = null;
-
-    /// <summary>
-    /// Whether the spider charge has been detonated on the target, used for objective
-    /// </summary>
-    [ViewVariables, AutoNetworkedField]
-    public bool SpiderChargeDetonated;
-
-    /// <summary>
-    /// Whether the comms console has been hacked, used for objective
-    /// </summary>
-    [ViewVariables, AutoNetworkedField]
-    public bool CalledInThreat;
 }
index bccb3d9521e0934f820c513b0b5f26557bc2bd74..b62feb188e9d8b8af2b73b6f731f792ab41e0949 100644 (file)
@@ -36,7 +36,7 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem
     [Dependency] private readonly SharedInteractionSystem _interaction = default!;
     [Dependency] private readonly INetManager _net = default!;
     [Dependency] private readonly SharedNinjaSystem _ninja = default!;
-    [Dependency] private readonly SharedPopupSystem _popups = default!;
+    [Dependency] protected readonly SharedPopupSystem Popups = default!;
     [Dependency] private readonly TagSystem _tags = default!;
     [Dependency] private readonly IGameTiming _timing = default!;
     [Dependency] private readonly UseDelaySystem _useDelay = default!;
@@ -72,7 +72,7 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem
         if (comp.User != null)
         {
             comp.User = null;
-            _popups.PopupEntity(Loc.GetString("ninja-gloves-off"), user, user);
+            Popups.PopupEntity(Loc.GetString("ninja-gloves-off"), user, user);
         }
     }
 
@@ -191,7 +191,7 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem
         // take charge from battery
         if (!_ninja.TryUseCharge(user, comp.StunCharge))
         {
-            _popups.PopupEntity(Loc.GetString("ninja-no-power"), user, user);
+            Popups.PopupEntity(Loc.GetString("ninja-no-power"), user, user);
             return;
         }
 
@@ -239,76 +239,18 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem
         args.Cancel();
     }
 
-    private void OnDownloadDoAfter(EntityUid uid, NinjaDownloadComponent comp, DownloadDoAfterEvent args)
-    {
-        if (args.Cancelled || args.Handled)
-            return;
-
-        var user = args.User;
-        var target = args.Target;
-
-        if (!TryComp<NinjaComponent>(user, out var ninja)
-            || !TryComp<TechnologyDatabaseComponent>(target, out var database))
-            return;
-
-        var gained = _ninja.Download(ninja, database.TechnologyIds);
-        var str = gained == 0
-            ? Loc.GetString("ninja-download-fail")
-            : Loc.GetString("ninja-download-success", ("count", gained), ("server", target));
-
-        _popups.PopupEntity(str, user, user, PopupType.Medium);
-    }
-
-    private void OnTerror(EntityUid uid, NinjaTerrorComponent comp, InteractionAttemptEvent args)
-    {
-        if (!GloveCheck(uid, args, out var gloves, out var user, out var target)
-            || !TryComp<NinjaComponent>(user, out var ninja))
-            return;
-
-        if (!IsCommsConsole(target))
-            return;
-
-        // can only do it once
-        if (ninja.CalledInThreat)
-        {
-            _popups.PopupEntity(Loc.GetString("ninja-terror-already-called"), user, user);
-            return;
-        }
-
-        var doAfterArgs = new DoAfterArgs(user, comp.TerrorTime, new TerrorDoAfterEvent(), target: target, used: uid, eventTarget: uid)
-        {
-            BreakOnDamage = true,
-            BreakOnUserMove = true,
-            MovementThreshold = 0.5f,
-            CancelDuplicate = false
-        };
+    // can't predict roles so only done on server.
+    protected virtual void OnDownloadDoAfter(EntityUid uid, NinjaDownloadComponent comp, DownloadDoAfterEvent args) { }
 
-        _doAfter.TryStartDoAfter(doAfterArgs);
-        // FIXME: doesnt work, don't show the console popup
-        args.Cancel();
-    }
+    // cant predict roles for checking if already called
+    protected virtual void OnTerror(EntityUid uid, NinjaTerrorComponent comp, InteractionAttemptEvent args) { }
 
-    //for some reason shared comms console component isn't a component, so this has to be done server-side
-    protected virtual bool IsCommsConsole(EntityUid uid)
-    {
-        return false;
-    }
-
-    private void OnTerrorDoAfter(EntityUid uid, NinjaTerrorComponent comp, TerrorDoAfterEvent args)
-    {
-        if (args.Cancelled || args.Handled)
-            return;
-
-        var user = args.User;
-        if (!TryComp<NinjaComponent>(user, out var ninja) || ninja.CalledInThreat)
-            return;
-
-        _ninja.CallInThreat(ninja);
-    }
+    // can't predict roles or anything announcements related so only done on server.
+    protected virtual void OnTerrorDoAfter(EntityUid uid, NinjaTerrorComponent comp, TerrorDoAfterEvent args) { }
 
     private void ClientPopup(string msg, EntityUid user, PopupType type = PopupType.Small)
     {
         if (_net.IsClient)
-            _popups.PopupEntity(msg, user, user, type);
+            Popups.PopupEntity(msg, user, user, type);
     }
 }
index d1b51ad77c022055a272a35551bef3d229fa42f9..1097db7f6785c55568820dda1aceafdb406a6ba0 100644 (file)
@@ -48,21 +48,6 @@ public abstract class SharedNinjaSystem : EntitySystem
         comp.Katana = katana;
     }
 
-    // TODO: remove when objective stuff moved into objectives somehow
-    public void DetonateSpiderCharge(NinjaComponent comp)
-    {
-        comp.SpiderChargeDetonated = true;
-    }
-
-    /// <summary>
-    /// Marks the objective as complete.
-    /// On server, makes announcement and adds rule of random threat.
-    /// </summary>
-    public virtual void CallInThreat(NinjaComponent comp)
-    {
-        comp.CalledInThreat = true;
-    }
-
     /// <summary>
     /// Drain power from a target battery into the ninja's suit battery.
     /// Serverside only.
@@ -71,17 +56,6 @@ public abstract class SharedNinjaSystem : EntitySystem
     {
     }
 
-    /// <summary>
-    /// Download the given set of nodes, returning how many new nodes were downloaded.'
-    /// </summary>
-    public int Download(NinjaComponent ninja, List<string> ids)
-    {
-        var oldCount = ninja.DownloadedNodes.Count;
-        ninja.DownloadedNodes.UnionWith(ids);
-        var newCount = ninja.DownloadedNodes.Count;
-        return newCount - oldCount;
-    }
-
     /// <summary>
     /// Gets the user's battery and tries to use some charge from it, returning true if successful.
     /// Serverside only.
index d2e1fa40684831d6754ed60a74e9e13db94e10d5..8b8208cffaa83fab3b7830cab8bf7bbbb03e99c5 100644 (file)
@@ -2,7 +2,7 @@
   id: DownloadObjective
   issuer: spiderclan
   requirements:
-  - !type:TraitorRequirement {}
+  - !type:NinjaRequirement {}
   conditions:
   - !type:DownloadCondition {}
 
@@ -10,7 +10,7 @@
   id: DoorjackObjective
   issuer: spiderclan
   requirements:
-  - !type:TraitorRequirement {}
+  - !type:NinjaRequirement {}
   conditions:
   - !type:DoorjackCondition {}
 
@@ -18,7 +18,7 @@
   id: SpiderChargeObjective
   issuer: spiderclan
   requirements:
-  - !type:TraitorRequirement {}
+  - !type:NinjaRequirement {}
   conditions:
   - !type:SpiderChargeCondition {}
 
@@ -26,7 +26,7 @@
   id: TerrorObjective
   issuer: spiderclan
   requirements:
-  - !type:TraitorRequirement {}
+  - !type:NinjaRequirement {}
   conditions:
   - !type:TerrorCondition {}
 
@@ -34,6 +34,6 @@
   id: SurviveObjective
   issuer: spiderclan
   requirements:
-  - !type:TraitorRequirement {}
+  - !type:NinjaRequirement {}
   conditions:
   - !type:SurviveCondition {}