Skip to content

Commit

Permalink
Merge branch 'master' into brain-eat-delay
Browse files Browse the repository at this point in the history
  • Loading branch information
angelofallars authored Jan 16, 2025
2 parents c809316 + 78347d7 commit fd916a7
Show file tree
Hide file tree
Showing 17 changed files with 287 additions and 58 deletions.
123 changes: 81 additions & 42 deletions Content.Server/Shuttles/Systems/ArrivalsSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Linq;
using System.Numerics;
using Content.Server.Administration;
using Content.Server.Chat.Managers;
using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.GameTicking;
Expand All @@ -16,12 +17,13 @@
using Content.Server.Station.Systems;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Damage.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.GameTicking;
using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Components;
using Content.Shared.Parallax.Biomes;
using Content.Shared.Roles;
using Content.Shared.Preferences;
using Content.Shared.Salvage;
using Content.Shared.Shuttles.Components;
using Content.Shared.Tiles;
Expand All @@ -30,6 +32,7 @@
using Robust.Shared.Configuration;
using Robust.Shared.Console;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
Expand All @@ -45,17 +48,20 @@ public sealed class ArrivalsSystem : EntitySystem
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
[Dependency] private readonly IConsoleHost _console = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IChatManager _chat = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
[Dependency] private readonly BiomeSystem _biomes = default!;
[Dependency] private readonly GameTicker _ticker = default!;
[Dependency] private readonly MapLoaderSystem _loader = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly ShuttleSystem _shuttles = default!;
[Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly ActorSystem _actor = default!;

private EntityQuery<PendingClockInComponent> _pendingQuery;
private EntityQuery<ArrivalsBlacklistComponent> _blacklistQuery;
Expand Down Expand Up @@ -87,7 +93,7 @@ public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<PlayerSpawningEvent>(HandlePlayerSpawning, before: new []{ typeof(ContainerSpawnPointSystem), typeof(SpawnPointSystem)});
SubscribeLocalEvent<PlayerSpawningEvent>(HandlePlayerSpawning, before: new []{ typeof(SpawnPointSystem)}, after: new [] { typeof(ContainerSpawnPointSystem)});

SubscribeLocalEvent<StationArrivalsComponent, StationPostInitEvent>(OnStationPostInit);

Expand All @@ -98,6 +104,8 @@ public override void Initialize()
SubscribeLocalEvent<ArrivalsShuttleComponent, FTLStartedEvent>(OnArrivalsFTL);
SubscribeLocalEvent<ArrivalsShuttleComponent, FTLCompletedEvent>(OnArrivalsDocked);

SubscribeLocalEvent<PlayerSpawnCompleteEvent>(SendDirections);

_pendingQuery = GetEntityQuery<PendingClockInComponent>();
_blacklistQuery = GetEntityQuery<ArrivalsBlacklistComponent>();
_mobQuery = GetEntityQuery<MobStateComponent>();
Expand Down Expand Up @@ -263,6 +271,9 @@ private void OnArrivalsFTL(EntityUid shuttleUid, ArrivalsShuttleComponent compon
// The player has successfully left arrivals and is also not on the shuttle. Remove their warp coupon.
RemCompDeferred<PendingClockInComponent>(pUid);
RemCompDeferred<AutoOrientComponent>(pUid);

if (ArrivalsGodmode)
RemCompDeferred<GodmodeComponent>(pUid);
}
}

Expand All @@ -287,16 +298,20 @@ private void OnArrivalsDocked(EntityUid uid, ArrivalsShuttleComponent component,
private void DumpChildren(EntityUid uid, ref FTLStartedEvent args)
{
var toDump = new List<Entity<TransformComponent>>();
DumpChildren(uid, ref args, toDump);
FindDumpChildren(uid, toDump);
foreach (var (ent, xform) in toDump)
{
var rotation = xform.LocalRotation;
_transform.SetCoordinates(ent, new EntityCoordinates(args.FromMapUid!.Value, Vector2.Transform(xform.LocalPosition, args.FTLFrom)));
_transform.SetWorldRotation(ent, args.FromRotation + rotation);
if (_actor.TryGetSession(ent, out var session))
{
_chat.DispatchServerMessage(session!, Loc.GetString("latejoin-arrivals-dumped-from-shuttle"));
}
}
}

private void DumpChildren(EntityUid uid, ref FTLStartedEvent args, List<Entity<TransformComponent>> toDump)
private void FindDumpChildren(EntityUid uid, List<Entity<TransformComponent>> toDump)
{
if (_pendingQuery.HasComponent(uid))
return;
Expand All @@ -312,7 +327,7 @@ private void DumpChildren(EntityUid uid, ref FTLStartedEvent args, List<Entity<T
var children = xform.ChildEnumerator;
while (children.MoveNext(out var child))
{
DumpChildren(child, ref args, toDump);
FindDumpChildren(child, toDump);
}
}

Expand All @@ -321,8 +336,7 @@ public void HandlePlayerSpawning(PlayerSpawningEvent ev)
if (ev.SpawnResult != null)
return;

if (ev.HumanoidCharacterProfile?.SpawnPriority != SpawnPriorityPreference.Arrivals)
return;
// We use arrivals as the default spawn so don't check for job prio.

// Only works on latejoin even if enabled.
if (!Enabled || _ticker.RunLevel != GameRunLevel.InRound)
Expand All @@ -333,39 +347,56 @@ public void HandlePlayerSpawning(PlayerSpawningEvent ev)
&& _protoManager.Index<JobPrototype>(ev.Job.Prototype.Value.Id).AlwaysUseSpawner)
return;


if (!HasComp<StationArrivalsComponent>(ev.Station))
return;

TryGetArrivals(out var arrivals);

if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
{
var mapId = arrivalsXform.MapID;
if (!TryComp(arrivals, out TransformComponent? arrivalsXform))
return;

var points = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
var possiblePositions = new List<EntityCoordinates>();
while (points.MoveNext(out var uid, out var spawnPoint, out var xform))
{
if (spawnPoint.SpawnType != SpawnPointType.LateJoin || xform.MapID != mapId)
continue;
var mapId = arrivalsXform.MapID;

possiblePositions.Add(xform.Coordinates);
}
var points = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
var possiblePositions = new List<EntityCoordinates>();
while (points.MoveNext(out var uid, out var spawnPoint, out var xform))
{
if (spawnPoint.SpawnType != SpawnPointType.LateJoin || xform.MapID != mapId)
continue;

if (possiblePositions.Count > 0)
{
var spawnLoc = _random.Pick(possiblePositions);
ev.SpawnResult = _stationSpawning.SpawnPlayerMob(
spawnLoc,
ev.Job,
ev.HumanoidCharacterProfile,
ev.Station);

EnsureComp<PendingClockInComponent>(ev.SpawnResult.Value);
EnsureComp<AutoOrientComponent>(ev.SpawnResult.Value);
}
possiblePositions.Add(xform.Coordinates);
}

if (possiblePositions.Count <= 0)
return;

var spawnLoc = _random.Pick(possiblePositions);
ev.SpawnResult = _stationSpawning.SpawnPlayerMob(
spawnLoc,
ev.Job,
ev.HumanoidCharacterProfile,
ev.Station);

EnsureComp<PendingClockInComponent>(ev.SpawnResult.Value);
EnsureComp<AutoOrientComponent>(ev.SpawnResult.Value);

// If you're forced to spawn, you're invincible until you leave wherever you were forced to spawn.
if (ArrivalsGodmode)
EnsureComp<GodmodeComponent>(ev.SpawnResult.Value);
}

private void SendDirections(PlayerSpawnCompleteEvent ev)
{
if (!Enabled || !ev.LateJoin || !_pendingQuery.HasComp(ev.Mob))
return;

var arrival = NextShuttleArrival();

var message = arrival is not null
? Loc.GetString("latejoin-arrivals-direction-time", ("time", $"{arrival:mm\\:ss}"))
: Loc.GetString("latejoin-arrivals-direction");

_chat.DispatchServerMessage(ev.Player, message);
}

private bool TryTeleportToMapSpawn(EntityUid player, EntityUid stationId, TransformComponent? transform = null)
Expand All @@ -391,6 +422,10 @@ private bool TryTeleportToMapSpawn(EntityUid player, EntityUid stationId, Transf
{
// Move the player to a random late-join spawnpoint.
_transform.SetCoordinates(player, transform, _random.Pick(possiblePositions));
if (_actor.TryGetSession(player, out var session))
{
_chat.DispatchServerMessage(session!, Loc.GetString("latejoin-arrivals-teleport-to-spawn"));
}
return true;
}

Expand Down Expand Up @@ -436,7 +471,7 @@ public override void Update(float frameTime)
var curTime = _timing.CurTime;
TryGetArrivals(out var arrivals);

if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
if (TryComp(arrivals, out TransformComponent? arrivalsXform))
{
while (query.MoveNext(out var uid, out var comp, out var shuttle, out var xform))
{
Expand All @@ -449,7 +484,7 @@ public override void Update(float frameTime)
if (xform.MapUid != arrivalsXform.MapUid)
{
if (arrivals.IsValid())
_shuttles.FTLToDock(uid, shuttle, arrivals, _cfgManager.GetCVar(CCVars.ArrivalsStartupTime), _cfgManager.GetCVar(CCVars.ArrivalsHyperspaceTime), "DockArrivals");
_shuttles.FTLToDock(uid, shuttle, arrivals);

comp.NextArrivalsTime = _timing.CurTime + TimeSpan.FromSeconds(tripTime);
}
Expand All @@ -459,7 +494,7 @@ public override void Update(float frameTime)
var targetGrid = _station.GetLargestGrid(data);

if (targetGrid != null)
_shuttles.FTLToDock(uid, shuttle, targetGrid.Value, _cfgManager.GetCVar(CCVars.ArrivalsStartupTime), _cfgManager.GetCVar(CCVars.ArrivalsHyperspaceTime), "DockArrivals");
_shuttles.FTLToDock(uid, shuttle, targetGrid.Value);

// The ArrivalsCooldown includes the trip there, so we only need to add the time taken for
// the trip back.
Expand All @@ -483,9 +518,8 @@ private void OnRoundStarting(RoundStartingEvent ev)

private void SetupArrivalsStation()
{
var mapId = _mapManager.CreateMap();
var mapUid = _mapManager.GetMapEntityId(mapId);
_mapManager.AddUninitializedMap(mapId);
var mapUid = _mapSystem.CreateMap(out var mapId, false);
_metaData.SetEntityName(mapUid, Loc.GetString("map-name-terminal"));

if (!_loader.TryLoad(mapId, _cfgManager.GetCVar(CCVars.ArrivalsMap), out var uids))
{
Expand All @@ -504,9 +538,14 @@ private void SetupArrivalsStation()
{
var template = _random.Pick(_arrivalsBiomeOptions);
_biomes.EnsurePlanet(mapUid, _protoManager.Index(template));
var restricted = new RestrictedRangeComponent
{
Range = 32f
};
AddComp(mapUid, restricted);
}

_mapManager.DoMapInitialize(mapId);
_mapSystem.InitializeMap(mapId);

// Handle roundstart stations.
var query = AllEntityQuery<StationArrivalsComponent>();
Expand Down Expand Up @@ -564,10 +603,10 @@ private void SetupShuttle(EntityUid uid, StationArrivalsComponent component)
return;

// Spawn arrivals on a dummy map then dock it to the source.
var dummyMap = _mapManager.CreateMap();
var dummpMapEntity = _mapSystem.CreateMap(out var dummyMapId);

if (TryGetArrivals(out var arrivals) &&
_loader.TryLoad(dummyMap, component.ShuttlePath.ToString(), out var shuttleUids))
_loader.TryLoad(dummyMapId, component.ShuttlePath.ToString(), out var shuttleUids))
{
component.Shuttle = shuttleUids[0];
var shuttleComp = Comp<ShuttleComponent>(component.Shuttle);
Expand All @@ -579,7 +618,7 @@ private void SetupShuttle(EntityUid uid, StationArrivalsComponent component)
}

// Don't start the arrivals shuttle immediately docked so power has a time to stabilise?
var timer = AddComp<TimedDespawnComponent>(_mapManager.GetMapEntityId(dummyMap));
var timer = AddComp<TimedDespawnComponent>(dummpMapEntity);
timer.Lifetime = 15f;
}
}
15 changes: 14 additions & 1 deletion Content.Server/Silicons/StationAi/StationAiSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using Content.Shared.Roles;
using Content.Shared.Silicons.StationAi;
using Content.Shared.StationAi;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Audio;
using Robust.Shared.Map.Components;
using Robust.Shared.Player;
using static Content.Server.Chat.Systems.ChatSystem;
Expand Down Expand Up @@ -87,6 +87,19 @@ public override bool SetWhitelistEnabled(Entity<StationAiWhitelistComponent> ent
return true;
}

public override void AnnounceIntellicardUsage(EntityUid uid, SoundSpecifier? cue = null)
{
if (!TryComp<ActorComponent>(uid, out var actor))
return;

var msg = Loc.GetString("ai-consciousness-download-warning");
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
_chats.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.Channel, colorOverride: Color.Red);

if (cue != null && _mind.TryGetMind(uid, out var mindId, out _))
_roles.MindPlaySound(mindId, cue);
}

private void AnnounceSnip(EntityUid entity)
{
var xform = Transform(entity);
Expand Down
10 changes: 10 additions & 0 deletions Content.Shared/Bed/Cryostorage/CanEnterCryostorageComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;

namespace Content.Shared.Bed.Cryostorage;

/// <summary>
/// Serves as a whitelist that allows an entity with this component to enter cryostorage.
/// It will also require MindContainerComponent.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class CanEnterCryostorageComponent : Component { }
2 changes: 1 addition & 1 deletion Content.Shared/Bed/Cryostorage/SharedCryostorageSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private void OnInsertAttempt(Entity<CryostorageComponent> ent, ref ContainerIsIn
return;
}

if (!TryComp<MindContainerComponent>(args.EntityUid, out var mindContainer))
if (!HasComp<CanEnterCryostorageComponent>(args.EntityUid) || !TryComp<MindContainerComponent>(args.EntityUid, out var mindContainer))
{
args.Cancel();
return;
Expand Down
39 changes: 39 additions & 0 deletions Content.Shared/Intellicard/Components/IntellicardComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;

namespace Content.Shared.Intellicard;

/// <summary>
/// Allows this entity to download the station AI onto an AiHolderComponent.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class IntellicardComponent : Component
{
/// <summary>
/// The duration it takes to download the AI from an AiHolder.
/// </summary>
[DataField, AutoNetworkedField]
public int DownloadTime = 15;

/// <summary>
/// The duration it takes to upload the AI to an AiHolder.
/// </summary>
[DataField, AutoNetworkedField]
public int UploadTime = 3;

/// <summary>
/// The sound that plays for the AI
/// when they are being downloaded
/// </summary>
[DataField, AutoNetworkedField]
public SoundSpecifier? WarningSound = new SoundPathSpecifier("/Audio/Misc/notice2.ogg");

/// <summary>
/// The delay before allowing the warning to play again in seconds.
/// </summary>
[DataField, AutoNetworkedField]
public TimeSpan WarningDelay = TimeSpan.FromSeconds(8);

[ViewVariables]
public TimeSpan NextWarningAllowed = TimeSpan.Zero;
}
Loading

0 comments on commit fd916a7

Please sign in to comment.