From f6ce07289a4e38eb4a865dbf5c70b9e1482899d1 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sat, 29 Jun 2024 04:11:31 +0000 Subject: [PATCH] plutonium core steal objective (#26786) * add textures * add SealingCabinet system * add StoreUnlocker/ObjectiveUnlock system * add plutonium core and nuke core container * make nuke deconstructable * add steal core objective * add core extraction toolbox to new category * typo ops wrench fuel * use queries and resolve, have it resolve instead of using Comp --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Components/StoreUnlockerComponent.cs | 14 ++++ .../Objectives/Systems/StoreUnlockerSystem.cs | 34 ++++++++ .../Conditions/ObjectiveUnlockCondition.cs | 21 +++++ Content.Shared/Cabinet/ItemCabinetSystem.cs | 25 ++++-- .../Cabinet/SealingCabinetComponent.cs | 23 +++++ .../Cabinet/SealingCabinetSystem.cs | 45 ++++++++++ .../Locale/en-US/nuke/nuke-core-container.ftl | 2 + .../en-US/objectives/conditions/steal.ftl | 1 + Resources/Locale/en-US/store/categories.ftl | 1 + .../Locale/en-US/store/uplink-catalog.ftl | 4 + .../Locale/en-US/tools/tool-qualities.ftl | 5 +- .../Catalog/Fills/Items/toolboxes.yml | 13 +++ .../Prototypes/Catalog/uplink_catalog.yml | 20 +++++ .../Entities/Objects/Misc/plutonium_core.yml | 63 ++++++++++++++ .../Entities/Objects/Tools/syndicate.yml | 10 +++ .../Entities/Structures/Machines/nuke.yml | 42 +++++++--- .../Prototypes/Objectives/objectiveGroups.yml | 3 +- .../Objectives/stealTargetGroups.yml | 7 ++ Resources/Prototypes/Objectives/traitor.yml | 18 ++++ .../Construction/Graphs/structures/nuke.yml | 79 ++++++++++++++++++ Resources/Prototypes/Store/categories.yml | 5 ++ Resources/Prototypes/Store/presets.yml | 1 + Resources/Prototypes/tags.yml | 3 + Resources/Prototypes/tool_qualities.yml | 8 ++ .../Misc/nuke_core_container.rsi/closed.png | Bin 0 -> 248 bytes .../nuke_core_container.rsi/core_closed.png | Bin 0 -> 461 bytes .../nuke_core_container.rsi/core_open.png | Bin 0 -> 351 bytes .../nuke_core_container.rsi/inhand-left.png | Bin 0 -> 285 bytes .../nuke_core_container.rsi/inhand-right.png | Bin 0 -> 293 bytes .../Misc/nuke_core_container.rsi/meta.json | 47 +++++++++++ .../Misc/nuke_core_container.rsi/open.png | Bin 0 -> 330 bytes .../Objects/Misc/plutonium_core.rsi/icon.png | Bin 0 -> 386 bytes .../Objects/Misc/plutonium_core.rsi/meta.json | 23 +++++ 33 files changed, 497 insertions(+), 20 deletions(-) create mode 100644 Content.Server/Objectives/Components/StoreUnlockerComponent.cs create mode 100644 Content.Server/Objectives/Systems/StoreUnlockerSystem.cs create mode 100644 Content.Server/Store/Conditions/ObjectiveUnlockCondition.cs create mode 100644 Content.Shared/Cabinet/SealingCabinetComponent.cs create mode 100644 Content.Shared/Cabinet/SealingCabinetSystem.cs create mode 100644 Resources/Locale/en-US/nuke/nuke-core-container.ftl create mode 100644 Resources/Prototypes/Entities/Objects/Misc/plutonium_core.yml create mode 100644 Resources/Prototypes/Entities/Objects/Tools/syndicate.yml create mode 100644 Resources/Prototypes/Recipes/Construction/Graphs/structures/nuke.yml create mode 100644 Resources/Textures/Objects/Misc/nuke_core_container.rsi/closed.png create mode 100644 Resources/Textures/Objects/Misc/nuke_core_container.rsi/core_closed.png create mode 100644 Resources/Textures/Objects/Misc/nuke_core_container.rsi/core_open.png create mode 100644 Resources/Textures/Objects/Misc/nuke_core_container.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Misc/nuke_core_container.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Misc/nuke_core_container.rsi/meta.json create mode 100644 Resources/Textures/Objects/Misc/nuke_core_container.rsi/open.png create mode 100644 Resources/Textures/Objects/Misc/plutonium_core.rsi/icon.png create mode 100644 Resources/Textures/Objects/Misc/plutonium_core.rsi/meta.json diff --git a/Content.Server/Objectives/Components/StoreUnlockerComponent.cs b/Content.Server/Objectives/Components/StoreUnlockerComponent.cs new file mode 100644 index 000000000000..b53aae945ace --- /dev/null +++ b/Content.Server/Objectives/Components/StoreUnlockerComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Store; +using Robust.Shared.Prototypes; + +namespace Content.Server.Objectives.Components; + +/// +/// Unlocks store listings that use . +/// +[RegisterComponent] +public sealed partial class StoreUnlockerComponent : Component +{ + [DataField(required: true)] + public List> Listings = new(); +} diff --git a/Content.Server/Objectives/Systems/StoreUnlockerSystem.cs b/Content.Server/Objectives/Systems/StoreUnlockerSystem.cs new file mode 100644 index 000000000000..28cf768d333a --- /dev/null +++ b/Content.Server/Objectives/Systems/StoreUnlockerSystem.cs @@ -0,0 +1,34 @@ +using Content.Server.Objectives.Components; +using Content.Shared.Mind; + +namespace Content.Server.Objectives.Systems; + +/// +/// Provides api for listings with ObjectiveUnlockRequirement to use. +/// +public sealed class StoreUnlockerSystem : EntitySystem +{ + private EntityQuery _query; + + public override void Initialize() + { + _query = GetEntityQuery(); + } + + /// + /// Returns true if a listing id is unlocked by any objectives on a mind. + /// + public bool IsUnlocked(MindComponent mind, string id) + { + foreach (var obj in mind.Objectives) + { + if (!_query.TryComp(obj, out var comp)) + continue; + + if (comp.Listings.Contains(id)) + return true; + } + + return false; + } +} diff --git a/Content.Server/Store/Conditions/ObjectiveUnlockCondition.cs b/Content.Server/Store/Conditions/ObjectiveUnlockCondition.cs new file mode 100644 index 000000000000..a9dafc28ff88 --- /dev/null +++ b/Content.Server/Store/Conditions/ObjectiveUnlockCondition.cs @@ -0,0 +1,21 @@ +using Content.Shared.Mind; +using Content.Shared.Store; +using Content.Server.Objectives.Systems; + +namespace Content.Server.Store.Conditions; + +/// +/// Requires that the buyer have an objective that unlocks this listing. +/// +public sealed partial class ObjectiveUnlockCondition : ListingCondition +{ + public override bool Condition(ListingConditionArgs args) + { + var minds = args.EntityManager.System(); + if (!minds.TryGetMind(args.Buyer, out _, out var mind)) + return false; + + var unlocker = args.EntityManager.System(); + return unlocker.IsUnlocked(mind, args.Listing.ID); + } +} diff --git a/Content.Shared/Cabinet/ItemCabinetSystem.cs b/Content.Shared/Cabinet/ItemCabinetSystem.cs index 749065ac4761..e14e269d4fdd 100644 --- a/Content.Shared/Cabinet/ItemCabinetSystem.cs +++ b/Content.Shared/Cabinet/ItemCabinetSystem.cs @@ -16,11 +16,17 @@ public sealed class ItemCabinetSystem : EntitySystem [Dependency] private readonly OpenableSystem _openable = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + private EntityQuery _cabinetQuery = default!; + private EntityQuery _slotsQuery = default!; + /// public override void Initialize() { base.Initialize(); + _cabinetQuery = GetEntityQuery(); + _slotsQuery = GetEntityQuery(); + SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnContainerModified); @@ -37,12 +43,12 @@ private void OnStartup(Entity ent, ref ComponentStartup ar private void OnMapInit(Entity ent, ref MapInitEvent args) { // update at mapinit to avoid copy pasting locked: true and locked: false for each closed/open prototype - SetSlotLock(ent, !_openable.IsOpen(ent)); + SetSlotLock((ent, ent.Comp), !_openable.IsOpen(ent)); } private void UpdateAppearance(Entity ent) { - _appearance.SetData(ent, ItemCabinetVisuals.ContainsItem, HasItem(ent)); + _appearance.SetData(ent, ItemCabinetVisuals.ContainsItem, HasItem((ent, ent.Comp))); } private void OnContainerModified(EntityUid uid, ItemCabinetComponent component, ContainerModifiedMessage args) @@ -53,21 +59,24 @@ private void OnContainerModified(EntityUid uid, ItemCabinetComponent component, private void OnOpened(Entity ent, ref OpenableOpenedEvent args) { - SetSlotLock(ent, false); + SetSlotLock((ent, ent.Comp), false); } private void OnClosed(Entity ent, ref OpenableClosedEvent args) { - SetSlotLock(ent, true); + SetSlotLock((ent, ent.Comp), true); } /// /// Tries to get the cabinet's item slot. /// - public bool TryGetSlot(Entity ent, [NotNullWhen(true)] out ItemSlot? slot) + public bool TryGetSlot(Entity ent, [NotNullWhen(true)] out ItemSlot? slot) { slot = null; - if (!TryComp(ent, out var slots)) + if (!_cabinetQuery.Resolve(ent, ref ent.Comp)) + return false; + + if (!_slotsQuery.TryComp(ent, out var slots)) return false; return _slots.TryGetSlot(ent, ent.Comp.Slot, out slot, slots); @@ -76,7 +85,7 @@ public bool TryGetSlot(Entity ent, [NotNullWhen(true)] out /// /// Returns true if the cabinet contains an item. /// - public bool HasItem(Entity ent) + public bool HasItem(Entity ent) { return TryGetSlot(ent, out var slot) && slot.HasItem; } @@ -86,7 +95,7 @@ public bool HasItem(Entity ent) /// public void SetSlotLock(Entity ent, bool closed) { - if (!TryComp(ent, out var slots)) + if (!_slotsQuery.TryComp(ent, out var slots)) return; if (_slots.TryGetSlot(ent, ent.Comp.Slot, out var slot, slots)) diff --git a/Content.Shared/Cabinet/SealingCabinetComponent.cs b/Content.Shared/Cabinet/SealingCabinetComponent.cs new file mode 100644 index 000000000000..53a4f7f3ff43 --- /dev/null +++ b/Content.Shared/Cabinet/SealingCabinetComponent.cs @@ -0,0 +1,23 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Cabinet; + +/// +/// Item cabinet that cannot be opened if it has an item inside. +/// The only way to open it after that is to emag it. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class SealingCabinetComponent : Component +{ + /// + /// Popup shown when trying to open the cabinet once sealed. + /// + [DataField(required: true)] + public LocId SealedPopup = string.Empty; + + /// + /// Set to false to disable emag unsealing. + /// + [DataField] + public bool Emaggable = true; +} diff --git a/Content.Shared/Cabinet/SealingCabinetSystem.cs b/Content.Shared/Cabinet/SealingCabinetSystem.cs new file mode 100644 index 000000000000..be07b8a61f4a --- /dev/null +++ b/Content.Shared/Cabinet/SealingCabinetSystem.cs @@ -0,0 +1,45 @@ +using Content.Shared.Emag.Systems; +using Content.Shared.Nutrition.Components; +using Content.Shared.Nutrition.EntitySystems; +using Content.Shared.Popups; + +namespace Content.Shared.Cabinet; + +public sealed class SealingCabinetSystem : EntitySystem +{ + [Dependency] private readonly ItemCabinetSystem _cabinet = default!; + [Dependency] private readonly OpenableSystem _openable = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnOpenAttempt); + SubscribeLocalEvent(OnEmagged); + } + + private void OnOpenAttempt(Entity ent, ref OpenableOpenAttemptEvent args) + { + if (!_cabinet.HasItem(ent.Owner)) + return; + + args.Cancelled = true; + if (args.User is {} user) + _popup.PopupClient(Loc.GetString(ent.Comp.SealedPopup, ("container", ent.Owner)), ent, user); + } + + private void OnEmagged(Entity ent, ref GotEmaggedEvent args) + { + if (!ent.Comp.Emaggable) + return; + + if (!_cabinet.HasItem(ent.Owner) || _openable.IsOpen(ent)) + return; + + _openable.SetOpen(ent, true); + + args.Handled = true; + args.Repeatable = true; + } +} diff --git a/Resources/Locale/en-US/nuke/nuke-core-container.ftl b/Resources/Locale/en-US/nuke/nuke-core-container.ftl new file mode 100644 index 000000000000..47ea15a8316a --- /dev/null +++ b/Resources/Locale/en-US/nuke/nuke-core-container.ftl @@ -0,0 +1,2 @@ +nuke-core-container-whitelist-fail-popup = That doesn't fit into the container. +nuke-core-container-sealed-popup = The {$container} is sealed shut! diff --git a/Resources/Locale/en-US/objectives/conditions/steal.ftl b/Resources/Locale/en-US/objectives/conditions/steal.ftl index 00c8e0fdaf93..1bca71ce90df 100644 --- a/Resources/Locale/en-US/objectives/conditions/steal.ftl +++ b/Resources/Locale/en-US/objectives/conditions/steal.ftl @@ -4,6 +4,7 @@ objective-condition-steal-title = Steal the {$owner}'s {$itemName}. objective-condition-steal-description = We need you to steal {$itemName}. Don't get caught. objective-condition-steal-station = station +objective-condition-steal-nuclear-bomb = nuclear bomb objective-condition-steal-Ian = head of personnel's corgi objective-condition-thief-description = The {$itemName} would be a great addition to my collection! diff --git a/Resources/Locale/en-US/store/categories.ftl b/Resources/Locale/en-US/store/categories.ftl index 4ebeff3b2376..e2804158c6cf 100644 --- a/Resources/Locale/en-US/store/categories.ftl +++ b/Resources/Locale/en-US/store/categories.ftl @@ -12,6 +12,7 @@ store-category-allies = Allies store-category-job = Job store-category-wearables = Wearables store-category-pointless = Pointless +store-category-objectives = Objectives # Revenant store-category-abilities = Abilities diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 2598970cefbe..8a7b0800c0ba 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -433,3 +433,7 @@ uplink-barber-scissors-desc = A good tool to give your fellow agent a nice hairc uplink-backpack-syndicate-name = Syndicate backpack uplink-backpack-syndicate-desc = Lightweight explosion-proof а backpack for holding various traitor goods + +# Objectives +uplink-core-extraction-toolbox-name = Core Extraction Toolbox +uplink-core-extraction-toolbox-desc = A toolbox containing everything you need to remove a nuclear bomb's plutonium core. Instructions not included. diff --git a/Resources/Locale/en-US/tools/tool-qualities.ftl b/Resources/Locale/en-US/tools/tool-qualities.ftl index 14e42390a766..a398d458505f 100644 --- a/Resources/Locale/en-US/tools/tool-qualities.ftl +++ b/Resources/Locale/en-US/tools/tool-qualities.ftl @@ -32,4 +32,7 @@ tool-quality-rolling-name = Rolling tool-quality-rolling-tool-name = Rolling Pin tool-quality-digging-name = Digging -tool-quality-digging-tool-name = Shovel \ No newline at end of file +tool-quality-digging-tool-name = Shovel + +tool-quality-fine-screwing-name = Fine Screwing +tool-quality-fine-screwing-tool-name = Thin-Tipped Screwdriver diff --git a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml index 1091207bba47..1b47a4f46dd7 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml @@ -121,6 +121,19 @@ - id: ClothingHandsGlovesCombat - id: ClothingMaskGasSyndicate +- type: entity + parent: ToolboxSyndicate + id: ToolboxSyndicateFilledCoreExtraction + suffix: Filled, Core Extraction + components: + - type: StorageFill + contents: + - id: Crowbar + - id: Welder + - id: Wrench + - id: ThinTippedScrewdriver + - id: NukeCoreContainer + - type: entity id: ToolboxGoldFilled name: golden toolbox diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 0ba83dfe735f..a921b7fbd375 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -1727,3 +1727,23 @@ blacklist: components: - SurplusBundle + +# Objective-specific +- type: listing + id: UplinkCoreExtractionToolbox + name: uplink-core-extraction-toolbox-name + description: uplink-core-extraction-toolbox-desc + icon: + sprite: Objects/Misc/nuke_core_container.rsi + state: closed + productEntity: ToolboxSyndicateFilledCoreExtraction + categories: + - UplinkObjectives + conditions: + - !type:ObjectiveUnlockCondition + - !type:ListingLimitedStockCondition + stock: 1 + - !type:BuyerWhitelistCondition + blacklist: + components: + - SurplusBundle diff --git a/Resources/Prototypes/Entities/Objects/Misc/plutonium_core.yml b/Resources/Prototypes/Entities/Objects/Misc/plutonium_core.yml new file mode 100644 index 000000000000..67910888871d --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Misc/plutonium_core.yml @@ -0,0 +1,63 @@ +- type: entity + parent: BaseItem + id: PlutoniumCore + name: plutonium core + description: Extremely radioactive, even looking at this with the naked eye is dangerous. + components: + - type: Sprite + sprite: Objects/Misc/plutonium_core.rsi + state: icon + - type: StealTarget + stealGroup: PlutoniumCore + - type: RadiationSource + intensity: 4 + slope: 1 + - type: StaticPrice + price: 49000 + - type: Tag + tags: + - PlutoniumCore + +- type: entity + parent: [BaseItem, BaseItemCabinet] + id: NukeCoreContainer + name: nuke core container + description: Solid container for radioactive objects. + components: + - type: Sprite + sprite: Objects/Misc/nuke_core_container.rsi + layers: + - state: closed + map: [ "enum.OpenableVisuals.Layer" ] + - state: core_closed + map: [ "enum.ItemCabinetVisuals.Layer" ] + visible: false + shader: unshaded + - type: Item + size: Normal + shape: + - 0,0,1,1 + - type: RadiationBlockingContainer + resistance: 4 + - type: SealingCabinet + sealedPopup: nuke-core-container-sealed-popup + - type: ItemSlots + slots: + ItemCabinet: + whitelist: + tags: + - PlutoniumCore + whitelistFailPopup: nuke-core-container-whitelist-fail-popup + - type: GenericVisualizer + visuals: + enum.OpenableVisuals.Opened: + enum.OpenableVisuals.Layer: + True: { state: open } + False: { state: closed } + enum.ItemCabinetVisuals.Layer: + True: { state: core_open } + False: { state: core_closed } + enum.ItemCabinetVisuals.ContainsItem: + enum.ItemCabinetVisuals.Layer: + True: { visible: true } + False: { visible: false } diff --git a/Resources/Prototypes/Entities/Objects/Tools/syndicate.yml b/Resources/Prototypes/Entities/Objects/Tools/syndicate.yml new file mode 100644 index 000000000000..3d42a17761a7 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Tools/syndicate.yml @@ -0,0 +1,10 @@ +- type: entity + parent: Screwdriver + id: ThinTippedScrewdriver + description: A screwdriver with an ultra thin tip that's carefully designed to boost screwing speed. + suffix: DO NOT MAP + components: + - type: Tool + qualities: + - Screwing + - FineScrewing diff --git a/Resources/Prototypes/Entities/Structures/Machines/nuke.yml b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml index 1cf9ceaeab34..c2b6ccdbc0ad 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/nuke.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml @@ -1,8 +1,8 @@ - type: entity + abstract: true parent: [BaseStructure, StructureWheeled] - id: NuclearBomb + id: BaseNuclearBomb name: nuclear fission explosive - description: You probably shouldn't stick around to see if this is armed. components: - type: Transform anchored: true @@ -61,6 +61,23 @@ - MachineMask layer: - HalfWallLayer + - type: InteractionOutline + - type: CargoSellBlacklist + - type: ArrivalsBlacklist + - type: WarpPoint + follow: true + location: nuclear bomb + - type: StealTarget + stealGroup: NuclearBomb + - type: Construction + graph: NuclearBomb + deconstructionTarget: disarmed + +- type: entity + parent: BaseNuclearBomb + id: NuclearBomb + description: You probably shouldn't stick around to see if this is armed. + components: - type: PointLight enabled: false radius: 4 @@ -90,7 +107,6 @@ - NukeDisk alertLevelOnActivate: delta alertLevelOnDeactivate: green - - type: InteractionOutline - type: ActivatableUI key: enum.NukeUiKey.Key - type: UserInterface @@ -99,17 +115,12 @@ type: NukeBoundUserInterface - type: StaticPrice price: 50000 # YOU STOLE A NUCLEAR FISSION EXPLOSIVE?! - - type: CargoSellBlacklist - - type: ArrivalsBlacklist - type: ItemSlots - type: ContainerContainer containers: Nuke: !type:ContainerSlot - - type: StealTarget - stealGroup: NuclearBomb - - type: WarpPoint - follow: true - location: nuclear bomb + - type: Construction + node: nuke - type: entity parent: NuclearBomb @@ -121,6 +132,17 @@ - type: Physics bodyType: Dynamic +- type: entity + parent: BaseNuclearBomb + id: NuclearBombDisarmed + suffix: Disarmed + description: "You can clearly see that this can't be armed, given its lack of nuclear material." + components: + - type: StaticPrice + price: 1000 # fancy paperweight + - type: Construction + node: disarmed + - type: entity parent: StorageTank id: NuclearBombKeg diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index bb74c92da3b5..9e73f5a55bc0 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -14,7 +14,6 @@ CMOHyposprayStealObjective: 1 CMOCrewMonitorStealObjective: 1 RDHardsuitStealObjective: 1 - NukeDiskStealObjective: 1 MagbootsStealObjective: 1 CorgiMeatStealObjective: 1 ClipboardStealObjective: 1 @@ -22,6 +21,8 @@ CaptainJetpackStealObjective: 0.5 HandTeleporterStealObjective: 0.5 SecretDocumentsStealObjective: 0.5 + PlutoniumCoreStealObjective: 0.5 + NukeDiskStealObjective: 0.25 - type: weightedRandom id: TraitorObjectiveGroupKill diff --git a/Resources/Prototypes/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Objectives/stealTargetGroups.yml index 52117b9ce9ca..aa9722cfbd24 100644 --- a/Resources/Prototypes/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Objectives/stealTargetGroups.yml @@ -84,6 +84,13 @@ sprite: Objects/Misc/nukedisk.rsi state: icon +- type: stealTargetGroup + id: PlutoniumCore + name: plutonium core + sprite: + sprite: Objects/Misc/plutonium_core.rsi + state: icon + # Thief Collection - type: stealTargetGroup diff --git a/Resources/Prototypes/Objectives/traitor.yml b/Resources/Prototypes/Objectives/traitor.yml index ad5f56a443ea..1e6795d4d471 100644 --- a/Resources/Prototypes/Objectives/traitor.yml +++ b/Resources/Prototypes/Objectives/traitor.yml @@ -293,3 +293,21 @@ - type: StealCondition stealGroup: NukeDisk owner: objective-condition-steal-station + +# Station + +- type: entity + noSpawn: true + parent: BaseTraitorStealObjective + id: PlutoniumCoreStealObjective + components: + - type: Objective + # its hard to steal and leaves evidence, but you can get away with it. + difficulty: 3.5 + - type: NotCommandRequirement + - type: StealCondition + stealGroup: PlutoniumCore + owner: objective-condition-steal-nuclear-bomb + - type: StoreUnlocker + listings: + - UplinkCoreExtractionToolbox diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/nuke.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/nuke.yml new file mode 100644 index 000000000000..0c63e82f4026 --- /dev/null +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/nuke.yml @@ -0,0 +1,79 @@ +- type: constructionGraph + id: NuclearBomb + start: disarmed + graph: + - node: disarmed + entity: NuclearBombDisarmed + edges: + - to: core_exposed + steps: + - tag: PlutoniumCore + name: "a plutonium core" + icon: + sprite: Objects/Misc/plutonium_core.rsi + state: icon + doAfter: 1 + + - node: core_exposed + edges: + - to: disarmed + completed: + - !type:GivePrototype + prototype: PlutoniumCore + steps: + - tool: Prying + doAfter: 2 + - to: panel_removed + steps: + - material: Plasteel + amount: 8 + doAfter: 2 + - tool: Welding + doAfter: 4 + + - node: panel_removed + edges: + - to: core_exposed + completed: + - !type:GivePrototype + prototype: SheetPlasteel1 + amount: 8 + steps: + - tool: Welding + doAfter: 6 + - tool: Anchoring + doAfter: 2 + - tool: Welding + doAfter: 8 + - to: panel_exposed + steps: + - material: Plasteel + amount: 4 + doAfter: 2 + - tool: Welding + doAfter: 2 + + - node: panel_exposed + edges: + - to: panel_removed + completed: + - !type:GivePrototype + prototype: SheetPlasteel1 + amount: 4 + steps: + - tool: Welding + doAfter: 2 + - tool: Prying + doAfter: 2 + - to: nuke + steps: + - tool: FineScrewing + doAfter: 2 + + - node: nuke + entity: NuclearBomb + edges: + - to: panel_exposed + steps: + - tool: FineScrewing + doAfter: 2 diff --git a/Resources/Prototypes/Store/categories.yml b/Resources/Prototypes/Store/categories.yml index 6bd9756c3e94..b4aea0bea4f6 100644 --- a/Resources/Prototypes/Store/categories.yml +++ b/Resources/Prototypes/Store/categories.yml @@ -89,6 +89,11 @@ name: store-category-pointless priority: 10 +- type: storeCategory + id: UplinkObjectives + name: store-category-objectives + priority: 11 + #revenant - type: storeCategory id: RevenantAbilities diff --git a/Resources/Prototypes/Store/presets.yml b/Resources/Prototypes/Store/presets.yml index 762ed68921aa..5905cb80bab6 100644 --- a/Resources/Prototypes/Store/presets.yml +++ b/Resources/Prototypes/Store/presets.yml @@ -16,6 +16,7 @@ - UplinkWearables - UplinkJob - UplinkPointless + - UplinkObjectives currencyWhitelist: - Telecrystal balance: diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index dee16b7414b5..ede344eeaba2 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -1020,6 +1020,9 @@ - type: Tag id: PlushieSharkPink +- type: Tag + id: PlutoniumCore + - type: Tag id: Potato diff --git a/Resources/Prototypes/tool_qualities.yml b/Resources/Prototypes/tool_qualities.yml index ff55d9fcf14c..a6c712c6842e 100644 --- a/Resources/Prototypes/tool_qualities.yml +++ b/Resources/Prototypes/tool_qualities.yml @@ -67,3 +67,11 @@ toolName: tool-quality-rolling-tool-name spawn: RollingPin icon: { sprite: Objects/Tools/rolling_pin.rsi, state: icon } + +# do not give this to normal tools, its for nuke deconstruction +- type: tool + id: FineScrewing + name: tool-quality-fine-screwing + toolName: tool-quality-fine-screwing-tool-name + spawn: ThinTippedScrewdriver + icon: { sprite: Objects/Tools/screwdriver.rsi, state: screwdriver-map } diff --git a/Resources/Textures/Objects/Misc/nuke_core_container.rsi/closed.png b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..ba6632404df871abafccbe942212e3adfb963efd GIT binary patch literal 248 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5D7ebg z#W5t}aB_kK>*55Fo{|F|Yn*s}@BTlsYH#6Rql?cr31shVo2I8J_uGGsa>NPVT@UU? z2mHv6tvzAX-WqfIC&GE7q}+TLh5Y@0GkAW`zf5A~CbN{b#9d^@-zCB%~F z>hzWG8KJr%Ne*=9^~rc%5m)Rp7Sb`A%%0>mj)fb t%O(xlhLa|FxC=jAkTs#FDbRq6fyK@;^3Lu)R-mgHJYD@<);T3K0RRGMThIUi literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/nuke_core_container.rsi/core_closed.png b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/core_closed.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5dbec62e88c0f1e32662e40b9e7d4770ca9fa7 GIT binary patch literal 461 zcmV;;0W$uHP)YHTbh(MX~H!Oqy&+4}ozjGZ=q{C54Rv3ld8cWJyl<;7(`P*}H^$o`z-E@b13M&3!Og1^@s6ZN*3@b`N^uFMSz4 zt1mQ_zLko14|_oi)-)ldzKvbf#ocY;{q^Ztt*NV}Z)3&l-f$}YCW_FIZCPM`gfYOvZ0XGeA>+ zqwSZ%tvA4irj<*@vJ|U|Yq7ciK69@huiGXc`}pz6SbmQaTm#%D%Z^7sp27&X!Q6;^ zyll`k)Ei=sb({s8&|8qEm$1C;dX z50FlzKY;##^@RQa$)wJ)opny8i}B!Q%N(6gSN@;(^A8(yFAB_uXTSw+2((Xr!qnsrv_jE4@3X}04n$b^!@YWodJnq00000NkvXXu0mjf DkSoxn literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/nuke_core_container.rsi/core_open.png b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/core_open.png new file mode 100644 index 0000000000000000000000000000000000000000..1bda771a78c67eaae8bcef342ed816661cd43c03 GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^3xHUGgAGVdtuOuxq&N#aB8wRq_>O=u<5X=vX$A&H zK~ERQkcwMxuiNuA8A!AzD##sP>|pSaY2CcTtmcoKy30Q@@vyk{KQs(ka%_@U!o%~| z8{SWza6!*L%I?-93!te`(6F>{W>e)ZJE!>j`Qed{j6n>SZtlAn8d24D@bUZDhTm7T zzy4LN>J;B}w#M{l<+SI!WLq2+LK$}bSoP<~340H*g=arr*Z=>`=IZoF9`EzvlkZQ< zU&j%g79M_QqP(~5;Tey=|Jw8C?z114m){C&q6c+^+ce&Gao#x^oUE_s^d{p^?2n+FmJZ mckW61|EGU2!u$ZFt@bh=-1(+2=Xel1NYvBS&t;ucLK6V-LY5%_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/nuke_core_container.rsi/inhand-left.png b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..f2c97f4374ed509ecbbdc5165896f62868213c72 GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1HB` zi(^Q|oVT|Oxegl$uwLYR(qXsk-HIcwJsyHdPgGs%mjyjOYBNFl{oD^M3O0-!{tSnN z8&H@UbMCf(e#?HoK9uvow%p^Vw_i(pwx{o}<#LvVObdc9+kG!$+0WP#&SX&hUi(?i zDy9dks-wO=mH*5oFpr@{o#7#;Lj@B~=AZia)y&JkafC5g+%gY7_b)JxDIw;hA&i91JWq`arKSc)I$ztaD0e0szpZWqJSr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/nuke_core_container.rsi/inhand-right.png b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..074c157c51cb4324a8e4625bdb30c1eb07666807 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1H5^ zi(^Q|oVT|e`I;OAST7oV?2wsky+}vl$cu#Cn^yi0Qxh@@TbBO#&O~p9CqfK6Sse5j zCm=H$4wj#O__?=kU)28scAv{z_UFudZYDVI^}YH(#di;gTe~DWM4fb{TP^ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/nuke_core_container.rsi/meta.json b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/meta.json new file mode 100644 index 000000000000..c72162e2fdb9 --- /dev/null +++ b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/meta.json @@ -0,0 +1,47 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/blob/c34d56a45b0461f5e0fad3cc75e81580c3357119/icons/obj/antags/syndicate_tools.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "open" + }, + { + "name": "closed" + }, + { + "name": "core_open", + "delays": [ + [ + 2.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "core_closed", + "delays": [ + [ + 2.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Objects/Misc/nuke_core_container.rsi/open.png b/Resources/Textures/Objects/Misc/nuke_core_container.rsi/open.png new file mode 100644 index 0000000000000000000000000000000000000000..3d4b830bf4aab35ed343095b451f1e96a0d82e28 GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5DEPa3 zyuLY8`%uBj_J3x_9-I+9xQb!I@02?06&Kco@)-HfWIU_LZ+y;**-$W2`$0$J6847W5}e9jH<^?ZT_V#Ce3d=* z|KHDuEvd73chBQ*F@Lyx#}57QvF8l4^+qJ$(*89EBt2q#)|^Ofx*+&&t;ucLK6UXD1W2? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/plutonium_core.rsi/icon.png b/Resources/Textures/Objects/Misc/plutonium_core.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..92782ce223cb83b31db03c95e1938143e95919dc GIT binary patch literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^3xHUGgAGVdtuOuxq&N#aB8wRq_>O=u<5X=vX$A&H z6Hgb%kcwMxZ#Z%_IY_i63a=L^X*)MTqNH)#+{K~R|D&Gln<9}zLSnvVOh5}|cAIJK)`3HSs_4leQX3%7Kd1vOeIgxMNAKwXM z-O+b9CN^KZ{A1F#ng8efG4Tv8eb2s6|Kq2xkF-B2>((nrw#4?{&;I-={PTvaj>9pV zIC7q?K6(9fdAot`t=fg6D|Gfn)h!WEj6Y`o>dDjaxdM@$InU~6)!5#D;`Jly@4c?| z)8fSzp0q2mtlOUHey;M**Lx