diff --git a/Content.Server/Chemistry/ReagentEntityReactions/AddToSolutionReaction.cs b/Content.Server/Chemistry/ReagentEntityReactions/AddToSolutionReaction.cs new file mode 100644 index 0000000000..ab2577e671 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEntityReactions/AddToSolutionReaction.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Chemistry; +using Content.Shared.Chemistry; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.Chemistry.ReagentEntityReactions +{ + [UsedImplicitly] + [DataDefinition] + public class AddToSolutionReaction : ReagentEntityReaction + { + [DataField("reagents", true, customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] + // ReSharper disable once CollectionNeverUpdated.Local + private readonly HashSet _reagents = new (); + + protected override void React(IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution? source) + { + if (!entity.TryGetComponent(out SolutionContainerComponent? solutionContainer) || (_reagents.Count > 0 && !_reagents.Contains(reagent.ID))) return; + + if(solutionContainer.TryAddReagent(reagent.ID, volume, out var accepted)) + source?.RemoveReagent(reagent.ID, accepted); + } + } +} diff --git a/Content.Server/Chemistry/ReagentEntityReactions/ExtinguishReaction.cs b/Content.Server/Chemistry/ReagentEntityReactions/ExtinguishReaction.cs new file mode 100644 index 0000000000..7f8d03d69b --- /dev/null +++ b/Content.Server/Chemistry/ReagentEntityReactions/ExtinguishReaction.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Atmos; +using Content.Shared.Chemistry; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.Chemistry.ReagentEntityReactions +{ + [UsedImplicitly] + [DataDefinition] + public class ExtinguishReaction : ReagentEntityReaction + { + [DataField("reagents", true, customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] + // ReSharper disable once CollectionNeverUpdated.Local + private readonly HashSet _reagents = new (); + + protected override void React(IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution? source) + { + if (!entity.TryGetComponent(out FlammableComponent? flammable) || !_reagents.Contains(reagent.ID)) return; + + flammable.Extinguish(); + flammable.AdjustFireStacks(-1.5f); + } + } +} diff --git a/Content.Server/Chemistry/ReagentEntityReactions/FlammableReaction.cs b/Content.Server/Chemistry/ReagentEntityReactions/FlammableReaction.cs new file mode 100644 index 0000000000..25e88e754a --- /dev/null +++ b/Content.Server/Chemistry/ReagentEntityReactions/FlammableReaction.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Atmos; +using Content.Shared.Chemistry; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.Chemistry.ReagentEntityReactions +{ + [UsedImplicitly] + [DataDefinition] + public class FlammableReaction : ReagentEntityReaction + { + [DataField("reagents", true, customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] + // ReSharper disable once CollectionNeverUpdated.Local + private readonly HashSet _reagents = new (); + + protected override void React(IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution? source) + { + if (!entity.TryGetComponent(out FlammableComponent? flammable) || !_reagents.Contains(reagent.ID)) return; + + flammable.AdjustFireStacks(volume.Float() / 10f); + source?.RemoveReagent(reagent.ID, volume); + } + } +} diff --git a/Content.Server/Chemistry/ReagentEntityReactions/WashCreamPieReaction.cs b/Content.Server/Chemistry/ReagentEntityReactions/WashCreamPieReaction.cs new file mode 100644 index 0000000000..9677a800e0 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEntityReactions/WashCreamPieReaction.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Nutrition; +using Content.Shared.Chemistry; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.Chemistry.ReagentEntityReactions +{ + [UsedImplicitly] + [DataDefinition] + public class WashCreamPieReaction : ReagentEntityReaction + { + [DataField("reagents", true, customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] + // ReSharper disable once CollectionNeverUpdated.Local + private readonly HashSet _reagents = new (); + + protected override void React(IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution? source) + { + if (!entity.TryGetComponent(out CreamPiedComponent? creamPied) || !_reagents.Contains(reagent.ID)) return; + + creamPied.Wash(); + } + } +} diff --git a/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs b/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs index fd6404848d..5030ae5647 100644 --- a/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs @@ -25,7 +25,7 @@ using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Atmos { [RegisterComponent] - public class FlammableComponent : SharedFlammableComponent, IStartCollide, IFireAct, IReagentReaction, IInteractUsing + public class FlammableComponent : SharedFlammableComponent, IStartCollide, IFireAct, IInteractUsing { private bool _resisting = false; private readonly List _collided = new(); @@ -205,27 +205,6 @@ namespace Content.Server.GameObjects.Components.Atmos }); } - ReagentUnit IReagentReaction.ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume) - { - switch (reagent.ID) - { - case "chem.Water": - Extinguish(); - AdjustFireStacks(-1.5f); - return ReagentUnit.Zero; - - case "chem.WeldingFuel": - case "chem.Thermite": - case "chem.Plasma": - case "chem.Ethanol": - AdjustFireStacks(volume.Float() / 10f); - return volume; - - default: - return ReagentUnit.Zero; - } - } - public async Task InteractUsing(InteractUsingEventArgs eventArgs) { foreach (var hotItem in eventArgs.Using.GetAllComponents()) diff --git a/Content.Server/GameObjects/Components/Botany/PlantHolderComponent.cs b/Content.Server/GameObjects/Components/Botany/PlantHolderComponent.cs index feb198567f..b4d5b629d9 100644 --- a/Content.Server/GameObjects/Components/Botany/PlantHolderComponent.cs +++ b/Content.Server/GameObjects/Components/Botany/PlantHolderComponent.cs @@ -36,7 +36,7 @@ using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Botany { [RegisterComponent] - public class PlantHolderComponent : Component, IInteractUsing, IInteractHand, IActivate, IReagentReaction, IExamine + public class PlantHolderComponent : Component, IInteractUsing, IInteractHand, IActivate, IExamine { public const float HydroponicsSpeedMultiplier = 1f; public const float HydroponicsConsumptionMultiplier = 4f; @@ -807,24 +807,6 @@ namespace Content.Server.GameObjects.Components.Botany return false; } - ReagentUnit IReagentReaction.ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume) - { - if(_solutionContainer == null) - return ReagentUnit.Zero; - - _solutionContainer.TryAddReagent(reagent.ID, volume, out var accepted); - return accepted; - } - - ReagentUnit IReagentReaction.ReagentReactInjection(ReagentPrototype reagent, ReagentUnit volume) - { - if(_solutionContainer == null) - return ReagentUnit.Zero; - - _solutionContainer.TryAddReagent(reagent.ID, volume, out var accepted); - return accepted; - } - bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs) { // DoHarvest does the sanity checks. diff --git a/Content.Server/GameObjects/Components/Chemistry/RehydratableComponent.cs b/Content.Server/GameObjects/Components/Chemistry/RehydratableComponent.cs index e9784e720d..e658e522eb 100644 --- a/Content.Server/GameObjects/Components/Chemistry/RehydratableComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/RehydratableComponent.cs @@ -17,9 +17,8 @@ namespace Content.Server.GameObjects.Components.Chemistry /// But specifically, this component deletes the entity and spawns in a new entity when the entity is exposed to a given reagent. /// [RegisterComponent] - [ComponentReference(typeof(IReagentReaction))] [ComponentReference(typeof(ISolutionChange))] - public class RehydratableComponent : Component, IReagentReaction, ISolutionChange + public class RehydratableComponent : Component, ISolutionChange { public override string Name => "Rehydratable"; @@ -28,22 +27,10 @@ namespace Content.Server.GameObjects.Components.Chemistry private string _catalystPrototype = "chem.Water"; [ViewVariables] [DataField("target")] - private string? _targetPrototype; + private string? _targetPrototype = default!; private bool _expanding; - ReagentUnit IReagentReaction.ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume) => Reaction(reagent, volume); - ReagentUnit IReagentReaction.ReagentReactInjection(ReagentPrototype reagent, ReagentUnit volume) => Reaction(reagent, volume); - - private ReagentUnit Reaction(ReagentPrototype reagent, ReagentUnit volume) - { - if ((volume > ReagentUnit.Zero) && (reagent.ID == _catalystPrototype)) - { - Expand(); - } - return ReagentUnit.Zero; - } - void ISolutionChange.SolutionChanged(SolutionChangeEventArgs eventArgs) { var solution = eventArgs.Owner.GetComponent(); diff --git a/Content.Server/GameObjects/Components/Chemistry/SmokeSolutionAreaEffectComponent.cs b/Content.Server/GameObjects/Components/Chemistry/SmokeSolutionAreaEffectComponent.cs index 43cd9a58aa..7a8970131a 100644 --- a/Content.Server/GameObjects/Components/Chemistry/SmokeSolutionAreaEffectComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/SmokeSolutionAreaEffectComponent.cs @@ -4,6 +4,7 @@ using Content.Server.GameObjects.Components.Body.Circulatory; using Content.Server.GameObjects.Components.Body.Respiratory; using Content.Shared.Chemistry; using Content.Shared.GameObjects.Components.Chemistry; +using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Interfaces.GameObjects.Components; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; @@ -37,6 +38,7 @@ namespace Content.Server.GameObjects.Components.Chemistry internals.AreInternalsWorking()) return; + var chemistry = EntitySystem.Get(); var cloneSolution = SolutionContainerComponent.Solution.Clone(); var transferAmount = ReagentUnit.Min(cloneSolution.TotalVolume * solutionFraction, bloodstream.EmptyVolume); var transferSolution = cloneSolution.SplitSolution(transferAmount); @@ -44,8 +46,7 @@ namespace Content.Server.GameObjects.Components.Chemistry foreach (var reagentQuantity in transferSolution.Contents.ToArray()) { if (reagentQuantity.Quantity == ReagentUnit.Zero) continue; - var reagent = PrototypeManager.Index(reagentQuantity.ReagentId); - transferSolution.RemoveReagent(reagentQuantity.ReagentId,reagent.ReactionEntity(entity, ReactionMethod.Ingestion, reagentQuantity.Quantity)); + chemistry.ReactionEntity(entity, ReactionMethod.Ingestion, reagentQuantity.ReagentId, reagentQuantity.Quantity, transferSolution); } bloodstream.TryTransferSolution(transferSolution); diff --git a/Content.Server/GameObjects/Components/Chemistry/SolutionAreaEffectComponent.cs b/Content.Server/GameObjects/Components/Chemistry/SolutionAreaEffectComponent.cs index e9b8514704..0a1dfb4057 100644 --- a/Content.Server/GameObjects/Components/Chemistry/SolutionAreaEffectComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/SolutionAreaEffectComponent.cs @@ -4,6 +4,7 @@ using System.Linq; using Content.Server.GameObjects.Components.Atmos; using Content.Server.Utility; using Content.Shared.Chemistry; +using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; using Robust.Shared.IoC; @@ -130,6 +131,7 @@ namespace Content.Server.GameObjects.Components.Chemistry if (SolutionContainerComponent == null) return; + var chemistry = EntitySystem.Get(); var mapGrid = MapManager.GetGrid(Owner.Transform.GridID); var tile = mapGrid.GetTileRef(Owner.Transform.Coordinates.ToVector2i(Owner.EntityManager, MapManager)); @@ -146,7 +148,7 @@ namespace Content.Server.GameObjects.Components.Chemistry // Touch every entity on the tile foreach (var entity in tile.GetEntitiesInTileFast().ToArray()) { - reagent.ReactionEntity(entity, ReactionMethod.Touch, reagentQuantity.Quantity * solutionFraction); + chemistry.ReactionEntity(entity, ReactionMethod.Touch, reagent, reagentQuantity.Quantity * solutionFraction, SolutionContainerComponent.Solution); } } diff --git a/Content.Server/GameObjects/Components/Nutrition/CreamPiedComponent.cs b/Content.Server/GameObjects/Components/Nutrition/CreamPiedComponent.cs index a617f15c7a..85bcb23f20 100644 --- a/Content.Server/GameObjects/Components/Nutrition/CreamPiedComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/CreamPiedComponent.cs @@ -12,7 +12,7 @@ using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Nutrition { [RegisterComponent] - public class CreamPiedComponent : SharedCreamPiedComponent, IReagentReaction, IThrowCollide + public class CreamPiedComponent : SharedCreamPiedComponent, IThrowCollide { private bool _creamPied; @@ -38,19 +38,6 @@ namespace Content.Server.GameObjects.Components.Nutrition CreamPied = false; } - ReagentUnit IReagentReaction.ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume) - { - switch (reagent.ID) - { - case "chem.SpaceCleaner": - case "chem.Water": - Wash(); - break; - } - - return ReagentUnit.Zero; - } - void IThrowCollide.HitBy(ThrowCollideEventArgs eventArgs) { if (eventArgs.Thrown.Deleted || !eventArgs.Thrown.TryGetComponent(out CreamPieComponent? creamPie)) return; diff --git a/Content.Shared/Chemistry/ReagentEntityReaction.cs b/Content.Shared/Chemistry/ReagentEntityReaction.cs new file mode 100644 index 0000000000..63fda54351 --- /dev/null +++ b/Content.Shared/Chemistry/ReagentEntityReaction.cs @@ -0,0 +1,56 @@ +using System; +using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Shared.Chemistry +{ + public enum ReactionMethod + { + Touch, + Injection, + Ingestion, + } + + [DataDefinition] + public abstract class ReagentEntityReaction + { + [ViewVariables] + [field: DataField("touch")] + public bool Touch { get; } = false; + + [ViewVariables] + [field: DataField("injection")] + public bool Injection { get; } = false; + + [ViewVariables] + [field: DataField("ingestion")] + public bool Ingestion { get; } = false; + + public void React(ReactionMethod method, IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution? source) + { + switch (method) + { + case ReactionMethod.Touch: + if (!Touch) + return; + break; + case ReactionMethod.Injection: + if(!Injection) + return; + break; + case ReactionMethod.Ingestion: + if(!Ingestion) + return; + break; + default: + throw new ArgumentOutOfRangeException(nameof(method), method, null); + } + + React(entity, reagent, volume, source); + } + + protected abstract void React(IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution? source); + } +} diff --git a/Content.Shared/Chemistry/ReagentPrototype.cs b/Content.Shared/Chemistry/ReagentPrototype.cs index c143d7bda2..afc78d9e1c 100644 --- a/Content.Shared/Chemistry/ReagentPrototype.cs +++ b/Content.Shared/Chemistry/ReagentPrototype.cs @@ -82,38 +82,6 @@ namespace Content.Shared.Chemistry return SubstanceColor; } - public ReagentUnit ReactionEntity(IEntity? entity, ReactionMethod method, ReagentUnit reactVolume) - { - var removed = ReagentUnit.Zero; - - if (entity == null || entity.Deleted) - return removed; - - foreach (var react in entity.GetAllComponents()) - { - switch (method) - { - case ReactionMethod.Touch: - removed += react.ReagentReactTouch(this, reactVolume); - break; - case ReactionMethod.Ingestion: - removed += react.ReagentReactIngestion(this, reactVolume); - break; - case ReactionMethod.Injection: - removed += react.ReagentReactInjection(this, reactVolume); - break; - } - - if (removed > reactVolume) - throw new Exception("Removed more than we have!"); - - if (removed == reactVolume) - break; - } - - return removed; - } - public ReagentUnit ReactionTile(TileRef tile, ReagentUnit reactVolume) { var removed = ReagentUnit.Zero; diff --git a/Content.Shared/Chemistry/Solution.cs b/Content.Shared/Chemistry/Solution.cs index 87c1402045..a1ebe75f26 100644 --- a/Content.Shared/Chemistry/Solution.cs +++ b/Content.Shared/Chemistry/Solution.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; using Robust.Shared.IoC; @@ -314,15 +315,11 @@ namespace Content.Shared.Chemistry public void DoEntityReaction(IEntity entity, ReactionMethod method) { - var proto = IoCManager.Resolve(); + var chemistry = EntitySystem.Get(); foreach (var (reagentId, quantity) in _contents.ToArray()) { - if (!proto.TryIndex(reagentId, out ReagentPrototype? reagent)) - continue; - - var removedAmount = reagent.ReactionEntity(entity, method, quantity); - RemoveReagent(reagentId, removedAmount); + chemistry.ReactionEntity(entity, method, reagentId, quantity, this); } } diff --git a/Content.Shared/GameObjects/Components/Chemistry/ReactiveComponent.cs b/Content.Shared/GameObjects/Components/Chemistry/ReactiveComponent.cs new file mode 100644 index 0000000000..ad04b6491b --- /dev/null +++ b/Content.Shared/GameObjects/Components/Chemistry/ReactiveComponent.cs @@ -0,0 +1,16 @@ +using System; +using Content.Shared.Chemistry; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Shared.GameObjects.Components.Chemistry +{ + [RegisterComponent] + public class ReactiveComponent : Component + { + public override string Name => "Reactive"; + + [field: DataField("reactions", true, serverOnly:true)] + public ReagentEntityReaction[] Reactions { get; } = Array.Empty(); + } +} diff --git a/Content.Shared/GameObjects/EntitySystems/ChemistrySystem.cs b/Content.Shared/GameObjects/EntitySystems/ChemistrySystem.cs index 92e48b8608..54acad1e2e 100644 --- a/Content.Shared/GameObjects/EntitySystems/ChemistrySystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/ChemistrySystem.cs @@ -1,8 +1,13 @@ #nullable enable using System; using System.Linq; +using Content.Shared.Chemistry; +using Content.Shared.GameObjects.Components.Chemistry; +using Content.Shared.Interfaces.GameObjects.Components; using JetBrains.Annotations; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Prototypes; namespace Content.Shared.GameObjects.EntitySystems { @@ -25,6 +30,8 @@ namespace Content.Shared.GameObjects.EntitySystems [UsedImplicitly] public class ChemistrySystem : EntitySystem { + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + public void HandleSolutionChange(IEntity owner) { var eventArgs = new SolutionChangeEventArgs @@ -41,5 +48,27 @@ namespace Content.Shared.GameObjects.EntitySystems return; } } + + public void ReactionEntity(IEntity? entity, ReactionMethod method, string reagentId, ReagentUnit reactVolume, Solution? source) + { + // We throw if the reagent specified doesn't exist. + ReactionEntity(entity, method, _prototypeManager.Index(reagentId), reactVolume, source); + } + + public void ReactionEntity(IEntity? entity, ReactionMethod method, ReagentPrototype reagent, ReagentUnit reactVolume, Solution? source) + { + if (entity == null || entity.Deleted || !entity.TryGetComponent(out ReactiveComponent? reactive)) + return; + + foreach (var reaction in reactive.Reactions) + { + // If we have a source solution, use the reagent quantity we have left. Otherwise, use the reaction volume specified. + reaction.React(method, entity, reagent, source?.GetReagentQuantity(reagent.ID) ?? reactVolume, source); + + // Make sure we still have enough reagent to go... + if (source != null && !source.ContainsReagent(reagent.ID)) + break; + } + } } } diff --git a/Content.Shared/GameObjects/EntitySystems/SlipperySystem.cs b/Content.Shared/GameObjects/EntitySystems/SlipperySystem.cs index dd6feabd28..9d95806eda 100644 --- a/Content.Shared/GameObjects/EntitySystems/SlipperySystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SlipperySystem.cs @@ -1,4 +1,5 @@ #nullable enable +using System.Linq; using Content.Shared.GameObjects.Components.Movement; using JetBrains.Annotations; using Robust.Shared.GameObjects; @@ -11,7 +12,7 @@ namespace Content.Shared.GameObjects.EntitySystems /// public override void Update(float frameTime) { - foreach (var slipperyComp in ComponentManager.EntityQuery(false)) + foreach (var slipperyComp in ComponentManager.EntityQuery().ToArray()) { slipperyComp.Update(); } diff --git a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IReagentReaction.cs b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IReagentReaction.cs deleted file mode 100644 index c2cefdcf72..0000000000 --- a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IReagentReaction.cs +++ /dev/null @@ -1,21 +0,0 @@ -#nullable enable -using Content.Shared.Chemistry; -using Robust.Shared.Analyzers; - -namespace Content.Shared.Interfaces.GameObjects.Components -{ - public enum ReactionMethod - { - Touch, - Injection, - Ingestion, - } - - [RequiresExplicitImplementation] - public interface IReagentReaction - { - ReagentUnit ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume) => ReagentUnit.Zero; - ReagentUnit ReagentReactInjection(ReagentPrototype reagent, ReagentUnit volume) => ReagentUnit.Zero; - ReagentUnit ReagentReactIngestion(ReagentPrototype reagent, ReagentUnit volume) => ReagentUnit.Zero; - } -} diff --git a/Resources/Prototypes/Entities/Constructible/Specific/barricades.yml b/Resources/Prototypes/Entities/Constructible/Specific/barricades.yml index 10de58542d..06872ce5a5 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/barricades.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/barricades.yml @@ -41,6 +41,19 @@ - type: AtmosExposed - type: Flammable fireSpread: true + - type: Reactive + reactions: + - !type:ExtinguishReaction + touch: true + reagents: + - chem.Water + - !type:FlammableReaction + touch: true + reagents: + - chem.WeldingFuel + - chem.Thermite + - chem.Plasma + - chem.Ethanol - type: Appearance visuals: - type: FireVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml b/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml index 7573f6e2b5..3ac867f696 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml @@ -44,6 +44,9 @@ caps: Refillable - type: SnapGrid offset: Center + - type: Reactive + reactions: + - !type:AddToSolutionReaction - type: Appearance visuals: - type: PlantHolderVisualizer diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index 9fb132ce24..8d35b91256 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -7,6 +7,19 @@ - type: Tag tags: - Teleportable + - type: Reactive + reactions: + - !type:ExtinguishReaction + touch: true + reagents: + - chem.Water + - !type:FlammableReaction + touch: true + reagents: + - chem.WeldingFuel + - chem.Thermite + - chem.Plasma + - chem.Ethanol - type: UtilityAI behaviorSets: - Clothing diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index c07a31912e..3a887ddcdb 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -10,6 +10,24 @@ tags: - Teleportable - FootstepSound + - type: Reactive + reactions: + - !type:ExtinguishReaction + touch: true + reagents: + - chem.Water + - !type:FlammableReaction + touch: true + reagents: + - chem.WeldingFuel + - chem.Thermite + - chem.Plasma + - chem.Ethanol + - !type:WashCreamPieReaction + touch: true + reagents: + - chem.Water + - chem.SpaceCleaner - type: Flashable - type: Hands - type: MovementSpeedModifier diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 7b06ab0acd..2a3185746d 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -85,13 +85,21 @@ state: pda-clown - type: Slippery paralyzeTime: 4 + - type: CollisionWake + enabled: false - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" - layer: - - MobImpassable + bodyType: KinematicController + mass: 2.5 + fixtures: # TODO: Make a second fixture. + - shape: + !type:PhysShapeAabb + bounds: "-0.3,-0.4,0.3,0.4" + hard: false + layer: + - SmallImpassable + mask: + - Impassable + - MobImpassable - type: entity name: Mime PDA diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index 0069a1c5b5..92b94dcb24 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -48,6 +48,7 @@ - state: extinguish map: [ "enum.VaporVisualLayers.Base" ] - type: Physics + bodyType: KinematicController fixtures: - shape: !type:PhysShapeAabb diff --git a/Resources/Prototypes/Entities/Objects/Specific/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/janitor.yml index 77ecd1b17c..ad36750a81 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/janitor.yml @@ -189,7 +189,7 @@ - state: chempuff map: [ "enum.VaporVisualLayers.Base" ] - type: Physics - bodyType: Dynamic + bodyType: KinematicController fixtures: - shape: !type:PhysShapeAabb diff --git a/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml b/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml index 7c9c5c04bd..6a88cdc602 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml @@ -13,8 +13,31 @@ caps: Refillable - type: Sprite sprite: Objects/Consumable/Food/monkeycube.rsi + - type: Reactive + reactions: + - !type:AddToSolutionReaction + touch: true + ingestion: true + injection: true + reagents: + - chem.Water - type: Rehydratable target: MonkeyMob_Content + - type: CollisionWake + enabled: false + - type: Physics + bodyType: KinematicController + mass: 2.5 + fixtures: # TODO: Make a second fixture. + - shape: + !type:PhysShapeAabb + bounds: "-0.3,-0.4,0.3,0.4" + hard: false + layer: + - SmallImpassable + mask: + - Impassable + - MobImpassable - type: entity parent: PlushieCarp @@ -29,5 +52,28 @@ Quantity: 10 maxVol: 11 # needs room for water caps: Refillable + - type: Reactive + reactions: + - !type:AddToSolutionReaction + touch: true + ingestion: true + injection: true + reagents: + - chem.Water - type: Rehydratable target: CarpMob_Content + - type: CollisionWake + enabled: false + - type: Physics + bodyType: KinematicController + mass: 2.5 + fixtures: # TODO: Make a second fixture. + - shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" + hard: false + layer: + - SmallImpassable + mask: + - Impassable + - MobImpassable