Files
wwdpublic/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs
sleepyyapril 61bba20418 Downstream Port (#1509)
# 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
-->

🆑 sleepyyapril, Stop-Signs, Memeji
- add: Changed the Warden suit's capabilities. (Original author:
Stop-Signs)
- add: Repeater, Argenti, and 45 magnum rubber box to Bartender's
loadout.
- add: Red cloak to loadout (Port from Floof PR #390)
- add: Witch Robes to loadout (Port from Floof PR #390)
- add: Sawed-off PKA (Port from Floof PR #390)
- add: The ChemMaster now has 20, 75, and 80 unit options available.
- tweak: Made the ChemMaster wider.
- fix: Ported Frontier fix to mag visuals on specific guns.
- fix: Fixed heirlooms flickering negative mood when the moodlet ended.

---------

Signed-off-by: Stop-Signs <stopsign221@gmail.com>
Signed-off-by: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com>
Co-authored-by: Stop-Signs <stopsign221@gmail.com>
Co-authored-by: FoxxoTrystan <45297731+FoxxoTrystan@users.noreply.github.com>
Co-authored-by: Radezolid <snappednexus@gmail.com>
Co-authored-by: ErhardSteinhauer <65374927+ErhardSteinhauer@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
(cherry picked from commit a9f7fe8e9a337d13ef34ec643064432d0cec2b60)
2025-01-20 21:01:27 +03:00

154 lines
5.4 KiB
C#

using System.Numerics;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Spawners.Components;
using Content.Shared.EntityTable;
using Content.Shared.GameTicking.Components;
using JetBrains.Annotations;
using Robust.Shared.Map;
using Robust.Shared.Random;
namespace Content.Server.Spawners.EntitySystems
{
[UsedImplicitly]
public sealed class ConditionalSpawnerSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly GameTicker _ticker = default!;
[Dependency] private readonly EntityTableSystem _entityTable = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GameRuleStartedEvent>(OnRuleStarted);
SubscribeLocalEvent<ConditionalSpawnerComponent, MapInitEvent>(OnCondSpawnMapInit);
SubscribeLocalEvent<RandomSpawnerComponent, MapInitEvent>(OnRandSpawnMapInit);
SubscribeLocalEvent<EntityTableSpawnerComponent, MapInitEvent>(OnEntityTableSpawnMapInit);
}
private void OnCondSpawnMapInit(EntityUid uid, ConditionalSpawnerComponent component, MapInitEvent args)
{
TrySpawn(uid, component);
}
private void OnRandSpawnMapInit(EntityUid uid, RandomSpawnerComponent component, MapInitEvent args)
{
Spawn(uid, component);
if (component.DeleteSpawnerAfterSpawn)
QueueDel(uid);
}
private void OnEntityTableSpawnMapInit(Entity<EntityTableSpawnerComponent> ent, ref MapInitEvent args)
{
Spawn(ent);
if (ent.Comp.DeleteSpawnerAfterSpawn && !TerminatingOrDeleted(ent) && Exists(ent))
QueueDel(ent);
}
private void OnRuleStarted(ref GameRuleStartedEvent args)
{
var query = EntityQueryEnumerator<ConditionalSpawnerComponent>();
while (query.MoveNext(out var uid, out var spawner))
{
RuleStarted(uid, spawner, args);
}
}
public void RuleStarted(EntityUid uid, ConditionalSpawnerComponent component, GameRuleStartedEvent obj)
{
if (component.GameRules.Contains(obj.RuleId))
Spawn(uid, component);
}
private void TrySpawn(EntityUid uid, ConditionalSpawnerComponent component)
{
if (component.GameRules.Count == 0)
{
Spawn(uid, component);
return;
}
foreach (var rule in component.GameRules)
{
if (!_ticker.IsGameRuleActive(rule))
continue;
Spawn(uid, component);
return;
}
}
private void Spawn(EntityUid uid, ConditionalSpawnerComponent component)
{
if (component.Chance != 1.0f && !_robustRandom.Prob(component.Chance))
return;
if (component.Prototypes.Count == 0)
{
Log.Warning($"Prototype list in ConditionalSpawnComponent is empty! Entity: {ToPrettyString(uid)}");
return;
}
if (Deleted(uid))
return;
var picked = _robustRandom.Pick(component.Prototypes);
try
{
EntityManager.SpawnEntity(picked, Transform(uid).Coordinates);
}
catch (EntityCreationException e)
{
Log.Warning($"Caught an exception while trying to process a conditional spawner {ToPrettyString(uid)} of type {picked}: {e}");
}
}
private void Spawn(EntityUid uid, RandomSpawnerComponent component)
{
if (component.RarePrototypes.Count > 0 && (component.RareChance == 1.0f || _robustRandom.Prob(component.RareChance)))
{
EntityManager.SpawnEntity(_robustRandom.Pick(component.RarePrototypes), Transform(uid).Coordinates);
return;
}
if (component.Chance != 1.0f && !_robustRandom.Prob(component.Chance))
return;
if (component.Prototypes.Count == 0)
{
Log.Warning($"Prototype list in RandomSpawnerComponent is empty! Entity: {ToPrettyString(uid)}");
return;
}
if (Deleted(uid))
return;
var offset = component.Offset;
var xOffset = _robustRandom.NextFloat(-offset, offset);
var yOffset = _robustRandom.NextFloat(-offset, offset);
var coordinates = Transform(uid).Coordinates.Offset(new Vector2(xOffset, yOffset));
EntityManager.SpawnEntity(_robustRandom.Pick(component.Prototypes), coordinates);
}
private void Spawn(Entity<EntityTableSpawnerComponent> ent)
{
if (TerminatingOrDeleted(ent) || !Exists(ent))
return;
var coords = Transform(ent).Coordinates;
var spawns = _entityTable.GetSpawns(ent.Comp.Table);
foreach (var proto in spawns)
{
var xOffset = _robustRandom.NextFloat(-ent.Comp.Offset, ent.Comp.Offset);
var yOffset = _robustRandom.NextFloat(-ent.Comp.Offset, ent.Comp.Offset);
var trueCoords = coords.Offset(new Vector2(xOffset, yOffset));
Spawn(proto, trueCoords);
}
}
}
}