diff --git a/Content.Server/Explosion/Components/ShockOnTriggerComponent.cs b/Content.Server/Explosion/Components/ShockOnTriggerComponent.cs new file mode 100644 index 0000000000..a553cc047a --- /dev/null +++ b/Content.Server/Explosion/Components/ShockOnTriggerComponent.cs @@ -0,0 +1,37 @@ +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +using Content.Server.Explosion.EntitySystems; + +namespace Content.Server.Explosion.Components; + +/// +/// A component that electrocutes an entity having this component when a trigger is triggered. +/// +[RegisterComponent, AutoGenerateComponentPause] +[Access(typeof(TriggerSystem))] +public sealed partial class ShockOnTriggerComponent : Component +{ + /// + /// The force of an electric shock when the trigger is triggered. + /// + [DataField] + public int Damage = 5; + + /// + /// Duration of electric shock when the trigger is triggered. + /// + [DataField] + public TimeSpan Duration = TimeSpan.FromSeconds(2); + + /// + /// The minimum delay between repeating triggers. + /// + [DataField] + public TimeSpan Cooldown = TimeSpan.FromSeconds(4); + + /// + /// When can the trigger run again? + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + [AutoPausedField] + public TimeSpan NextTrigger = TimeSpan.Zero; +} diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index 1fde61cada..be47585f5a 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Body.Systems; using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.Explosion.Components; using Content.Server.Flash; +using Content.Server.Electrocution; using Content.Server.Pinpointer; using Content.Shared.Flash.Components; using Content.Server.Radio.EntitySystems; @@ -33,6 +34,7 @@ using Robust.Shared.Random; using Robust.Shared.Player; using Content.Shared.Coordinates; using Robust.Shared.Utility; +using Robust.Shared.Timing; namespace Content.Server.Explosion.EntitySystems { @@ -75,6 +77,7 @@ namespace Content.Server.Explosion.EntitySystems [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly ElectrocutionSystem _electrocution = default!; public override void Initialize() { @@ -104,6 +107,7 @@ namespace Content.Server.Explosion.EntitySystems SubscribeLocalEvent(OnAnchorTrigger); SubscribeLocalEvent(OnSoundTrigger); + SubscribeLocalEvent(HandleShockTrigger); SubscribeLocalEvent(HandleRattleTrigger); } @@ -120,6 +124,24 @@ namespace Content.Server.Explosion.EntitySystems } } + private void HandleShockTrigger(Entity shockOnTrigger, ref TriggerEvent args) + { + if (!_container.TryGetContainingContainer(shockOnTrigger, out var container)) + return; + + var containerEnt = container.Owner; + var curTime = _timing.CurTime; + + if (curTime < shockOnTrigger.Comp.NextTrigger) + { + // The trigger's on cooldown. + return; + } + + _electrocution.TryDoElectrocution(containerEnt, null, shockOnTrigger.Comp.Damage, shockOnTrigger.Comp.Duration, true); + shockOnTrigger.Comp.NextTrigger = curTime + shockOnTrigger.Comp.Cooldown; + } + private void OnAnchorTrigger(EntityUid uid, AnchorOnTriggerComponent component, TriggerEvent args) { var xform = Transform(uid); diff --git a/Content.Server/Nyanotrasen/Item/ShockCollar/ShockCollarComponent.cs b/Content.Server/Nyanotrasen/Item/ShockCollar/ShockCollarComponent.cs deleted file mode 100644 index 1dcbc48676..0000000000 --- a/Content.Server/Nyanotrasen/Item/ShockCollar/ShockCollarComponent.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Content.Server.ShockCollar; - -[RegisterComponent] -public sealed partial class ShockCollarComponent : Component -{ - [DataField] - public int ShockDamage = 1; - - [DataField] - public TimeSpan ShockTime = TimeSpan.FromSeconds(2); -} - diff --git a/Content.Server/Nyanotrasen/Item/ShockCollar/ShockCollarSystem.cs b/Content.Server/Nyanotrasen/Item/ShockCollar/ShockCollarSystem.cs deleted file mode 100644 index eeb0f59d42..0000000000 --- a/Content.Server/Nyanotrasen/Item/ShockCollar/ShockCollarSystem.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Content.Shared.Mobs.Components; -using Content.Shared.Timing; -using Content.Server.Explosion.EntitySystems; // Why is trigger under explosions by the way? Even doors already use it. -using Content.Server.Electrocution; -using Robust.Shared.Containers; - -namespace Content.Server.ShockCollar; - -public sealed partial class ShockCollarSystem : EntitySystem -{ - [Dependency] private readonly SharedContainerSystem _container = default!; - [Dependency] private readonly ElectrocutionSystem _electrocutionSystem = default!; - [Dependency] private readonly UseDelaySystem _useDelay = default!; - - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnTrigger); - } - - private void OnTrigger(EntityUid uid, ShockCollarComponent component, TriggerEvent args) - { - if (!_container.TryGetContainingContainer(uid, out var container)) // Try to get the entity directly containing this - return; - - var containerEnt = container.Owner; - - if (!HasComp(containerEnt)) // If it's not a mob we don't care - return; - - // DeltaV: prevent clocks from instantly killing people - if (TryComp(uid, out var useDelay) - && !_useDelay.TryResetDelay((uid, useDelay), true)) - return; - - _electrocutionSystem.TryDoElectrocution(containerEnt, null, component.ShockDamage, component.ShockTime, true, ignoreInsulation: true); - } -} - diff --git a/Content.Server/Strip/StrippableSystem.cs b/Content.Server/Strip/StrippableSystem.cs index 4a03bfba9e..7f00c63c4f 100644 --- a/Content.Server/Strip/StrippableSystem.cs +++ b/Content.Server/Strip/StrippableSystem.cs @@ -219,7 +219,7 @@ namespace Content.Server.Strip return; } - var (time, stealth) = GetStripTimeModifiers(user, target, slotDef.StripTime); + var (time, stealth) = GetStripTimeModifiers(user, target, held, slotDef.StripTime); bool hidden = stealth == ThievingStealth.Hidden; @@ -309,7 +309,7 @@ namespace Content.Server.Strip return; } - var (time, stealth) = GetStripTimeModifiers(user, target, slotDef.StripTime); + var (time, stealth) = GetStripTimeModifiers(user, target, item, slotDef.StripTime); bool hidden = stealth == ThievingStealth.Hidden; @@ -416,7 +416,7 @@ namespace Content.Server.Strip if (!CanStripInsertHand(user, target, held, handName)) return; - var (time, stealth) = GetStripTimeModifiers(user, target, targetStrippable.HandStripDelay); + var (time, stealth) = GetStripTimeModifiers(user, target, null, targetStrippable.HandStripDelay); bool hidden = stealth == ThievingStealth.Hidden; @@ -517,7 +517,7 @@ namespace Content.Server.Strip if (!CanStripRemoveHand(user, target, item, handName)) return; - var (time, stealth) = GetStripTimeModifiers(user, target, targetStrippable.HandStripDelay); + var (time, stealth) = GetStripTimeModifiers(user, target, null, targetStrippable.HandStripDelay); bool hidden = stealth == ThievingStealth.Hidden; diff --git a/Content.Shared/Clothing/Components/ClothingComponent.cs b/Content.Shared/Clothing/Components/ClothingComponent.cs index 02a0181eb5..bf52720fe6 100644 --- a/Content.Shared/Clothing/Components/ClothingComponent.cs +++ b/Content.Shared/Clothing/Components/ClothingComponent.cs @@ -71,6 +71,13 @@ public sealed partial class ClothingComponent : Component [DataField] public TimeSpan UnequipDelay = TimeSpan.Zero; + /// + /// Offset for the strip time for an entity with this component. + /// Only applied when it is being equipped or removed by another player. + /// + [DataField] + public TimeSpan StripDelay = TimeSpan.Zero; + /// /// These functions are called when an entity equips an item with this component. /// diff --git a/Content.Shared/Clothing/Components/SelfUnremovableClothingComponent.cs b/Content.Shared/Clothing/Components/SelfUnremovableClothingComponent.cs new file mode 100644 index 0000000000..1d624516ec --- /dev/null +++ b/Content.Shared/Clothing/Components/SelfUnremovableClothingComponent.cs @@ -0,0 +1,18 @@ +using Content.Shared.Clothing.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Clothing.Components; + +/// +/// The component prohibits the player from taking off clothes on them that have this component. +/// +/// +/// See also ClothingComponent.EquipDelay if you want the clothes that the player cannot take off by himself to be put on by the player with a delay. +/// +[NetworkedComponent] +[RegisterComponent] +[Access(typeof(SelfUnremovableClothingSystem))] +public sealed partial class SelfUnremovableClothingComponent : Component +{ + +} diff --git a/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs index b97348bf11..2d4c073e0c 100644 --- a/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs +++ b/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Item; +using Content.Shared.Strip.Components; using Robust.Shared.Containers; using Robust.Shared.GameStates; @@ -36,6 +37,8 @@ public abstract class ClothingSystem : EntitySystem SubscribeLocalEvent(OnEquipDoAfter); SubscribeLocalEvent(OnUnequipDoAfter); + + SubscribeLocalEvent(OnItemStripped); } private void OnUseInHand(Entity ent, ref UseInHandEvent args) @@ -227,6 +230,11 @@ public abstract class ClothingSystem : EntitySystem _handsSystem.TryPickup(args.User, ent); } + private void OnItemStripped(Entity ent, ref BeforeItemStrippedEvent args) + { + args.Additive += ent.Comp.StripDelay; + } + private void CheckEquipmentForLayerHide(EntityUid equipment, EntityUid equipee) { if (TryComp(equipment, out HideLayerClothingComponent? clothesComp) && TryComp(equipee, out HumanoidAppearanceComponent? appearanceComp)) diff --git a/Content.Shared/Clothing/EntitySystems/SelfUnremovableClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/SelfUnremovableClothingSystem.cs new file mode 100644 index 0000000000..ab0c41c5c7 --- /dev/null +++ b/Content.Shared/Clothing/EntitySystems/SelfUnremovableClothingSystem.cs @@ -0,0 +1,36 @@ +using Content.Shared.Clothing.Components; +using Content.Shared.Examine; +using Content.Shared.Inventory; +using Content.Shared.Inventory.Events; + +namespace Content.Shared.Clothing.EntitySystems; + +/// +/// A system for the operation of a component that prohibits the player from taking off his own clothes that have this component. +/// +public sealed class SelfUnremovableClothingSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUnequip); + SubscribeLocalEvent(OnUnequipMarkup); + } + + private void OnUnequip(Entity selfUnremovableClothing, ref BeingUnequippedAttemptEvent args) + { + if (TryComp(selfUnremovableClothing, out var clothing) && (clothing.Slots & args.SlotFlags) == SlotFlags.NONE) + return; + + if (args.UnEquipTarget == args.Unequipee) + { + args.Cancel(); + } + } + + private void OnUnequipMarkup(Entity selfUnremovableClothing, ref ExaminedEvent args) + { + args.PushMarkup(Loc.GetString("comp-self-unremovable-clothing")); + } +} diff --git a/Content.Shared/Clothing/EntitySystems/ToggleableClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/ToggleableClothingSystem.cs index 63f817f9bb..4b9db83722 100644 --- a/Content.Shared/Clothing/EntitySystems/ToggleableClothingSystem.cs +++ b/Content.Shared/Clothing/EntitySystems/ToggleableClothingSystem.cs @@ -106,7 +106,7 @@ public sealed class ToggleableClothingSystem : EntitySystem if (comp.StripDelay == null) return; - var (time, stealth) = _strippable.GetStripTimeModifiers(user, wearer, comp.StripDelay.Value); + var (time, stealth) = _strippable.GetStripTimeModifiers(user, wearer, toggleable, comp.StripDelay.Value); bool hidden = stealth == ThievingStealth.Hidden; diff --git a/Content.Shared/Strip/Components/StrippableComponent.cs b/Content.Shared/Strip/Components/StrippableComponent.cs index 0072580829..551fdfda67 100644 --- a/Content.Shared/Strip/Components/StrippableComponent.cs +++ b/Content.Shared/Strip/Components/StrippableComponent.cs @@ -44,6 +44,15 @@ namespace Content.Shared.Strip.Components public SlotFlags TargetSlots { get; } = SlotFlags.GLOVES; } + /// + /// Used to modify strip times. Raised directed at the item being stripped. + /// + /// + /// This is also used by some stripping related interactions, i.e., interactions with items that are currently equipped by another player. + /// + [ByRefEvent] + public sealed class BeforeItemStrippedEvent(TimeSpan initialTime, ThievingStealth stealth = ThievingStealth.Obvious) : BaseBeforeStripEvent(initialTime, stealth); + /// /// Used to modify strip times. Raised directed at the user. /// diff --git a/Content.Shared/Strip/SharedStrippableSystem.cs b/Content.Shared/Strip/SharedStrippableSystem.cs index 3897c6cc7d..e402a00341 100644 --- a/Content.Shared/Strip/SharedStrippableSystem.cs +++ b/Content.Shared/Strip/SharedStrippableSystem.cs @@ -26,20 +26,26 @@ public abstract class SharedStrippableSystem : EntitySystem private void OnActivateInWorld(EntityUid uid, StrippableComponent component, ActivateInWorldEvent args) { - if (args.Handled || args.Target == args.User) + if (args.Handled || !args.Complex || args.Target == args.User) return; if (TryOpenStrippingUi(args.User, (uid, component))) args.Handled = true; } - public (TimeSpan Time, ThievingStealth Stealth) GetStripTimeModifiers(EntityUid user, EntityUid target, TimeSpan initialTime) + /// + /// Modify the strip time via events. Raised directed at the item being stripped, the player stripping someone and the player being stripped. + /// + public (TimeSpan Time, ThievingStealth Stealth) GetStripTimeModifiers(EntityUid user, EntityUid targetPlayer, EntityUid? targetItem, TimeSpan initialTime) { - var userEv = new BeforeStripEvent(initialTime); + var itemEv = new BeforeItemStrippedEvent(initialTime); + if (targetItem != null) + RaiseLocalEvent(targetItem.Value, ref itemEv); + var userEv = new BeforeStripEvent(itemEv.Time, itemEv.Stealth); RaiseLocalEvent(user, ref userEv); - var ev = new BeforeGettingStrippedEvent(userEv.Time, userEv.Stealth); - RaiseLocalEvent(target, ref ev); - return (ev.Time, ev.Stealth); + var targetEv = new BeforeGettingStrippedEvent(userEv.Time, userEv.Stealth); + RaiseLocalEvent(targetPlayer, ref targetEv); + return (targetEv.Time, targetEv.Stealth); } private void OnDragDrop(EntityUid uid, StrippableComponent component, ref DragDropDraggedEvent args) diff --git a/Resources/Locale/en-US/clothing/components/self-unremovable-clothing-component.ftl b/Resources/Locale/en-US/clothing/components/self-unremovable-clothing-component.ftl new file mode 100644 index 0000000000..bb7ff0206f --- /dev/null +++ b/Resources/Locale/en-US/clothing/components/self-unremovable-clothing-component.ftl @@ -0,0 +1 @@ +comp-self-unremovable-clothing = This cannot be removed without outside help. diff --git a/Resources/Locale/en-US/research/technologies.ftl b/Resources/Locale/en-US/research/technologies.ftl index 620d9bfcdf..55a255ac62 100644 --- a/Resources/Locale/en-US/research/technologies.ftl +++ b/Resources/Locale/en-US/research/technologies.ftl @@ -27,6 +27,7 @@ research-technology-basic-weapons = Basic Weapons research-technology-draconic-munitions = Draconic Munitions research-technology-uranium-munitions = Uranium Munitions research-technology-explosive-technology = Explosive Technology +research-technology-special-means = Special Means research-technology-practice-ammunition = Practice Ammunition research-technology-shrapnel-munitions = Shrapnel Munitions research-technology-advanced-weapons = Advanced Weapons diff --git a/Resources/Migrations/eeMigration.yml b/Resources/Migrations/eeMigration.yml index 30884009d6..9810f61b62 100644 --- a/Resources/Migrations/eeMigration.yml +++ b/Resources/Migrations/eeMigration.yml @@ -143,3 +143,6 @@ SpeedLoaderRifleHeavyRubber: SpeedLoaderRifleHeavy WeaponRifleGestioRubber: WeaponRifleGestio WeaponRifleNovaliteC1Rubber: WeaponRifleNovaliteC1 WeaponSniperRepeaterNonlethal: WeaponSniperRepeater + +# 2025-06-09 +ShockCollar: ClothingNeckShockCollar diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml index b5678fd72a..9a50363ec4 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml @@ -21,7 +21,10 @@ - id: ClothingOuterHardsuitCombatWarden # WD EDIT: ClothingOuterHardsuitCombatWarden -> ClothingOuterHardsuitWarden - id: HoloprojectorSecurity - id: BookSpaceLaw - # - id: ClothingEyesHudSecurity - WD EDIT + - id: ClothingNeckShockCollar + amount: 2 + - id: RemoteSignaller + amount: 2 - id: BoxPDAPrisoner - id: ClothingShoesBootsWinterWarden - id: BoxEncryptionKeyPrisoner @@ -56,7 +59,10 @@ - id: DoorRemoteArmory - id: HoloprojectorSecurity - id: BookSpaceLaw - # - id: ClothingEyesHudSecurity - WD EDIT + - id: ClothingNeckShockCollar + amount: 2 + - id: RemoteSignaller + amount: 2 - id: BoxPDAPrisoner - id: ClothingShoesBootsWinterWarden - id: BoxEncryptionKeyPrisoner diff --git a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml index 645e9db503..c4f090c2b6 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml @@ -348,6 +348,29 @@ - type: Unremoveable deleteOnDrop: false +- type: entity + parent: ClothingBackpack + id: ClothingBackpackElectropack + name: electropack + suffix: SelfUnremovable + description: Shocks on the signal. It is used to keep a particularly dangerous criminal under control. + components: + - type: Sprite + sprite: Clothing/Back/Backpacks/electropack.rsi + state: icon + - type: Clothing + stripDelay: 10 + equipDelay: 5 # to avoid accidentally falling into the trap associated with SelfUnremovableClothing + - type: SelfUnremovableClothing + - type: ShockOnTrigger + damage: 5 + duration: 3 + cooldown: 4 + - type: TriggerOnSignal + - type: DeviceLinkSink + ports: + - Trigger + # Debug - type: entity parent: ClothingBackpack diff --git a/Resources/Prototypes/Entities/Objects/Devices/shock_collar.yml b/Resources/Prototypes/Entities/Objects/Devices/shock_collar.yml new file mode 100644 index 0000000000..22f2d097fc --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Devices/shock_collar.yml @@ -0,0 +1,36 @@ +- type: entity + parent: Clothing + id: ClothingNeckShockCollar + name: shock collar + suffix: SelfUnremovable + description: An electric collar that shocks on the signal. + components: + - type: Item + size: Small + - type: Sprite + sprite: Clothing/Neck/Misc/shock_collar.rsi + state: icon + - type: Clothing + sprite: Clothing/Neck/Misc/shock_collar.rsi + stripDelay: 10 + equipDelay: 5 # to avoid accidentally falling into the trap associated with SelfUnremovableClothing + quickEquip: true + slots: + - neck + - type: SelfUnremovableClothing + - type: ShockOnTrigger + damage: 5 + duration: 3 + cooldown: 4 + - type: TriggerOnSignal + - type: DeviceLinkSink + ports: + - Trigger + - type: GuideHelp + guides: + - Security + - type: StealTarget + stealGroup: ClothingNeckShockCollar + - type: Tag + tags: + - WhitelistChameleon diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 74adc977ec..c378bbf044 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -1000,8 +1000,7 @@ - WeaponFlareGunSecurity - WeaponLaserCarbinePractice - Zipties - - GrenadeFlashBang # Goobstation - - ShockCollar + - GrenadeFlashBang # # DeltaV - .38 special ammo - Add various .38 special ammo to security techfab # WWDP disable "special" # - MagazineBoxSpecial # - MagazineBoxSpecialPractice @@ -1101,9 +1100,8 @@ - WeaponLaserCannon - WeaponLaserCarbine - ClothingEyesNightVisionSecurityGoggles - - ClothingHeadHelmetInsulated # Nyanotrasen - Insulative headgear - - ClothingHeadCage # Nyanotrasen - Insulative headgear - - ShockCollar # Nyanotrasen - Shock Collar + - ClothingHeadHelmetInsulated + - ClothingHeadCage - WeaponXrayCannon - WeaponEnergyGun - WeaponEnergyGunMini @@ -1166,6 +1164,7 @@ - MagazineUniversalMagnumIncendiary - MagazineUniversalMagnumShrapnel - WeaponPistolUniversal + - ClothingBackpackElectropack # WD EDIT START - MagazineShotgunLaser - BoxLaser diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml index fde726ed03..2a334ef5e6 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml @@ -115,7 +115,7 @@ - TelecomServerCircuitboard - MiniGravityGeneratorCircuitboard - Portafib - - ShockCollar + - ClothingNeckShockCollar - GlimmerMonitorCartridge - PotatoAIChip - CargoTelepadMachineCircuitboard diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/shock_collar.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/shock_collar.yml deleted file mode 100644 index 1266a721fe..0000000000 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/shock_collar.yml +++ /dev/null @@ -1,24 +0,0 @@ -- type: entity - parent: ClothingNeckBase - id: ShockCollar - name: shock collar - description: Shocking. # DeltaV: sprite is fine - components: - - type: Sprite - sprite: Nyanotrasen/Clothing/Neck/Misc/shock.rsi - - type: Clothing - sprite: Nyanotrasen/Clothing/Neck/Misc/shock.rsi - equipDelay: 1 - unequipDelay: 10 # It's a collar meant to be used on prisoners (or not), so it probably has some sort of safety. - - type: ShockCollar - - type: UseDelay - delay: 3 # DeltaV: prevent clocks instakilling people - - type: TriggerOnSignal - - type: DeviceNetwork - deviceNetId: Wireless - receiveFrequencyId: BasicDevice - - type: WirelessNetworkConnection - range: 200 - - type: DeviceLinkSink - ports: - - Trigger diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/security.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/security.yml index 34aa7e7ce8..ac6a9395b3 100644 --- a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/security.yml +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/security.yml @@ -17,18 +17,6 @@ Steel: 400 Bluespace: 20 -- type: latheRecipe - id: ShockCollar - icon: - sprite: Nyanotrasen/Clothing/Neck/Misc/shock.rsi - state: icon - result: ShockCollar - completetime: 2 - materials: - Steel: 300 - Glass: 100 - Plastic: 100 - - type: latheRecipe id: ShellSoulbreaker icon: diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index 4db5b4e54e..9c61d0a803 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -17,14 +17,14 @@ NukeDiskStealObjective: 1 MagbootsStealObjective: 1 CorgiMeatStealObjective: 1 - MantisKnifeStealObjective: 1 # Nyanotrasen - ForensicMantis steal objective, see Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml + MantisKnifeStealObjective: 1 ClipboardStealObjective: 1 CaptainGunStealObjective: 0.5 NTRepGunStealObjective: 0.5 CaptainJetpackStealObjective: 0.5 HandTeleporterStealObjective: 0.5 - LOLuckyBillStealObjective: 0.5 # DeltaV - LO steal objective, see Resources/Prototypes/DeltaV/Objectives/traitor.yml - HoPBookIanDossierStealObjective: 1 # DeltaV - HoP steal objective, see Resources/Prototypes/DeltaV/Objectives/traitor.yml + LOLuckyBillStealObjective: 0.5 + HoPBookIanDossierStealObjective: 1 HoSGunStealObjective: 0.5 StealSupermatterSliverObjective: 0.5 EnergyShotgunStealObjective: 0.5 @@ -47,7 +47,7 @@ weights: # RandomTraitorAliveObjective: 1 # WWDP - disabled because it was very boring RandomTraitorProgressObjective: 1 - # RaiseGlimmerObjective: 0.5 # Nyanotrasen - Raise glimmer to a target amount, see Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml + # RaiseGlimmerObjective: 0.5 #Thief groups - type: weightedRandom @@ -65,32 +65,33 @@ - type: weightedRandom id: ThiefObjectiveGroupCollection weights: - HeadCloakStealCollectionObjective: 1 #command + HeadCloakStealCollectionObjective: 1 #command HeadBedsheetStealCollectionObjective: 1 StampStealCollectionObjective: 1 DoorRemoteStealCollectionObjective: 1 - TechnologyDiskStealCollectionObjective: 1 #rnd - FigurineStealCollectionObjective: 0.3 #service + TechnologyDiskStealCollectionObjective: 1 #rnd + FigurineStealCollectionObjective: 0.3 #service IDCardsStealCollectionObjective: 1 LAMPStealCollectionObjective: 2 #only for moth - type: weightedRandom id: ThiefObjectiveGroupItem weights: - ForensicScannerStealObjective: 1 #sec + ForensicScannerStealObjective: 1 #sec FlippoEngravedLighterStealObjective: 0.5 ClothingHeadHatWardenStealObjective: 1 - ClothingOuterHardsuitVoidParamedStealObjective: 1 #med + ClothingNeckShockCollarStealObjective: 1 + ClothingOuterHardsuitVoidParamedStealObjective: 1 #med MedicalTechFabCircuitboardStealObjective: 1 ClothingHeadsetAltMedicalStealObjective: 1 - FireAxeStealObjective: 1 #eng + FireAxeStealObjective: 1 #eng AmePartFlatpackStealObjective: 1 - ExpeditionsCircuitboardStealObjective: 1 #sup + ExpeditionsCircuitboardStealObjective: 1 #sup CargoShuttleCircuitboardStealObjective: 1 SalvageShuttleCircuitboardStealObjective: 1 - ClothingEyesHudBeerStealObjective: 1 #srv + ClothingEyesHudBeerStealObjective: 1 #srv BibleStealObjective: 1 - ClothingNeckGoldmedalStealObjective: 1 #other + ClothingNeckGoldmedalStealObjective: 1 #other ClothingNeckClownmedalStealObjective: 0.5 - type: weightedRandom diff --git a/Resources/Prototypes/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Objectives/stealTargetGroups.yml index dfd3481c96..b614558f3f 100644 --- a/Resources/Prototypes/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Objectives/stealTargetGroups.yml @@ -279,6 +279,13 @@ sprite: Clothing/Neck/Medals/clownmedal.rsi state: icon +- type: stealTargetGroup + id: ClothingNeckShockCollar + name: shock collar + sprite: + sprite: Clothing/Neck/Misc/shock_collar.rsi + state: icon + #Thief structures - type: stealTargetGroup diff --git a/Resources/Prototypes/Objectives/thief.yml b/Resources/Prototypes/Objectives/thief.yml index 2a26ec2d7b..aef30d1b58 100644 --- a/Resources/Prototypes/Objectives/thief.yml +++ b/Resources/Prototypes/Objectives/thief.yml @@ -316,6 +316,17 @@ - type: Objective difficulty: 1 +- type: entity + parent: BaseThiefStealObjective + id: ClothingNeckShockCollarStealObjective + components: + - type: NotJobRequirement + job: Warden + - type: StealCondition + stealGroup: ClothingNeckShockCollar + - type: Objective + difficulty: 1 + # Structures - type: entity diff --git a/Resources/Prototypes/Recipes/Lathes/security.yml b/Resources/Prototypes/Recipes/Lathes/security.yml index 9f35cb9490..5d5e2e238d 100644 --- a/Resources/Prototypes/Recipes/Lathes/security.yml +++ b/Resources/Prototypes/Recipes/Lathes/security.yml @@ -125,6 +125,15 @@ Plastic: 250 Gold: 100 +- type: latheRecipe + id: ClothingBackpackElectropack + result: ClothingBackpackElectropack + completetime: 4 + materials: + Steel: 500 + Plastic: 250 + Cloth: 500 + - type: latheRecipe id: ForensicPad result: ForensicPad diff --git a/Resources/Prototypes/Research/arsenal.yml b/Resources/Prototypes/Research/arsenal.yml index 9883965a01..bbe87369ad 100644 --- a/Resources/Prototypes/Research/arsenal.yml +++ b/Resources/Prototypes/Research/arsenal.yml @@ -128,6 +128,18 @@ - BoxFrag # TODO: Add "Explosive Ammunition" to this tech to make it waaaay more interesting. +- type: technology + id: SpecialMeans + name: research-technology-special-means + icon: + sprite: Clothing/Back/Backpacks/electropack.rsi + state: icon + discipline: Arsenal + tier: 1 + cost: 5000 + recipeUnlocks: + - ClothingBackpackElectropack + # Tier 2 - type: technology diff --git a/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/equipped-BACKPACK.png b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..3ea6cdc4b0 Binary files /dev/null and b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/icon.png b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/icon.png new file mode 100644 index 0000000000..b4b755e008 Binary files /dev/null and b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/icon.png differ diff --git a/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/inhand-left.png b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/inhand-left.png new file mode 100644 index 0000000000..49f6243a2c Binary files /dev/null and b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/inhand-left.png differ diff --git a/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/inhand-right.png b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/inhand-right.png new file mode 100644 index 0000000000..26901ce4c9 Binary files /dev/null and b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/inhand-right.png differ diff --git a/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/meta.json b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/meta.json new file mode 100644 index 0000000000..4e7738117e --- /dev/null +++ b/Resources/Textures/Clothing/Back/Backpacks/electropack.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/2d26ce62c273d025bed77a0e6c4bdc770b789bb0", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "delays": [ + [ + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/equipped-NECK.png b/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/equipped-NECK.png new file mode 100644 index 0000000000..ffca3249f1 Binary files /dev/null and b/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/equipped-NECK.png differ diff --git a/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/icon.png b/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/icon.png new file mode 100644 index 0000000000..f8e0a9cb8e Binary files /dev/null and b/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/icon.png differ diff --git a/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/meta.json b/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/meta.json new file mode 100644 index 0000000000..3119a51a15 --- /dev/null +++ b/Resources/Textures/Clothing/Neck/Misc/shock_collar.rsi/meta.json @@ -0,0 +1,19 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Drawn by EmoGarbage404 (github) for Space Station 14", + "size": { + "x": 32, + "y": 32 + }, + + "states": [ + { + "name": "equipped-NECK", + "directions": 4 + }, + { + "name": "icon" + } + ] + } diff --git a/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/equipped-NECK.png b/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/equipped-NECK.png deleted file mode 100644 index 811be7f35d..0000000000 Binary files a/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/equipped-NECK.png and /dev/null differ diff --git a/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/icon.png b/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/icon.png deleted file mode 100644 index b595a3dc89..0000000000 Binary files a/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/icon.png and /dev/null differ diff --git a/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/meta.json b/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/meta.json deleted file mode 100644 index 81e3dd2539..0000000000 --- a/Resources/Textures/Nyanotrasen/Clothing/Neck/Misc/shock.rsi/meta.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "Created by Juhius", - "size": { - "x": 32, - "y": 32 - }, - - "states": [ - { - "name": "equipped-NECK", - "directions": 4 - }, - { - "name": "icon" - } - ] -}