diff --git a/Content.Client/CriminalRecords/Systems/CriminalRecordsHackerSystem.cs b/Content.Client/CriminalRecords/Systems/CriminalRecordsHackerSystem.cs new file mode 100644 index 0000000000..21fccc880d --- /dev/null +++ b/Content.Client/CriminalRecords/Systems/CriminalRecordsHackerSystem.cs @@ -0,0 +1,7 @@ +using Content.Shared.CriminalRecords.Systems; + +namespace Content.Client.CriminalRecords.Systems; + +public sealed class CriminalRecordsHackerSystem : SharedCriminalRecordsHackerSystem +{ +} diff --git a/Content.Server/CriminalRecords/Systems/CriminalRecordsHackerSystem.cs b/Content.Server/CriminalRecords/Systems/CriminalRecordsHackerSystem.cs new file mode 100644 index 0000000000..91285a1ca7 --- /dev/null +++ b/Content.Server/CriminalRecords/Systems/CriminalRecordsHackerSystem.cs @@ -0,0 +1,62 @@ +using Content.Server.Chat.Systems; +using Content.Server.Station.Systems; +using Content.Server.StationRecords.Systems; +using Content.Shared.CriminalRecords; +using Content.Shared.CriminalRecords.Components; +using Content.Shared.CriminalRecords.Systems; +using Content.Shared.Dataset; +using Content.Shared.Security; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server.CriminalRecords.Systems; + +public sealed class CriminalRecordsHackerSystem : SharedCriminalRecordsHackerSystem +{ + [Dependency] private readonly ChatSystem _chat = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly StationSystem _station = default!; + [Dependency] private readonly StationRecordsSystem _records = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnDoAfter); + } + + private void OnDoAfter(Entity ent, ref CriminalRecordsHackDoAfterEvent args) + { + if (args.Cancelled || args.Handled || args.Target == null) + return; + + if (_station.GetOwningStation(ent) is not {} station) + return; + + var reasons = _proto.Index(ent.Comp.Reasons); + foreach (var (key, record) in _records.GetRecordsOfType(station)) + { + var reason = _random.Pick(reasons.Values); + record.Status = SecurityStatus.Wanted; + record.Reason = reason; + // no radio message since spam + // no history since lazy and its easy to remove anyway + // main damage with this is existing arrest warrants are lost and to anger beepsky + } + + _chat.DispatchGlobalAnnouncement(Loc.GetString(ent.Comp.Announcement), playSound: true, colorOverride: Color.Red); + + // once is enough + RemComp(ent); + + var ev = new CriminalRecordsHackedEvent(ent, args.Target.Value); + RaiseLocalEvent(args.User, ref ev); + } +} + +/// +/// Raised on the user after hacking a criminal records console. +/// +[ByRefEvent] +public record struct CriminalRecordsHackedEvent(EntityUid User, EntityUid Target); diff --git a/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs b/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs index d84a728775..2c0f6c63e3 100644 --- a/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs +++ b/Content.Server/Ninja/Systems/NinjaGlovesSystem.cs @@ -1,8 +1,9 @@ using Content.Server.Communications; using Content.Server.Mind; using Content.Server.Ninja.Events; -using Content.Server.Objectives.Components; +using Content.Server.Objectives.Systems; using Content.Shared.Communications; +using Content.Shared.CriminalRecords.Components; using Content.Shared.Ninja.Components; using Content.Shared.Ninja.Systems; using Content.Shared.Research.Components; @@ -16,6 +17,7 @@ namespace Content.Server.Ninja.Systems; public sealed class NinjaGlovesSystem : SharedNinjaGlovesSystem { [Dependency] private readonly EmagProviderSystem _emagProvider = default!; + [Dependency] private readonly CodeConditionSystem _codeCondition = default!; [Dependency] private readonly CommsHackerSystem _commsHacker = default!; [Dependency] private readonly MindSystem _mind = default!; [Dependency] private readonly SharedStunProviderSystem _stunProvider = default!; @@ -88,12 +90,16 @@ public sealed class NinjaGlovesSystem : SharedNinjaGlovesSystem EnsureComp(user); // prevent calling in multiple threats by toggling gloves after - if (_mind.TryGetObjectiveComp(user, out var obj) && !obj.CalledInThreat) + if (!_codeCondition.IsCompleted(user, ninja.TerrorObjective)) { var hacker = EnsureComp(user); var rule = _ninja.NinjaRule(user); if (rule != null) _commsHacker.SetThreats(user, rule.Threats, hacker); } + if (!_codeCondition.IsCompleted(user, ninja.MassArrestObjective)) + { + EnsureComp(user); + } } } diff --git a/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs b/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs index 835ac7ad6c..1dfaf4f339 100644 --- a/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs +++ b/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs @@ -1,12 +1,15 @@ using Content.Server.Communications; using Content.Server.Chat.Managers; +using Content.Server.CriminalRecords.Systems; using Content.Server.GameTicking.Rules.Components; +using Content.Server.GenericAntag; +using Content.Server.Objectives.Components; +using Content.Server.Objectives.Systems; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Server.PowerCell; using Content.Server.Research.Systems; using Content.Server.Roles; -using Content.Server.GenericAntag; using Content.Shared.Alert; using Content.Shared.Clothing.EntitySystems; using Content.Shared.Doors.Components; @@ -19,7 +22,6 @@ using Content.Shared.Rounding; using Robust.Shared.Audio; using Robust.Shared.Player; using System.Diagnostics.CodeAnalysis; -using Content.Server.Objectives.Components; using Robust.Shared.Audio.Systems; namespace Content.Server.Ninja.Systems; @@ -28,7 +30,6 @@ namespace Content.Server.Ninja.Systems; // engi -> saboteur // medi -> idk reskin it // other -> assault -// TODO: when criminal records is merged, hack it to set everyone to arrest /// /// Main ninja system that handles ninja setup, provides helper methods for the rest of the code to use. @@ -37,6 +38,7 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem { [Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly CodeConditionSystem _codeCondition = default!; [Dependency] private readonly IChatManager _chatMan = default!; [Dependency] private readonly PowerCellSystem _powerCell = default!; [Dependency] private readonly RoleSystem _role = default!; @@ -52,6 +54,7 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem SubscribeLocalEvent(OnDoorjack); SubscribeLocalEvent(OnResearchStolen); SubscribeLocalEvent(OnThreatCalledIn); + SubscribeLocalEvent(OnCriminalRecordsHacked); } public override void Update(float frameTime) @@ -216,11 +219,21 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem Popup.PopupEntity(str, uid, uid, PopupType.Medium); } - private void OnThreatCalledIn(EntityUid uid, SpaceNinjaComponent comp, ref ThreatCalledInEvent args) + private void OnThreatCalledIn(Entity ent, ref ThreatCalledInEvent args) { - if (_mind.TryGetObjectiveComp(uid, out var obj)) - { - obj.CalledInThreat = true; - } + _codeCondition.SetCompleted(ent.Owner, ent.Comp.TerrorObjective); + } + + private void OnCriminalRecordsHacked(Entity ent, ref CriminalRecordsHackedEvent args) + { + _codeCondition.SetCompleted(ent.Owner, ent.Comp.MassArrestObjective); + } + + /// + /// Called by when it detonates. + /// + public void DetonatedSpiderCharge(Entity ent) + { + _codeCondition.SetCompleted(ent.Owner, ent.Comp.SpiderChargeObjective); } } diff --git a/Content.Server/Ninja/Systems/SpiderChargeSystem.cs b/Content.Server/Ninja/Systems/SpiderChargeSystem.cs index 948d715f0a..64c958d6f1 100644 --- a/Content.Server/Ninja/Systems/SpiderChargeSystem.cs +++ b/Content.Server/Ninja/Systems/SpiderChargeSystem.cs @@ -19,6 +19,7 @@ public sealed class SpiderChargeSystem : EntitySystem [Dependency] private readonly MindSystem _mind = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SpaceNinjaSystem _ninja = default!; public override void Initialize() { @@ -76,10 +77,10 @@ public sealed class SpiderChargeSystem : EntitySystem /// private void OnExplode(EntityUid uid, SpiderChargeComponent comp, TriggerEvent args) { - if (comp.Planter == null || !_mind.TryGetObjectiveComp(comp.Planter.Value, out var obj)) + if (!TryComp(comp.Planter, out var ninja)) return; // assumes the target was destroyed, that the charge wasn't moved somehow - obj.Detonated = true; + _ninja.DetonatedSpiderCharge((comp.Planter.Value, ninja)); } } diff --git a/Content.Server/Objectives/Components/CodeConditionSystem.cs b/Content.Server/Objectives/Components/CodeConditionSystem.cs new file mode 100644 index 0000000000..581098c3f7 --- /dev/null +++ b/Content.Server/Objectives/Components/CodeConditionSystem.cs @@ -0,0 +1,17 @@ +using Content.Server.Objectives.Systems; + +namespace Content.Server.Objectives.Components; + +/// +/// An objective that is set to complete by code in another system. +/// Use to check and set this. +/// +[RegisterComponent, Access(typeof(CodeConditionSystem))] +public sealed partial class CodeConditionComponent : Component +{ + /// + /// Whether the objective is complete or not. + /// + [DataField] + public bool Completed; +} diff --git a/Content.Server/Objectives/Components/SpiderChargeConditionComponent.cs b/Content.Server/Objectives/Components/SpiderChargeConditionComponent.cs index 368c9f27ed..9983b35969 100644 --- a/Content.Server/Objectives/Components/SpiderChargeConditionComponent.cs +++ b/Content.Server/Objectives/Components/SpiderChargeConditionComponent.cs @@ -9,9 +9,6 @@ namespace Content.Server.Objectives.Components; [RegisterComponent, Access(typeof(NinjaConditionsSystem), typeof(SpiderChargeSystem), typeof(SpaceNinjaSystem))] public sealed partial class SpiderChargeConditionComponent : Component { - [DataField, ViewVariables(VVAccess.ReadWrite)] - public bool Detonated; - /// /// Warp point that the spider charge has to target /// diff --git a/Content.Server/Objectives/Components/TerrorConditionComponent.cs b/Content.Server/Objectives/Components/TerrorConditionComponent.cs deleted file mode 100644 index acd3218ad4..0000000000 --- a/Content.Server/Objectives/Components/TerrorConditionComponent.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Content.Server.Objectives.Systems; -using Content.Shared.Ninja.Systems; - -namespace Content.Server.Objectives.Components; - -/// -/// Requires that the player is a ninja and has called in a threat. -/// -[RegisterComponent, Access(typeof(NinjaConditionsSystem), typeof(SharedSpaceNinjaSystem))] -public sealed partial class TerrorConditionComponent : Component -{ - /// - /// Whether the comms console has been hacked - /// - [DataField("calledInThreat"), ViewVariables(VVAccess.ReadWrite)] - public bool CalledInThreat; -} diff --git a/Content.Server/Objectives/Systems/CodeConditionSystem.cs b/Content.Server/Objectives/Systems/CodeConditionSystem.cs new file mode 100644 index 0000000000..7ba312f4bb --- /dev/null +++ b/Content.Server/Objectives/Systems/CodeConditionSystem.cs @@ -0,0 +1,76 @@ +using Content.Server.Objectives.Components; +using Content.Shared.Objectives.Components; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; + +namespace Content.Server.Objectives.Systems; + +/// +/// Handles progress and provides API for systems to use. +/// +public sealed class CodeConditionSystem : EntitySystem +{ + [Dependency] private readonly SharedMindSystem _mind = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetProgress); + } + + private void OnGetProgress(Entity ent, ref ObjectiveGetProgressEvent args) + { + args.Progress = ent.Comp.Completed ? 1f : 0f; + } + + /// + /// Returns whether an objective is completed. + /// + public bool IsCompleted(Entity ent) + { + if (!Resolve(ent, ref ent.Comp)) + return false; + + return ent.Comp.Completed; + } + + /// + /// Returns true if a mob's objective with a certain prototype is completed. + /// + public bool IsCompleted(Entity mob, string prototype) + { + if (_mind.GetMind(mob, mob.Comp) is not {} mindId) + return false; + + if (!_mind.TryFindObjective(mindId, prototype, out var obj)) + return false; + + return IsCompleted(obj.Value); + } + + /// + /// Sets an objective's completed field. + /// + public void SetCompleted(Entity ent, bool completed = true) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + ent.Comp.Completed = completed; + } + + /// + /// Sets a mob's objective to complete. + /// + public void SetCompleted(Entity mob, string prototype, bool completed = true) + { + if (_mind.GetMind(mob, mob.Comp) is not {} mindId) + return; + + if (!_mind.TryFindObjective(mindId, prototype, out var obj)) + return; + + SetCompleted(obj.Value, completed); + } +} diff --git a/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs b/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs index 888a365a5d..47c54b937a 100644 --- a/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs +++ b/Content.Server/Objectives/Systems/NinjaConditionsSystem.cs @@ -23,11 +23,8 @@ public sealed class NinjaConditionsSystem : EntitySystem SubscribeLocalEvent(OnSpiderChargeRequirementCheck); SubscribeLocalEvent(OnSpiderChargeAfterAssign); - SubscribeLocalEvent(OnSpiderChargeGetProgress); SubscribeLocalEvent(OnStealResearchGetProgress); - - SubscribeLocalEvent(OnTerrorGetProgress); } // doorjack @@ -88,11 +85,6 @@ public sealed class NinjaConditionsSystem : EntitySystem _metaData.SetEntityName(uid, title, args.Meta); } - private void OnSpiderChargeGetProgress(EntityUid uid, SpiderChargeConditionComponent comp, ref ObjectiveGetProgressEvent args) - { - args.Progress = comp.Detonated ? 1f : 0f; - } - // steal research private void OnStealResearchGetProgress(EntityUid uid, StealResearchConditionComponent comp, ref ObjectiveGetProgressEvent args) @@ -108,9 +100,4 @@ public sealed class NinjaConditionsSystem : EntitySystem return MathF.Min(comp.DownloadedNodes.Count / (float) target, 1f); } - - private void OnTerrorGetProgress(EntityUid uid, TerrorConditionComponent comp, ref ObjectiveGetProgressEvent args) - { - args.Progress = comp.CalledInThreat ? 1f : 0f; - } } diff --git a/Content.Shared/CriminalRecords/Components/CriminalRecordsHackerComponent.cs b/Content.Shared/CriminalRecords/Components/CriminalRecordsHackerComponent.cs new file mode 100644 index 0000000000..189a387a5d --- /dev/null +++ b/Content.Shared/CriminalRecords/Components/CriminalRecordsHackerComponent.cs @@ -0,0 +1,31 @@ +using Content.Shared.CriminalRecords.Systems; +using Content.Shared.Dataset; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.CriminalRecords.Components; + +/// +/// Lets the user hack a criminal records console, once. +/// Everyone is set to wanted with a randomly picked reason. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(SharedCriminalRecordsHackerSystem))] +public sealed partial class CriminalRecordsHackerComponent : Component +{ + /// + /// How long the doafter is for hacking it. + /// + public TimeSpan Delay = TimeSpan.FromSeconds(20); + + /// + /// Dataset of random reasons to use. + /// + [DataField] + public ProtoId Reasons = "CriminalRecordsWantedReasonPlaceholders"; + + /// + /// Announcement made after the console is hacked. + /// + [DataField] + public LocId Announcement = "ninja-criminal-records-hack-announcement"; +} diff --git a/Content.Shared/CriminalRecords/Systems/SharedCriminalRecordsHackerSystem.cs b/Content.Shared/CriminalRecords/Systems/SharedCriminalRecordsHackerSystem.cs new file mode 100644 index 0000000000..e8e8e524e2 --- /dev/null +++ b/Content.Shared/CriminalRecords/Systems/SharedCriminalRecordsHackerSystem.cs @@ -0,0 +1,48 @@ +using Content.Shared.CriminalRecords.Components; +using Content.Shared.DoAfter; +using Content.Shared.Interaction; +using Content.Shared.Ninja.Systems; +using Robust.Shared.Serialization; + +namespace Content.Shared.CriminalRecords.Systems; + +public abstract class SharedCriminalRecordsHackerSystem : EntitySystem +{ + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedNinjaGlovesSystem _gloves = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnBeforeInteractHand); + } + + private void OnBeforeInteractHand(Entity ent, ref BeforeInteractHandEvent args) + { + // TODO: generic event + if (args.Handled || !_gloves.AbilityCheck(ent, args, out var target)) + return; + + if (!HasComp(target)) + return; + + var doAfterArgs = new DoAfterArgs(EntityManager, ent, ent.Comp.Delay, new CriminalRecordsHackDoAfterEvent(), target: target, used: ent, eventTarget: ent) + { + BreakOnDamage = true, + BreakOnUserMove = true, + MovementThreshold = 0.5f + }; + + _doAfter.TryStartDoAfter(doAfterArgs); + args.Handled = true; + } +} + +/// +/// Raised on the user when the doafter completes. +/// +[Serializable, NetSerializable] +public sealed partial class CriminalRecordsHackDoAfterEvent : SimpleDoAfterEvent +{ +} diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index 1898126d80..7887b8f9b2 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -383,6 +383,30 @@ public abstract class SharedMindSystem : EntitySystem return false; } + /// + /// Tries to find an objective that has the same prototype as the argument. + /// + /// + /// Will not work for objectives that have no prototype, or duplicate objectives with the same prototype. + /// + public bool TryFindObjective(Entity mind, string prototype, [NotNullWhen(true)] out EntityUid? objective) + { + objective = null; + if (!Resolve(mind, ref mind.Comp)) + return false; + + foreach (var uid in mind.Comp.Objectives) + { + if (MetaData(uid).EntityPrototype?.ID == prototype) + { + objective = uid; + return true; + } + } + + return false; + } + public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out ICommonSession? session) { session = null; diff --git a/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs b/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs index dff4b56aa4..0f3bff265c 100644 --- a/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs +++ b/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs @@ -1,6 +1,6 @@ using Content.Shared.Ninja.Systems; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; +using Robust.Shared.Prototypes; namespace Content.Shared.Ninja.Components; @@ -35,4 +35,22 @@ public sealed partial class SpaceNinjaComponent : Component /// [DataField("katana"), AutoNetworkedField] public EntityUid? Katana; + + /// + /// Objective to complete after calling in a threat. + /// + [DataField] + public EntProtoId TerrorObjective = "TerrorObjective"; + + /// + /// Objective to complete after setting everyone to arrest. + /// + [DataField] + public EntProtoId MassArrestObjective = "MassArrestObjective"; + + /// + /// Objective to complete after the spider charge detonates. + /// + [DataField] + public EntProtoId SpiderChargeObjective = "SpiderChargeObjective"; } diff --git a/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs b/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs index 815464bf7a..f61d0c6a90 100644 --- a/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs +++ b/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Actions; using Content.Shared.CombatMode; using Content.Shared.Communications; +using Content.Shared.CriminalRecords.Components; using Content.Shared.Examine; using Content.Shared.Hands.Components; using Content.Shared.Interaction; @@ -62,6 +63,7 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem RemComp(user); RemComp(user); RemComp(user); + RemComp(user); } /// diff --git a/Resources/Locale/en-US/ninja/ninja-actions.ftl b/Resources/Locale/en-US/ninja/ninja-actions.ftl index b42da33a29..f01f02a60e 100644 --- a/Resources/Locale/en-US/ninja/ninja-actions.ftl +++ b/Resources/Locale/en-US/ninja/ninja-actions.ftl @@ -4,3 +4,5 @@ ninja-suit-cooldown = The suit needs time to recuperate from the last attack. ninja-research-steal-fail = No new research nodes were stolen... ninja-research-steal-success = Stole {$count} new nodes from {THE($server)}. + +ninja-criminal-records-hack-announcement = ERROR: Criminal records has detected a [REDACTED] error #*;" diff --git a/Resources/Prototypes/Datasets/criminal_records.yml b/Resources/Prototypes/Datasets/criminal_records.yml index ee28309184..fe21757cd2 100644 --- a/Resources/Prototypes/Datasets/criminal_records.yml +++ b/Resources/Prototypes/Datasets/criminal_records.yml @@ -2,17 +2,23 @@ - type: dataset id: CriminalRecordsWantedReasonPlaceholders values: + - Ate a delicious valid salad - Ate their own shoes - Being a clown - Being a mime - Breathed the wrong way - Broke into evac - Did literally nothing + - Did their job - Didn't say hello to me - Drank one too many + - Had two toolboxes, that's too many - Lied on common radio - Looked at me funny + - Lubed up the entire way to evac + - Set AME up on time - Slipped the HoS - Stole the clown's mask - Told an unfunny joke - Wore a gasmask + - Wore boxing gloves diff --git a/Resources/Prototypes/GameRules/midround.yml b/Resources/Prototypes/GameRules/midround.yml index c417132992..5a4cde3101 100644 --- a/Resources/Prototypes/GameRules/midround.yml +++ b/Resources/Prototypes/GameRules/midround.yml @@ -12,6 +12,7 @@ - DoorjackObjective - SpiderChargeObjective - TerrorObjective + - MassArrestObjective - NinjaSurviveObjective - type: NinjaRule threats: NinjaThreats diff --git a/Resources/Prototypes/Objectives/base_objectives.yml b/Resources/Prototypes/Objectives/base_objectives.yml index e24b26e6e8..2ab5149213 100644 --- a/Resources/Prototypes/Objectives/base_objectives.yml +++ b/Resources/Prototypes/Objectives/base_objectives.yml @@ -103,3 +103,11 @@ id: BaseSurviveObjective components: - type: SurviveCondition + +# objective progress is controlled by a system and not the objective itself +- type: entity + abstract: true + parent: BaseObjective + id: BaseCodeObjective + components: + - type: CodeCondition diff --git a/Resources/Prototypes/Objectives/ninja.yml b/Resources/Prototypes/Objectives/ninja.yml index f2ac97be58..0203059c2c 100644 --- a/Resources/Prototypes/Objectives/ninja.yml +++ b/Resources/Prototypes/Objectives/ninja.yml @@ -46,7 +46,7 @@ - type: entity noSpawn: true - parent: BaseNinjaObjective + parent: [BaseNinjaObjective, BaseCodeObjective] id: SpiderChargeObjective description: This bomb can be detonated in a specific location. Note that the bomb will not work anywhere else! components: @@ -54,7 +54,6 @@ icon: sprite: Objects/Weapons/Bombs/spidercharge.rsi state: icon - - type: SpiderChargeCondition - type: entity noSpawn: true @@ -70,7 +69,7 @@ - type: entity noSpawn: true - parent: BaseNinjaObjective + parent: [BaseNinjaObjective, BaseCodeObjective] id: TerrorObjective name: Call in a threat description: Use your gloves on a communication console in order to bring another threat to the station. @@ -79,4 +78,15 @@ icon: sprite: Objects/Fun/Instruments/otherinstruments.rsi state: red_phone - - type: TerrorCondition + +- type: entity + noSpawn: true + parent: [BaseNinjaObjective, BaseCodeObjective] + id: MassArrestObjective + name: Set everyone to wanted + description: Use your gloves to hack a criminal records console, setting the entire station to be wanted! + components: + - type: Objective + icon: + sprite: Objects/Weapons/Melee/stunbaton.rsi + state: stunbaton_on