Skip to content

Commit

Permalink
purr! mreow
Browse files Browse the repository at this point in the history
  • Loading branch information
AwareFoxy committed Nov 5, 2024
1 parent 417f9dc commit 2c6a911
Show file tree
Hide file tree
Showing 19 changed files with 673 additions and 114 deletions.
4 changes: 3 additions & 1 deletion Content.Client/LateJoin/LateJoinGui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ private void RebuildUI()
if (!_gameTicker.DisallowedLateJoin && _gameTicker.StationNames.Count == 0)
Logger.Warning("No stations exist, nothing to display in late-join GUI");

foreach (var (id, name) in _gameTicker.StationNames)
foreach (var (id, name) in _gameTicker.StationNames
.OrderBy(x=> x.Value.Contains("Central Command") ? 1 : -1) //backmen: centcom
)
{
var jobList = new BoxContainer
{
Expand Down
373 changes: 373 additions & 0 deletions Content.Server/Backmen/Arrivals/CentcommSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,373 @@
using System.Numerics;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Events;
using Content.Server.Maps;
using Content.Server.Popups;
using Content.Server.Power.EntitySystems;
using Content.Server.Salvage.Expeditions;
using Content.Server.Shuttles;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared.Backmen.Abilities;
using Content.Shared._FishStation.CentComm;
using Content.Shared.Cargo.Components;
using Content.Shared.CCVar;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
using Content.Shared.GameTicking;
using Content.Shared.Random;
using Content.Shared.Random.Helpers;
using Content.Shared.Shuttles.Components;
using Content.Shared.Whitelist;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;

namespace Content.Server.Backmen.Arrivals;

public sealed class FtlCentComAnnounce : EntityEventArgs
{
public Entity<ShuttleComponent> Source { get; set; }
}

public sealed class CentcommSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly ShuttleSystem _shuttleSystem = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly ShuttleSystem _shuttle = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly MetaDataSystem _metaDataSystem = default!;
private ISawmill _sawmill = default!;


public EntityUid CentComGrid { get; private set; } = EntityUid.Invalid;
public MapId CentComMap { get; private set; } = MapId.Nullspace;
public EntityUid CentComMapUid { get; private set; } = EntityUid.Invalid;
public float ShuttleIndex { get; set; } = 0;

private WeightedRandomPrototype _stationCentComMapPool = default!;

public override void Initialize()
{
base.Initialize();
_sawmill = Logger.GetSawmill("centcom");
SubscribeLocalEvent<ActorComponent, CentcomFtlAction>(OnFtlActionUsed);
SubscribeLocalEvent<PreGameMapLoad>(OnPreGameMapLoad, after: new[] { typeof(StationSystem) });
SubscribeLocalEvent<RoundStartingEvent>(OnCentComInit, before: new[] { typeof(EmergencyShuttleSystem) });
SubscribeLocalEvent<RoundEndedEvent>(OnCentComEndRound);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnCleanup);
SubscribeLocalEvent<ShuttleConsoleComponent, GotEmaggedEvent>(OnShuttleConsoleEmaged);
SubscribeLocalEvent<FTLCompletedEvent>(OnFTLCompleted);
SubscribeLocalEvent<FtlCentComAnnounce>(OnFtlAnnounce);
_cfg.OnValueChanged(CCVars.GridFill, OnGridFillChange);

_stationCentComMapPool = _prototypeManager.Index<WeightedRandomPrototype>(StationCentComMapPool);
}

private void OnCentComEndRound(RoundEndedEvent ev)
{
if (CentComMapUid.IsValid() && _shuttleSystem.TryAddFTLDestination(CentComMap, true, out var ftl))
{
EnableFtl((CentComMapUid, ftl));
}
}

private void OnFtlAnnounce(FtlCentComAnnounce ev)
{
if (!CentComGrid.IsValid())
{
return; // not loaded centcom
}

var transformQuery = EntityQueryEnumerator<TransformComponent, IFFConsoleComponent>();

var shuttleName = "Неизвестный";

while (transformQuery.MoveNext(out var owner, out var transformComponent, out var iff))
{
if (transformComponent.GridUid != ev.Source)
{
continue;
}

var f = iff.AllowedFlags;
if (f.HasFlag(IFFFlags.Hide))
{
continue;
}

var name = MetaData(ev.Source).EntityName;
if (string.IsNullOrWhiteSpace(name))
{
continue;
}

shuttleName = name;
}

if (_gameTicker.RunLevel != GameRunLevel.InRound)
{
return; // Do not announce out of round
}

_chat.DispatchStationAnnouncement(CentComGrid,
$"Внимание! Радары обнаружили {shuttleName} шаттл, входящий в космическое пространство объекта Центрального Командования!",
"Радар", colorOverride: Color.Crimson);
}

private void OnFTLCompleted(ref FTLCompletedEvent ev)
{
if (!CentComGrid.IsValid())
{
return; // not loaded centcom
}

if (ev.MapUid != _mapManager.GetMapEntityId(CentComMap))
{
return; // not centcom
}

if (!TryComp<ShuttleComponent>(ev.Entity, out var shuttleComponent))
{
return;
}

QueueLocalEvent(new FtlCentComAnnounce
{
Source = (ev.Entity, shuttleComponent!)
});
}

private static readonly SoundSpecifier SparkSound = new SoundCollectionSpecifier("sparks");

[ValidatePrototypeId<EntityPrototype>]
private const string StationShuttleConsole = "ComputerShuttle";

private void OnShuttleConsoleEmaged(Entity<ShuttleConsoleComponent> ent, ref GotEmaggedEvent args)
{
if (Prototype(ent)?.ID != StationShuttleConsole)
{
return;
}

if (!this.IsPowered(ent, EntityManager))
return;

var shuttle = Transform(ent).GridUid;
if (!HasComp<ShuttleComponent>(shuttle))
return;

if (!(HasComp<CargoShuttleComponent>(shuttle) || HasComp<SalvageShuttleComponent>(shuttle)))
return;

_audio.PlayPvs(SparkSound, ent);
_popupSystem.PopupEntity(Loc.GetString("shuttle-console-component-upgrade-emag-requirement"), ent);
args.Handled = true;
EnsureComp<AllowFtlToCentComComponent>(shuttle.Value); // для обновления консоли нужно чтобы компонент был до вызыва RefreshShuttleConsoles
_console.RefreshShuttleConsoles();
}

private void OnGridFillChange(bool obj)
{
if (obj)
{
EnsureCentcom(true);
}
}

private void OnCleanup(RoundRestartCleanupEvent ev)
{
_sawmill.Info("OnCleanup");
QueueDel(CentComGrid);
CentComGrid = EntityUid.Invalid;

if (_mapManager.MapExists(CentComMap))
_mapManager.DeleteMap(CentComMap);

CentComMap = MapId.Nullspace;
CentComMapUid = EntityUid.Invalid;
ShuttleIndex = 0;
}

[ValidatePrototypeId<WeightedRandomPrototype>]
private const string StationCentComMapPool = "DefaultCentcomPool";

[ValidatePrototypeId<GameMapPrototype>]
private const string StationCentComMapDefault = "centcommcorvax";


public void EnsureCentcom(bool force = false)
{
if (!_cfg.GetCVar(CCVars.GridFill) && !force)
{
return;
}

_sawmill.Info("EnsureCentcom");
if (CentComGrid.IsValid())
{
return;
}

_sawmill.Info("Start load centcom");

if (CentComMap == MapId.Nullspace)
{
CentComMap = _mapManager.CreateMap();
}

CentComMapUid = _mapManager.GetMapEntityId(CentComMap);

var mapId = _stationCentComMapPool.Pick();
if (!_prototypeManager.TryIndex<GameMapPrototype>(mapId, out var map))
{
mapId = StationCentComMapDefault;
map = _prototypeManager.Index<GameMapPrototype>(StationCentComMapDefault);
}


var ent = _gameTicker.LoadGameMap(
map, CentComMap, new MapLoadOptions()
{
LoadMap = false
}, "Central Command").FirstOrNull(HasComp<BecomesStationComponent>);

_metaDataSystem.SetEntityName(_mapManager.GetMapEntityId(CentComMap), "CentCom");

if (ent != null)
{
CentComGrid = ent.Value;
if (_shuttle.TryAddFTLDestination(CentComMap, true, out var ftl))
{
DisableFtl((CentComMapUid,ftl));
}
}
else
{
_sawmill.Warning("No CentComm map found, skipping setup.");
return;
}

var q = EntityQueryEnumerator<StationCentcommComponent>();
while (q.MoveNext(out var station))
{
station.MapEntity = CentComMapUid;
station.Entity = CentComGrid;
station.ShuttleIndex = ShuttleIndex;
}
}

// ReSharper disable once MemberCanBePrivate.Global
public void DisableFtl(Entity<FTLDestinationComponent?> ent)
{
var d = new EntityWhitelist();
d.RequireAll = false;
d.Components = new[] { "AllowFtlToCentCom" };
d.UpdateRegistrations();
_shuttle.SetFTLWhitelist(ent, d);
}

public void EnableFtl(Entity<FTLDestinationComponent?> ent)
{
_shuttle.SetFTLWhitelist(ent, null);
}

private void OnCentComInit(RoundStartingEvent ev)
{
{
return;
}
}

private void OnPreGameMapLoad(PreGameMapLoad ev)
{
if (!_stationCentComMapPool.Weights.ContainsKey(ev.GameMap.ID))
{
if(ev.GameMap.ID != StationCentComMapDefault) // fallback
return;
}

ev.Options.Offset = new Vector2(0, 0);
}

private void OnFtlActionUsed(EntityUid uid, ActorComponent component, CentcomFtlAction args)
{
var grid = Transform(args.Performer);
if (grid.GridUid == null)
{
return;
}

if (!TryComp<PilotComponent>(args.Performer, out var pilotComponent) || pilotComponent.Console == null)
{
_popup.PopupEntity(Loc.GetString("centcom-ftl-action-no-pilot"), args.Performer, args.Performer);
return;
}

TransformComponent shuttle;

if (TryComp<DroneConsoleComponent>(pilotComponent.Console, out var droneConsoleComponent) &&
droneConsoleComponent.Entity != null)
{
shuttle = Transform(droneConsoleComponent.Entity.Value);
}
else
{
shuttle = grid;
}


if (!TryComp<ShuttleComponent>(shuttle.GridUid, out var comp) || HasComp<FTLComponent>(shuttle.GridUid) || (
HasComp<BecomesStationComponent>(shuttle.GridUid) &&
!(
HasComp<SalvageShuttleComponent>(shuttle.GridUid) ||
HasComp<CargoShuttleComponent>(shuttle.GridUid)
)
))
{
return;
}

var stationUid = _stationSystem.GetStations().FirstOrNull(HasComp<StationCentcommComponent>);

if (!TryComp<StationCentcommComponent>(stationUid, out var centcomm) ||
centcomm.Entity == null || !centcomm.Entity.Value.IsValid() || Deleted(centcomm.Entity))
{
_popup.PopupEntity(Loc.GetString("centcom-ftl-action-no-station"), args.Performer, args.Performer);
return;
}
/*
if (shuttle.MapUid == centcomm.MapEntity)
{
_popup.PopupEntity(Loc.GetString("centcom-ftl-action-at-centcomm"), args.Performer, args.Performer);
return;
}
*/
if (!_shuttleSystem.CanFTL(shuttle.GridUid.Value, out var reason))
{
_popup.PopupEntity(reason, args.Performer, args.Performer);
return;
}

_shuttleSystem.FTLToDock(shuttle.GridUid.Value, comp, centcomm.Entity.Value);
}
}
Loading

0 comments on commit 2c6a911

Please sign in to comment.