/// <param name="component"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
- public bool TryGetNodeData<T>(EntityUid uid, string key, [NotNullWhen(true)] out T data, ArtifactComponent? component = null)
+ public bool TryGetNodeData<T>(EntityUid uid, string key, [NotNullWhen(true)] out T? data, ArtifactComponent? component = null)
{
- data = default!;
+ data = default;
if (!Resolve(uid, ref component))
return false;
--- /dev/null
+using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.Reagent;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
+
+namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
+
+/// <summary>
+/// This is used for an artifact that creates a puddle of
+/// random chemicals upon being triggered.
+/// </summary>
+[RegisterComponent, Access(typeof(ChemicalPuddleArtifactSystem))]
+public sealed class ChemicalPuddleArtifactComponent : Component
+{
+ /// <summary>
+ /// The prototype id of the puddle
+ /// </summary>
+ [DataField("puddlePrototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
+ public string PuddlePrototype = "PuddleSmear";
+
+ /// <summary>
+ /// The solution where all the chemicals are stored
+ /// </summary>
+ [DataField("chemicalSolution", required: true), ViewVariables(VVAccess.ReadWrite)]
+ public Solution ChemicalSolution = default!;
+
+ /// <summary>
+ /// The different chemicals that can be spawned by this effect
+ /// </summary>
+ [DataField("possibleChemicals", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<ReagentPrototype>))]
+ public List<string> PossibleChemicals = default!;
+
+ /// <summary>
+ /// The number of chemicals in the puddle
+ /// </summary>
+ [DataField("chemAmount")]
+ public int ChemAmount = 3;
+}
--- /dev/null
+using Content.Server.Fluids.EntitySystems;
+using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
+using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
+using Robust.Shared.Random;
+
+namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
+
+/// <summary>
+/// This handles <see cref="ChemicalPuddleArtifactComponent"/>
+/// </summary>
+public sealed class ChemicalPuddleArtifactSystem : EntitySystem
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly ArtifactSystem _artifact = default!;
+ [Dependency] private readonly SpillableSystem _spillable = default!;
+
+ /// <summary>
+ /// The key for the node data entry containing
+ /// the chemicals that the puddle is made of.
+ /// </summary>
+ public const string NodeDataChemicalList = "nodeDataSpawnAmount";
+
+ /// <inheritdoc/>
+ public override void Initialize()
+ {
+ SubscribeLocalEvent<ChemicalPuddleArtifactComponent, ArtifactActivatedEvent>(OnActivated);
+ }
+
+ private void OnActivated(EntityUid uid, ChemicalPuddleArtifactComponent component, ArtifactActivatedEvent args)
+ {
+ if (!TryComp<ArtifactComponent>(uid, out var artifact))
+ return;
+
+ if (!_artifact.TryGetNodeData(uid, NodeDataChemicalList, out List<string>? chemicalList, artifact))
+ {
+ chemicalList = new();
+ for (var i = 0; i < component.ChemAmount; i++)
+ {
+ var chemProto = _random.Pick(component.PossibleChemicals);
+ chemicalList.Add(chemProto);
+ }
+
+ _artifact.SetNodeData(uid, NodeDataChemicalList, chemicalList, artifact);
+ }
+
+ var amountPerChem = component.ChemicalSolution.MaxVolume / component.ChemAmount;
+ foreach (var reagent in chemicalList)
+ {
+ component.ChemicalSolution.AddReagent(reagent, amountPerChem);
+ }
+
+ _spillable.SpillAt(uid, component.ChemicalSolution, component.PuddlePrototype);
+ }
+}
spawns:
- id: FoodBanana
+- type: artifactEffect
+ id: EffectChemicalPuddle
+ targetDepth: 1
+ effectHint: artifact-effect-hint-biochemical
+ components:
+ - type: ChemicalPuddleArtifact
+ chemicalSolution:
+ maxVol: 500
+ canReact: false
+ possibleChemicals:
+ - Aluminium
+ - Carbon
+ - Chlorine
+ - Copper
+ - Ethanol
+ - Fluorine
+ - Sugar
+ - Hydrogen
+ - Iodine
+ - Iron
+ - Lithium
+ - Mercury
+ - Nitrogen
+ - Oxygen
+ - Phosphorus
+ - Potassium
+ - Radium
+ - Silicon
+ - Sodium
+ - Water
+ - Sulfur
+
- type: artifactEffect
id: EffectCold
targetDepth: 1
reagents:
- Dermaline
- Arithrazine
- - Spaceacillin
+ - Bicaridine
+ - Inaprovaline
+ - Kelotane
+ - Dexalin
+ - Omnizine
+
+- type: artifactEffect
+ id: EffectChemicalPuddleRare
+ targetDepth: 2
+ effectHint: artifact-effect-hint-biochemical
+ components:
+ - type: ChemicalPuddleArtifact
+ chemicalSolution:
+ maxVol: 500
+ canReact: false
+ possibleChemicals:
+ - Dermaline
+ - Arithrazine
+ - Bicaridine
- Inaprovaline
- Kelotane
- Dexalin
- Omnizine
+ - Napalm
+ - Toxin
+ - Epinephrine
+ - Cognizine
+ - Ultravasculine
+ - Desoxyephedrine
+ - Pax
+ - Siderlac
- type: artifactEffect
id: EffectHealAll