diff --git a/Content.Server/Spawners/Components/EntityTableSpawnerComponent.cs b/Content.Server/Spawners/Components/EntityTableSpawnerComponent.cs
new file mode 100644
index 0000000000..d122eb098b
--- /dev/null
+++ b/Content.Server/Spawners/Components/EntityTableSpawnerComponent.cs
@@ -0,0 +1,30 @@
+using Content.Server.Spawners.EntitySystems;
+using Content.Shared.EntityTable.EntitySelectors;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Spawners.Components;
+
+[RegisterComponent, EntityCategory("Spawner"), Access(typeof(ConditionalSpawnerSystem))]
+public sealed partial class EntityTableSpawnerComponent : Component
+{
+ ///
+ /// Table that determines what gets spawned.
+ ///
+ [DataField(required: true)]
+ public EntityTableSelector Table = default!;
+
+ ///
+ /// Scatter of entity spawn coordinates
+ ///
+ [DataField]
+ public float Offset = 0.2f;
+
+ ///
+ /// A variable meaning whether the spawn will
+ /// be able to be used again or whether
+ /// it will be destroyed after the first use
+ ///
+ [DataField]
+ public bool DeleteSpawnerAfterSpawn = true;
+}
+
diff --git a/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs b/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs
index f57481b05b..ad59fc83cf 100644
--- a/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs
+++ b/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs
@@ -1,9 +1,10 @@
using System.Numerics;
using Content.Server.GameTicking;
-using Content.Server.GameTicking.Rules.Components;
using Content.Server.Spawners.Components;
+using Content.Shared.EntityTable;
using Content.Shared.GameTicking.Components;
using JetBrains.Annotations;
+using Robust.Shared.Map;
using Robust.Shared.Random;
namespace Content.Server.Spawners.EntitySystems
@@ -13,6 +14,7 @@ namespace Content.Server.Spawners.EntitySystems
{
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly GameTicker _ticker = default!;
+ [Dependency] private readonly EntityTableSystem _entityTable = default!;
public override void Initialize()
{
@@ -21,6 +23,7 @@ namespace Content.Server.Spawners.EntitySystems
SubscribeLocalEvent(OnRuleStarted);
SubscribeLocalEvent(OnCondSpawnMapInit);
SubscribeLocalEvent(OnRandSpawnMapInit);
+ SubscribeLocalEvent(OnEntityTableSpawnMapInit);
}
private void OnCondSpawnMapInit(EntityUid uid, ConditionalSpawnerComponent component, MapInitEvent args)
@@ -35,6 +38,13 @@ namespace Content.Server.Spawners.EntitySystems
QueueDel(uid);
}
+ private void OnEntityTableSpawnMapInit(Entity ent, ref MapInitEvent args)
+ {
+ Spawn(ent);
+ if (ent.Comp.DeleteSpawnerAfterSpawn && !TerminatingOrDeleted(ent) && Exists(ent))
+ QueueDel(ent);
+ }
+
private void OnRuleStarted(ref GameRuleStartedEvent args)
{
var query = EntityQueryEnumerator();
@@ -110,5 +120,23 @@ namespace Content.Server.Spawners.EntitySystems
EntityManager.SpawnEntity(_robustRandom.Pick(component.Prototypes), coordinates);
}
+
+ private void Spawn(Entity ent)
+ {
+ if (TerminatingOrDeleted(ent) || !Exists(ent))
+ return;
+
+ var coords = Transform(ent).Coordinates;
+
+ var spawns = _entityTable.GetSpawns(ent.Comp.Table);
+ foreach (var proto in spawns)
+ {
+ var xOffset = _robustRandom.NextFloat(-ent.Comp.Offset, ent.Comp.Offset);
+ var yOffset = _robustRandom.NextFloat(-ent.Comp.Offset, ent.Comp.Offset);
+ var trueCoords = coords.Offset(new Vector2(xOffset, yOffset));
+
+ Spawn(proto, trueCoords);
+ }
+ }
}
}
diff --git a/Content.Shared/Containers/ContainerFillSystem.cs b/Content.Shared/Containers/ContainerFillSystem.cs
index e120b6bc88..51c7c48e40 100644
--- a/Content.Shared/Containers/ContainerFillSystem.cs
+++ b/Content.Shared/Containers/ContainerFillSystem.cs
@@ -1,4 +1,5 @@
using System.Numerics;
+using Content.Shared.EntityTable;
using Robust.Shared.Containers;
using Robust.Shared.Map;
@@ -7,11 +8,14 @@ namespace Content.Shared.Containers;
public sealed class ContainerFillSystem : EntitySystem
{
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+ [Dependency] private readonly EntityTableSystem _entityTable = default!;
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent(OnMapInit);
+ SubscribeLocalEvent(OnTableMapInit);
}
private void OnMapInit(EntityUid uid, ContainerFillComponent component, MapInitEvent args)
@@ -42,4 +46,37 @@ public sealed class ContainerFillSystem : EntitySystem
}
}
}
+
+ private void OnTableMapInit(Entity ent, ref MapInitEvent args)
+ {
+ if (!TryComp(ent, out ContainerManagerComponent? containerComp))
+ return;
+
+ if (TerminatingOrDeleted(ent) || !Exists(ent))
+ return;
+
+ var xform = Transform(ent);
+ var coords = new EntityCoordinates(ent, Vector2.Zero);
+
+ foreach (var (containerId, table) in ent.Comp.Containers)
+ {
+ if (!_containerSystem.TryGetContainer(ent, containerId, out var container, containerComp))
+ {
+ Log.Error($"Entity {ToPrettyString(ent)} with a {nameof(EntityTableContainerFillComponent)} is missing a container ({containerId}).");
+ continue;
+ }
+
+ var spawns = _entityTable.GetSpawns(table);
+ foreach (var proto in spawns)
+ {
+ var spawn = Spawn(proto, coords);
+ if (!_containerSystem.Insert(spawn, container, containerXform: xform))
+ {
+ Log.Error($"Entity {ToPrettyString(ent)} with a {nameof(EntityTableContainerFillComponent)} failed to insert an entity: {ToPrettyString(spawn)}.");
+ _transform.AttachToGridOrMap(spawn);
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/Content.Shared/Containers/EntityTableContainerFillComponent.cs b/Content.Shared/Containers/EntityTableContainerFillComponent.cs
new file mode 100644
index 0000000000..3f30dc86d6
--- /dev/null
+++ b/Content.Shared/Containers/EntityTableContainerFillComponent.cs
@@ -0,0 +1,13 @@
+using Content.Shared.EntityTable.EntitySelectors;
+
+namespace Content.Shared.Containers;
+
+///
+/// Version of that utilizes
+///
+[RegisterComponent, Access(typeof(ContainerFillSystem))]
+public sealed partial class EntityTableContainerFillComponent : Component
+{
+ [DataField]
+ public Dictionary Containers = new();
+}
diff --git a/Content.Shared/EntityTable/EntitySelectors/AllSelector.cs b/Content.Shared/EntityTable/EntitySelectors/AllSelector.cs
new file mode 100644
index 0000000000..8fb8b5e546
--- /dev/null
+++ b/Content.Shared/EntityTable/EntitySelectors/AllSelector.cs
@@ -0,0 +1,25 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable.EntitySelectors;
+
+///
+/// Gets spawns from all of the child selectors
+///
+public sealed partial class AllSelector : EntityTableSelector
+{
+ [DataField(required: true)]
+ public List Children;
+
+ protected override IEnumerable GetSpawnsImplementation(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto)
+ {
+ foreach (var child in Children)
+ {
+ foreach (var spawn in child.GetSpawns(rand, entMan, proto))
+ {
+ yield return spawn;
+ }
+ }
+ }
+}
diff --git a/Content.Shared/EntityTable/EntitySelectors/EntSelector.cs b/Content.Shared/EntityTable/EntitySelectors/EntSelector.cs
new file mode 100644
index 0000000000..b1e712b4b3
--- /dev/null
+++ b/Content.Shared/EntityTable/EntitySelectors/EntSelector.cs
@@ -0,0 +1,27 @@
+using Content.Shared.EntityTable.ValueSelector;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable.EntitySelectors;
+
+///
+/// Gets the spawn for the entity prototype specified at whatever count specified.
+///
+public sealed partial class EntSelector : EntityTableSelector
+{
+ [DataField(required: true)]
+ public EntProtoId Id;
+
+ [DataField]
+ public NumberSelector Amount = new ConstantNumberSelector(1);
+
+ protected override IEnumerable GetSpawnsImplementation(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto)
+ {
+ var num = (int) Math.Round(Amount.Get(rand, entMan, proto));
+ for (var i = 0; i < num; i++)
+ {
+ yield return Id;
+ }
+ }
+}
diff --git a/Content.Shared/EntityTable/EntitySelectors/EntityTableSelector.cs b/Content.Shared/EntityTable/EntitySelectors/EntityTableSelector.cs
new file mode 100644
index 0000000000..2533f17dc5
--- /dev/null
+++ b/Content.Shared/EntityTable/EntitySelectors/EntityTableSelector.cs
@@ -0,0 +1,49 @@
+using Content.Shared.EntityTable.ValueSelector;
+using JetBrains.Annotations;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+
+namespace Content.Shared.EntityTable.EntitySelectors;
+
+[ImplicitDataDefinitionForInheritors, UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
+public abstract partial class EntityTableSelector
+{
+ ///
+ /// The number of times this selector is run
+ ///
+ [DataField]
+ public NumberSelector Rolls = new ConstantNumberSelector(1);
+
+ ///
+ /// A weight used to pick between selectors.
+ ///
+ [DataField]
+ public float Weight = 1;
+
+ ///
+ /// A simple chance that the selector will run.
+ ///
+ [DataField]
+ public double Prob = 1;
+
+ public IEnumerable GetSpawns(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto)
+ {
+ var rolls = Rolls.Get(rand, entMan, proto);
+ for (var i = 0; i < rolls; i++)
+ {
+ if (!rand.Prob(Prob))
+ continue;
+
+ foreach (var spawn in GetSpawnsImplementation(rand, entMan, proto))
+ {
+ yield return spawn;
+ }
+ }
+ }
+
+ protected abstract IEnumerable GetSpawnsImplementation(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto);
+}
diff --git a/Content.Shared/EntityTable/EntitySelectors/GroupSelector.cs b/Content.Shared/EntityTable/EntitySelectors/GroupSelector.cs
new file mode 100644
index 0000000000..8f761f9866
--- /dev/null
+++ b/Content.Shared/EntityTable/EntitySelectors/GroupSelector.cs
@@ -0,0 +1,28 @@
+using Content.Shared.Random.Helpers;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable.EntitySelectors;
+
+///
+/// Gets the spawns from one of the child selectors, based on the weight of the children
+///
+public sealed partial class GroupSelector : EntityTableSelector
+{
+ [DataField(required: true)]
+ public List Children = new();
+
+ protected override IEnumerable GetSpawnsImplementation(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto)
+ {
+ var children = new Dictionary(Children.Count);
+ foreach (var child in Children)
+ {
+ children.Add(child, child.Weight);
+ }
+
+ var pick = SharedRandomExtensions.Pick(children, rand);
+
+ return pick.GetSpawns(rand, entMan, proto);
+ }
+}
diff --git a/Content.Shared/EntityTable/EntitySelectors/NestedSelector.cs b/Content.Shared/EntityTable/EntitySelectors/NestedSelector.cs
new file mode 100644
index 0000000000..fc8d8f08d3
--- /dev/null
+++ b/Content.Shared/EntityTable/EntitySelectors/NestedSelector.cs
@@ -0,0 +1,20 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable.EntitySelectors;
+
+///
+/// Gets the spawns from the entity table prototype specified.
+/// Can be used to reuse common tables.
+///
+public sealed partial class NestedSelector : EntityTableSelector
+{
+ [DataField(required: true)]
+ public ProtoId TableId;
+
+ protected override IEnumerable GetSpawnsImplementation(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto)
+ {
+ return proto.Index(TableId).Table.GetSpawns(rand, entMan, proto);
+ }
+}
diff --git a/Content.Shared/EntityTable/EntitySelectors/NoneSelector.cs b/Content.Shared/EntityTable/EntitySelectors/NoneSelector.cs
new file mode 100644
index 0000000000..21fcb6d279
--- /dev/null
+++ b/Content.Shared/EntityTable/EntitySelectors/NoneSelector.cs
@@ -0,0 +1,16 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable.EntitySelectors;
+
+///
+/// Selects nothing.
+///
+public sealed partial class NoneSelector : EntityTableSelector
+{
+ protected override IEnumerable GetSpawnsImplementation(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto)
+ {
+ yield break;
+ }
+}
diff --git a/Content.Shared/EntityTable/EntityTablePrototype.cs b/Content.Shared/EntityTable/EntityTablePrototype.cs
new file mode 100644
index 0000000000..63cebe9aeb
--- /dev/null
+++ b/Content.Shared/EntityTable/EntityTablePrototype.cs
@@ -0,0 +1,18 @@
+using Content.Shared.EntityTable.EntitySelectors;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable;
+
+///
+/// This is a prototype for...
+///
+[Prototype]
+public sealed partial class EntityTablePrototype : IPrototype
+{
+ ///
+ [IdDataField]
+ public string ID { get; } = default!;
+
+ [DataField(required: true)]
+ public EntityTableSelector Table = default!;
+}
diff --git a/Content.Shared/EntityTable/EntityTableSystem.cs b/Content.Shared/EntityTable/EntityTableSystem.cs
new file mode 100644
index 0000000000..ff499e6760
--- /dev/null
+++ b/Content.Shared/EntityTable/EntityTableSystem.cs
@@ -0,0 +1,20 @@
+using Content.Shared.EntityTable.EntitySelectors;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+
+namespace Content.Shared.EntityTable;
+
+public sealed class EntityTableSystem : EntitySystem
+{
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+
+ public IEnumerable GetSpawns(EntityTableSelector? table, System.Random? rand = null)
+ {
+ if (table == null)
+ return new List();
+
+ rand ??= _random.GetRandom();
+ return table.GetSpawns(rand, EntityManager, _prototypeManager);
+ }
+}
diff --git a/Content.Shared/EntityTable/ValueSelector/ConstantNumberSelector.cs b/Content.Shared/EntityTable/ValueSelector/ConstantNumberSelector.cs
new file mode 100644
index 0000000000..0baf6785f4
--- /dev/null
+++ b/Content.Shared/EntityTable/ValueSelector/ConstantNumberSelector.cs
@@ -0,0 +1,22 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable.ValueSelector;
+
+///
+/// Gives a constant value.
+///
+public sealed partial class ConstantNumberSelector : NumberSelector
+{
+ [DataField]
+ public float Value = 1;
+
+ public ConstantNumberSelector(float value)
+ {
+ Value = value;
+ }
+
+ public override float Get(System.Random rand, IEntityManager entMan, IPrototypeManager proto)
+ {
+ return Value;
+ }
+}
diff --git a/Content.Shared/EntityTable/ValueSelector/NumberSelector.cs b/Content.Shared/EntityTable/ValueSelector/NumberSelector.cs
new file mode 100644
index 0000000000..8a7743c9dd
--- /dev/null
+++ b/Content.Shared/EntityTable/ValueSelector/NumberSelector.cs
@@ -0,0 +1,16 @@
+using Content.Shared.EntityTable.EntitySelectors;
+using JetBrains.Annotations;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.EntityTable.ValueSelector;
+
+///
+/// Used for implementing custom value selection for
+///
+[ImplicitDataDefinitionForInheritors, UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
+public abstract partial class NumberSelector
+{
+ public abstract float Get(System.Random rand,
+ IEntityManager entMan,
+ IPrototypeManager proto);
+}
diff --git a/Content.Shared/EntityTable/ValueSelector/RangeNumberSelector.cs b/Content.Shared/EntityTable/ValueSelector/RangeNumberSelector.cs
new file mode 100644
index 0000000000..e8356fcbb7
--- /dev/null
+++ b/Content.Shared/EntityTable/ValueSelector/RangeNumberSelector.cs
@@ -0,0 +1,19 @@
+using System.Numerics;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+
+namespace Content.Shared.EntityTable.ValueSelector;
+
+///
+/// Gives a value between the two numbers specified, inclusive.
+///
+public sealed partial class RangeNumberSelector : NumberSelector
+{
+ [DataField]
+ public Vector2 Range = new(1, 1);
+
+ public override float Get(System.Random rand, IEntityManager entMan, IPrototypeManager proto)
+ {
+ return rand.NextFloat(Range.X, Range.Y + 1);
+ }
+}
diff --git a/Content.Shared/Random/Helpers/SharedRandomExtensions.cs b/Content.Shared/Random/Helpers/SharedRandomExtensions.cs
index 376e91743d..42d92a9065 100644
--- a/Content.Shared/Random/Helpers/SharedRandomExtensions.cs
+++ b/Content.Shared/Random/Helpers/SharedRandomExtensions.cs
@@ -108,6 +108,27 @@ namespace Content.Shared.Random.Helpers
return true;
}
+ public static T Pick(Dictionary weights, System.Random random)
+ where T : notnull
+ {
+ var sum = weights.Values.Sum();
+ var accumulated = 0f;
+
+ var rand = random.NextFloat() * sum;
+
+ foreach (var (key, weight) in weights)
+ {
+ accumulated += weight;
+
+ if (accumulated >= rand)
+ {
+ return key;
+ }
+ }
+
+ throw new InvalidOperationException("Invalid weighted pick");
+ }
+
public static (string reagent, FixedPoint2 quantity) Pick(this WeightedRandomFillSolutionPrototype prototype, IRobustRandom? random = null)
{
var randomFill = prototype.PickRandomFill(random);
diff --git a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml
index c52e13bd13..ebc7a446b9 100644
--- a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml
+++ b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml
@@ -1,33 +1,81 @@
+- type: entityTable
+ id: AllPlushiesTable
+ table: !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: PlushieBee
+ - !type:EntSelector
+ id: PlushieNar
+ weight: 0.5
+ - !type:EntSelector
+ id: PlushieRatvar
+ weight: 0.5
+ - !type:EntSelector
+ id: PlushieNuke
+ - !type:EntSelector
+ id: PlushieSlime
+ - !type:EntSelector
+ id: PlushieSnake
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: PlushieLizard
+ weight: 9
+ - !type:EntSelector
+ id: PlushieSpaceLizard
+ weight: 1
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: PlushieCarp
+ - !type:EntSelector
+ id: PlushieHolocarp
+ weight: 0.25
+ - !type:EntSelector
+ id: PlushieMagicarp
+ weight: 0.25
+ - !type:EntSelector
+ id: PlushieRainbowCarp
+ weight: 0.15
+ - !type:EntSelector
+ id: PlushieVox
+ - !type:EntSelector
+ id: PlushieRouny
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: PlushieSharkBlue
+ - !type:EntSelector
+ id: PlushieSharkGrey
+ - !type:EntSelector
+ id: PlushieSharkPink
+ - !type:EntSelector
+ id: PlushieAtmosian
+ - !type:EntSelector
+ id: PlushieDiona
+ - !type:EntSelector
+ id: PlushieXeno
+ - !type:EntSelector
+ id: PlushieHampter
+ - !type:EntSelector
+ id: PlushieMoth
+ - !type:EntSelector
+ id: PlushieArachind
+ - !type:EntSelector
+ id: PlushiePenguin
+
- type: entity
id: CrateFunPlushie
parent: CrateGenericSteel
name: plushie crate
description: A buncha soft plushies. Throw them around and then wonder how you're gonna explain this purchase to NT.
components:
- - type: StorageFill
- contents:
- - id: PlushieBee
- - id: PlushieNar
- - id: PlushieCarp
- - id: PlushieNuke
- - id: PlushieSlime
- - id: PlushieSnake
- - id: PlushieLizard
- - id: PlushieSpaceLizard
- - id: PlushieVox
- - id: PlushieRouny
- - id: PlushieRatvar
- - id: PlushieSharkBlue
- orGroup: PlushieShark
- - id: PlushieSharkGrey
- orGroup: PlushieShark
- - id: PlushieAtmosian
- - id: PlushieDiona
- - id: PlushieXeno
- - id: PlushieHampter
- - id: PlushieMoth
- - id: PlushieArachind
- - id: PlushiePenguin
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:NestedSelector
+ tableId: AllPlushiesTable
+ rolls: !type:ConstantNumberSelector
+ value: 10
- type: entity
id: CrateFunLizardPlushieBulk
@@ -35,12 +83,18 @@
name: bulk lizard plushie crate
description: A buncha soft lizard plushies. Throw them around and then wonder how you're gonna explain this purchase to NT.
components:
- - type: StorageFill
- contents:
- - id: PlushieLizard
- amount: 3
- - id: PlushieSpaceLizard
- amount: 2
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: PlushieLizard
+ amount: !type:ConstantNumberSelector
+ value: 3
+ - !type:EntSelector
+ id: PlushieSpaceLizard
+ amount: !type:ConstantNumberSelector
+ value: 3
- type: entity
id: CrateFunInstrumentsVariety
diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml
index a5b06fca03..cf270a6310 100644
--- a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml
+++ b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml
@@ -3,338 +3,218 @@
suffix: Filled
parent: LockerSyndicatePersonal
components:
- - type: StorageFill
- contents:
- - id: ClothingBeltMilitaryWebbing
- - id: ClothingHandsGlovesCombat
- - id: JetpackBlackFilled
- - id: ClothingUniformJumpsuitOperative
- - id: ClothingUniformJumpskirtOperative
- - id: ClothingHeadsetAltSyndicate
- - id: ClothingEyesHudSyndicate
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: ClothingBeltMilitaryWebbing
+ - !type:EntSelector
+ id: ClothingHandsGlovesCombat
+ - !type:EntSelector
+ id: JetpackBlackFilled
+ - !type:EntSelector
+ id: ClothingUniformJumpsuitOperative
+ - !type:EntSelector
+ id: ClothingUniformJumpskirtOperative
+ - !type:EntSelector
+ id: ClothingHeadsetAltSyndicate
+ - !type:EntSelector
+ id: ClothingEyesHudSyndicate
+
+- type: entityTable
+ id: FillLockerEmergencyStandard
+ table: !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: ClothingMaskBreath
+ - !type:EntSelector
+ id: ClothingOuterSuitEmergency
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: EmergencyOxygenTankFilled
+ - !type:EntSelector
+ id: OxygenTankFilled
+ - !type:EntSelector
+ id: ToolboxEmergencyFilled
+ prob: 0.5
+ - !type:EntSelector
+ id: MedkitOxygenFilled
+ prob: 0.2
+ - !type:EntSelector
+ id: WeaponFlareGun
+ prob: 0.05
+ - !type:EntSelector
+ id: BoxMRE
+ prob: 0.1
- type: entity
id: ClosetEmergencyFilledRandom
parent: ClosetEmergency
suffix: Filled, Random
components:
- - type: StorageFill
- contents:
- - id: ClothingMaskBreath
- - id: ClothingOuterSuitEmergency
- - id: EmergencyOxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: OxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: ToolboxEmergencyFilled
- prob: 0.5
- - id: MedkitOxygenFilled
- prob: 0.2
- - id: WeaponFlareGun
- prob: 0.05
- - id: BoxMRE
- prob: 0.1
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:NestedSelector
+ tableId: FillLockerEmergencyStandard
- type: entity
id: ClosetWallEmergencyFilledRandom
parent: ClosetWallEmergency
suffix: Filled, Random
components:
- - type: StorageFill
- contents:
- - id: ClothingMaskBreath
- - id: ClothingOuterSuitEmergency
- - id: EmergencyOxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: OxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: ToolboxEmergencyFilled
- prob: 0.5
- - id: MedkitOxygenFilled
- prob: 0.2
- - id: WeaponFlareGun
- prob: 0.05
- - id: BoxMRE
- prob: 0.1
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:NestedSelector
+ tableId: FillLockerEmergencyStandard
- type: entity
id: ClosetEmergencyN2FilledRandom
parent: ClosetEmergencyN2
suffix: Filled, Random
components:
- - type: StorageFill
- contents:
- - id: ClothingMaskBreath
- - id: ClothingOuterSuitEmergency
- - id: EmergencyNitrogenTankFilled
- prob: 0.5
- orGroup: NitrogenTank
- - id: NitrogenTankFilled
- prob: 0.5
- orGroup: NitrogenTank
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: ClothingMaskBreath
+ - !type:EntSelector
+ id: ClothingOuterSuitEmergency
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: EmergencyNitrogenTankFilled
+ - !type:EntSelector
+ id: NitrogenTankFilled
+
+- type: entityTable
+ id: FillLockerFireStandard
+ table: !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: ClothingOuterSuitFire
+ - !type:EntSelector
+ id: ClothingHeadHelmetFire
+ - !type:EntSelector
+ id: ClothingMaskGas
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: EmergencyOxygenTankFilled
+ - !type:EntSelector
+ id: OxygenTankFilled
+ - !type:EntSelector
+ id: CrowbarRed
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: FireExtinguisher
+ weight: 98
+ - !type:EntSelector
+ id: SprayBottleWater #It's just budget cut after budget cut man
+ weight: 2
- type: entity
id: ClosetFireFilled
parent: ClosetFire
suffix: Filled
components:
- - type: StorageFill
- contents:
- - id: ClothingOuterSuitFire
- - id: ClothingHeadHelmetFire
- - id: ClothingMaskGas
- - id: EmergencyOxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: OxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: CrowbarRed
- - id: FireExtinguisher
- prob: 0.98
- orGroup: FireExtinguisher
- - id: SprayBottleWater #It's just budget cut after budget cut man
- prob: 0.02
- orGroup: FireExtinguisher
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:NestedSelector
+ tableId: FillLockerFireStandard
- type: entity
id: ClosetWallFireFilledRandom
parent: ClosetWallFire
suffix: Filled
components:
- - type: StorageFill
- contents:
- - id: ClothingOuterSuitFire
- - id: ClothingHeadHelmetFire
- - id: ClothingMaskGas
- - id: EmergencyOxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: OxygenTankFilled
- prob: 0.5
- orGroup: OxygenTank
- - id: CrowbarRed
- - id: FireExtinguisher
- prob: 0.98
- orGroup: FireExtinguisher
- - id: SprayBottleWater #It's just budget cut after budget cut man
- prob: 0.02
- orGroup: FireExtinguisher
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:NestedSelector
+ tableId: FillLockerFireStandard
+
+- type: entityTable
+ id: SyndieMaintLoot
+ table: !type:GroupSelector
+ children:
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: ClothingUniformJumpsuitOperative
+ - !type:EntSelector
+ id: ClothingUniformJumpskirtOperative
+ - !type:EntSelector
+ id: ClothingBackpackDuffelSyndicate
+ - !type:EntSelector
+ id: CyberPen
+ - !type:EntSelector
+ id: CigPackSyndicate
+ - !type:EntSelector
+ id: ClothingBackpackDuffelSyndicatePyjamaBundle
+ - !type:EntSelector
+ id: ClothingBeltMilitaryWebbing
+ - !type:EntSelector
+ id: ClothingShoesBootsCombatFilled
+ - !type:EntSelector
+ id: ToolboxSyndicateFilled
+ - !type:EntSelector
+ id: BalloonSyn
+ - !type:EntSelector
+ id: WeaponSniperMosin
+ weight: 2
+
+- type: entityTable
+ id: MaintenanceLockerLoot
+ table: !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: StrangePill
+ prob: 0.20
+ # Tools
+ - !type:NestedSelector
+ tableId: MaintToolsTable
+ rolls: !type:RangeNumberSelector
+ range: 1, 5
+ # Fluff
+ - !type:NestedSelector
+ tableId: MaintFluffTable
+ prob: 0.33
+ rolls: !type:RangeNumberSelector
+ range: 0, 2
+ # Plushies
+ - !type:NestedSelector
+ tableId: AllPlushiesTable
+ prob: 0.10
+ rolls: !type:RangeNumberSelector
+ range: 1, 2
+ # Weapons
+ - !type:NestedSelector
+ tableId: MaintWeaponTable
+ prob: 0.075
+ # Syndie Loot
+ - !type:NestedSelector
+ tableId: SyndieMaintLoot
+ prob: 0.05
- type: entity
id: ClosetMaintenanceFilledRandom
suffix: Filled, Random
parent: ClosetMaintenance
components:
- - type: StorageFill
- contents:
- - id: Lantern
- prob: 0.50
- - id: Wirecutter
- prob: 0.33
- - id: Screwdriver
- prob: 0.33
- - id: Wrench
- prob: 0.33
- - id: Crowbar
- prob: 0.50
- - id: Welder
- prob: 0.33
- - id: Multitool
- prob: 0.10
- - id: Soap
- prob: 0.44
- - id: null
- prob: 0.67
- orGroup: carp
- - id: PlushieCarp
- prob: 0.2
- orGroup: carp
- - id: PlushieHolocarp
- prob: 0.05
- orGroup: carp
- - id: PlushieMagicarp
- prob: 0.05
- orGroup: carp
- - id: PlushieRainbowCarp
- prob: 0.03
- orGroup: carp
- - id: PlushieSlime
- prob: 0.2
- - id: PlushieSnake
- prob: 0.2
- - id: ClothingShoesSkates
- prob: 0.1
- - id: ClothingHandsGlovesColorYellow
- prob: 0.05
- - id: ClothingHandsGlovesFingerlessInsulated
- prob: 0.07
- - id: ClothingBeltUtility
- prob: 0.10
- - id: ClothingHeadHatCone
- prob: 0.2
- - id: WeaponFlareGun
- prob: 0.1
- - id: ClothingHandsGlovesColorYellowBudget
- prob: 0.25
- - id: StrangePill
- prob: 0.20
- - id: DrinkMopwataBottleRandom
- prob: 0.20
- - id: ModularReceiver
- prob: 0.1
- - id: DrinkSpaceGlue
- prob: 0.20
- - id: DrinkSpaceLube
- prob: 0.20
- - id: BarberScissors
- prob: 0.05
- - id: Wristwatch
- prob: 0.05
- - id: BookRandomStory
- prob: 0.1
- # Syndicate loot
- - id: null
- prob: 0.95
- orGroup: syndiemaintloot
- - id: ClothingUniformJumpskirtOperative
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingUniformJumpsuitOperative
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingBackpackDuffelSyndicate
- prob: 0.005
- orGroup: syndiemaintloot
- - id: CyberPen
- prob: 0.005
- orGroup: syndiemaintloot
- - id: CigPackSyndicate
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingBackpackDuffelSyndicatePyjamaBundle
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingBeltMilitaryWebbing
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingShoesBootsCombatFilled
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ToolboxSyndicateFilled
- prob: 0.005
- orGroup: syndiemaintloot
- - id: BalloonSyn
- prob: 0.005
- orGroup: syndiemaintloot
- - id: WeaponSniperMosin
- prob: 0.0010
- orGroup: syndiemaintloot
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:NestedSelector
+ tableId: MaintenanceLockerLoot
- type: entity
id: ClosetWallMaintenanceFilledRandom
parent: ClosetWall
suffix: Filled, Random
components:
- - type: StorageFill
- contents:
- - id: Lantern
- prob: 0.50
- - id: Wirecutter
- prob: 0.33
- - id: Screwdriver
- prob: 0.33
- - id: Wrench
- prob: 0.33
- - id: Crowbar
- prob: 0.50
- - id: Welder
- prob: 0.33
- - id: Multitool
- prob: 0.10
- - id: Soap
- prob: 0.44
- - id: null
- prob: 0.67
- orGroup: carp
- - id: PlushieCarp
- prob: 0.2
- orGroup: carp
- - id: PlushieHolocarp
- prob: 0.05
- orGroup: carp
- - id: PlushieMagicarp
- prob: 0.05
- orGroup: carp
- - id: PlushieRainbowCarp
- prob: 0.03
- orGroup: carp
- - id: PlushieSlime
- prob: 0.2
- - id: PlushieSnake
- prob: 0.2
- - id: ClothingHandsGlovesColorYellow
- prob: 0.05
- - id: ClothingBeltQuiver
- prob: 0.02
- - id: ClothingBeltUtility
- prob: 0.10
- - id: ClothingHeadHatCone
- prob: 0.2
- - id: WeaponFlareGun
- prob: 0.1
- - id: ClothingHandsGlovesColorYellowBudget
- prob: 0.25
- - id: StrangePill
- prob: 0.20
- - id: DrinkSpaceGlue
- prob: 0.20
- - id: ModularReceiver
- prob: 0.1
- # Syndicate loot
- - id: null
- prob: 0.95
- orGroup: syndiemaintloot
- - id: ClothingUniformJumpskirtOperative
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingUniformJumpsuitOperative
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingBackpackDuffelSyndicate
- prob: 0.005
- orGroup: syndiemaintloot
- - id: CyberPen
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingHeadHatOutlawHat
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingEyesGlassesOutlawGlasses
- prob: 0.005
- orGroup: syndiemaintloot
- - id: CigPackSyndicate
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingBackpackDuffelSyndicatePyjamaBundle
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingBeltMilitaryWebbing
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ClothingShoesBootsCombatFilled
- prob: 0.005
- orGroup: syndiemaintloot
- - id: ToolboxSyndicateFilled
- prob: 0.005
- orGroup: syndiemaintloot
- - id: BalloonSyn
- prob: 0.005
- orGroup: syndiemaintloot
- - id: WeaponSniperMosin
- prob: 0.0010
- orGroup: syndiemaintloot
+ - type: EntityTableContainerFill
+ containers:
+ entity_storage: !type:NestedSelector
+ tableId: MaintenanceLockerLoot
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml
index 00798b36e0..193edb069e 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml
@@ -1,138 +1,478 @@
+- type: entityTable
+ id: MaintFluffTable
+ table: !type:GroupSelector
+ children:
+ # Common Group
+ - !type:GroupSelector
+ weight: 75
+ children:
+ # Smoker's specialty
+ - !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: Lighter
+ - !type:EntSelector
+ id: CigCartonBlue
+ # Gar glasses
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: ClothingEyesGlassesGar
+ - !type:EntSelector
+ id: ClothingEyesGlassesGarOrange
+ - !type:EntSelector
+ id: ClothingEyesGlassesGarGiga
+ - !type:EntSelector
+ id: Wristwatch
+ weight: 0.5
+ - !type:EntSelector
+ id: ClothingHeadHatCake
+ - !type:EntSelector
+ id: ClothingHeadHatSkub
+ - !type:EntSelector
+ id: ClothingHeadHatCone
+ - !type:EntSelector
+ id: ClothingNeckBling
+ - !type:EntSelector
+ id: ClothingHeadHelmetCosmonaut
+ - !type:EntSelector
+ id: ClothingHeadHelmetBasic
+ - !type:EntSelector
+ id: ClothingShoeSlippersDuck
+ - !type:EntSelector
+ id: ClothingUnderSocksBee
+ - !type:EntSelector
+ id: ClothingUnderSocksCoder
+ - !type:EntSelector
+ id: ClothingHeadHatSquid
+ # Animal Masks
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: ClothingMaskRat
+ - !type:EntSelector
+ id: ClothingMaskFox
+ - !type:EntSelector
+ id: ClothingMaskBee
+ - !type:EntSelector
+ id: ClothingMaskBear
+ - !type:EntSelector
+ id: ClothingMaskRaven
+ - !type:EntSelector
+ id: ClothingMaskJackal
+ - !type:EntSelector
+ id: ClothingMaskBat
+ - !type:EntSelector
+ id: ClothingBeltSuspenders
+ - !type:EntSelector
+ id: ClothingEyesEyepatch
+ - !type:EntSelector
+ id: ClothingEyesGlasses
+ - !type:EntSelector
+ id: ClothingHandsGlovesLatex
+ - !type:EntSelector
+ id: ClothingHandsGlovesFingerless
+ - !type:EntSelector
+ id: ClothingHandsGlovesColorBlack
+ - !type:EntSelector
+ id: ClothingHeadHatBeret
+ - !type:EntSelector
+ id: ClothingHeadHatBowlerHat
+ - !type:EntSelector
+ id: ClothingHeadHatFedoraBrown
+ weight: 0.5
+ - !type:EntSelector
+ id: ClothingHeadHatFedoraGrey
+ weight: 0.5
+ - !type:EntSelector
+ id: ClothingHeadHatFez
+ - !type:EntSelector
+ id: ClothingHeadHatPaper
+ - !type:EntSelector
+ id: ClothingHeadHatPirate
+ - !type:EntSelector
+ id: ClothingMaskSterile
+ - !type:EntSelector
+ id: ClothingNeckHeadphones
+ - !type:EntSelector
+ id: ClothingNeckTieRed
+ - !type:EntSelector
+ id: ClothingOuterCoatGentle
+ - !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: ClothingOuterCoatJensen
+ - !type:EntSelector
+ id: ClothingEyesGlassesJensen
+ - !type:EntSelector
+ id: ClothingOuterCoatLab
+ - !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: ClothingOuterCoatPirate
+ - !type:EntSelector
+ id: ClothingHeadHatPirateTricord
+ - !type:EntSelector
+ id: ClothingHeadHatTophat
+ - !type:EntSelector
+ id: ClothingOuterHoodieBlack
+ weight: 0.5
+ - !type:EntSelector
+ id: ClothingOuterHoodieGrey
+ weight: 0.5
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: ClothingOuterFlannelRed
+ - !type:EntSelector
+ id: ClothingOuterFlannelBlue
+ - !type:EntSelector
+ id: ClothingOuterFlannelGreen
+ - !type:EntSelector
+ id: ClothingOuterVestHazard
+ - !type:EntSelector
+ id: ClothingShoesBootsJack
+ - !type:EntSelector
+ id: ClothingShoesHighheelBoots
+ - !type:EntSelector
+ id: ClothingShoesBootsLaceup
+ - !type:EntSelector
+ id: ClothingShoesLeather
+ - !type:EntSelector
+ id: ClothingShoesBootsSalvage
+ - !type:EntSelector
+ id: ClothingShoesBootsWork
+ - !type:EntSelector
+ id: ClothingShoesTourist
+ - !type:EntSelector
+ id: ClothingUniformJumpsuitLoungewear
+ - !type:EntSelector
+ id: ClothingHeadHatCowboyRed
+ # Uncommon Group
+ - !type:GroupSelector
+ weight: 23
+ children:
+ - !type:EntSelector
+ id: ClothingNeckCloakHerald
+ - !type:EntSelector
+ id: ClothingHeadHelmetTemplar
+ # Cloaks
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: ClothingNeckCloakTrans
+ - !type:EntSelector
+ id: ClothingNeckCloakAdmin
+ - !type:EntSelector
+ id: ClothingNeckCloakMoth
+ - !type:EntSelector
+ id: ClothingNeckCloakVoid
+ - !type:EntSelector
+ id: ClothingNeckCloakGoliathCloak
+ - !type:EntSelector
+ id: ClothingNeckCloakAce
+ - !type:EntSelector
+ id: ClothingNeckCloakAro
+ - !type:EntSelector
+ id: ClothingNeckCloakBi
+ - !type:EntSelector
+ id: ClothingNeckCloakIntersex
+ - !type:EntSelector
+ id: ClothingNeckCloakLesbian
+ - !type:EntSelector
+ id: ClothingNeckCloakGay
+ - !type:EntSelector
+ id: ClothingNeckCloakEnby
+ - !type:EntSelector
+ id: ClothingNeckCloakPan
+ - !type:EntSelector
+ id: ToySkeleton
+ - !type:EntSelector
+ id: Basketball
+ - !type:EntSelector
+ id: Football
+ - !type:EntSelector
+ id: BalloonNT
+ - !type:EntSelector
+ id: BalloonCorgi
+ - !type:EntSelector
+ id: MysteryFigureBox
+ # Cult
+ - !type:AllSelector
+ children:
+ - !type:EntSelector
+ id: ClothingOuterRobesCult
+ - !type:EntSelector
+ id: ClothingShoesCult
+ - !type:EntSelector
+ id: ClothingHandsGlovesMercFingerless
+ - !type:EntSelector
+ id: ClothingHandsGlovesNitrile
+ - !type:EntSelector
+ id: ClothingHandsGlovesPowerglove
+ - !type:EntSelector
+ id: ClothingHeadHatAnimalHeadslime
+ - !type:EntSelector
+ id: ClothingHeadHatBeretMerc
+ - !type:EntSelector
+ id: ClothingHeadHatOutlawHat
+ - !type:EntSelector
+ id: ClothingHeadHatUshanka
+ - !type:EntSelector
+ id: ClothingHeadHatBunny
+ - !type:EntSelector
+ id: ClothingMaskNeckGaiter
+ - !type:EntSelector
+ id: ClothingNeckScarfStripedZebra
+ - !type:EntSelector
+ id: ClothingOuterGhostSheet
+ - !type:EntSelector
+ id: ClothingUniformJumpsuitAncient
+ - !type:EntSelector
+ id: ClothingUniformJumpsuitPirate
+ - !type:EntSelector
+ id: ClothingShoesBootsCowboyFancy
+ - !type:EntSelector
+ id: ClothingHeadHatCowboyBountyHunter
+ # Pins
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: ClothingNeckLGBTPin
+ - !type:EntSelector
+ id: ClothingNeckAromanticPin
+ - !type:EntSelector
+ id: ClothingNeckAsexualPin
+ - !type:EntSelector
+ id: ClothingNeckBisexualPin
+ - !type:EntSelector
+ id: ClothingNeckIntersexPin
+ - !type:EntSelector
+ id: ClothingNeckLesbianPin
+ - !type:EntSelector
+ id: ClothingNeckNonBinaryPin
+ - !type:EntSelector
+ id: ClothingNeckPansexualPin
+ - !type:EntSelector
+ id: ClothingNeckTransPin
+ - !type:EntSelector
+ id: ClothingNeckAutismPin
+ - !type:EntSelector
+ id: ClothingNeckGoldAutismPin
+ # Rare Group
+ - !type:GroupSelector
+ weight: 2
+ children:
+ - !type:EntSelector
+ id: Skub
+ - !type:EntSelector
+ id: PonderingOrb
+ - !type:EntSelector
+ id: CluwneHorn
+ - !type:EntSelector
+ id: ClothingShoesSkates
+ - !type:EntSelector
+ id: DrinkMugDog
+ - !type:EntSelector
+ id: CigarGold
+ - !type:EntSelector
+ id: ClothingUniformJumpsuitFamilyGuy
+ - !type:EntSelector
+ id: WristwatchGold
+
- type: entity
name: Maint Loot Spawner
suffix: Fluff+Clothes
id: MaintenanceFluffSpawner
parent: MarkerBase
components:
- - type: Sprite
- layers:
- - state: red
- - sprite: Clothing/Eyes/Glasses/gar.rsi
- state: icon-super
- - type: RandomSpawner
- rarePrototypes:
- - ClothingUniformJumpsuitFamilyGuy
- - CigarGold
- - ClothingNeckCloakHerald
- - ClothingHeadHelmetTemplar
- - ClothingNeckCloakTrans
- - ClothingNeckCloakAdmin
- - ClothingNeckCloakMoth
- - ClothingNeckCloakVoid
- - ClothingNeckCloakGoliathCloak
- - ClothingNeckCloakAce
- - ClothingNeckCloakAro
- - ClothingNeckCloakBi
- - ClothingNeckCloakIntersex
- - ClothingNeckCloakLesbian
- - ClothingNeckCloakGay
- - ClothingNeckCloakEnby
- - ClothingNeckCloakPan
- - ToySkeleton
- - Basketball
- - Football
- - BalloonCorgi
- - BalloonNT
- - PonderingOrb
- - Skub
- - DrinkMugDog
- - ClothingNeckLGBTPin
- - ClothingNeckAromanticPin
- - ClothingNeckAsexualPin
- - ClothingNeckBisexualPin
- - ClothingNeckIntersexPin
- - ClothingNeckLesbianPin
- - ClothingNeckNonBinaryPin
- - ClothingNeckPansexualPin
- - ClothingNeckTransPin
- - CluwneHorn
- - ClothingMaskRat
- - MysteryFigureBox
- - ClothingHandsGlovesMercFingerless
- - ClothingHandsGlovesNitrile
- - ClothingHandsGlovesPowerglove
- - ClothingHeadHatAnimalHeadslime
- - ClothingHeadHatBeretMerc
- - ClothingHeadHatOutlawHat
- - ClothingHeadHatUshanka
- - ClothingHeadHatBunny
- - ClothingMaskNeckGaiter
- - ClothingNeckScarfStripedZebra
- - ClothingOuterRobesCult
- - ClothingOuterGhostSheet
- - ClothingShoesCult
- - ClothingUniformJumpsuitAncient
- - ClothingUniformJumpsuitPirate
- - ClothingShoesBootsCowboyFancy
- - ClothingHeadHatCowboyBountyHunter
- - ClothingNeckAutismPin
- - ClothingNeckGoldAutismPin
- - WristwatchGold
- rareChance: 0.01
- prototypes:
- - Lighter
- - CigCartonBlue
- - ClothingEyesGlassesGarGiga
- - ClothingEyesGlassesGarOrange
- - ClothingEyesGlassesGar
- - ClothingHeadHatCake
- - ClothingHeadHatSkub
- - ClothingHeadHatCone
- - ClothingNeckBling
- - ClothingHeadHelmetCosmonaut
- - ClothingHeadHelmetBasic
- - ClothingShoeSlippersDuck
- - ClothingUnderSocksBee
- - ClothingUnderSocksCoder
- - ClothingHeadHatSquid
- - ClothingMaskFox
- - ClothingMaskBee
- - ClothingMaskBear
- - ClothingMaskRaven
- - ClothingMaskJackal
- - ClothingMaskBat
- - ClothingBeltSuspenders
- - ClothingEyesEyepatch
- - ClothingEyesGlasses
- - ClothingHandsGlovesLatex
- - ClothingHandsGlovesFingerless
- - ClothingHandsGlovesColorBlack
- - ClothingHeadHatBeret
- - ClothingHeadHatBowlerHat
- - ClothingHeadHatFedoraBrown
- - ClothingHeadHatFedoraGrey
- - ClothingHeadHatFez
- - ClothingHeadHatPaper
- - ClothingHeadHatPirate
- - ClothingHeadHatPirateTricord
- - ClothingHeadHatTophat
- - ClothingMaskSterile
- - ClothingNeckHeadphones
- - ClothingNeckTieRed
- - ClothingOuterCoatGentle
- - ClothingOuterCoatJensen
- - ClothingEyesGlassesJensen
- - ClothingOuterCoatLab
- - ClothingOuterCoatPirate
- - ClothingOuterHoodieBlack
- - ClothingOuterHoodieGrey
- - ClothingOuterFlannelRed
- - ClothingOuterFlannelBlue
- - ClothingOuterFlannelGreen
- - ClothingOuterVestHazard
- - ClothingShoesBootsJack
- - ClothingShoesHighheelBoots
- - ClothingShoesBootsLaceup
- - ClothingShoesLeather
- - ClothingShoesBootsSalvage
- - ClothingShoesBootsWork
- - ClothingShoesTourist
- - ClothingUniformJumpsuitLoungewear
- - ClothingHeadHatCowboyRed
- - Wristwatch
- chance: 0.6
- offset: 0.0
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Clothing/Eyes/Glasses/gar.rsi
+ state: icon-super
+ - type: EntityTableSpawner
+ table: !type:NestedSelector
+ tableId: MaintFluffTable
+ prob: 0.6
+- type: entityTable
+ id: MaintToolsTable
+ table: !type:GroupSelector
+ children:
+ # Common Group
+ - !type:GroupSelector
+ weight: 75
+ children:
+ - !type:EntSelector
+ id: FlashlightLantern
+ - !type:EntSelector
+ id: ToolboxEmergencyFilled
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: OxygenTankFilled
+ - !type:EntSelector
+ id: DoubleEmergencyOxygenTankFilled
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: NitrogenTankFilled
+ - !type:EntSelector
+ id: DoubleEmergencyNitrogenTankFilled
+ - !type:EntSelector
+ id: EmergencyFunnyOxygenTankFilled
+ weight: 0.5
+ - !type:GroupSelector
+ weight: 3
+ children:
+ - !type:EntSelector
+ id: SheetSteel10
+ - !type:EntSelector
+ id: SheetPlastic10
+ - !type:EntSelector
+ id: SheetGlass10
+ - !type:EntSelector
+ id: PartRodMetal10
+ - !type:EntSelector
+ id: MaterialCardboard10
+ weight: 0.25
+ - !type:EntSelector
+ id: MaterialCloth10
+ weight: 0.25
+ - !type:EntSelector
+ id: MaterialWoodPlank10
+ weight: 0.25
+ - !type:EntSelector
+ id: Plunger
+ - !type:EntSelector
+ id: PowerCellMedium
+ - !type:EntSelector
+ id: PowerCellSmall
+ - !type:EntSelector
+ id: Soap
+ - !type:EntSelector
+ id: Wirecutter
+ - !type:EntSelector
+ id: Screwdriver
+ - !type:EntSelector
+ id: Wrench
+ - !type:EntSelector
+ id: Crowbar
+ - !type:EntSelector
+ id: Multitool
+ - !type:EntSelector
+ id: Shovel
+ - !type:EntSelector
+ id: Welder
+ - !type:EntSelector
+ id: GasAnalyzer
+ - !type:EntSelector
+ id: SprayPainter
+ - !type:EntSelector
+ id: Flare
+ - !type:EntSelector
+ id: Beaker
+ - !type:EntSelector
+ id: ClothingMaskGas
+ - !type:EntSelector
+ id: ClothingMaskBreath
+ - !type:EntSelector
+ id: DoorElectronics
+ - !type:EntSelector
+ id: APCElectronics
+ - !type:EntSelector
+ id: InflatableWallStack5
+ - !type:EntSelector
+ id: CableHVStack10
+ - !type:EntSelector
+ id: CableMVStack10
+ - !type:EntSelector
+ id: CableApcStack10
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: ClothingHandsGlovesColorYellowBudget
+ weight: 5
+ - !type:EntSelector
+ id: ClothingHandsGlovesFingerlessInsulated
+ weight: 0.5
+ - !type:EntSelector
+ id: ClothingHandsGlovesColorYellow
+ weight: 1
+ # Uncommon Group
+ - !type:GroupSelector
+ weight: 23
+ children:
+ - !type:EntSelector
+ id: ClothingHeadHatCone
+ weight: 2
+ - !type:EntSelector
+ id: BookRandomStory
+ weight: 0.25
+ - !type:EntSelector
+ id: ToolboxElectricalFilled
+ - !type:EntSelector
+ id: ToolboxMechanicalFilled
+ - !type:EntSelector
+ id: ClothingBeltUtility
+ - !type:EntSelector
+ id: ToolboxArtisticFilled
+ - !type:EntSelector
+ id: GeigerCounter
+ - !type:EntSelector
+ id: trayScanner
+ - !type:EntSelector
+ id: HandheldGPSBasic
+ - !type:EntSelector
+ id: HandLabeler
+ - !type:EntSelector
+ id: GlowstickBase
+ - !type:EntSelector
+ id: Bucket
+ - !type:EntSelector
+ id: RadioHandheld
+ - !type:EntSelector
+ id: AppraisalTool
+ - !type:EntSelector
+ id: ModularReceiver
+ - !type:EntSelector
+ id: WeaponFlareGun
+ - !type:EntSelector
+ id: BarberScissors
+ - !type:GroupSelector
+ children:
+ - !type:EntSelector
+ id: DrinkSpaceGlue
+ - !type:EntSelector
+ id: DrinkSpaceLube
+ # Rare Group
+ - !type:GroupSelector
+ weight: 2
+ children:
+ - !type:EntSelector
+ id: LanternFlash
+ - !type:EntSelector
+ id: PowerCellHigh
+ - !type:EntSelector
+ id: NetProbeCartridge
+ - !type:EntSelector
+ id: WelderIndustrial
+ - !type:EntSelector
+ id: SheetPlasteel10
+ - !type:EntSelector
+ id: ClothingMaskGasExplorer
+ - !type:EntSelector
+ id: TechnologyDisk
+ - !type:EntSelector
+ id: ResearchDisk5000
+ - !type:EntSelector
+ id: PetCarrier
+ - !type:EntSelector
+ id: DrinkMopwataBottleRandom
+ - !type:EntSelector
+ id: LidSalami
+ weight: 0.05
- type: entity
name: Maint Loot Spawner
@@ -140,75 +480,80 @@
id: MaintenanceToolSpawner
parent: MarkerBase
components:
- - type: Sprite
- layers:
- - state: red
- - sprite: Objects/Power/power_cells.rsi
- state: high
- - type: RandomSpawner
- rarePrototypes:
- - LanternFlash
- - PowerCellHigh
- - NetProbeCartridge
- - WelderIndustrial
- - SheetPlasteel10
- - ClothingMaskGasExplorer
- rareChance: 0.08
- prototypes:
- - FlashlightLantern
- - OxygenTankFilled
- - DoubleEmergencyOxygenTankFilled
- - ToolboxEmergencyFilled
- - ToolboxArtisticFilled
- - NitrogenTankFilled
- - DoubleEmergencyNitrogenTankFilled
- - EmergencyFunnyOxygenTankFilled
- - ToolboxElectricalFilled
- - ToolboxMechanicalFilled
- - ClothingBeltUtility
- - Shovel
- - Welder
- - WeaponFlareGun
- - SheetSteel10
- - SheetPlastic10
- - SheetGlass10
- - PartRodMetal10
- - MaterialCardboard10
- - MaterialCloth10
- - MaterialWoodPlank10
- - ResearchDisk
- - Plunger
- - TechnologyDisk
- - PowerCellMedium
- - PowerCellSmall
- - Wirecutter
- - Screwdriver
- - Wrench
- - Crowbar
- - NetworkConfigurator
- - trayScanner
- - GasAnalyzer
- - SprayPainter
- - AppraisalTool
- - Flare
- - HandheldGPSBasic
- - HandLabeler
- - GlowstickBase
- - Bucket
- - RadioHandheld
- - GeigerCounter
- - Beaker
- - ClothingMaskGas
- - ClothingMaskBreath
- - DoorElectronics
- - APCElectronics
- - InflatableWallStack5
- - CableHVStack10
- - CableMVStack10
- - CableApcStack10
- - PetCarrier
- chance: 0.6
- offset: 0.0
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Power/power_cells.rsi
+ state: high
+ - type: EntityTableSpawner
+ table: !type:NestedSelector
+ tableId: MaintToolsTable
+ prob: 0.6
+
+- type: entityTable
+ id: MaintWeaponTable
+ table: !type:GroupSelector
+ children:
+ # Common Group
+ - !type:GroupSelector
+ weight: 95
+ children:
+ - !type:EntSelector
+ id: Machete
+ - !type:EntSelector
+ id: BaseBallBat
+ - !type:EntSelector
+ id: CombatKnife
+ - !type:EntSelector
+ id: Spear
+ - !type:EntSelector
+ id: RifleStock
+ - !type:EntSelector
+ id: ModularReceiver
+ - !type:EntSelector
+ id: HydroponicsToolScythe
+ # Rare Group
+ - !type:GroupSelector
+ weight: 5
+ children:
+ - !type:EntSelector
+ id: Lighter
+ - !type:EntSelector
+ id: Matchbox
+ - !type:EntSelector
+ id: ClothingEyesBlindfold
+ - !type:EntSelector
+ id: ClothingMaskMuzzle
+ - !type:EntSelector
+ id: ClothingMaskGasSecurity
+ - !type:EntSelector
+ id: ShardGlass
+ weight: 2
+ - !type:EntSelector
+ id: Syringe
+ - !type:EntSelector
+ id: Mousetrap
+ - !type:GroupSelector
+ weight: 2
+ children:
+ - !type:EntSelector
+ id: Brutepack1
+ - !type:EntSelector
+ id: Ointment1
+ - !type:EntSelector
+ id: Gauze1
+ - !type:EntSelector
+ id: Bola
+ - !type:EntSelector
+ id: SurvivalKnife
+ - !type:EntSelector
+ id: ScalpelShiv
+ - !type:EntSelector
+ id: Shiv
+ - !type:EntSelector
+ id: SawImprov
+ - !type:EntSelector
+ id: HydroponicsToolMiniHoe
- type: entity
name: Maint Loot Spawner
@@ -216,51 +561,15 @@
id: MaintenanceWeaponSpawner
parent: MarkerBase
components:
- - type: Sprite
- layers:
- - state: red
- - sprite: Objects/Weapons/Melee/machete.rsi
- state: icon
- - type: RandomSpawner
- rarePrototypes:
- - Machete
- - BaseBallBat
- - CombatKnife
- - Spear
- - RifleStock
- - ModularReceiver
- - HydroponicsToolScythe
- rareChance: 0.05
- prototypes:
- - FlashlightLantern
- - OxygenTankFilled
- - DoubleEmergencyOxygenTankFilled
- - NitrogenTankFilled
- - DoubleEmergencyNitrogenTankFilled
- - Lighter
- - Matchbox
- - Crowbar
- - Shovel
- - Welder
- - WeaponFlareGun
- - LidSalami
- - ClothingEyesBlindfold
- - ClothingMaskMuzzle
- - ClothingMaskGasSecurity
- - ShardGlass
- - Syringe
- - Mousetrap
- - Brutepack1
- - Ointment1
- - Gauze1
- - Bola
- - SurvivalKnife
- - ScalpelShiv
- - Shiv
- - SawImprov
- - HydroponicsToolMiniHoe
- chance: 0.6
- offset: 0.0
+ - type: Sprite
+ layers:
+ - state: red
+ - sprite: Objects/Weapons/Melee/machete.rsi
+ state: icon
+ - type: EntityTableSpawner
+ table: !type:NestedSelector
+ tableId: MaintWeaponTable
+ prob: 0.6
- type: entity
name: Maint Loot Spawner