diff --git a/Content.Server/Ninja/NinjaRole.cs b/Content.Server/Ninja/NinjaRole.cs new file mode 100644 index 0000000000..80b0f47984 --- /dev/null +++ b/Content.Server/Ninja/NinjaRole.cs @@ -0,0 +1,43 @@ +using Content.Server.Traitor; +using Content.Shared.Roles; + +namespace Content.Server.Ninja; + +/// +/// Stores the ninja's objectives in the mind so if they die the rest of the greentext persists. +/// +public sealed class NinjaRole : TraitorRole +{ + public NinjaRole(Mind.Mind mind, AntagPrototype antagPrototype) : base(mind, antagPrototype) { } + + /// + /// Number of doors that have been doorjacked, used for objective + /// + [ViewVariables] + public int DoorsJacked = 0; + + /// + /// Research nodes that have been downloaded, used for objective + /// + // TODO: client doesn't need to know what nodes are downloaded, just how many + [ViewVariables] + public HashSet DownloadedNodes = new(); + + /// + /// Warp point that the spider charge has to target + /// + [ViewVariables] + public EntityUid? SpiderChargeTarget = null; + + /// + /// Whether the spider charge has been detonated on the target, used for objective + /// + [ViewVariables] + public bool SpiderChargeDetonated; + + /// + /// Whether the comms console has been hacked, used for objective + /// + [ViewVariables] + public bool CalledInThreat; +} diff --git a/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs b/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs index 0a7fe722ec..57377da556 100644 --- a/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs +++ b/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs @@ -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) { - return HasComp(uid); + if (args.Cancelled || args.Handled) + return; + + var user = args.User; + var target = args.Target; + + if (!TryComp(user, out var ninja) + || !TryComp(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(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) + { + if (args.Cancelled || args.Handled) + return; + + _ninja.CallInThreat(args.User); } } diff --git a/Content.Server/Ninja/Systems/NinjaSystem.cs b/Content.Server/Ninja/Systems/NinjaSystem.cs index 318d1115bd..b9812c5be4 100644 --- a/Content.Server/Ninja/Systems/NinjaSystem.cs +++ b/Content.Server/Ninja/Systems/NinjaSystem.cs @@ -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); } + /// + /// Download the given set of nodes, returning how many new nodes were downloaded.' + /// + public int Download(EntityUid uid, List 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; + } + + /// + /// Gets a ninja's role using the player's mind + /// + 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; + } + + /// + /// Gets a ninja's role using the player's entity id + /// + public bool GetNinjaRole(EntityUid uid, [NotNullWhen(true)] out NinjaRole? role) + { + role = null; + if (!TryComp(uid, out var mind)) + return false; + + return GetNinjaRole(mind.Mind, out role); + } + /// /// Returns the space ninja spawn gamerule's config /// @@ -150,14 +194,17 @@ public sealed class NinjaSystem : SharedNinjaSystem return GetNinjaBattery(user, out var battery) && battery.TryUseCharge(charge); } - public override void CallInThreat(NinjaComponent comp) + /// + /// Completes the objective, makes announcement and adds rule of a random threat. + /// + 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(threat.Rule, out var rule)) { @@ -224,7 +271,38 @@ public sealed class NinjaSystem : SharedNinjaSystem _implants.ForceImplant(uid, implant, implantComp); } + } + private void OnNinjaSpawned(EntityUid uid, NinjaComponent comp, GhostRoleSpawnerUsedEvent args) + { + // inherit spawner's station grid + if (TryComp(args.Spawner, out var station)) + SetNinjaStationGrid(uid, station.Grid); + } + + private void OnNinjaMindAdded(EntityUid uid, NinjaComponent comp, MindAddedMessage args) + { + Logger.ErrorS("ninja_testing", "AMONG US 2 RELASED"); + if (TryComp(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 NinjaRole(mind, _proto.Index("SpaceNinja")); + mind.AddRole(role); + _traitorRule.Traitors.Add(role); + foreach (var objective in config.Objectives) + { + 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(); @@ -237,35 +315,7 @@ public sealed class NinjaSystem : SharedNinjaSystem } if (warps.Count > 0) - comp.SpiderChargeTarget = _random.Pick(warps); - } - - private void OnNinjaSpawned(EntityUid uid, NinjaComponent comp, GhostRoleSpawnerUsedEvent args) - { - // inherit spawner's station grid - if (TryComp(args.Spawner, out var station)) - SetNinjaStationGrid(uid, station.Grid); - } - - private void OnNinjaMindAdded(EntityUid uid, NinjaComponent comp, MindAddedMessage args) - { - if (TryComp(uid, out var mind) && mind.Mind != null) - GreetNinja(mind.Mind); - } - - private void GreetNinja(Mind.Mind mind) - { - if (!mind.TryGetSession(out var session)) - return; - - var config = RuleConfig(); - var role = new TraitorRole(mind, _proto.Index("SpaceNinja")); - mind.AddRole(role); - _traitorRule.Traitors.Add(role); - foreach (var objective in config.Objectives) - { - AddObjective(mind, objective); - } + 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(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) diff --git a/Content.Server/Ninja/Systems/SpiderChargeSystem.cs b/Content.Server/Ninja/Systems/SpiderChargeSystem.cs index 94d3fb7911..35cad95335 100644 --- a/Content.Server/Ninja/Systems/SpiderChargeSystem.cs +++ b/Content.Server/Ninja/Systems/SpiderChargeSystem.cs @@ -26,7 +26,7 @@ public sealed class SpiderChargeSystem : EntitySystem { var user = args.User; - if (!TryComp(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(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; } } diff --git a/Content.Server/Objectives/Conditions/DoorjackCondition.cs b/Content.Server/Objectives/Conditions/DoorjackCondition.cs index 335b18f198..fc46d03836 100644 --- a/Content.Server/Objectives/Conditions/DoorjackCondition.cs +++ b/Content.Server/Objectives/Conditions/DoorjackCondition.cs @@ -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(); - if (_mind?.OwnedEntity == null - || !entMan.TryGetComponent(_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; } } diff --git a/Content.Server/Objectives/Conditions/DownloadCondition.cs b/Content.Server/Objectives/Conditions/DownloadCondition.cs index 18948b1955..fe71aa05da 100644 --- a/Content.Server/Objectives/Conditions/DownloadCondition.cs +++ b/Content.Server/Objectives/Conditions/DownloadCondition.cs @@ -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(); - if (_mind?.OwnedEntity == null - || !entMan.TryGetComponent(_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; } } diff --git a/Content.Server/Objectives/Conditions/SpiderChargeCondition.cs b/Content.Server/Objectives/Conditions/SpiderChargeCondition.cs index c8ea4897df..5ae9cad3b1 100644 --- a/Content.Server/Objectives/Conditions/SpiderChargeCondition.cs +++ b/Content.Server/Objectives/Conditions/SpiderChargeCondition.cs @@ -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(); - if (_mind?.OwnedEntity == null - || !entMan.TryGetComponent(_mind.OwnedEntity, out var ninja) - || ninja.SpiderChargeTarget == null - || !entMan.TryGetComponent(ninja.SpiderChargeTarget, out var warp) + if (!NinjaSystem.GetNinjaRole(_mind, out var role) + || role.SpiderChargeTarget == null + || !entMan.TryGetComponent(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(); - if (_mind?.OwnedEntity == null - || !entMan.TryGetComponent(_mind.OwnedEntity, out var ninja)) + if (!NinjaSystem.GetNinjaRole(_mind, out var role)) return 0f; - return ninja.SpiderChargeDetonated ? 1f : 0f; + return role.SpiderChargeDetonated ? 1f : 0f; } } diff --git a/Content.Server/Objectives/Conditions/SurviveCondition.cs b/Content.Server/Objectives/Conditions/SurviveCondition.cs index b4bfe4426d..2641918238 100644 --- a/Content.Server/Objectives/Conditions/SurviveCondition.cs +++ b/Content.Server/Objectives/Conditions/SurviveCondition.cs @@ -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; + + public IObjectiveCondition GetAssigned(Mind.Mind mind) { - private 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); } } diff --git a/Content.Server/Objectives/Conditions/TerrorCondition.cs b/Content.Server/Objectives/Conditions/TerrorCondition.cs index 10f76b6a6e..89d5f41263 100644 --- a/Content.Server/Objectives/Conditions/TerrorCondition.cs +++ b/Content.Server/Objectives/Conditions/TerrorCondition.cs @@ -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(); - if (_mind?.OwnedEntity == null - || !entMan.TryGetComponent(_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 index 0000000000..e330a7f1e8 --- /dev/null +++ b/Content.Server/Objectives/Requirements/NinjaRequirement.cs @@ -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(); + } +} diff --git a/Content.Server/Traitor/TraitorRole.cs b/Content.Server/Traitor/TraitorRole.cs index 4e23122e7d..d7b4d39f30 100644 --- a/Content.Server/Traitor/TraitorRole.cs +++ b/Content.Server/Traitor/TraitorRole.cs @@ -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; } diff --git a/Content.Shared/Ninja/Components/NinjaComponent.cs b/Content.Shared/Ninja/Components/NinjaComponent.cs index 851be9a5a9..3036e06b73 100644 --- a/Content.Shared/Ninja/Components/NinjaComponent.cs +++ b/Content.Shared/Ninja/Components/NinjaComponent.cs @@ -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. /// -// 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 /// /// Grid entity of the station the ninja was spawned around. Set if spawned naturally by the event. /// + [ViewVariables, AutoNetworkedField] public EntityUid? StationGrid; /// @@ -35,35 +35,4 @@ public sealed partial class NinjaComponent : Component /// [ViewVariables] public EntityUid? Katana = null; - - /// - /// Number of doors that have been doorjacked, used for objective - /// - [ViewVariables, AutoNetworkedField] - public int DoorsJacked = 0; - - /// - /// Research nodes that have been downloaded, used for objective - /// - // TODO: client doesn't need to know what nodes are downloaded, just how many - [ViewVariables, AutoNetworkedField] - public HashSet DownloadedNodes = new(); - - /// - /// Warp point that the spider charge has to target - /// - [ViewVariables, AutoNetworkedField] - public EntityUid? SpiderChargeTarget = null; - - /// - /// Whether the spider charge has been detonated on the target, used for objective - /// - [ViewVariables, AutoNetworkedField] - public bool SpiderChargeDetonated; - - /// - /// Whether the comms console has been hacked, used for objective - /// - [ViewVariables, AutoNetworkedField] - public bool CalledInThreat; } diff --git a/Content.Shared/Ninja/Systems/NinjaGlovesSystem.cs b/Content.Shared/Ninja/Systems/NinjaGlovesSystem.cs index bccb3d9521..b62feb188e 100644 --- a/Content.Shared/Ninja/Systems/NinjaGlovesSystem.cs +++ b/Content.Shared/Ninja/Systems/NinjaGlovesSystem.cs @@ -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; + // can't predict roles so only done on server. + protected virtual void OnDownloadDoAfter(EntityUid uid, NinjaDownloadComponent comp, DownloadDoAfterEvent args) { } - var user = args.User; - var target = args.Target; + // cant predict roles for checking if already called + protected virtual void OnTerror(EntityUid uid, NinjaTerrorComponent comp, InteractionAttemptEvent args) { } - if (!TryComp(user, out var ninja) - || !TryComp(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(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 - }; - - _doAfter.TryStartDoAfter(doAfterArgs); - // FIXME: doesnt work, don't show the console popup - args.Cancel(); - } - - //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(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); } } diff --git a/Content.Shared/Ninja/Systems/NinjaSystem.cs b/Content.Shared/Ninja/Systems/NinjaSystem.cs index d1b51ad77c..1097db7f67 100644 --- a/Content.Shared/Ninja/Systems/NinjaSystem.cs +++ b/Content.Shared/Ninja/Systems/NinjaSystem.cs @@ -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; - } - - /// - /// Marks the objective as complete. - /// On server, makes announcement and adds rule of random threat. - /// - public virtual void CallInThreat(NinjaComponent comp) - { - comp.CalledInThreat = true; - } - /// /// Drain power from a target battery into the ninja's suit battery. /// Serverside only. @@ -71,17 +56,6 @@ public abstract class SharedNinjaSystem : EntitySystem { } - /// - /// Download the given set of nodes, returning how many new nodes were downloaded.' - /// - public int Download(NinjaComponent ninja, List ids) - { - var oldCount = ninja.DownloadedNodes.Count; - ninja.DownloadedNodes.UnionWith(ids); - var newCount = ninja.DownloadedNodes.Count; - return newCount - oldCount; - } - /// /// Gets the user's battery and tries to use some charge from it, returning true if successful. /// Serverside only. diff --git a/Resources/Prototypes/Objectives/ninjaObjectives.yml b/Resources/Prototypes/Objectives/ninjaObjectives.yml index d2e1fa4068..8b8208cffa 100644 --- a/Resources/Prototypes/Objectives/ninjaObjectives.yml +++ b/Resources/Prototypes/Objectives/ninjaObjectives.yml @@ -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 {}