Emergent Sanitation Gameplay (#1378)

* Emergent Sanitation Gameplay

* Fix the map

* Address review

* Mention if it's slippery in the description
This commit is contained in:
ike709
2020-07-11 16:49:54 -05:00
committed by GitHub
parent 531d9626ad
commit 203a835264
20 changed files with 1011 additions and 45 deletions

View File

@@ -132,6 +132,9 @@
"EmitSoundOnThrow", "EmitSoundOnThrow",
"Flash", "Flash",
"DamageOnToolInteract", "DamageOnToolInteract",
"CustodialClosetFill",
"NoSlip",
"TrashSpawner",
}; };
} }
} }

View File

@@ -65,17 +65,16 @@ namespace Content.Server.GameObjects.Components.Fluids
{ {
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return; if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
Solution solution; if (CurrentVolume <= 0)
{
return;
}
//Solution solution;
if (eventArgs.Target == null) if (eventArgs.Target == null)
{ {
if (CurrentVolume <= 0) // Drop the liquid on the mop on to the ground
{ SpillHelper.SpillAt(eventArgs.ClickLocation, _contents.SplitSolution(CurrentVolume), "PuddleSmear");
return;
}
// Drop the liquid on the mop on to the ground I guess? Potentially change by design
// Maybe even use a toggle mode instead of "Pickup" and "dropoff"
solution = _contents.SplitSolution(CurrentVolume);
SpillHelper.SpillAt(eventArgs.ClickLocation, solution, "PuddleSmear");
return; return;
} }
@@ -88,18 +87,34 @@ namespace Content.Server.GameObjects.Components.Fluids
// - _pickupAmount, // - _pickupAmount,
// - whatever's left in the puddle, or // - whatever's left in the puddle, or
// - whatever we can still hold (whichever's smallest) // - whatever we can still hold (whichever's smallest)
var transferAmount = ReagentUnit.Min(ReagentUnit.New(5), puddleComponent.CurrentVolume, MaxVolume - CurrentVolume); var transferAmount = ReagentUnit.Min(ReagentUnit.New(5), puddleComponent.CurrentVolume, CurrentVolume);
bool puddleCleaned = puddleComponent.CurrentVolume - transferAmount <= 0;
if (transferAmount == 0) if (transferAmount == 0)
{ {
return; if(puddleComponent.EmptyHolder) //The puddle doesn't actually *have* reagents, for example vomit because there's no "vomit" reagent.
{
puddleComponent.Owner.Delete();
transferAmount = ReagentUnit.Min(ReagentUnit.New(5), CurrentVolume);
puddleCleaned = true;
}
else
{
return;
}
}
else
{
puddleComponent.SplitSolution(transferAmount);
} }
solution = puddleComponent.SplitSolution(transferAmount); if (puddleCleaned) //After cleaning the puddle, make a new puddle with solution from the mop as a "wet floor". Then evaporate it slowly.
// Probably don't recolor a mop? Could work, if we layered it maybe
if (!_contents.TryAddSolution(solution, false, true))
{ {
// I can't imagine why this would happen SpillHelper.SpillAt(eventArgs.ClickLocation, _contents.SplitSolution(transferAmount), "PuddleSmear");
throw new InvalidOperationException(); }
else
{
_contents.SplitSolution(transferAmount);
} }
// Give some visual feedback shit's happening (for anyone who can't hear sound) // Give some visual feedback shit's happening (for anyone who can't hear sound)

View File

@@ -2,7 +2,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using Content.Server.GameObjects.Components.Movement;
using Content.Server.GameObjects.Components.Chemistry; using Content.Server.GameObjects.Components.Chemistry;
using Content.Server.GameObjects.EntitySystems.Click;
using Content.Shared.Chemistry; using Content.Shared.Chemistry;
using Content.Shared.Physics; using Content.Shared.Physics;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
@@ -15,6 +17,7 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Random; using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -27,7 +30,7 @@ namespace Content.Server.GameObjects.Components.Fluids
/// Puddle on a floor /// Puddle on a floor
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent]
public class PuddleComponent : Component public class PuddleComponent : Component, IExamine
{ {
// Current design: Something calls the SpillHelper.Spill, that will either // Current design: Something calls the SpillHelper.Spill, that will either
// A) Add to an existing puddle at the location (normalised to tile-center) or // A) Add to an existing puddle at the location (normalised to tile-center) or
@@ -44,12 +47,25 @@ namespace Content.Server.GameObjects.Components.Fluids
#pragma warning disable 649 #pragma warning disable 649
[Dependency] private readonly IMapManager _mapManager; [Dependency] private readonly IMapManager _mapManager;
[Dependency] private readonly ILocalizationManager _loc;
#pragma warning restore 649 #pragma warning restore 649
public override string Name => "Puddle"; public override string Name => "Puddle";
private CancellationTokenSource _evaporationToken; private CancellationTokenSource _evaporationToken;
private ReagentUnit _evaporateThreshold; // How few <Solution Quantity> we can hold prior to self-destructing private ReagentUnit _evaporateThreshold; // How few <Solution Quantity> we can hold prior to self-destructing
public ReagentUnit EvaporateThreshold
{
get => _evaporateThreshold;
set => _evaporateThreshold = value;
}
private ReagentUnit _slipThreshold = ReagentUnit.New(3);
public ReagentUnit SlipThreshold
{
get => _slipThreshold;
set => _slipThreshold = value;
}
private bool _slippery = false;
private float _evaporateTime; private float _evaporateTime;
private string _spillSound; private string _spillSound;
@@ -78,6 +94,7 @@ namespace Content.Server.GameObjects.Components.Fluids
private ReagentUnit OverflowLeft => CurrentVolume - OverflowVolume; private ReagentUnit OverflowLeft => CurrentVolume - OverflowVolume;
private SolutionComponent _contents; private SolutionComponent _contents;
public bool EmptyHolder => _contents.ReagentList.Count == 0;
private int _spriteVariants; private int _spriteVariants;
// Whether the underlying solution color should be used // Whether the underlying solution color should be used
private bool _recolor; private bool _recolor;
@@ -87,11 +104,12 @@ namespace Content.Server.GameObjects.Components.Fluids
{ {
serializer.DataFieldCached(ref _spillSound, "spill_sound", "/Audio/Effects/Fluids/splat.ogg"); serializer.DataFieldCached(ref _spillSound, "spill_sound", "/Audio/Effects/Fluids/splat.ogg");
serializer.DataField(ref _overflowVolume, "overflow_volume", ReagentUnit.New(20)); serializer.DataField(ref _overflowVolume, "overflow_volume", ReagentUnit.New(20));
serializer.DataField(ref _evaporateTime, "evaporate_time", 600.0f); serializer.DataField(ref _evaporateTime, "evaporate_time", 5.0f);
// Long-term probably have this based on the underlying reagents // Long-term probably have this based on the underlying reagents
serializer.DataField(ref _evaporateThreshold, "evaporate_threshold", ReagentUnit.New(2)); serializer.DataField(ref _evaporateThreshold, "evaporate_threshold", ReagentUnit.New(20));
serializer.DataField(ref _spriteVariants, "variants", 1); serializer.DataField(ref _spriteVariants, "variants", 1);
serializer.DataField(ref _recolor, "recolor", false); serializer.DataField(ref _recolor, "recolor", false);
} }
public override void Initialize() public override void Initialize()
@@ -121,6 +139,16 @@ namespace Content.Server.GameObjects.Components.Fluids
_spriteComponent.LayerSetState(0, $"{baseName}-{randomVariant}"); // TODO: Remove hardcode _spriteComponent.LayerSetState(0, $"{baseName}-{randomVariant}"); // TODO: Remove hardcode
_spriteComponent.Rotation = Angle.FromDegrees(robustRandom.Next(0, 359)); _spriteComponent.Rotation = Angle.FromDegrees(robustRandom.Next(0, 359));
// UpdateAppearance should get called soon after this so shouldn't need to call Dirty() here // UpdateAppearance should get called soon after this so shouldn't need to call Dirty() here
UpdateStatus();
}
void IExamine.Examine(FormattedMessage message, bool inDetailsRange)
{
if(_slippery)
{
message.AddText(_loc.GetString("It looks slippery."));
}
} }
// Flow rate should probably be controlled globally so this is it for now // Flow rate should probably be controlled globally so this is it for now
@@ -174,12 +202,28 @@ namespace Content.Server.GameObjects.Components.Fluids
} }
} }
private void UpdateStatus() public void Evaporate()
{ {
// If UpdateStatus is getting called again it means more fluid has been updated so let's just wait _contents.SplitSolution(ReagentUnit.Min(ReagentUnit.New(1), _contents.CurrentVolume));
_evaporationToken?.Cancel(); if (CurrentVolume == 0)
{
Owner.Delete();
}
else
{
UpdateStatus();
}
}
if (CurrentVolume > _evaporateThreshold) public void UpdateStatus()
{
_evaporationToken?.Cancel();
if(Owner.Deleted) return;
UpdateAppearance();
UpdateSlip();
if (_evaporateThreshold == ReagentUnit.New(-1) || CurrentVolume > _evaporateThreshold)
{ {
return; return;
} }
@@ -187,12 +231,26 @@ namespace Content.Server.GameObjects.Components.Fluids
_evaporationToken = new CancellationTokenSource(); _evaporationToken = new CancellationTokenSource();
// KYS to evaporate // KYS to evaporate
Timer.Spawn(TimeSpan.FromSeconds(_evaporateTime), CheckEvaporate, _evaporationToken.Token); Timer.Spawn(TimeSpan.FromSeconds(_evaporateTime), Evaporate, _evaporationToken.Token);
}
private void UpdateSlip()
{
if ((_slipThreshold == ReagentUnit.New(-1) || CurrentVolume < _slipThreshold) && Owner.TryGetComponent(out SlipperyComponent existingSlipperyComponent))
{
Owner.RemoveComponent<SlipperyComponent>();
_slippery = false;
}
else if (CurrentVolume >= _slipThreshold && !Owner.TryGetComponent(out SlipperyComponent newSlipperyComponent))
{
Owner.AddComponent<SlipperyComponent>();
_slippery = true;
}
} }
private void UpdateAppearance() private void UpdateAppearance()
{ {
if (Owner.Deleted) if (Owner.Deleted || EmptyHolder)
{ {
return; return;
} }

View File

@@ -1,3 +1,4 @@
#nullable enable
using Content.Shared.Chemistry; using Content.Shared.Chemistry;
using Robust.Server.Interfaces.GameObjects; using Robust.Server.Interfaces.GameObjects;
@@ -31,11 +32,11 @@ namespace Content.Server.GameObjects.Components.Fluids
/// <param name="gridCoordinates"></param> /// <param name="gridCoordinates"></param>
/// <param name="solution">Initial solution for the prototype</param> /// <param name="solution">Initial solution for the prototype</param>
/// <param name="prototype">Prototype to use</param> /// <param name="prototype">Prototype to use</param>
internal static void SpillAt(GridCoordinates gridCoordinates, Solution solution, string prototype) internal static PuddleComponent? SpillAt(GridCoordinates gridCoordinates, Solution solution, string prototype)
{ {
if (solution.TotalVolume == 0) if (solution.TotalVolume == 0)
{ {
return; return null;
} }
var mapManager = IoCManager.Resolve<IMapManager>(); var mapManager = IoCManager.Resolve<IMapManager>();
@@ -48,7 +49,7 @@ namespace Content.Server.GameObjects.Components.Fluids
var tileRef = mapGrid.GetTileRef(gridCoordinates); var tileRef = mapGrid.GetTileRef(gridCoordinates);
if (tileRef.Tile.IsEmpty) if (tileRef.Tile.IsEmpty)
{ {
return; return null;
} }
// Get normalized co-ordinate for spill location and spill it in the centre // Get normalized co-ordinate for spill location and spill it in the centre
@@ -78,11 +79,13 @@ namespace Content.Server.GameObjects.Components.Fluids
// Did we add to an existing puddle // Did we add to an existing puddle
if (spilt) if (spilt)
{ {
return; return null;
} }
var puddle = serverEntityManager.SpawnEntity(prototype, spillGridCoords); var puddle = serverEntityManager.SpawnEntity(prototype, spillGridCoords);
puddle.GetComponent<PuddleComponent>().TryAddSolution(solution); var newPuddleComponent = puddle.GetComponent<PuddleComponent>();
newPuddleComponent.TryAddSolution(solution);
return newPuddleComponent;
} }
} }

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.Server.GameObjects.Components; using Content.Server.GameObjects.Components;
using Content.Shared.GameObjects.Components.Inventory;
using Content.Server.GameObjects.EntitySystems.Click; using Content.Server.GameObjects.EntitySystems.Click;
using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Server.Interfaces; using Content.Server.Interfaces;
@@ -23,7 +24,7 @@ using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventory
namespace Content.Server.GameObjects namespace Content.Server.GameObjects
{ {
[RegisterComponent] [RegisterComponent]
public class InventoryComponent : SharedInventoryComponent, IExAct public class InventoryComponent : SharedInventoryComponent, IExAct, IEffectBlocker
{ {
#pragma warning disable 649 #pragma warning disable 649
[Dependency] private readonly IEntitySystemManager _entitySystemManager; [Dependency] private readonly IEntitySystemManager _entitySystemManager;
@@ -46,6 +47,18 @@ namespace Content.Server.GameObjects
} }
} }
bool IEffectBlocker.CanSlip()
{
if(Owner.TryGetComponent(out InventoryComponent inventoryComponent) &&
inventoryComponent.TryGetSlotItem(EquipmentSlotDefines.Slots.SHOES, out ItemComponent shoes)
)
{
return EffectBlockerSystem.CanSlip(shoes.Owner);
}
return true;
}
public override void OnRemove() public override void OnRemove()
{ {
var slots = SlotContainers.Keys.ToList(); var slots = SlotContainers.Keys.ToList();

View File

@@ -0,0 +1,33 @@
using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Random;
namespace Content.Server.GameObjects.Components.Items.Storage.Fill
{
[RegisterComponent]
internal sealed class CustodialClosetFillComponent : Component, IMapInit
{
public override string Name => "CustodialClosetFill";
void IMapInit.MapInit()
{
var storage = Owner.GetComponent<IStorageComponent>();
var random = IoCManager.Resolve<IRobustRandom>();
void Spawn(string prototype)
{
storage.Insert(Owner.EntityManager.SpawnEntity(prototype, Owner.Transform.GridPosition));
}
Spawn("MopItem");
Spawn("MopBucket");
Spawn("WetFloorSign");
Spawn("WetFloorSign");
Spawn("WetFloorSign");
Spawn("TrashBag");
Spawn("TrashBag");
}
}
}

View File

@@ -77,7 +77,7 @@ namespace Content.Server.GameObjects.Components.Markers
} }
} }
private void Spawn() public virtual void Spawn()
{ {
if (Chance != 1.0f && !_robustRandom.Prob(Chance)) if (Chance != 1.0f && !_robustRandom.Prob(Chance))
return; return;
@@ -92,7 +92,7 @@ namespace Content.Server.GameObjects.Components.Markers
_entityManager.SpawnEntity(_robustRandom.Pick(Prototypes), Owner.Transform.GridPosition); _entityManager.SpawnEntity(_robustRandom.Pick(Prototypes), Owner.Transform.GridPosition);
} }
public void MapInit() public virtual void MapInit()
{ {
_gameTicker.OnRuleAdded += RuleAdded; _gameTicker.OnRuleAdded += RuleAdded;

View File

@@ -0,0 +1,86 @@
using System;
using Content.Server.GameObjects.Components.Markers;
using System.Collections.Generic;
using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking;
using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.Maths;
using Robust.Shared.IoC;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using Logger = Robust.Shared.Log.Logger;
namespace Content.Server.GameObjects.Components.Markers
{
[RegisterComponent]
public class TrashSpawnerComponent : ConditionalSpawnerComponent
{
public override string Name => "TrashSpawner";
#pragma warning disable 649
[Dependency] private IEntityManager _entityManager;
[Dependency] private IRobustRandom _robustRandom;
#pragma warning restore 649
[ViewVariables(VVAccess.ReadWrite)]
public List<string> RarePrototypes { get; set; } = new List<string>();
[ViewVariables(VVAccess.ReadWrite)]
private List<string> _gameRules = new List<string>();
[ViewVariables(VVAccess.ReadWrite)]
public float RareChance { get; set; } = 0.05f;
[ViewVariables(VVAccess.ReadWrite)]
public float Offset { get; set; } = 0.2f;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(this, x => RarePrototypes, "rarePrototypes", new List<string>());
serializer.DataField(this, x => RareChance, "rareChance", 0.05f);
serializer.DataField(this, x => Offset, "offset", 0.2f);
}
public override void Spawn()
{
if (RarePrototypes.Count > 0 && (RareChance == 1.0f || _robustRandom.Prob(RareChance)))
{
_entityManager.SpawnEntity(_robustRandom.Pick(RarePrototypes), Owner.Transform.GridPosition);
return;
}
if (Chance != 1.0f && !_robustRandom.Prob(Chance))
{
return;
}
if (Prototypes.Count == 0)
{
Logger.Warning($"Prototype list in TrashSpawnComponent is empty! Entity: {Owner}");
return;
}
if(!Owner.Deleted)
{
var random = IoCManager.Resolve<IRobustRandom>();
var x_negative = random.Prob(0.5f) ? -1 : 1;
var y_negative = random.Prob(0.5f) ? -1 : 1;
var entity = _entityManager.SpawnEntity(_robustRandom.Pick(Prototypes), Owner.Transform.GridPosition);
entity.Transform.LocalPosition += new Vector2(random.NextFloat() * Offset * x_negative, random.NextFloat() * Offset * y_negative);
}
}
public override void MapInit()
{
Spawn();
Owner.Delete();
}
}
}

View File

@@ -0,0 +1,13 @@
using Robust.Shared.GameObjects;
using Content.Shared.GameObjects.EntitySystems;
namespace Content.Server.GameObjects.Components.Movement
{
[RegisterComponent]
public class NoSlipComponent : Component, IEffectBlocker
{
public override string Name => "NoSlip";
bool IEffectBlocker.CanSlip() => false;
}
}

View File

@@ -3,6 +3,7 @@ using System.Timers;
using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Mobs;
using Content.Server.Throw; using Content.Server.Throw;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.Physics; using Content.Shared.Physics;
using Robust.Server.GameObjects.EntitySystems; using Robust.Server.GameObjects.EntitySystems;
using Robust.Shared.Containers; using Robust.Shared.Containers;
@@ -90,6 +91,9 @@ namespace Content.Server.GameObjects.Components.Movement
if (percentage < IntersectPercentage) if (percentage < IntersectPercentage)
return; return;
if(!EffectBlockerSystem.CanSlip(collidedWith))
return;
stun.Paralyze(5f); stun.Paralyze(5f);
_slipped.Add(collidedWith.Uid); _slipped.Add(collidedWith.Uid);

View File

@@ -10,6 +10,7 @@ namespace Content.Shared.GameObjects.EntitySystems
public interface IEffectBlocker public interface IEffectBlocker
{ {
bool CanFall() => true; bool CanFall() => true;
bool CanSlip() => true;
} }
/// <summary> /// <summary>
@@ -28,5 +29,16 @@ namespace Content.Shared.GameObjects.EntitySystems
return canFall; return canFall;
} }
public static bool CanSlip(IEntity entity)
{
var canSlip = true;
foreach (var blocker in entity.GetAllComponents<IEffectBlocker>())
{
canSlip &= blocker.CanSlip(); // Sets var to false if false
}
return canSlip;
}
} }
} }

View File

@@ -27621,7 +27621,7 @@ entities:
WireSeed: 772636827 WireSeed: 772636827
type: Wires type: Wires
- uid: 2915 - uid: 2915
type: AirlockServiceLocked type: Airlock
components: components:
- name: Custodial Closet - name: Custodial Closet
type: MetaData type: MetaData
@@ -27632,6 +27632,9 @@ entities:
- SerialNumber: BJWI-6517 - SerialNumber: BJWI-6517
WireSeed: 1001186873 WireSeed: 1001186873
type: Wires type: Wires
- access:
- - Janitor
type: AccessReader
- uid: 2916 - uid: 2916
type: AirlockMaintCommonLocked type: AirlockMaintCommonLocked
components: components:
@@ -29503,4 +29506,669 @@ entities:
components: components:
- parent: 3112 - parent: 3112
type: Transform type: Transform
- uid: 3114
type: TrashSpawner
components:
- parent: 0
pos: -21.5,10.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3115
type: TrashSpawner
components:
- parent: 0
pos: -31.5,7.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3116
type: TrashSpawner
components:
- parent: 0
pos: -32.5,11.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3117
type: TrashSpawner
components:
- parent: 0
pos: -30.5,14.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3118
type: TrashSpawner
components:
- parent: 0
pos: -25.5,13.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3119
type: TrashSpawner
components:
- parent: 0
pos: -23.5,14.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3120
type: TrashSpawner
components:
- parent: 0
pos: -21.5,12.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3121
type: TrashSpawner
components:
- parent: 0
pos: -17.5,13.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3122
type: TrashSpawner
components:
- parent: 0
pos: -15.5,9.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3123
type: TrashSpawner
components:
- parent: 0
pos: -18.5,19.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3124
type: TrashSpawner
components:
- parent: 0
pos: -18.5,25.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3125
type: TrashSpawner
components:
- parent: 0
pos: -15.5,24.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3126
type: TrashSpawner
components:
- parent: 0
pos: -8.5,25.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3127
type: TrashSpawner
components:
- parent: 0
pos: -7.5,23.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3128
type: TrashSpawner
components:
- parent: 0
pos: -4.5,22.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3129
type: TrashSpawner
components:
- parent: 0
pos: -2.5,20.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3130
type: TrashSpawner
components:
- parent: 0
pos: -3.5,7.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3131
type: TrashSpawner
components:
- parent: 0
pos: 0.5,8.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3132
type: TrashSpawner
components:
- parent: 0
pos: -36.5,10.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3133
type: TrashSpawner
components:
- parent: 0
pos: -35.5,-2.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3134
type: TrashSpawner
components:
- parent: 0
pos: -32.5,5.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3135
type: TrashSpawner
components:
- parent: 0
pos: -22.5,6.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3136
type: TrashSpawner
components:
- parent: 0
pos: -30.5,1.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3137
type: TrashSpawner
components:
- parent: 0
pos: -30.5,-8.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3138
type: TrashSpawner
components:
- parent: 0
pos: -19.5,-5.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3139
type: TrashSpawner
components:
- parent: 0
pos: -32.5,-0.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3140
type: TrashSpawner
components:
- parent: 0
pos: -33.5,-7.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3141
type: TrashSpawner
components:
- parent: 0
pos: -33.5,-11.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3142
type: TrashSpawner
components:
- parent: 0
pos: -32.5,-5.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3143
type: TrashSpawner
components:
- parent: 0
pos: -28.5,-11.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3144
type: TrashSpawner
components:
- parent: 0
pos: -21.5,-10.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3145
type: TrashSpawner
components:
- parent: 0
pos: -21.5,-12.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3146
type: TrashSpawner
components:
- parent: 0
pos: -18.5,-13.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3147
type: TrashSpawner
components:
- parent: 0
pos: -12.5,-15.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3148
type: TrashSpawner
components:
- parent: 0
pos: -8.5,-15.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3149
type: TrashSpawner
components:
- parent: 0
pos: -9.5,-12.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3150
type: TrashSpawner
components:
- parent: 0
pos: -8.5,-11.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3151
type: TrashSpawner
components:
- parent: 0
pos: -11.5,-6.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3152
type: TrashSpawner
components:
- parent: 0
pos: -16.5,-5.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3153
type: TrashSpawner
components:
- parent: 0
pos: -6.5,-9.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3154
type: TrashSpawner
components:
- parent: 0
pos: -2.5,-10.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3155
type: TrashSpawner
components:
- parent: 0
pos: -0.5,-9.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3156
type: TrashSpawner
components:
- parent: 0
pos: -0.5,-8.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3157
type: TrashSpawner
components:
- parent: 0
pos: 0.5,-6.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3158
type: TrashSpawner
components:
- parent: 0
pos: -11.5,-23.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3159
type: TrashSpawner
components:
- parent: 0
pos: -11.5,-27.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3160
type: TrashSpawner
components:
- parent: 0
pos: -9.5,-25.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3161
type: TrashSpawner
components:
- parent: 0
pos: -5.5,-27.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3162
type: TrashSpawner
components:
- parent: 0
pos: -2.5,-26.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3163
type: TrashSpawner
components:
- parent: 0
pos: -0.5,-22.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3164
type: TrashSpawner
components:
- parent: 0
pos: -10.5,-17.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3165
type: TrashSpawner
components:
- parent: 0
pos: 7.5,-18.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3166
type: TrashSpawner
components:
- parent: 0
pos: 12.5,-19.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3167
type: TrashSpawner
components:
- parent: 0
pos: 14.5,-21.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3168
type: TrashSpawner
components:
- parent: 0
pos: 14.5,-24.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3169
type: TrashSpawner
components:
- parent: 0
pos: 18.5,-25.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3170
type: TrashSpawner
components:
- parent: 0
pos: 22.5,-23.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3171
type: TrashSpawner
components:
- parent: 0
pos: 21.5,-20.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3172
type: TrashSpawner
components:
- parent: 0
pos: 21.5,-17.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3173
type: TrashSpawner
components:
- parent: 0
pos: 26.5,-17.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3174
type: TrashSpawner
components:
- parent: 0
pos: 27.5,-13.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3175
type: TrashSpawner
components:
- parent: 0
pos: 24.5,-9.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3176
type: TrashSpawner
components:
- parent: 0
pos: 27.5,-7.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3177
type: TrashSpawner
components:
- parent: 0
pos: 27.5,-3.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3178
type: TrashSpawner
components:
- parent: 0
pos: 25.5,-1.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3179
type: TrashSpawner
components:
- parent: 0
pos: 21.5,-2.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3180
type: TrashSpawner
components:
- parent: 0
pos: 20.5,0.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3181
type: TrashSpawner
components:
- parent: 0
pos: 32.5,-6.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3182
type: TrashSpawner
components:
- parent: 0
pos: 37.5,-7.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3183
type: TrashSpawner
components:
- parent: 0
pos: 37.5,-3.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3184
type: TrashSpawner
components:
- parent: 0
pos: 42.5,-2.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3185
type: TrashSpawner
components:
- parent: 0
pos: 44.5,6.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3186
type: TrashSpawner
components:
- parent: 0
pos: 35.5,2.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3187
type: TrashSpawner
components:
- parent: 0
pos: 27.5,0.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3188
type: TrashSpawner
components:
- parent: 0
pos: 28.5,8.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3189
type: TrashSpawner
components:
- parent: 0
pos: 26.5,10.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3190
type: TrashSpawner
components:
- parent: 0
pos: 27.5,13.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3191
type: TrashSpawner
components:
- parent: 0
pos: 24.5,11.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3192
type: TrashSpawner
components:
- parent: 0
pos: 12.5,12.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3193
type: TrashSpawner
components:
- parent: 0
pos: 12.5,7.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3194
type: TrashSpawner
components:
- parent: 0
pos: 6.5,1.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3195
type: TrashSpawner
components:
- parent: 0
pos: 25.5,6.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3196
type: TrashSpawner
components:
- parent: 0
pos: 19.5,3.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3197
type: TrashSpawner
components:
- parent: 0
pos: -7.5,5.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3198
type: TrashSpawner
components:
- parent: 0
pos: -1.5,-0.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3199
type: TrashSpawner
components:
- parent: 0
pos: -8.5,-1.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3200
type: TrashSpawner
components:
- parent: 0
pos: -17.5,3.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3201
type: TrashSpawner
components:
- parent: 0
pos: -25.5,0.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3202
type: TrashSpawner
components:
- parent: 0
pos: -22.5,-6.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3203
type: TrashSpawner
components:
- parent: 0
pos: 4.5,9.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3204
type: TrashSpawner
components:
- parent: 0
pos: 1.5,16.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3205
type: TrashSpawner
components:
- parent: 0
pos: 13.5,19.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3206
type: TrashSpawner
components:
- parent: 0
pos: 12.5,15.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3207
type: TrashSpawner
components:
- parent: 0
pos: 9.5,13.5
rot: -1.5707963267948966 rad
type: Transform
- uid: 3208
type: TrashSpawner
components:
- parent: 0
pos: 7.5,13.5
rot: -1.5707963267948966 rad
type: Transform
... ...

View File

@@ -18,6 +18,8 @@
parent: WardrobeMixed parent: WardrobeMixed
name: "custodial closet" name: "custodial closet"
description: "It's a storage unit for janitorial clothes and gear." description: "It's a storage unit for janitorial clothes and gear."
components:
- type: CustodialClosetFill
# Legal # Legal
- type: entity - type: entity

View File

@@ -30,7 +30,7 @@
name: gibblets name: gibblets
id: PuddleGibblet id: PuddleGibblet
parent: PuddleBase parent: PuddleBase
description: Holds spilt milk description: Gross.
components: components:
- type: Sprite - type: Sprite
sprite: Fluids/gibblet.rsi # Placeholder sprite: Fluids/gibblet.rsi # Placeholder
@@ -42,10 +42,10 @@
variants: 5 variants: 5
- type: entity - type: entity
name: smear name: puddle
id: PuddleSmear id: PuddleSmear
parent: PuddleBase parent: PuddleBase
description: Holds spilt milk description: A puddle of liquid.
components: components:
- type: Sprite - type: Sprite
sprite: Fluids/smear.rsi # Placeholder sprite: Fluids/smear.rsi # Placeholder
@@ -57,10 +57,10 @@
variants: 7 variants: 7
- type: entity - type: entity
name: splatter name: puddle
id: PuddleSplatter id: PuddleSplatter
parent: PuddleBase parent: PuddleBase
description: Holds spilt milk description: A puddle of liquid.
components: components:
- type: Sprite - type: Sprite
sprite: Fluids/splatter.rsi # Placeholder sprite: Fluids/splatter.rsi # Placeholder
@@ -75,7 +75,7 @@
name: vomit name: vomit
id: PuddleVomit id: PuddleVomit
parent: PuddleBase parent: PuddleBase
description: description: Gross.
components: components:
- type: Sprite - type: Sprite
sprite: Fluids/vomit.rsi sprite: Fluids/vomit.rsi
@@ -86,12 +86,13 @@
- type: Puddle - type: Puddle
variants: 4 variants: 4
recolor: false recolor: false
evaporate_threshold: -1
- type: entity - type: entity
name: toxins vomit name: toxins vomit
id: PuddleVomitToxin id: PuddleVomitToxin
parent: PuddleBase parent: PuddleVomit
description: You probably don't want to get too close to this description: You probably don't want to get too close to this.
components: components:
- type: Sprite - type: Sprite
sprite: Fluids/vomit_toxin.rsi sprite: Fluids/vomit_toxin.rsi
@@ -107,7 +108,7 @@
name: writing name: writing
id: PuddleWriting id: PuddleWriting
parent: PuddleBase parent: PuddleBase
description: Holds spilt milk description: A bit of liquid.
components: components:
- type: Sprite - type: Sprite
sprite: Fluids/writing.rsi # Placeholder sprite: Fluids/writing.rsi # Placeholder

View File

@@ -387,6 +387,7 @@
sprite: Clothing/Shoes/galoshes.rsi sprite: Clothing/Shoes/galoshes.rsi
- type: Clothing - type: Clothing
sprite: Clothing/Shoes/galoshes.rsi sprite: Clothing/Shoes/galoshes.rsi
- type: NoSlip
- type: entity - type: entity
parent: ShoesBase parent: ShoesBase

View File

@@ -170,9 +170,8 @@
- type: Icon - type: Icon
sprite: Objects/Consumable/Trash/tastybread.rsi sprite: Objects/Consumable/Trash/tastybread.rsi
# TODO: Container
- type: entity - type: entity
name: trash bag (trash) name: trash bag
parent: TrashBase parent: TrashBase
id: TrashBag id: TrashBag
components: components:
@@ -180,6 +179,8 @@
sprite: Objects/Consumable/Trash/trashbag.rsi sprite: Objects/Consumable/Trash/trashbag.rsi
- type: Icon - type: Icon
sprite: Objects/Consumable/Trash/trashbag.rsi sprite: Objects/Consumable/Trash/trashbag.rsi
- type: Storage
Capacity: 125
- type: entity - type: entity
name: tray (trash) name: tray (trash)

View File

@@ -0,0 +1,44 @@
- type: entity
name: Trash Spawner
id: TrashSpawner
components:
- type: Sprite
netsync: false
visible: false
sprite: Interface/Misc/markers.rsi
state: spawner_trash
- type: Icon
sprite: Interface/Misc/markers.rsi
state: spawner_trash
- type: Marker
- type: Clickable
- type: InteractionOutline
- type: Collidable
- type: TrashSpawner
rarePrototypes:
- PuddleVomit
- TrashPizzaBoxMessy
- TrashPlate
- TrashSnackBowl
- TrashTray
rareChance: 0.05
prototypes:
- TrashRaisins
- TrashCandy
- TrashCheesieHonkers
- TrashChips
- TrashCornCob
- TrashLiquidFood
- TrashPistachiosPack
- TrashPizzaBoxMessy
- TrashPlasticBag
- TrashPopcorn
- TrashSemkiPack
- TrashSOSJerky
- TrashSyndiCakes
- TrashTastyBread
chance: 0.75
offset: 0.2
placement:
mode: AlignTileAny

View File

@@ -465,6 +465,15 @@
1.0 1.0
] ]
] ]
},
{
"name": "spawner_trash",
"directions": 1,
"delays": [
[
1.0
]
]
}, },
{ {
"name": "spawner_xenoai", "name": "spawner_xenoai",

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B