From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Mon, 6 Nov 2023 03:04:47 +0000 (+0000) Subject: add ied (#20966) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=96e27810cfdc9bbe4ffbbb3e82e2e567eca7ff40;p=space-station-14.git add ied (#20966) * MinSolution and SolutionEmpty construction conditions * make ied sprites * add ied * ied crafting stuff * deconstruct give cable yes * fix * tags * tag * 3x3 * sharing is caring * buff damage --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- diff --git a/Content.Server/Construction/Conditions/MinSolution.cs b/Content.Server/Construction/Conditions/MinSolution.cs new file mode 100644 index 0000000000..d70e84761d --- /dev/null +++ b/Content.Server/Construction/Conditions/MinSolution.cs @@ -0,0 +1,83 @@ +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Construction; +using Content.Shared.Examine; +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; + +namespace Content.Server.Construction.Conditions; + +/// +/// Requires that a certain solution has a minimum amount of a reagent to proceed. +/// +[DataDefinition] +public sealed partial class MinSolution : IGraphCondition +{ + /// + /// The solution that needs to have the reagent. + /// + [DataField(required: true)] + public string Solution = string.Empty; + + /// + /// The reagent that needs to be present. + /// + [DataField(required: true)] + public ReagentId Reagent = new(); + + /// + /// How much of the reagent must be present. + /// + [DataField] + public FixedPoint2 Quantity = 1; + + public bool Condition(EntityUid uid, IEntityManager entMan) + { + var containerSys = entMan.System(); + if (!containerSys.TryGetSolution(uid, Solution, out var solution)) + return false; + + solution.TryGetReagentQuantity(Reagent, out var quantity); + return quantity >= Quantity; + } + + public bool DoExamine(ExaminedEvent args) + { + var entMan = IoCManager.Resolve(); + var uid = args.Examined; + + var containerSys = entMan.System(); + if (!containerSys.TryGetSolution(uid, Solution, out var solution)) + return false; + + solution.TryGetReagentQuantity(Reagent, out var quantity); + + // already has enough so dont show examine + if (quantity >= Quantity) + return false; + + args.PushMarkup(Loc.GetString("construction-examine-condition-min-solution", + ("quantity", Quantity - quantity), ("reagent", Name())) + "\n"); + return true; + } + + public IEnumerable GenerateGuideEntry() + { + yield return new ConstructionGuideEntry() + { + Localization = "construction-guide-condition-min-solution", + Arguments = new (string, object)[] + { + ("quantity", Quantity), + ("reagent", Name()) + } + }; + } + + private string Name() + { + var protoMan = IoCManager.Resolve(); + var proto = protoMan.Index(Reagent.Prototype); + return proto.LocalizedName; + } +} diff --git a/Content.Server/Construction/Conditions/SolutionEmpty.cs b/Content.Server/Construction/Conditions/SolutionEmpty.cs new file mode 100644 index 0000000000..d3cbd7356e --- /dev/null +++ b/Content.Server/Construction/Conditions/SolutionEmpty.cs @@ -0,0 +1,52 @@ +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Construction; +using Content.Shared.Examine; + +namespace Content.Server.Construction.Conditions; + +/// +/// Requires that a certain solution be empty to proceed. +/// +[DataDefinition] +public sealed partial class SolutionEmpty : IGraphCondition +{ + /// + /// The solution that needs to be empty. + /// + [DataField] + public string Solution; + + public bool Condition(EntityUid uid, IEntityManager entMan) + { + var containerSys = entMan.System(); + if (!containerSys.TryGetSolution(uid, Solution, out var solution)) + return false; + + return solution.Volume == 0; + } + + public bool DoExamine(ExaminedEvent args) + { + var entMan = IoCManager.Resolve(); + var uid = args.Examined; + + var containerSys = entMan.System(); + if (!containerSys.TryGetSolution(uid, Solution, out var solution)) + return false; + + // already empty so dont show examine + if (solution.Volume == 0) + return false; + + args.PushMarkup(Loc.GetString("construction-examine-condition-solution-empty")); + return true; + } + + public IEnumerable GenerateGuideEntry() + { + yield return new ConstructionGuideEntry() + { + Localization = "construction-guide-condition-solution-empty" + }; + } +} diff --git a/Resources/Locale/en-US/construction/conditions/min-solution.ftl b/Resources/Locale/en-US/construction/conditions/min-solution.ftl new file mode 100644 index 0000000000..884a351998 --- /dev/null +++ b/Resources/Locale/en-US/construction/conditions/min-solution.ftl @@ -0,0 +1,2 @@ +construction-examine-condition-min-solution = First, add {$quantity}u of {$reagent}. +construction-guide-condition-min-solution = Add {$quantity}u of {$reagent} diff --git a/Resources/Locale/en-US/construction/conditions/solution-empty.ftl b/Resources/Locale/en-US/construction/conditions/solution-empty.ftl new file mode 100644 index 0000000000..0fd577a0f5 --- /dev/null +++ b/Resources/Locale/en-US/construction/conditions/solution-empty.ftl @@ -0,0 +1,3 @@ +# SolutionEmpty +construction-examine-condition-solution-empty = First, empty the contents. +construction-guide-condition-solution-empty = Empty the contents. diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml index 3595d93ea0..9fdc594ed0 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml @@ -59,6 +59,9 @@ - type: PhysicalComposition materialComposition: Steel: 50 #reduce, reuse, recycle + - type: Tag + tags: + - DrinkCan - type: entity parent: DrinkCanBaseFull @@ -76,12 +79,38 @@ - type: Tag tags: - Cola + - DrinkCan - Recyclable - type: Sprite sprite: Objects/Consumable/Drinks/cola.rsi - type: Item sprite: Objects/Consumable/Drinks/cola.rsi +# created when taking apart an ied +- type: entity + parent: DrinkColaCan + id: DrinkColaCanEmpty + suffix: empty + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + - type: Openable + opened: true + - type: Sprite + sprite: Objects/Consumable/Drinks/cola.rsi + layers: + - state: icon_open + - type: Item + sprite: Objects/Consumable/Drinks/cola.rsi + - type: Tag + tags: + - Cola + - DrinkCan + - Recyclable + - Trash + - type: entity parent: DrinkCanBaseFull id: DrinkIcedTeaCan @@ -317,6 +346,7 @@ Quantity: 5 - type: Tag tags: + - DrinkCan - Recyclable - type: Sprite sprite: Objects/Consumable/Drinks/robustnukie.rsi diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/ied.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/ied.yml new file mode 100644 index 0000000000..7e669aea52 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/ied.yml @@ -0,0 +1,101 @@ +# ied crafted from random stuff +# ideally it would be dynamic and work by actually sparking the solution but that doesnt exist yet :( +# with that you could make napalm ied instead of welding fuel with no additional complexity +- type: entity + parent: BaseItem + id: ImprovisedExplosive + name: improvised explosive device + description: A weak, improvised incendiary device. + components: + - type: Sprite + sprite: Objects/Weapons/Bombs/ied.rsi + layers: + - state: base + - state: fuel + - state: wires + - type: Item + sprite: Objects/Consumable/Drinks/cola.rsi + - type: OnUseTimerTrigger + delay: 5 + examinable: false + initialBeepDelay: 0 + beepSound: /Audio/Effects/lightburn.ogg + # TODO: random timer when crafted + - type: TriggerOnSignal + - type: DeviceLinkSink + ports: + - Trigger + - type: Explosive # Weak explosion in a very small radius. Doesn't break underplating. + explosionType: Default + totalIntensity: 50 + intensitySlope: 5 + maxIntensity: 6 + canCreateVacuum: false + - type: ExplodeOnTrigger + - type: Damageable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:ExplodeBehavior + - type: Construction + graph: ImprovisedExplosive + node: ied + +# has igniter but no fuel or wires +- type: entity + parent: DrinkColaCanEmpty + id: ImprovisedExplosiveEmpty + name: improvised explosive device + suffix: empty + description: A weak, improvised incendiary device. This one has no fuel. + components: + - type: Sprite + sprite: Objects/Weapons/Bombs/ied.rsi + layers: + - state: base + map: ["enum.OpenableVisuals.Layer"] + # bad dog + - type: GenericVisualizer + visuals: + enum.OpenableVisuals.Opened: + enum.OpenableVisuals.Layer: + True: {state: "base"} + False: {state: "base"} + - type: Construction + graph: ImprovisedExplosive + node: empty + defaultTarget: ied + - type: Tag + tags: + - Trash + # no DrinkCan, prevent using it to make another ied + +- type: entity + parent: ImprovisedExplosiveEmpty + id: ImprovisedExplosiveFuel + suffix: fuel + description: A weak, improvised incendiary device. This one is missing wires. + components: + - type: Sprite + layers: + - state: base + map: ["enum.OpenableVisuals.Layer"] + - state: fuel + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: WeldingFuel + Quantity: 30 + - type: Construction + node: fuel + defaultTarget: ied + - type: Tag + tags: [] diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/ied.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/ied.yml new file mode 100644 index 0000000000..bdf06e558f --- /dev/null +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/ied.yml @@ -0,0 +1,75 @@ +- type: constructionGraph + id: ImprovisedExplosive + start: start + graph: + - node: start + edges: + - to: empty + steps: + - tag: DrinkCan + name: an empty can + icon: + sprite: Objects/Consumable/Drinks/cola.rsi + state: icon_open + doAfter: 1 + - tag: Igniter + name: an igniter + icon: + sprite: Objects/Devices/igniter.rsi + state: icon + doAfter: 1 + - node: empty + entity: ImprovisedExplosiveEmpty + edges: + - to: start + completed: + - !type:SpawnPrototype + prototype: DrinkColaCanEmpty + - !type:SpawnPrototype + prototype: Igniter + - !type:DeleteEntity {} + steps: + - tool: Prying + doAfter: 1 + - to: fuel + conditions: + - !type:MinSolution + solution: drink + reagent: + ReagentId: WeldingFuel + quantity: 30 + steps: + - tool: Screwing + doAfter: 1 + - node: fuel + entity: ImprovisedExplosiveFuel + edges: + - to: empty + conditions: + - !type:SolutionEmpty + solution: drink + steps: + - tool: Screwing + doAfter: 1 + - to: ied + conditions: # no dumping out 29u of the fuel then adding wires :) + - !type:MinSolution + solution: drink + reagent: + ReagentId: WeldingFuel + quantity: 30 + steps: + - material: Cable + amount: 5 + doAfter: 2 + - node: ied + entity: ImprovisedExplosive + edges: + - to: fuel + completed: + - !type:SpawnPrototype + prototype: CableApcStack1 + amount: 5 + steps: + - tool: Cutting + doAfter: 2 diff --git a/Resources/Prototypes/Recipes/Crafting/improvised.yml b/Resources/Prototypes/Recipes/Crafting/improvised.yml index 2f3b34db2b..df3a3bbdab 100644 --- a/Resources/Prototypes/Recipes/Crafting/improvised.yml +++ b/Resources/Prototypes/Recipes/Crafting/improvised.yml @@ -162,3 +162,16 @@ icon: sprite: Objects/Misc/rifle_stock.rsi state: icon + +- type: construction + name: improvised explosive device + id: improvisedexplosive + graph: ImprovisedExplosive + startNode: start + targetNode: ied + category: construction-category-weapons + objectType: Item + description: A weak, improvised incendiary device. + icon: + sprite: Objects/Weapons/Bombs/ied.rsi + state: icon diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 8a120d7bf0..6d72187985 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -407,6 +407,9 @@ - type: Tag id: Donut +- type: Tag + id: DrinkCan + - type: Tag id: DrinkSpaceGlue diff --git a/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/base.png b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/base.png new file mode 100644 index 0000000000..dda9a11195 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/base.png differ diff --git a/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/fuel.png b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/fuel.png new file mode 100644 index 0000000000..217abeb24f Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/fuel.png differ diff --git a/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/icon.png b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/icon.png new file mode 100644 index 0000000000..a8c37b9910 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/meta.json b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/meta.json new file mode 100644 index 0000000000..6ec234fecd --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by deltanedas (github) for SS14, icon and base based on cola sprite from cev-eris", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "base" + }, + { + "name": "fuel" + }, + { + "name": "wires" + } + ] +} diff --git a/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/wires.png b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/wires.png new file mode 100644 index 0000000000..bfc9beed6d Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Bombs/ied.rsi/wires.png differ