Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Lost and Found Storage to Cryosleep #31

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a51d5ac
Add lost and found and sleep pod
vaketola Jan 16, 2024
73dd581
Fix spacing error
vaketola Jan 16, 2024
df63e85
Unbreak namespaces
vaketola Jan 16, 2024
845d2de
Add cryo sound effects
vaketola Jan 16, 2024
39ac47f
Flatten nested UI in cs
vaketola Jan 19, 2024
d74544f
Merge remote-tracking branch 'upstream/master' into cryopod
vaketola Jan 19, 2024
d526351
Fix sounds
vaketola Jan 19, 2024
a538ff3
Fix some naming and spacing uniformity issues
vaketola Jan 19, 2024
759a401
Fix more names and spacing
vaketola Jan 19, 2024
523e575
Change sprite
vaketola Jan 19, 2024
d34582d
Fix UI not closing
vaketola Jan 19, 2024
d67a5bc
Update Content.Client/CosmaticDrift/CryoSleep/AcceptCryoWindow.cs
Finket Jan 20, 2024
d6d6764
Update Content.Client/CosmaticDrift/CryoSleep/AcceptCryoWindow.cs
Finket Jan 20, 2024
ff21a84
Update Resources/Textures/Structures/cryosleep_pod.rsi/meta.json
Finket Jan 20, 2024
e765683
Merge branch 'master' into cryopod
vaketola Jan 28, 2024
c4684ea
Merge branch 'cryopod' of https://github.com/Finket/Parkstation-Frien…
vaketola Jan 28, 2024
bf6970e
Resolve rsi locations and fix spacing
vaketola Feb 2, 2024
8e6bbae
Merge branch 'master' into cryopod
vaketola Feb 21, 2024
84cbb9a
Replace CosmaticDrift code with modification of Wizden code
vaketola Feb 21, 2024
8f80035
Update lost and found yaml
vaketola Feb 21, 2024
3d05478
Add pausedMap checks to lost and found systems instead
vaketola Feb 21, 2024
fef065c
Change UI window title
vaketola Feb 22, 2024
bcf2442
Cryopod drops items if no lost and found available
vaketola Feb 24, 2024
ce5bc4f
Move LostAndFound to be handled in original cryostorage systems
vaketola Feb 26, 2024
42a4524
Update lost and found sprite
vaketola Feb 26, 2024
e691b27
Animate lost and found sprite screen
vaketola Feb 26, 2024
84eb666
Update sprite again
vaketola Feb 26, 2024
71a3af2
Merge branch 'master' into cryopod
vaketola Mar 18, 2024
2d801d6
Move from SimpleStation14 to Parkstation namespaces
vaketola Mar 18, 2024
9abc874
Fix reference to parkstation audio
vaketola Mar 18, 2024
936fc79
Apply suggestions from code review
Finket Apr 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 53 additions & 112 deletions Content.Server/Bed/Cryostorage/CryostorageSystem.cs
Finket marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
using System.Linq;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Hands.Systems;
using Content.Server.Inventory;
using Content.Server.Popups;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared.UserInterface;
using Content.Shared.Access.Systems;
using Content.Shared.Bed.Cryostorage;
using Content.Shared.Chat;
using Content.Shared.Climbing.Systems;
using Content.Shared.Database;
using Content.Shared.Hands.Components;
using Content.Shared.Inventory;
using Content.Shared.Mind.Components;
using Robust.Server.Audio;
using Robust.Server.Containers;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Enums;
using Robust.Shared.Network;
Expand All @@ -30,27 +25,21 @@ public sealed class CryostorageSystem : SharedCryostorageSystem
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly ClimbSystem _climb = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly HandsSystem _hands = default!;
[Dependency] private readonly ServerInventorySystem _inventory = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly StationJobsSystem _stationJobs = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly LostAndFoundSystem _lostAndFound = default!;

/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<CryostorageComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpened);
SubscribeLocalEvent<CryostorageComponent, CryostorageRemoveItemBuiMessage>(OnRemoveItemBuiMessage);

SubscribeLocalEvent<CryostorageContainedComponent, PlayerSpawnCompleteEvent>(OnPlayerSpawned);
SubscribeLocalEvent<CryostorageContainedComponent, MindRemovedMessage>(OnMindRemoved);

Expand All @@ -64,61 +53,6 @@ public override void Shutdown()
_playerManager.PlayerStatusChanged -= PlayerStatusChanged;
}

private void OnBeforeUIOpened(Entity<CryostorageComponent> ent, ref BeforeActivatableUIOpenEvent args)
{
UpdateCryostorageUIState(ent);
}

private void OnRemoveItemBuiMessage(Entity<CryostorageComponent> ent, ref CryostorageRemoveItemBuiMessage args)
{
var (_, comp) = ent;
if (args.Session.AttachedEntity is not { } attachedEntity)
return;

var cryoContained = GetEntity(args.StoredEntity);

if (!comp.StoredPlayers.Contains(cryoContained) || !IsInPausedMap(cryoContained))
return;

if (!HasComp<HandsComponent>(attachedEntity))
return;

if (!_accessReader.IsAllowed(attachedEntity, ent))
{
_popup.PopupEntity(Loc.GetString("cryostorage-popup-access-denied"), attachedEntity, attachedEntity);
return;
}

EntityUid? entity = null;
if (args.Type == CryostorageRemoveItemBuiMessage.RemovalType.Hand)
{
if (_hands.TryGetHand(cryoContained, args.Key, out var hand))
entity = hand.HeldEntity;
}
else
{
if (_inventory.TryGetSlotContainer(cryoContained, args.Key, out var slot, out _))
entity = slot.ContainedEntity;
}

if (entity == null)
return;

AdminLog.Add(LogType.Action, LogImpact.High,
$"{ToPrettyString(attachedEntity):player} removed item {ToPrettyString(entity)} from cryostorage-contained player " +
$"{ToPrettyString(cryoContained):player}, stored in cryostorage {ToPrettyString(ent)}");
_container.TryRemoveFromContainer(entity.Value);
_transform.SetCoordinates(entity.Value, Transform(attachedEntity).Coordinates);
_hands.PickupOrDrop(attachedEntity, entity.Value);
UpdateCryostorageUIState(ent);
}

private void UpdateCryostorageUIState(Entity<CryostorageComponent> ent)
{
var state = new CryostorageBuiState(GetAllContainedData(ent).ToList());
_ui.TrySetUiState(ent, CryostorageUIKey.Key, state);
}

private void OnPlayerSpawned(Entity<CryostorageContainedComponent> ent, ref PlayerSpawnCompleteEvent args)
{
// if you spawned into cryostorage, we're not gonna round-remove you.
Expand Down Expand Up @@ -186,10 +120,10 @@ public void HandleEnterCryostorage(Entity<CryostorageContainedComponent> ent, Ne
}
}

_audio.PlayPvs(cryostorageComponent.RemoveSound, ent);
_audio.PlayPvs("/Audio/SimpleStation14/Effects/cryostasis.ogg", cryostorageEnt.Value, AudioParams.Default.WithVolume(6f));

Finket marked this conversation as resolved.
Show resolved Hide resolved
EnsurePausedMap();
if (PausedMap == null)
_lostAndFound.EnsurePausedMap();
if (_lostAndFound.PausedMap == null)
{
Log.Error("CryoSleep map was unexpectedly null");
return;
Expand All @@ -203,17 +137,45 @@ public void HandleEnterCryostorage(Entity<CryostorageContainedComponent> ent, Ne
}
}
comp.AllowReEnteringBody = false;
_transform.SetParent(ent, PausedMap.Value);
cryostorageComponent.StoredPlayers.Add(ent);
Dirty(ent, comp);
UpdateCryostorageUIState((cryostorageEnt.Value, cryostorageComponent));
_transform.SetParent(ent, _lostAndFound.PausedMap.Value);

// try to get the lost and found and add the player to it
var query = EntityQueryEnumerator<LostAndFoundComponent>();
Finket marked this conversation as resolved.
Show resolved Hide resolved
query.MoveNext(out var storage, out var lostAndFoundComponent);

Comment on lines +210 to +211
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should randomly pick one if multiple exist

if (TryComp<LostAndFoundComponent>(storage, out var lostAndFoundComp))
{
Comment on lines +211 to +213
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already got the lost and found comp, don't need to check again

lostAndFoundComp.StoredPlayers.Add(ent);
Dirty(ent, comp);
_lostAndFound.UpdateCryostorageUIState((storage, lostAndFoundComp));
}
else // if there is no lost and found, just drop the items instead of deleting them
{
Finket marked this conversation as resolved.
Show resolved Hide resolved
DropItems(ent, cryostorageEnt.Value);
}

AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(ent):player} was entered into cryostorage inside of {ToPrettyString(cryostorageEnt.Value)}");
}

private void DropItems(EntityUid uid, EntityUid cryopod)
{
if (!_inventory.TryGetSlots(uid, out var slotDefinitions))
return;

foreach (var slot in slotDefinitions)
{
if (!_inventory.TryGetSlotEntity(uid, slot.Name, out var item))
continue;

_inventory.TryUnequip(uid, slot.Name, true, true);
_transform.SetCoordinates(uid, Transform(cryopod).Coordinates);
}
}

private void HandleCryostorageReconnection(Entity<CryostorageContainedComponent> entity)
{
var (uid, comp) = entity;
if (!CryoSleepRejoiningEnabled || !IsInPausedMap(uid))
if (!CryoSleepRejoiningEnabled || !_lostAndFound.IsInPausedMap(uid))
return;

// how did you destroy these? they're indestructible.
Expand All @@ -235,9 +197,18 @@ private void HandleCryostorageReconnection(Entity<CryostorageContainedComponent>
}

comp.GracePeriodEndTime = null;
cryostorageComponent.StoredPlayers.Remove(uid);

// try to get the lost and found and remove the player from it
var query = EntityQueryEnumerator<LostAndFoundComponent>();
Finket marked this conversation as resolved.
Show resolved Hide resolved
query.MoveNext(out var storage, out var lostAndFoundComponent);

if (TryComp<LostAndFoundComponent>(storage, out var lostAndFoundComp))
{
lostAndFoundComp.StoredPlayers.Remove(uid);
_lostAndFound.UpdateCryostorageUIState((storage, lostAndFoundComp));
}

AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(entity):player} re-entered the game from cryostorage {ToPrettyString(cryostorage)}");
UpdateCryostorageUIState((cryostorage, cryostorageComponent));
}

protected override void OnInsertedContainer(Entity<CryostorageComponent> ent, ref EntInsertedIntoContainerMessage args)
Expand All @@ -257,36 +228,6 @@ protected override void OnInsertedContainer(Entity<CryostorageComponent> ent, re
_chatManager.ChatMessageToOne(ChatChannel.Server, msg, msg, uid, false, actor.PlayerSession.Channel);
}

private IEnumerable<CryostorageContainedPlayerData> GetAllContainedData(Entity<CryostorageComponent> ent)
{
foreach (var contained in ent.Comp.StoredPlayers)
{
yield return GetContainedData(contained);
}
}

private CryostorageContainedPlayerData GetContainedData(EntityUid uid)
{
var data = new CryostorageContainedPlayerData();
data.PlayerName = Name(uid);
data.PlayerEnt = GetNetEntity(uid);

var enumerator = _inventory.GetSlotEnumerator(uid);
while (enumerator.NextItem(out var item, out var slotDef))
{
data.ItemSlots.Add(slotDef.Name, Name(item));
}

foreach (var hand in _hands.EnumerateHands(uid))
{
if (hand.HeldEntity == null)
continue;

data.HeldItems.Add(hand.Name, Name(hand.HeldEntity.Value));
}

return data;
}

public override void Update(float frameTime)
{
Expand Down
124 changes: 124 additions & 0 deletions Content.Server/Bed/Cryostorage/LostAndFoundSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System.Linq;
using Content.Server.Hands.Systems;
using Content.Server.Inventory;
using Content.Server.Popups;
using Content.Shared.Access.Systems;
using Content.Shared.UserInterface;
using Content.Shared.Bed.Cryostorage;
using Content.Shared.Database;
using Content.Shared.Hands.Components;
using Robust.Server.Containers;
using Robust.Server.GameObjects;

namespace Content.Server.Bed.Cryostorage;

/// <inheritdoc/>
public sealed class LostAndFoundSystem : SharedLostAndFoundSystem
{
[Dependency] private readonly ServerInventorySystem _inventory = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly HandsSystem _hands = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly TransformSystem _transform = default!;

/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<LostAndFoundComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpened);
SubscribeLocalEvent<LostAndFoundComponent, CryostorageRemoveItemBuiMessage>(OnRemoveItemBuiMessage);
}

private void OnBeforeUIOpened(Entity<LostAndFoundComponent> ent, ref BeforeActivatableUIOpenEvent args)
{
UpdateCryostorageUIState(ent);
}

private void OnRemoveItemBuiMessage(Entity<LostAndFoundComponent> ent, ref CryostorageRemoveItemBuiMessage args)
{
Log.Debug("on remove item bui message");

var (_, comp) = ent;
if (args.Session.AttachedEntity is not { } attachedEntity)
return;

var cryoContained = GetEntity(args.StoredEntity);

if (!comp.StoredPlayers.Contains(cryoContained) || !IsInPausedMap(cryoContained))
return;

if (!HasComp<HandsComponent>(attachedEntity))
return;

if (!_accessReader.IsAllowed(attachedEntity, ent))
{
_popup.PopupEntity(Loc.GetString("cryostorage-popup-access-denied"), attachedEntity, attachedEntity);
return;
}

EntityUid? entity = null;
if (args.Type == CryostorageRemoveItemBuiMessage.RemovalType.Hand)
{
if (_hands.TryGetHand(cryoContained, args.Key, out var hand))
entity = hand.HeldEntity;
}
else
{
if (_inventory.TryGetSlotContainer(cryoContained, args.Key, out var slot, out _))
entity = slot.ContainedEntity;
}

if (entity == null)
return;

AdminLog.Add(LogType.Action, LogImpact.High,
$"{ToPrettyString(attachedEntity):player} removed item {ToPrettyString(entity)} from cryostorage-contained player " +
$"{ToPrettyString(cryoContained):player}, stored in cryostorage {ToPrettyString(ent)}");
_container.TryRemoveFromContainer(entity.Value);
_transform.SetCoordinates(entity.Value, Transform(attachedEntity).Coordinates);
_hands.PickupOrDrop(attachedEntity, entity.Value);
UpdateCryostorageUIState(ent);
}


public void UpdateCryostorageUIState(Entity<LostAndFoundComponent> ent)
{
var state = new CryostorageBuiState(GetAllContainedData(ent).ToList());
_ui.TrySetUiState(ent, CryostorageUIKey.Key, state);
}

private IEnumerable<CryostorageContainedPlayerData> GetAllContainedData(Entity<LostAndFoundComponent> ent)
{
foreach (var contained in ent.Comp.StoredPlayers)
{
yield return GetContainedData(contained);
}
}

private CryostorageContainedPlayerData GetContainedData(EntityUid uid)
{
var data = new CryostorageContainedPlayerData();
data.PlayerName = Name(uid);
data.PlayerEnt = GetNetEntity(uid);

var enumerator = _inventory.GetSlotEnumerator(uid);
while (enumerator.NextItem(out var item, out var slotDef))
{
data.ItemSlots.Add(slotDef.Name, Name(item));
}

foreach (var hand in _hands.EnumerateHands(uid))
{
if (hand.HeldEntity == null)
continue;

data.HeldItems.Add(hand.Name, Name(hand.HeldEntity.Value));
}

return data;
}

}
Loading
Loading