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 30 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
72 changes: 56 additions & 16 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
Expand Up @@ -2,7 +2,6 @@
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;
Expand All @@ -13,11 +12,13 @@
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,13 +31,13 @@ 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!;
Expand All @@ -48,8 +49,8 @@ public override void Initialize()
{
base.Initialize();

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

SubscribeLocalEvent<CryostorageContainedComponent, PlayerSpawnCompleteEvent>(OnPlayerSpawned);
SubscribeLocalEvent<CryostorageContainedComponent, MindRemovedMessage>(OnMindRemoved);
Expand All @@ -64,13 +65,15 @@ public override void Shutdown()
_playerManager.PlayerStatusChanged -= PlayerStatusChanged;
}

private void OnBeforeUIOpened(Entity<CryostorageComponent> ent, ref BeforeActivatableUIOpenEvent args)
private void OnBeforeUIOpened(Entity<LostAndFoundComponent> ent, ref BeforeActivatableUIOpenEvent args)
Finket marked this conversation as resolved.
Show resolved Hide resolved
{
UpdateCryostorageUIState(ent);
}

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

Finket marked this conversation as resolved.
Show resolved Hide resolved
var (_, comp) = ent;
if (args.Session.AttachedEntity is not { } attachedEntity)
return;
Expand Down Expand Up @@ -113,7 +116,7 @@ private void OnRemoveItemBuiMessage(Entity<CryostorageComponent> ent, ref Cryost
UpdateCryostorageUIState(ent);
}

private void UpdateCryostorageUIState(Entity<CryostorageComponent> ent)
public void UpdateCryostorageUIState(Entity<LostAndFoundComponent> ent)
{
var state = new CryostorageBuiState(GetAllContainedData(ent).ToList());
_ui.TrySetUiState(ent, CryostorageUIKey.Key, state);
Expand Down Expand Up @@ -186,7 +189,7 @@ public void HandleEnterCryostorage(Entity<CryostorageContainedComponent> ent, Ne
}
}

_audio.PlayPvs(cryostorageComponent.RemoveSound, ent);
_audio.PlayPvs(cryostorageComponent.RemoveSound, cryostorageEnt.Value, AudioParams.Default.WithVolume(6f));

EnsurePausedMap();
if (PausedMap == null)
Expand All @@ -204,12 +207,40 @@ 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));

// try to get the lost and found and add the player to it
Finket marked this conversation as resolved.
Show resolved Hide resolved
var query = EntityQueryEnumerator<LostAndFoundComponent>();
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);
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;
Expand All @@ -235,9 +266,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
Finket marked this conversation as resolved.
Show resolved Hide resolved
var query = EntityQueryEnumerator<LostAndFoundComponent>();
query.MoveNext(out var storage, out var lostAndFoundComponent);

if (TryComp<LostAndFoundComponent>(storage, out var lostAndFoundComp))
{
lostAndFoundComp.StoredPlayers.Remove(uid);
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,7 +297,7 @@ 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)
private IEnumerable<CryostorageContainedPlayerData> GetAllContainedData(Entity<LostAndFoundComponent> ent)
{
foreach (var contained in ent.Comp.StoredPlayers)
{
Expand Down
73 changes: 4 additions & 69 deletions Content.Shared/Bed/Cryostorage/CryostorageComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,85 +30,20 @@ public sealed partial class CryostorageComponent : Component
public TimeSpan GracePeriod = TimeSpan.FromMinutes(5f);

/// <summary>
/// A list of players who have actively entered cryostorage.
/// Sound that is played when a player is removed by a cryostorage.
/// </summary>
[DataField]
[AutoNetworkedField]
public List<EntityUid> StoredPlayers = new();
public SoundSpecifier? RemoveSound = new SoundPathSpecifier("/Audio/Parkstation/Effects/cryostasis.ogg");

/// <summary>
/// Sound that is played when a player is removed by a cryostorage.
/// Sound that is played when a player goes inside of the cryostorage pod.
/// </summary>
[DataField]
public SoundSpecifier? RemoveSound = new SoundPathSpecifier("/Audio/Effects/teleport_departure.ogg");
public static SoundSpecifier? EnterSound = new SoundPathSpecifier("/Audio/Parkstation/Effects/cryosleep_open.ogg");
}

[Serializable, NetSerializable]
public enum CryostorageVisuals : byte
{
Full
}

[Serializable, NetSerializable]
public record struct CryostorageContainedPlayerData()
{
/// <summary>
/// The player's IC name
/// </summary>
public string PlayerName = string.Empty;

/// <summary>
/// The player's entity
/// </summary>
public NetEntity PlayerEnt = NetEntity.Invalid;

/// <summary>
/// A dictionary relating a slot definition name to the name of the item inside of it.
/// </summary>
public Dictionary<string, string> ItemSlots = new();

/// <summary>
/// A dictionary relating a hand ID to the hand name and the name of the item being held.
/// </summary>
public Dictionary<string, string> HeldItems = new();
}

[Serializable, NetSerializable]
public sealed class CryostorageBuiState : BoundUserInterfaceState
{
public List<CryostorageContainedPlayerData> PlayerData;

public CryostorageBuiState(List<CryostorageContainedPlayerData> playerData)
{
PlayerData = playerData;
}
}

[Serializable, NetSerializable]
public sealed class CryostorageRemoveItemBuiMessage : BoundUserInterfaceMessage
{
public NetEntity StoredEntity;

public string Key;

public RemovalType Type;

public enum RemovalType : byte
{
Hand,
Inventory
}

public CryostorageRemoveItemBuiMessage(NetEntity storedEntity, string key, RemovalType type)
{
StoredEntity = storedEntity;
Key = key;
Type = type;
}
}

[Serializable, NetSerializable]
public enum CryostorageUIKey : byte
{
Key
}
85 changes: 85 additions & 0 deletions Content.Shared/Bed/Cryostorage/LostAndFoundComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;

namespace Content.Shared.Bed.Cryostorage;

/// <summary>
/// This is used for a container which holds the items lost
/// when a player enters cryostorage.
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
public sealed partial class LostAndFoundComponent : Component
{
/// <summary>
/// A list of players who have actively entered cryostorage.
/// </summary>
[DataField]
[AutoNetworkedField]
public List<EntityUid> StoredPlayers = new();

}

[Serializable, NetSerializable]
public record struct CryostorageContainedPlayerData()
{
/// <summary>
/// The player's IC name
/// </summary>
public string PlayerName = string.Empty;

/// <summary>
/// The player's entity
/// </summary>
public NetEntity PlayerEnt = NetEntity.Invalid;

/// <summary>
/// A dictionary relating a slot definition name to the name of the item inside of it.
/// </summary>
public Dictionary<string, string> ItemSlots = new();

/// <summary>
/// A dictionary relating a hand ID to the hand name and the name of the item being held.
/// </summary>
public Dictionary<string, string> HeldItems = new();
}

[Serializable, NetSerializable]
public sealed class CryostorageBuiState : BoundUserInterfaceState
{
public List<CryostorageContainedPlayerData> PlayerData;

public CryostorageBuiState(List<CryostorageContainedPlayerData> playerData)
{
PlayerData = playerData;
}
}

[Serializable, NetSerializable]
public sealed class CryostorageRemoveItemBuiMessage : BoundUserInterfaceMessage
{
public NetEntity StoredEntity;

public string Key;

public RemovalType Type;

public enum RemovalType : byte
{
Hand,
Inventory
}

public CryostorageRemoveItemBuiMessage(NetEntity storedEntity, string key, RemovalType type)
{
StoredEntity = storedEntity;
Key = key;
Type = type;
}
}

[Serializable, NetSerializable]
public enum CryostorageUIKey : byte
{
Key
}
Loading
Loading