Janitor cart (#7367)

This commit is contained in:
Alex Evgrashin
2022-04-12 02:21:15 +03:00
committed by GitHub
parent c4ebfc22e3
commit 9c65f4b324
20 changed files with 320 additions and 25 deletions

View File

@@ -71,6 +71,15 @@ namespace Content.Server.Storage.Components
[DataField("whitelist")] [DataField("whitelist")]
private EntityWhitelist? _whitelist = null; private EntityWhitelist? _whitelist = null;
[DataField("blacklist")]
public EntityWhitelist? Blacklist = null;
/// <summary>
/// If true, storage will show popup messages to the player after failed interactions.
/// Usually this is message that item doesn't fit inside container.
/// </summary>
[DataField("popup")]
public bool ShowPopup = true;
private bool _storageInitialCalculated; private bool _storageInitialCalculated;
public int StorageUsed; public int StorageUsed;
@@ -165,6 +174,11 @@ namespace Content.Server.Storage.Components
return false; return false;
} }
if (Blacklist != null && Blacklist.IsValid(entity))
{
return false;
}
if (_entityManager.GetComponent<TransformComponent>(entity).Anchored) if (_entityManager.GetComponent<TransformComponent>(entity).Anchored)
{ {
return false; return false;
@@ -256,14 +270,14 @@ namespace Content.Server.Storage.Components
if (!handSys.TryDrop(player, toInsert.Value, handsComp: hands)) if (!handSys.TryDrop(player, toInsert.Value, handsComp: hands))
{ {
Owner.PopupMessage(player, Loc.GetString("comp-storage-cant-insert")); Popup(player, "comp-storage-cant-insert");
return false; return false;
} }
if (!Insert(toInsert.Value)) if (!Insert(toInsert.Value))
{ {
handSys.PickupOrDrop(player, toInsert.Value, handsComp: hands); handSys.PickupOrDrop(player, toInsert.Value, handsComp: hands);
Owner.PopupMessage(player, Loc.GetString("comp-storage-cant-insert")); Popup(player, "comp-storage-cant-insert");
return false; return false;
} }
@@ -282,7 +296,7 @@ namespace Content.Server.Storage.Components
if (!Insert(toInsert)) if (!Insert(toInsert))
{ {
Owner.PopupMessage(player, Loc.GetString("comp-storage-cant-insert")); Popup(player, "comp-storage-cant-insert");
return false; return false;
} }
return true; return true;
@@ -482,7 +496,7 @@ namespace Content.Server.Storage.Components
return; return;
} }
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(player, Owner, popup: true)) if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(player, Owner, popup: ShowPopup))
{ {
return; return;
} }
@@ -638,6 +652,13 @@ namespace Content.Server.Storage.Components
} }
} }
private void Popup(EntityUid player, string message)
{
if (!ShowPopup) return;
Owner.PopupMessage(player, Loc.GetString(message));
}
private void PlaySoundCollection() private void PlaySoundCollection()
{ {
SoundSystem.Play(Filter.Pvs(Owner), StorageSoundCollection.GetSound(), Owner, AudioParams.Default); SoundSystem.Play(Filter.Pvs(Owner), StorageSoundCollection.GetSound(), Owner, AudioParams.Default);

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Content.Server.Storage.Components; using Content.Server.Storage.Components;
using Content.Shared.Storage.Components; using Content.Shared.Storage.Components;
using Content.Shared.Storage.EntitySystems; using Content.Shared.Storage.EntitySystems;
@@ -12,32 +13,27 @@ namespace Content.Server.Storage.EntitySystems
[UsedImplicitly] [UsedImplicitly]
public sealed class ItemMapperSystem : SharedItemMapperSystem public sealed class ItemMapperSystem : SharedItemMapperSystem
{ {
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
protected override bool TryGetLayers(ContainerModifiedMessage msg, protected override bool TryGetLayers(ContainerModifiedMessage msg,
ItemMapperComponent itemMapper, ItemMapperComponent itemMapper,
out IReadOnlyList<string> showLayers) out IReadOnlyList<string> showLayers)
{ {
if (EntityManager.TryGetComponent(msg.Container.Owner, out ServerStorageComponent? component)) var containedLayers = _containerSystem.GetAllContainers(msg.Container.Owner)
{ .SelectMany(cont => cont.ContainedEntities).ToArray();
var containedLayers = component.StoredEntities ?? new List<EntityUid>();
var list = new List<string>();
foreach (var mapLayerData in itemMapper.MapLayers.Values)
{
foreach (var entity in containedLayers)
{
if (mapLayerData.ServerWhitelist.IsValid(entity))
{
list.Add(mapLayerData.Layer);
break;
}
}
}
showLayers = list; var list = new List<string>();
return true; foreach (var mapLayerData in itemMapper.MapLayers.Values)
{
var count = containedLayers.Count(uid => mapLayerData.ServerWhitelist.IsValid(uid));
if (count >= mapLayerData.MinCount && count <= mapLayerData.MaxCount)
{
list.Add(mapLayerData.Layer);
}
} }
showLayers = new List<string>(); showLayers = list;
return false; return true;
} }
} }
} }

View File

@@ -116,6 +116,13 @@ namespace Content.Shared.Containers.ItemSlots
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public bool Locked = false; public bool Locked = false;
/// <summary>
/// Whether the item slots system will attempt to insert item from the user's hands into this slot when interacted with.
/// It doesn't block other insertion methods, like verbs.
/// </summary>
[DataField("insertOnInteract")]
public bool InsertOnInteract = true;
/// <summary> /// <summary>
/// Whether the item slots system will attempt to eject this item to the user's hands when interacted with. /// Whether the item slots system will attempt to eject this item to the user's hands when interacted with.
/// </summary> /// </summary>

View File

@@ -170,6 +170,9 @@ namespace Content.Shared.Containers.ItemSlots
foreach (var slot in itemSlots.Slots.Values) foreach (var slot in itemSlots.Slots.Values)
{ {
if (!slot.InsertOnInteract)
continue;
if (!CanInsert(uid, args.Used, slot, swap: slot.Swap, popup: args.User)) if (!CanInsert(uid, args.Used, slot, swap: slot.Swap, popup: args.User))
continue; continue;

View File

@@ -21,6 +21,20 @@ namespace Content.Shared.Storage.Components
[DataField("whitelist", required: true, serverOnly: true)] [DataField("whitelist", required: true, serverOnly: true)]
public EntityWhitelist ServerWhitelist { get; set; } = new(); public EntityWhitelist ServerWhitelist { get; set; } = new();
/// <summary>
/// Minimal amount of entities that are valid for whitelist.
/// If it's smaller than minimal amount, layer will be hidden.
/// </summary>
[DataField("minCount")]
public int MinCount = 1;
/// <summary>
/// Max amount of entities that are valid for whitelist.
/// If it's bigger than max amount, layer will be hidden.
/// </summary>
[DataField("maxCount")]
public int MaxCount = int.MaxValue;
} }
[Serializable, NetSerializable] [Serializable, NetSerializable]

View File

@@ -9,7 +9,7 @@
sprite: Objects/Specific/Janitorial/mop.rsi sprite: Objects/Specific/Janitorial/mop.rsi
state: mop state: mop
- type: Item - type: Item
size: 10 size: 15
sprite: Objects/Specific/Janitorial/mop.rsi sprite: Objects/Specific/Janitorial/mop.rsi
- type: Absorbent - type: Absorbent
- type: SolutionContainerManager - type: SolutionContainerManager
@@ -74,3 +74,129 @@
state: caution state: caution
- type: Item - type: Item
sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi
size: 15
- type: Tag
tags:
- WetFloorSign
- type: entity
name: janitorial trolley
id: JanitorialTrolley
parent: BaseStructureDynamic
description: This is the alpha and omega of sanitation.
components:
- type: Sprite
netSync: false
noRot: true
sprite: Objects/Specific/Janitorial/janitorial_cart.rsi
layers:
- state: cart
- state: cart_water_1
map: ["enum.SolutionContainerLayers.Fill"]
- type: Rotatable
- type: InteractionOutline
- type: Storage
popup: false
capacity: 80
blacklist: # there is exclusive item slots for that
tags:
- Mop
- TrashBag
- type: ItemSlots
slots:
mop_slot:
name: Mop
whitelist:
tags:
- Mop
insertOnInteract: false # or it conflicts with bucket logic
trashbag_slot:
name: Bag
whitelist:
tags:
- TrashBag
- type: Fixtures
fixtures:
- shape:
!type:PhysShapeCircle
radius: 0.3
layer:
- SmallImpassable
mask:
- VaultImpassable
mass: 100
- type: SolutionContainerManager
solutions:
bucket:
maxVol: 500
reagents:
- ReagentId: Water
Quantity: 250 # half-full at roundstart to leave room for puddles
- type: DrainableSolution
solution: bucket
- type: RefillableSolution
solution: bucket
- type: Tag
tags:
- Wringer
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 200
behaviors:
- !type:EmptyAllContainersBehaviour
- !type:DoActsBehavior
acts: ["Destruction"]
- !type:PlaySoundBehavior
sound:
path: /Audio/Effects/metalbreak.ogg
- type: ItemMapper
mapLayers:
cart_mop:
whitelist:
tags:
- Mop
cart_garbage:
whitelist:
tags:
- TrashBag
cart_replacer:
whitelist:
components:
- LightReplacer
cart_spray:
whitelist:
tags:
- Spray
cart_sign1: # this is like stack of floor signs
minCount: 1
whitelist:
tags:
- WetFloorSign
cart_sign2:
minCount: 2
whitelist:
tags:
- WetFloorSign
cart_sign3:
minCount: 3
whitelist:
tags:
- WetFloorSign
cart_sign4:
minCount: 4
whitelist:
tags:
- WetFloorSign
- type: Appearance
visuals:
- type: MappedItemVisualizer
sprite: Objects/Specific/Janitorial/janitorial_cart.rsi
- type: SolutionContainerVisualizer
maxFillLevels: 3
fillBaseName: cart_water_
changeColor: false

View File

@@ -298,6 +298,9 @@
- type: Tag - type: Tag
id: TrashBag id: TrashBag
- type: Tag
id: WetFloorSign
- type: Tag - type: Tag
id: Wall id: Wall

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

View File

@@ -0,0 +1,125 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/f8f4aeda930fcd0805ca4cc76d9bc9412a5b3428",
"states": [
{
"name": "cart",
"directions": 4
},
{
"name": "cart_garbage",
"directions": 4
},
{
"name": "cart_mop",
"directions": 4
},
{
"name": "cart_replacer",
"directions": 4
},
{
"name": "cart_sign1",
"directions": 4
},
{
"name": "cart_sign2",
"directions": 4
},
{
"name": "cart_sign3",
"directions": 4
},
{
"name": "cart_sign4",
"directions": 4
},
{
"name": "cart_spray",
"directions": 4
},
{
"name": "cart_water_1",
"directions": 4,
"delays": [
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
]
]
},
{
"name": "cart_water_2",
"directions": 4,
"delays": [
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
]
]
},
{
"name": "cart_water_3",
"directions": 4,
"delays": [
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
],
[
0.2,
0.2,
0.2
]
]
}
]
}