Files
wwdpublic/Content.Server/Spawners/EntitySystems/ContainerSpawnPointSystem.cs
sleepyyapril 67ea5d8c3e Station AI Features and Fixes (Also General Fixes) (#1525)
<!--
This is a semi-strict format, you can add/remove sections as needed but
the order/format should be kept the same
Remove these comments before submitting
-->

# Description

<!--
Explain this PR in as much detail as applicable

Some example prompts to consider:
How might this affect the game? The codebase?
What might be some alternatives to this?
How/Who does this benefit/hurt [the game/codebase]?
-->

Check the changelog for the full list.

---

# Changelog

<!--
You can add an author after the `🆑` to change the name that appears
in the changelog (ex: `🆑 Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->

🆑
- add: Added Holopads (unmapped)
- add: Intellicards are now useful for removing/adding a Station AI's
brain.
- add: Added the Communications Console to Station AI actions.
- add: AI now has a warp point.
- add: Added more things for the AI to press.
- add: More AI laws have been added.
- fix: Fixed the mail system
- fix: Fixed AI actions
- fix: Fixed invalid spawns for station AI breaking and ruining your
ability to play it.
- fix: The Station AI's name will now properly send in "arrived to the
station" announcements.
- fix: Changed the CPR sound to simply not loop until fixed.
- fix: Fixed unlocalized messages being sent for the random sentience
event.

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Co-authored-by: Zachary Higgs <compgeek223@gmail.com>
Co-authored-by: MendaxxDev <153332064+MendaxxDev@users.noreply.github.com>
Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

(cherry picked from commit 3e8a7d9b00e19e160321eb81d69a884189dfa4e6)
2025-01-15 00:12:29 +03:00

109 lines
4.4 KiB
C#

using Content.Server.GameTicking;
using Content.Server.Spawners.Components;
using Content.Server.Station.Systems;
using Content.Shared.Preferences;
using Content.Shared.Roles;
using Robust.Server.Containers;
using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Spawners.EntitySystems;
public sealed class ContainerSpawnPointSystem : EntitySystem
{
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PlayerSpawningEvent>(HandlePlayerSpawning, before: [ typeof(SpawnPointSystem) ]);
}
public void HandlePlayerSpawning(PlayerSpawningEvent args)
{
if (args.SpawnResult != null)
return;
JobPrototype? jobProto = null;
// If it's just a spawn pref check if it's for cryo (silly).
if (args.HumanoidCharacterProfile?.SpawnPriority != SpawnPriorityPreference.Cryosleep &&
(!_proto.TryIndex(args.Job?.Prototype, out jobProto) || jobProto.JobEntity == null))
return;
if (jobProto == null && !_proto.TryIndex(args.Job?.Prototype, out jobProto))
return;
var query = EntityQueryEnumerator<ContainerSpawnPointComponent, ContainerManagerComponent, TransformComponent>();
var possibleContainers = new List<Entity<ContainerSpawnPointComponent, ContainerManagerComponent, TransformComponent>>();
while (query.MoveNext(out var uid, out var spawnPoint, out var container, out var xform))
{
if (args.Station != null && _station.GetOwningStation(uid, xform) != args.Station)
continue;
// DeltaV - Custom override for override spawnpoints, only used for prisoners currently. This shouldn't run for any other jobs
if (args.DesiredSpawnPointType == SpawnPointType.Job
&& spawnPoint.SpawnType == SpawnPointType.Job
&& args.Job is not null
&& spawnPoint.Job is not ""
&& spawnPoint.Job == args.Job.Prototype)
{
possibleContainers.Add((uid, spawnPoint, container, xform));
continue;
}
// If it's unset, then we allow it to be used for both roundstart and midround joins
if (spawnPoint.SpawnType == SpawnPointType.Unset)
{
// make sure we also check the job here for various reasons.
if (spawnPoint.Job == null || spawnPoint.Job == args.Job?.Prototype)
possibleContainers.Add((uid, spawnPoint, container, xform));
continue;
}
if (_gameTicker.RunLevel == GameRunLevel.InRound
&& spawnPoint.SpawnType == SpawnPointType.LateJoin
&& jobProto.JobEntity == null)
possibleContainers.Add((uid, spawnPoint, container, xform));
if (_gameTicker.RunLevel != GameRunLevel.InRound &&
spawnPoint.SpawnType == SpawnPointType.Job &&
(args.Job == null || spawnPoint.Job == args.Job.Prototype))
possibleContainers.Add((uid, spawnPoint, container, xform));
}
if (possibleContainers.Count == 0)
return;
// we just need some default coords so we can spawn the player entity.
var baseCoords = possibleContainers[0].Comp3.Coordinates;
args.SpawnResult = _stationSpawning.SpawnPlayerMob(
baseCoords,
args.Job,
args.HumanoidCharacterProfile,
args.Station);
_random.Shuffle(possibleContainers);
foreach (var (uid, spawnPoint, manager, xform) in possibleContainers)
{
if (!_container.TryGetContainer(uid, spawnPoint.ContainerId, out var container, manager))
continue;
if (!_container.Insert(args.SpawnResult.Value, container, containerXform: xform))
continue;
return;
}
Del(args.SpawnResult);
args.SpawnResult = null;
}
}