Skip to content
Open
6 changes: 6 additions & 0 deletions Content.Client/Ghost/GhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using Content.Client._Shitcode.Wizard.Systems;
using Content.Client.Movement.Systems;
using Content.Shared._CorvaxGoob.Events;
using Content.Shared.Actions;
using Content.Shared.Ghost;
using Robust.Client.Console;
Expand Down Expand Up @@ -209,6 +210,11 @@ public void GhostBarSpawn() // CorvaxGoob-GhostBar
RaiseNetworkEvent(new GhostBarSpawnEvent());
}

public void GhostGoLobby() // CorvaxGoob-Golobby
{
RaiseNetworkEvent(new GhostGoLobbyEvent());
}

public void ToggleGhostVisibility(bool? visibility = null)
{
GhostVisibility = visibility ?? !GhostVisibility;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

using Content.Client._CorvaxGoob.Ghost;
using Content.Client.Ghost;
using Content.Client.UserInterface.Systems.Gameplay;
using Content.Client.UserInterface.Systems.Ghost.Widgets;
using Content.Goobstation.Shared.MisandryBox.Thunderdome;
using Content.Shared._CorvaxGoob.CCCVars;
using Content.Shared.Ghost;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Robust.Shared.Configuration; // CorvaxGoob-GoLobby

namespace Content.Client.UserInterface.Systems.Ghost;

Expand All @@ -15,10 +18,14 @@ public sealed class GhostUIController : UIController, IOnSystemChanged<GhostSyst
{
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IEntityNetworkManager _net = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!; // CorvaxGoob-GoLobby
[UISystemDependency] private readonly GhostSystem? _system = default;

private GhostGui? Gui => UIManager.GetActiveUIWidgetOrNull<GhostGui>();

private GhostGoLobbyConfirmWindow? _goLobbyConfirmWindow; // CorvaxGoob-GoLobby
private bool _goLobbyEnabled = true; // CorvaxGoob-GoLobby

public override void Initialize()
{
base.Initialize();
Expand All @@ -30,6 +37,15 @@ public override void Initialize()
// Goobstation - Thunderdome
_entManager.EventBus.SubscribeEvent<ThunderdomePlayerCountEvent>
(EventSource.Network, this, OnThunderdomePlayerCount);

// CorvaxGoob-GoLobby
_cfg.OnValueChanged(CCCVars.GhostGoLobbyEnabled, OnGoLobbyEnabledChanged, true);
}

private void OnGoLobbyEnabledChanged(bool enabled) // CorvaxGoob-GoLobby
{
_goLobbyEnabled = enabled;
UpdateGui();
}

private void OnScreenLoad()
Expand Down Expand Up @@ -70,7 +86,7 @@ public void UpdateGui()
}

Gui.Visible = _system?.IsGhost ?? false;
Gui.Update(_system?.AvailableGhostRoleCount, _system?.Player?.CanReturnToBody, _system?.Player?.CanEnterGhostBar, _system?.Player?.CanTakeGhostRoles); // CorvaxGoob-GhostBar edit
Gui.Update(_system?.AvailableGhostRoleCount, _system?.Player?.CanReturnToBody, _system?.Player?.CanEnterGhostBar, _system?.Player?.CanTakeGhostRoles, _goLobbyEnabled); // CorvaxGoob-GhostBar edit, CorvaxGoob-GoLobby edit
}

private void OnPlayerRemoved(GhostComponent component)
Expand Down Expand Up @@ -131,6 +147,7 @@ public void LoadGui()
Gui.RequestWarpsPressed += RequestWarps;
Gui.ReturnToBodyPressed += ReturnToBody;
Gui.GhostRolesPressed += GhostRolesPressed;
Gui.GhostGoLobbyPressed += GhostGoLobby; // CorvaxGoob-GoLobby
Gui.GhostBarPressed += GhostBarPressed; // CorvaxGoob-GhostBar
Gui.GhostBarWindow.SpawnButtonPressed += GhostBarSpawnPressed; // CorvaxGoob-GhostBar
Gui.ThunderdomePressed += ThunderdomePressed; // Goobstation - Thunderdome
Expand All @@ -148,6 +165,7 @@ public void UnloadGui()
Gui.RequestWarpsPressed -= RequestWarps;
Gui.ReturnToBodyPressed -= ReturnToBody;
Gui.GhostRolesPressed -= GhostRolesPressed;
Gui.GhostGoLobbyPressed -= GhostGoLobby; // CorvaxGoob-GoLobby
Gui.ThunderdomePressed -= ThunderdomePressed; // Goobstation - Thunderdome
Gui.TargetWindow.WarpClicked -= OnWarpClicked;

Expand All @@ -159,6 +177,20 @@ private void ReturnToBody()
_system?.ReturnToBody();
}

private void GhostGoLobby() // CorvaxGoob-GoLobby
{
if (_goLobbyConfirmWindow is { Disposed: false })
{
_goLobbyConfirmWindow.MoveToFront();
return;
}

_goLobbyConfirmWindow = new GhostGoLobbyConfirmWindow();
_goLobbyConfirmWindow.ContinuePressed += () => _system?.GhostGoLobby();
_goLobbyConfirmWindow.OnClose += () => _goLobbyConfirmWindow = null;
_goLobbyConfirmWindow.OpenCentered();
}

private void RequestWarps()
{
_system?.RequestWarps();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<Button Name="GhostBarButton" Text="{Loc 'ghost-target-window-ghostbar'}" />
<!-- CorvaxGoob - Ghost Bar -->
<Button Name="ThunderdomeButton" Text="{Loc thunderdome-ghost-button-default}" />
<!-- CorvaxGoob - Возвращение в лобби -->
<Button Name="GhostGoLobbyButton" Text="{Loc ghost-go-lobby-button}" />
</BoxContainer>
</widgets:GhostGui>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public sealed partial class GhostGui : UIWidget
public event Action? GhostRolesPressed;
public event Action? GhostBarPressed; // CorvaxGoob-GhostBar
public event Action? ThunderdomePressed; // Goobstation - Thunderdome
public event Action? GhostGoLobbyPressed; // CorvaxGoob-GoLobby
private int _prevNumberRoles;

public GhostGui()
Expand All @@ -38,6 +39,7 @@ public GhostGui()
GhostRolesButton.OnPressed += _ => GhostRolesButton.StyleClasses.Remove(StyleClass.Negative);
GhostBarButton.OnPressed += _ => GhostBarPressed?.Invoke(); // CorvaxGoob-GhostBar
ThunderdomeButton.OnPressed += _ => ThunderdomePressed?.Invoke(); // Goobstation - Thunderdome
GhostGoLobbyButton.OnPressed += _ => GhostGoLobbyPressed?.Invoke(); // CorvaxGoob-GOlobby
}

public void Hide()
Expand All @@ -47,14 +49,15 @@ public void Hide()
Visible = false;
}

// Ghoob edit && CorvaxGoob edit : GhostBar
public void Update(int? roles, bool? canReturnToBody, bool? canEnterGhostBar = true, bool? canTakeGhostRoles = true)
// Ghoob edit && CorvaxGoob edit : GhostBar and GhostGoLobby
public void Update(int? roles, bool? canReturnToBody, bool? canEnterGhostBar = true, bool? canTakeGhostRoles = true, bool? canGoLobby = true)
{
ReturnToBodyButton.Disabled = !canReturnToBody ?? true;
GhostBarButton.Disabled = !canEnterGhostBar ?? true; // CorvaxGoob-GhostBar
// Goobstation start
GhostRolesButton.Disabled = !canTakeGhostRoles ?? true;
// Goobstation end
GhostGoLobbyButton.Visible = canGoLobby ?? true; // CorvaxGoob-GoLobby

if (roles != null)
{
Expand Down
15 changes: 15 additions & 0 deletions Content.Client/_CorvaxGoob/Ghost/GhostGoLobbyConfirmWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'ghost-go-lobby-confirm-title'}"
Resizable="False">
<BoxContainer Orientation="Vertical" VerticalExpand="True" SetWidth="420">
<RichTextLabel Name="WarningLabel" Margin="20 10 20 10"/>
<BoxContainer HorizontalExpand="True" HorizontalAlignment="Center">
<Button Name="ContinueButton"
Text="{Loc 'ghost-go-lobby-confirm-continue'}"
SetWidth="150"
Margin="0 10 0 10"/>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Content.Client.UserInterface.Controls;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Utility;

namespace Content.Client._CorvaxGoob.Ghost;

[GenerateTypedNameReferences]
public sealed partial class GhostGoLobbyConfirmWindow : FancyWindow
{
public event Action? ContinuePressed;

public GhostGoLobbyConfirmWindow()
{
RobustXamlLoader.Load(this);

WarningLabel.SetMessage(FormattedMessage.FromMarkupPermissive(Loc.GetString("ghost-go-lobby-confirm")));

ContinueButton.OnPressed += _ =>
{
ContinuePressed?.Invoke();
Close();
};
}
}
9 changes: 8 additions & 1 deletion Content.Server/GameTicking/GameTicker.Player.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

using Content.Server._CorvaxGoob.Events; // CorvaxGoob-GoLobby
using Content.Corvax.Interfaces.Server;
using Content.Shared.Administration;
using Content.Shared.CCVar;
Expand All @@ -26,6 +27,7 @@ public sealed partial class GameTicker
private void InitializePlayer()
{
_playerManager.PlayerStatusChanged += PlayerStatusChanged;
SubscribeLocalEvent<GhostJoinLobbyRequestEvent>(OnGhostJoinLobbyRequest); // CorvaxGoob-GoLobby
}

private async void PlayerStatusChanged(object? sender, SessionStatusEventArgs args)
Expand Down Expand Up @@ -210,7 +212,7 @@ public void PlayerJoinGame(ICommonSession session, bool silent = false)
RaiseNetworkEvent(new TickerJoinGameEvent(), session.Channel);
}

private void PlayerJoinLobby(ICommonSession session)
private void PlayerJoinLobby(ICommonSession session)
{
_playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay;
_db.AddRoundPlayers(RoundId, session.UserId);
Expand All @@ -222,6 +224,11 @@ private void PlayerJoinLobby(ICommonSession session)
RaiseLocalEvent(new PlayerJoinedLobbyEvent(session));
}

private void OnGhostJoinLobbyRequest(GhostJoinLobbyRequestEvent ev) // CorvaxGoob-GoLobby
{
PlayerJoinLobby(ev.Session);
}

private void ReqWindowAttentionAll()
{
RaiseNetworkEvent(new RequestWindowAttentionEvent());
Expand Down
9 changes: 9 additions & 0 deletions Content.Server/GameTicking/GameTicker.Spawning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ private void SpawnPlayer(ICommonSession player,
if (DummyTicker)
return;

// CorvaxGoob-GoLobby-start
var selectedSlot = _ghostGoLobby.GetSelectedSlot(player.UserId);
if (!_ghostGoLobby.CanUseCharacter(player.UserId, selectedSlot))
{
_chatManager.DispatchServerMessage(player,Loc.GetString("ghost-go-lobby-used"));
return;
}
// CorvaxGoob-GoLobby-end

if (station == EntityUid.Invalid)
{
var stations = GetSpawnableStations();
Expand Down
4 changes: 3 additions & 1 deletion Content.Server/GameTicking/GameTicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Content.Server.Chat.Systems;
using Content.Server.Database;
using Content.Server.Ghost;
using Content.Server._CorvaxGoob.Ghost;
using Content.Server.Maps;
using Content.Server.Players.PlayTimeTracking;
using Content.Server.Preferences.Managers;
Expand Down Expand Up @@ -55,6 +56,7 @@ public sealed partial class GameTicker : SharedGameTicker
[Dependency] private readonly MapLoaderSystem _loader = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly GhostSystem _ghost = default!;
[Dependency] private readonly GhostGoLobbySystem _ghostGoLobby = default!; // CorvaxGoob-GoLobby
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly PlayTimeTrackingSystem _playTimeTrackings = default!;
[Dependency] private readonly PvsOverrideSystem _pvsOverride = default!;
Expand Down Expand Up @@ -136,4 +138,4 @@ public override void Update(float frameTime)
UpdateGameRules();
}
}
}
}
13 changes: 13 additions & 0 deletions Content.Server/_CorvaxGoob/Events/GhostJoinLobbyRequestEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Robust.Shared.Player;

namespace Content.Server._CorvaxGoob.Events;

public sealed class GhostJoinLobbyRequestEvent : EntityEventArgs
{
public readonly ICommonSession Session;

public GhostJoinLobbyRequestEvent(ICommonSession session)
{
Session = session;
}
}
105 changes: 105 additions & 0 deletions Content.Server/_CorvaxGoob/Ghost/GhostGoLobbySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Content.Server._CorvaxGoob.Events;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Mind;
using Content.Server.Players.PlayTimeTracking;
using Content.Server.Preferences.Managers;
using Content.Shared._CorvaxGoob.CCCVars;
using Content.Shared._CorvaxGoob.Events;
using Content.Shared.GameTicking;
using Content.Shared.Ghost;
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Popups;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;

namespace Content.Server._CorvaxGoob.Ghost;

public sealed class GhostGoLobbySystem : EntitySystem
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly PlayTimeTrackingManager _playTime = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IServerPreferencesManager _prefsManager = default!;

private bool _enabled;
private TimeSpan _requiredPlaytime;
private TimeSpan _deathTime;

private readonly Dictionary<NetUserId, HashSet<int>> _usedCharacterSlots = new();

public int GetSelectedSlot(NetUserId userId)
{
return _prefsManager.GetPreferences(userId).SelectedCharacterIndex;
}

public bool CanUseCharacter(NetUserId userId, int characterSlot)
{
return !_usedCharacterSlots.TryGetValue(userId, out var slots) || !slots.Contains(characterSlot);
}

public override void Initialize()
{
SubscribeNetworkEvent<GhostGoLobbyEvent>(OnGhostGoLobby);
SubscribeLocalEvent<GameRunLevelChangedEvent>(OnRunLevelChanged);

Subs.CVar(_cfg, CCCVars.GhostGoLobbyEnabled, value => _enabled = value, true);
Subs.CVar(_cfg, CCCVars.GhostGoLobbyTimeHours, value => _requiredPlaytime = TimeSpan.FromHours(value), true);
Subs.CVar(_cfg, CCCVars.GhostGoLobbyDeathTimeMinutes, value => _deathTime = TimeSpan.FromMinutes(value), true);
}

private void OnRunLevelChanged(GameRunLevelChangedEvent ev)
{
if (ev.New == GameRunLevel.PreRoundLobby)
_usedCharacterSlots.Clear();
}

private void OnGhostGoLobby(GhostGoLobbyEvent msg, EntitySessionEventArgs args)
{
if (args.SenderSession.AttachedEntity is not { Valid: true } attached)
return;

TryGhostGoLobby(attached, args.SenderSession);
}

private void TryGhostGoLobby(EntityUid uid, ICommonSession session)
{
if (!_enabled)
return;

if (_playTime.TryGetTrackerTime(session, PlayTimeTrackingShared.TrackerOverall, out var all)
&& all.Value < _requiredPlaytime)
{
var remaining = (int) Math.Ceiling((_requiredPlaytime - all.Value).TotalHours);
_popup.PopupEntity(Loc.GetString("ghost-go-lobby-playtime", ("hours", remaining)), uid, uid);
return;
}

if (!TryComp<GhostComponent>(uid, out var ghost))
return;

var timeSinceDeath = _timing.RealTime - ghost.TimeOfDeath;
if (timeSinceDeath < _deathTime)
{
var remaining = (int) Math.Ceiling((_deathTime - timeSinceDeath).TotalMinutes);
_popup.PopupEntity(Loc.GetString("ghost-go-lobby-deathtime", ("minutes", remaining)), uid, uid);
return;
}

var slot = GetSelectedSlot(session.UserId);
if (!_usedCharacterSlots.TryGetValue(session.UserId, out var slots))
_usedCharacterSlots[session.UserId] = slots = new HashSet<int>();

slots.Add(slot);

_mind.WipeMind(session);

RaiseLocalEvent(new GhostJoinLobbyRequestEvent(session));
}
}
Loading
Loading