diff --git a/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs b/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs index 684d857272..e53b9f8fc0 100644 --- a/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs +++ b/Content.IntegrationTests/Tests/Chemistry/TryAllReactionsTest.cs @@ -16,10 +16,20 @@ namespace Content.IntegrationTests.Tests.Chemistry [TestOf(typeof(ReactionPrototype))] public class TryAllReactionsTest : ContentIntegrationTest { + private const string Prototypes = @" +- type: entity + id: TestSolutionContainer + components: + - type: SolutionContainerManager + solutions: + beaker: + maxVol: 50"; + [Test] public async Task TryAllTest() { - var server = StartServer(); + var options = new ServerContentIntegrationOption{ExtraPrototypes = Prototypes}; + var server = StartServer(options); await server.WaitIdleAsync(); @@ -38,7 +48,7 @@ namespace Content.IntegrationTests.Tests.Chemistry server.Assert(() => { - beaker = entityManager.SpawnEntity("BluespaceBeaker", coordinates); + beaker = entityManager.SpawnEntity("TestSolutionContainer", coordinates); Assert.That(EntitySystem.Get() .TryGetSolution(beaker.Uid, "beaker", out component)); foreach (var (id, reactant) in reactionPrototype.Reactants) diff --git a/Content.Server/Chemistry/ReagentEffects/CreateGas.cs b/Content.Server/Chemistry/ReagentEffects/CreateGas.cs new file mode 100644 index 0000000000..2cd8fd0347 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffects/CreateGas.cs @@ -0,0 +1,36 @@ +using Content.Server.Atmos.EntitySystems; +using Content.Shared.Atmos; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Database; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Chemistry.ReagentEffects; + +public class CreateGas : ReagentEffect +{ + [DataField("gas", required: true)] + public Gas Gas = default!; + + /// + /// For each unit consumed, how many moles of gas should be created? + /// + [DataField("multiplier")] + public float Multiplier = 3f; + + public override bool ShouldLog => true; + public override LogImpact LogImpact => LogImpact.High; + + public override void Effect(ReagentEffectArgs args) + { + var atmosSys = EntitySystem.Get(); + + var xform = args.EntityManager.GetComponent(args.SolutionEntity); + var tileMix = atmosSys.GetTileMixture(xform.Coordinates); + + if (tileMix != null) + { + tileMix.AdjustMoles(Gas, args.Quantity.Float() * Multiplier); + } + } +} diff --git a/Content.Server/Chemistry/ReagentEffects/FlammableReaction.cs b/Content.Server/Chemistry/ReagentEffects/FlammableReaction.cs index b5282c4fcb..e72a8d5a29 100644 --- a/Content.Server/Chemistry/ReagentEffects/FlammableReaction.cs +++ b/Content.Server/Chemistry/ReagentEffects/FlammableReaction.cs @@ -16,6 +16,9 @@ namespace Content.Server.Chemistry.ReagentEffects [UsedImplicitly] public class FlammableReaction : ReagentEffect { + [DataField("multiplier")] + public float Multiplier = 0.05f; + public override bool ShouldLog => true; public override LogImpact LogImpact => LogImpact.Medium; @@ -23,7 +26,7 @@ namespace Content.Server.Chemistry.ReagentEffects { if (!args.EntityManager.TryGetComponent(args.SolutionEntity, out FlammableComponent? flammable)) return; - EntitySystem.Get().AdjustFireStacks(args.SolutionEntity, args.Quantity.Float() / 5f, flammable); + EntitySystem.Get().AdjustFireStacks(args.SolutionEntity, args.Quantity.Float() * Multiplier, flammable); args.Source?.RemoveReagent(args.Reagent.ID, args.Quantity); } } diff --git a/Content.Server/Chemistry/ReagentEffects/Ignite.cs b/Content.Server/Chemistry/ReagentEffects/Ignite.cs new file mode 100644 index 0000000000..110bcd003f --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffects/Ignite.cs @@ -0,0 +1,21 @@ +using Content.Server.Atmos.EntitySystems; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Database; +using Robust.Shared.GameObjects; + +namespace Content.Server.Chemistry.ReagentEffects; + +/// +/// Ignites a mob. +/// +public class Ignite : ReagentEffect +{ + public override bool ShouldLog => true; + public override LogImpact LogImpact => LogImpact.Medium; + + public override void Effect(ReagentEffectArgs args) + { + var flamSys = EntitySystem.Get(); + flamSys.Ignite(args.SolutionEntity); + } +} diff --git a/Content.Server/Chemistry/TileReactions/PryTileReaction.cs b/Content.Server/Chemistry/TileReactions/PryTileReaction.cs new file mode 100644 index 0000000000..efbaec151c --- /dev/null +++ b/Content.Server/Chemistry/TileReactions/PryTileReaction.cs @@ -0,0 +1,20 @@ +using Content.Shared.Chemistry.Reaction; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Content.Shared.Maps; +using JetBrains.Annotations; +using Robust.Shared.Map; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Chemistry.TileReactions; + +[UsedImplicitly] +[DataDefinition] +public class PryTileReaction : ITileReaction +{ + public FixedPoint2 TileReact(TileRef tile, ReagentPrototype reagent, FixedPoint2 reactVolume) + { + tile.PryTile(); + return reactVolume; + } +} diff --git a/Content.Shared/Chemistry/Reaction/ReactionPrototype.cs b/Content.Shared/Chemistry/Reaction/ReactionPrototype.cs index 5534a7351e..3369207d2c 100644 --- a/Content.Shared/Chemistry/Reaction/ReactionPrototype.cs +++ b/Content.Shared/Chemistry/Reaction/ReactionPrototype.cs @@ -6,6 +6,7 @@ using Content.Shared.FixedPoint; using Content.Shared.Sound; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; using Robust.Shared.ViewVariables; namespace Content.Shared.Chemistry.Reaction @@ -26,12 +27,14 @@ namespace Content.Shared.Chemistry.Reaction /// /// Reactants required for the reaction to occur. /// - [DataField("reactants")] public Dictionary Reactants = new(); + [DataField("reactants", customTypeSerializer:typeof(PrototypeIdDictionarySerializer))] + public Dictionary Reactants = new(); /// /// Reagents created when the reaction occurs. /// - [DataField("products")] public Dictionary Products = new(); + [DataField("products", customTypeSerializer:typeof(PrototypeIdDictionarySerializer))] + public Dictionary Products = new(); /// /// Effects to be triggered when the reaction occurs. diff --git a/Resources/Locale/en-US/reagents/clf3.ftl b/Resources/Locale/en-US/reagents/clf3.ftl new file mode 100644 index 0000000000..9055e232b4 --- /dev/null +++ b/Resources/Locale/en-US/reagents/clf3.ftl @@ -0,0 +1,3 @@ +clf3-it-burns = It burns like hell!! +clf3-get-away = You need to get away now! +clf3-explosion = The mixture fireballs outwards! diff --git a/Resources/Locale/en-US/reagents/phlogiston.ftl b/Resources/Locale/en-US/reagents/phlogiston.ftl new file mode 100644 index 0000000000..df43a42cad --- /dev/null +++ b/Resources/Locale/en-US/reagents/phlogiston.ftl @@ -0,0 +1 @@ +phlogiston-plasma-created = The mixture bubbles, and plasma rises from it! diff --git a/Resources/Prototypes/Reagents/pyrotechnic.yml b/Resources/Prototypes/Reagents/pyrotechnic.yml index b663c1df06..0a35699178 100644 --- a/Resources/Prototypes/Reagents/pyrotechnic.yml +++ b/Resources/Prototypes/Reagents/pyrotechnic.yml @@ -5,6 +5,11 @@ methods: [ Touch ] effects: - !type:FlammableReaction + plantMetabolism: + - !type:PlantAdjustWeeds + amount: -2 + - !type:PlantAdjustHealth + amount: -2 - type: reagent id: Thermite @@ -26,6 +31,93 @@ types: Heat: 2 +- type: reagent + id: Napalm + name: napalm + parent: BasePyrotechnic + desc: It's just a little flammable. + physicalDesc: soapy + color: "#FA00AF" + tileReactions: + - !type:FlammableTileReaction + temperatureMultiplier: 5 + reactiveEffects: + Flammable: + methods: [ Touch ] + effects: + - !type:FlammableReaction + multiplier: 0.4 + metabolisms: + Poison: + effects: + - !type:HealthChange + damage: + types: + Heat: 1 + - !type:FlammableReaction + multiplier: 0.4 + +- type: reagent + id: Phlogiston + name: phlogiston + parent: BasePyrotechnic + desc: Catches you on fire and makes you ignite. + physicalDesc: burning + color: "#D4872A" + metabolisms: + Poison: + effects: + - !type:HealthChange + damage: + types: + Heat: 3 + - !type:FlammableReaction + multiplier: 0.1 + - !type:AdjustTemperature + amount: 6000 + reactiveEffects: + Flammable: + methods: [ Touch ] + effects: + - !type:FlammableReaction + multiplier: 0.2 + - !type:Ignite + +- type: reagent + id: ChlorineTrifluoride + name: CLF3 + parent: BasePyrotechnic + desc: You really, REALLY don't want to get this shit anywhere near you. + physicalDesc: blazing + color: "#FFC8C8" + tileReactions: + - !type:PryTileReaction + metabolisms: + Poison: + effects: + - !type:HealthChange + damage: + types: + Heat: 1 + - !type:FlammableReaction + multiplier: 0.2 + - !type:AdjustTemperature + amount: 6000 + reactiveEffects: + Flammable: + methods: [ Touch ] + effects: + - !type:FlammableReaction + multiplier: 0.3 + - !type:Ignite + - !type:DoAction + probability: 0.2 + action: HumanScream + - !type:PopupMessage + messages: [ "clf3-it-burns", "clf3-get-away" ] + probability: 0.3 + type: Local + - type: reagent id: FoamingAgent name: foaming agent diff --git a/Resources/Prototypes/Recipes/Reactions/pyrotechnic.yml b/Resources/Prototypes/Recipes/Reactions/pyrotechnic.yml new file mode 100644 index 0000000000..62731c9062 --- /dev/null +++ b/Resources/Prototypes/Recipes/Reactions/pyrotechnic.yml @@ -0,0 +1,50 @@ +- type: reaction + id: Napalm + reactants: + Oil: + amount: 1 + WeldingFuel: + amount: 1 + Ethanol: + amount: 1 + products: + Napalm: 3 + +- type: reaction + id: Phlogiston + reactants: + Phosphorus: + amount: 1 + SulfuricAcid: + amount: 1 + Plasma: + amount: 1 + effects: + - !type:CreateGas + gas: Plasma + - !type:PopupMessage + messages: [ "phlogiston-plasma-created" ] + type: Pvs + products: + Phlogiston: 3 + +- type: reaction + id: ChlorineTrifluoride + reactants: + Chlorine: + amount: 1 + Fluorine: + amount: 3 + effects: + # TODO electro's pretty explosions PR make this big and firey!! + # TODO solution temperature!! + - !type:ExplosionReactionEffect + devastationRange: 0 + heavyImpactRange: 0 + lightImpactRange: 2 + scaled: false + - !type:PopupMessage + messages: [ "clf3-explosion" ] + type: Pvs + products: + ChlorineTrifluoride: 4