From 9beaf06897887b41d03e9d888876e2a7bff4b51c Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:45:33 +0000 Subject: [PATCH 1/4] vent critters rework (#2495) * vent critters rework * change pests timer to 15 * nullspace check and loggy * OH * 15 -> 30 seconds --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Components/VentCrittersRuleComponent.cs | 25 ++++++ .../StationEvents/Events/VentCrittersRule.cs | 86 ++++++++++++++----- .../station-events/events/vent-critters.ftl | 1 + .../Prototypes/DeltaV/GameRules/events.yml | 4 +- Resources/Prototypes/GameRules/events.yml | 9 +- Resources/Prototypes/GameRules/pests.yml | 10 +-- 6 files changed, 101 insertions(+), 34 deletions(-) create mode 100644 Resources/Locale/en-US/deltav/station-events/events/vent-critters.ftl diff --git a/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs b/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs index f280468fc34..a575075632e 100644 --- a/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs +++ b/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs @@ -1,5 +1,6 @@ using Content.Server.StationEvents.Events; using Content.Shared.Storage; +using Robust.Shared.Map; // DeltaV namespace Content.Server.StationEvents.Components; @@ -14,4 +15,28 @@ public sealed partial class VentCrittersRuleComponent : Component /// [DataField("specialEntries")] public List SpecialEntries = new(); + + /// + /// DeltaV: The location of the vent that got picked. + /// + [ViewVariables] + public EntityCoordinates? Location; + + /// + /// DeltaV: Base minimum number of critters to spawn. + /// + [DataField] + public int Min = 2; + + /// + /// DeltaV: Base maximum number of critters to spawn. + /// + [DataField] + public int Max = 3; + + /// + /// DeltaV: Min and max get multiplied by the player count then divided by this. + /// + [DataField] + public int PlayerRatio = 25; } diff --git a/Content.Server/StationEvents/Events/VentCrittersRule.cs b/Content.Server/StationEvents/Events/VentCrittersRule.cs index aee141f2dba..20143a77591 100644 --- a/Content.Server/StationEvents/Events/VentCrittersRule.cs +++ b/Content.Server/StationEvents/Events/VentCrittersRule.cs @@ -1,13 +1,23 @@ -using Content.Server.StationEvents.Components; +using Content.Server.Antag; using Content.Server.GameTicking.Rules.Components; +using Content.Server.Pinpointer; +using Content.Server.StationEvents.Components; using Content.Shared.GameTicking.Components; using Content.Shared.Station.Components; using Content.Shared.Storage; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Random; namespace Content.Server.StationEvents.Events; +/// +/// DeltaV: Reworked vent critters to spawn a number of mobs at a single telegraphed location. +/// This gives players time to run away and let sec do their job. +/// +/// +/// This entire file is rewritten, ignore upstream changes. +/// public sealed class VentCrittersRule : StationEventSystem { /* @@ -15,45 +25,75 @@ public sealed class VentCrittersRule : StationEventSystem _locations = new(); + + protected override void Added(EntityUid uid, VentCrittersRuleComponent comp, GameRuleComponent gameRule, GameRuleAddedEvent args) + { + PickLocation(comp); + if (comp.Location is not {} coords) { + ForceEndSelf(uid, gameRule); return; } - var locations = EntityQueryEnumerator(); - var validLocations = new List(); - while (locations.MoveNext(out _, out _, out var transform)) + var mapCoords = _transform.ToMapCoordinates(coords); + if (!_navMap.TryGetNearestBeacon(mapCoords, out var beacon, out _)) + return; + + var nearest = beacon?.Comp?.Text!; + Comp(uid).StartAnnouncement = Loc.GetString("station-event-vent-creatures-start-announcement-deltav", ("location", nearest)); + + base.Added(uid, comp, gameRule, args); + } + + protected override void Ended(EntityUid uid, VentCrittersRuleComponent comp, GameRuleComponent gameRule, GameRuleEndedEvent args) + { + base.Ended(uid, comp, gameRule, args); + + if (comp.Location is not {} coords) + return; + + var players = _antag.GetTotalPlayerCount(_player.Sessions); + var min = comp.Min * players / comp.PlayerRatio; + var max = comp.Max * players / comp.PlayerRatio; + var count = Math.Max(RobustRandom.Next(min, max), 1); + for (int i = 0; i < count; i++) { - if (CompOrNull(transform.GridUid)?.Station == station) + foreach (var spawn in EntitySpawnCollection.GetSpawns(comp.Entries, RobustRandom)) { - validLocations.Add(transform.Coordinates); - foreach (var spawn in EntitySpawnCollection.GetSpawns(component.Entries, RobustRandom)) - { - Spawn(spawn, transform.Coordinates); - } + Spawn(spawn, coords); } } - if (component.SpecialEntries.Count == 0 || validLocations.Count == 0) - { + if (comp.SpecialEntries.Count == 0) return; - } // guaranteed spawn - var specialEntry = RobustRandom.Pick(component.SpecialEntries); - var specialSpawn = RobustRandom.Pick(validLocations); - Spawn(specialEntry.PrototypeId, specialSpawn); + var specialEntry = RobustRandom.Pick(comp.SpecialEntries); + Spawn(specialEntry.PrototypeId, coords); + } - foreach (var location in validLocations) + private void PickLocation(VentCrittersRuleComponent comp) + { + if (!TryGetRandomStation(out var station)) + return; + + var locations = EntityQueryEnumerator(); + _locations.Clear(); + while (locations.MoveNext(out var uid, out _, out var transform)) { - foreach (var spawn in EntitySpawnCollection.GetSpawns(component.SpecialEntries, RobustRandom)) + if (CompOrNull(transform.GridUid)?.Station == station) { - Spawn(spawn, location); + _locations.Add(transform.Coordinates); } } + + if (_locations.Count > 0) + comp.Location = RobustRandom.Pick(_locations); } } diff --git a/Resources/Locale/en-US/deltav/station-events/events/vent-critters.ftl b/Resources/Locale/en-US/deltav/station-events/events/vent-critters.ftl new file mode 100644 index 00000000000..046b0ca7126 --- /dev/null +++ b/Resources/Locale/en-US/deltav/station-events/events/vent-critters.ftl @@ -0,0 +1 @@ +station-event-vent-creatures-start-announcement-deltav = Attention. A large influx of unknown life forms has been detected in ventilation systems near {$location}. All personnel must vacate the area immediately. diff --git a/Resources/Prototypes/DeltaV/GameRules/events.yml b/Resources/Prototypes/DeltaV/GameRules/events.yml index 45a6a1d0237..94217ab589a 100644 --- a/Resources/Prototypes/DeltaV/GameRules/events.yml +++ b/Resources/Prototypes/DeltaV/GameRules/events.yml @@ -45,7 +45,7 @@ earliestStart: 45 minimumPlayers: 20 weight: 1 - duration: 60 + duration: 30 - type: PrecognitionResult message: psionic-power-precognition-xeno-vents-result-message - type: VentCrittersRule @@ -75,7 +75,7 @@ earliestStart: 15 minimumPlayers: 15 weight: 4 - duration: 60 + duration: 30 - type: PrecognitionResult message: psionic-power-precognition-mothroach-spawn-result-message - type: VentCrittersRule diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index b22bc621c80..849a9418be8 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -389,7 +389,7 @@ earliestStart: 20 minimumPlayers: 15 weight: 5 - duration: 60 + duration: 30 # DeltaV: was 60, used as a delay now - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-slimes-spawn-result-message - type: VentCrittersRule @@ -412,7 +412,7 @@ earliestStart: 20 minimumPlayers: 15 weight: 5 - duration: 60 + duration: 30 # DeltaV: was 60, used as a delay now - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-snake-spawn-result-message - type: VentCrittersRule @@ -435,7 +435,7 @@ earliestStart: 20 minimumPlayers: 15 weight: 5 - duration: 60 + duration: 30 # DeltaV: was 60, used as a delay now - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-spider-spawn-result-message - type: VentCrittersRule @@ -454,10 +454,11 @@ earliestStart: 45 # DeltaV - was 20 minimumPlayers: 30 # DeltaV - was 20 weight: 1 # DeltaV - was 1.5 - duration: 60 + duration: 30 # DeltaV: was 60, used as a delay now - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-spider-clown-spawn-result-message - type: VentCrittersRule + playerRatio: 35 # DeltaV: Clown spiders are very robust entries: - id: MobClownSpider prob: 0.03 # DeltaV - was 0.05 diff --git a/Resources/Prototypes/GameRules/pests.yml b/Resources/Prototypes/GameRules/pests.yml index 0bc1e582e37..8ddde7e1a61 100644 --- a/Resources/Prototypes/GameRules/pests.yml +++ b/Resources/Prototypes/GameRules/pests.yml @@ -27,7 +27,7 @@ path: /Audio/Announcements/attention.ogg earliestStart: 15 weight: 6 - duration: 50 + duration: 30 # DeltaV: was 50, used as a delay now - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-mouse-migration-result-message - type: VentCrittersRule @@ -52,7 +52,7 @@ path: /Audio/Announcements/attention.ogg earliestStart: 15 weight: 6 - duration: 50 + duration: 30 # DeltaV: was 50, used as a delay now minimumPlayers: 30 # Hopefully this is enough for the Rat King's potential Army (it was not, raised from 15 -> 30) - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-king-rat-migration-result-message @@ -79,7 +79,7 @@ startAudio: path: /Audio/Announcements/attention.ogg weight: 6 - duration: 50 + duration: 30 # DeltaV: was 50, used as a delay now - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-cockroach-migration-result-message - type: VentCrittersRule @@ -98,7 +98,7 @@ startAudio: path: /Audio/Announcements/attention.ogg weight: 6 - duration: 50 + duration: 30 # DeltaV: was 50, used as a delay now - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-snail-migration-result-message - type: VentCrittersRule @@ -120,7 +120,7 @@ path: /Audio/Announcements/attention.ogg earliestStart: 15 weight: 6 - duration: 50 + duration: 30 # DeltaV: was 50, used as a delay now minimumPlayers: 30 - type: PrecognitionResult # DeltaV - Precogniton message: psionic-power-precognition-snail-migration-result-message From 08b0fa572bbf8d1a2e1ed988aa2e25e6b5e6d00d Mon Sep 17 00:00:00 2001 From: Delta-V bot <135767721+DeltaV-Bot@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:45:52 +0100 Subject: [PATCH 2/4] Automatic changelog update --- Resources/Changelog/DeltaVChangelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/DeltaVChangelog.yml b/Resources/Changelog/DeltaVChangelog.yml index cdbf76a776d..322e931cb51 100644 --- a/Resources/Changelog/DeltaVChangelog.yml +++ b/Resources/Changelog/DeltaVChangelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Adrian16199 - changes: - - message: Clown hardsuit is craftable once again. - type: Tweak - id: 313 - time: '2024-04-12T14:10:59.0000000+00:00' - url: https://github.com/DeltaV-Station/Delta-v/pull/1083 - author: pissdemon changes: - message: Gumballs and lollipops now come in 32 awesome flavors! Try them all! @@ -3832,3 +3825,11 @@ id: 812 time: '2024-12-22T20:30:24.0000000+00:00' url: https://github.com/DeltaV-Station/Delta-v/pull/2506 +- author: deltanedas + changes: + - message: Reworked vent critters, now after a 30 second delay all the mobs spawn + from 1 vent from the announcement. + type: Tweak + id: 813 + time: '2024-12-23T10:45:34.0000000+00:00' + url: https://github.com/DeltaV-Station/Delta-v/pull/2495 From 69db4ca0d391b32ea6025baa623dee407c5f94fc Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:46:05 +0000 Subject: [PATCH 3/4] cleanup more stuff (#2481) * ICEE cleanup * full cleanup of precognition --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Psionics/PrecognitionPowerSystem.cs | 105 ++++++++++-------- .../NextEvent/NextEventComponent.cs | 4 +- .../BasicStationEventSchedulerSystem.cs | 17 +-- .../StationEvents/EventManagerSystem.cs | 74 ++++-------- .../RampingStationEventSchedulerSystem.cs | 15 +-- .../Weapons/Ranged/Systems/GunSystem.cs | 7 +- .../Psionics/PrecognitionPowerComponent.cs | 8 +- .../Psionics/PrecognitionResultComponent.cs | 7 +- Content.Shared/DeltaV/Psionics/Events.cs | 10 ++ Content.Shared/Nyanotrasen/Psionics/Events.cs | 49 ++------ .../Locale/en-US/deltav/abilities/psionic.ftl | 6 +- .../Entities/Structures/Machines/lathe.yml | 1 - Resources/Prototypes/GameRules/events.yml | 2 +- 13 files changed, 138 insertions(+), 167 deletions(-) create mode 100644 Content.Shared/DeltaV/Psionics/Events.cs diff --git a/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs b/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs index 23fe9d7e3eb..60d574192e1 100644 --- a/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs +++ b/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Abilities.Psionics; using Content.Shared.Actions.Events; using Content.Shared.Actions; +using Content.Shared.Chat; using Content.Shared.DoAfter; using Content.Shared.Eye.Blinding.Components; using Content.Shared.Popups; @@ -22,32 +23,38 @@ namespace Content.Server.Abilities.Psionics; public sealed class PrecognitionPowerSystem : EntitySystem { - [Dependency] private readonly DoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly DoAfterSystem _doAfter = default!; [Dependency] private readonly GameTicker _gameTicker = default!; [Dependency] private readonly MindSystem _mind = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SharedPopupSystem _popups = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!; [Dependency] private readonly StatusEffectsSystem _statusEffects = default!; [Dependency] private readonly IChatManager _chat = default!; [Dependency] private readonly IComponentFactory _factory = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IRobustRandom _random = default!; + /// + /// A map between game rule prototypes and their results to give. + /// + public Dictionary Results = new(); + public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnPowerUsed); SubscribeLocalEvent(OnDoAfter); + SubscribeLocalEvent(OnPrototypesReloaded); } private void OnMapInit(Entity ent, ref MapInitEvent args) { - ent.Comp.AllResults = GetAllPrecognitionResults(); _actions.AddAction(ent, ref ent.Comp.PrecognitionActionEntity, ent.Comp.PrecognitionActionId); _actions.StartUseDelay(ent.Comp.PrecognitionActionEntity); if (TryComp(ent, out var psionic) && psionic.PsionicAbility == null) @@ -66,7 +73,7 @@ private void OnShutdown(EntityUid uid, PrecognitionPowerComponent component, Com private void OnPowerUsed(EntityUid uid, PrecognitionPowerComponent component, PrecognitionPowerActionEvent args) { - var ev = new PrecognitionDoAfterEvent(_gameTiming.CurTime); + var ev = new PrecognitionDoAfterEvent(); var doAfterArgs = new DoAfterArgs(EntityManager, uid, component.UseDelay, ev, uid) { BreakOnDamage = true @@ -76,7 +83,7 @@ private void OnPowerUsed(EntityUid uid, PrecognitionPowerComponent component, Pr _statusEffects.TryAddStatusEffect(uid, "TemporaryBlindness", component.UseDelay, true); _statusEffects.TryAddStatusEffect(uid, "SlowedDown", component.UseDelay, true); - _doAfterSystem.TryStartDoAfter(doAfterArgs, out var doAfterId); + _doAfter.TryStartDoAfter(doAfterArgs, out var doAfterId); component.DoAfter = doAfterId; var player = _audio.PlayGlobal(component.VisionSound, Filter.Entities(uid), true); @@ -104,7 +111,7 @@ private void OnDoAfter(EntityUid uid, PrecognitionPowerComponent component, Prec _statusEffects.TryRemoveStatusEffect(uid, "TemporaryBlindness"); _statusEffects.TryRemoveStatusEffect(uid, "SlowedDown"); - _popups.PopupEntity( + _popup.PopupEntity( Loc.GetString("psionic-power-precognition-failure-by-damage"), uid, uid, @@ -121,33 +128,31 @@ private void OnDoAfter(EntityUid uid, PrecognitionPowerComponent component, Prec // Determines the window that will be looked at for events, avoiding events that are too close or too far to be useful. var minDetectWindow = TimeSpan.FromSeconds(30); var maxDetectWindow = TimeSpan.FromMinutes(10); - string? message = null; if (!_mind.TryGetMind(uid, out _, out var mindComponent) || mindComponent.Session == null) return; - var nextEvent = (FindEarliestNextEvent(minDetectWindow, maxDetectWindow)); - if (nextEvent == null) // A special message given if there is no event within the time window. - message = "psionic-power-precognition-no-event-result-message"; - - if (nextEvent != null && nextEvent.NextEventId != null) - message = GetResultMessage(nextEvent.NextEventId, component); + var nextEvent = FindEarliestNextEvent(minDetectWindow, maxDetectWindow); + LocId? message = nextEvent?.NextEventId is {} nextEventId + ? GetResultMessage(nextEventId) + // A special message given if there is no event within the time window. + : "psionic-power-precognition-no-event-result-message"; if (_random.Prob(component.RandomResultChance)) // This will replace the proper result message with a random one occasionaly to simulate some unreliablity. message = GetRandomResult(); - if (string.IsNullOrEmpty(message)) // If there is no message to send don't bother trying to send it. + if (message is not {} locId) // If there is no message to send don't bother trying to send it. return; // Send a message describing the vision they see - message = Loc.GetString(message); - _chat.ChatMessageToOne(Shared.Chat.ChatChannel.Server, - message, - Loc.GetString("chat-manager-server-wrap-message", ("message", message)), - uid, - false, - mindComponent.Session.Channel, - Color.PaleVioletRed); + var msg = Loc.GetString(locId); + _chat.ChatMessageToOne(ChatChannel.Server, + msg, + Loc.GetString("chat-manager-server-wrap-message", ("message", message)), + uid, + false, + mindComponent.Session.Channel, + Color.PaleVioletRed); component.DoAfter = null; } @@ -156,37 +161,37 @@ private void OnDoAfter(EntityUid uid, PrecognitionPowerComponent component, Prec /// Gets the precognition result message corosponding to the passed event id. /// /// message string corosponding to the event id passed - private string GetResultMessage(EntProtoId? eventId, PrecognitionPowerComponent component) + private LocId GetResultMessage(EntProtoId eventId) { - foreach (var (eventProto, precognitionResult) in component.AllResults) + if (!Results.TryGetValue(eventId, out var result)) { - if (eventProto.ID == eventId && precognitionResult != null) - return precognitionResult.Message; + Log.Error($"Prototype {eventId} does not have an associated precognitionResult!"); + return string.Empty; } - Log.Error($"Prototype {eventId} does not have an associated precognitionResult!"); - return string.Empty; + + return result.Message; } /// /// - /// The localized string of a weighted randomly chosen precognition result - public string? GetRandomResult() + /// The locale message id of a weighted randomly chosen precognition result + public LocId? GetRandomResult() { - var precognitionResults = GetAllPrecognitionResults(); - var sumOfWeights = 0; - foreach (var precognitionResult in precognitionResults.Values) - sumOfWeights += (int)precognitionResult.Weight; + // funny weighted random + var sumOfWeights = 0f; + foreach (var precognitionResult in Results.Values) + sumOfWeights += precognitionResult.Weight; - sumOfWeights = _random.Next(sumOfWeights); - foreach (var precognitionResult in precognitionResults.Values) + sumOfWeights = (float) _random.Next((double) sumOfWeights); + foreach (var precognitionResult in Results.Values) { - sumOfWeights -= (int)precognitionResult.Weight; + sumOfWeights -= precognitionResult.Weight; - if (sumOfWeights <= 0) + if (sumOfWeights <= 0f) return precognitionResult.Message; } - Log.Error("Result was not found after weighted pick process!"); + Log.Error("Precognition result was not found after weighted pick process!"); return null; } @@ -208,15 +213,25 @@ private string GetResultMessage(EntProtoId? eventId, PrecognitionPowerComponent && nextEventComponent.NextEventTime < _gameTicker.RoundDuration() + maxDetectWindow && earliestNextEvent == null || nextEventComponent.NextEventTime < earliestNextEventTime) + { earliestNextEvent ??= nextEventComponent; + } } return earliestNextEvent; } - public Dictionary GetAllPrecognitionResults() + private void OnPrototypesReloaded(PrototypesReloadedEventArgs args) { - var allEvents = new Dictionary(); - foreach (var prototype in _prototype.EnumeratePrototypes()) + if (!args.WasModified()) + return; + + CachePrecognitionResults(); + } + + private void CachePrecognitionResults() + { + Results.Clear(); + foreach (var prototype in _proto.EnumeratePrototypes()) { if (prototype.Abstract) continue; @@ -224,9 +239,7 @@ public Dictionary GetAllPrecogniti if (!prototype.TryGetComponent(out var precognitionResult, _factory)) continue; - allEvents.Add(prototype, precognitionResult); + Results.Add(prototype.ID, precognitionResult); } - - return allEvents; } } diff --git a/Content.Server/DeltaV/StationEvents/NextEvent/NextEventComponent.cs b/Content.Server/DeltaV/StationEvents/NextEvent/NextEventComponent.cs index 78fa5a2f067..944a440eab1 100644 --- a/Content.Server/DeltaV/StationEvents/NextEvent/NextEventComponent.cs +++ b/Content.Server/DeltaV/StationEvents/NextEvent/NextEventComponent.cs @@ -1,8 +1,10 @@ using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Server.DeltaV.StationEvents.NextEvent; [RegisterComponent, Access(typeof(NextEventSystem))] +[AutoGenerateComponentPause] public sealed partial class NextEventComponent : Component { /// @@ -14,6 +16,6 @@ public sealed partial class NextEventComponent : Component /// /// Round time of the scheduler's next station event. /// - [DataField] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] public TimeSpan NextEventTime; } diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index b3fbea035ae..ada862092e4 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -36,15 +36,14 @@ protected override void Started(EntityUid uid, BasicStationEventSchedulerCompone // A little starting variance so schedulers dont all proc at once. component.TimeUntilNextEvent = RobustRandom.NextFloat(component.MinimumTimeUntilFirstEvent, component.MinimumTimeUntilFirstEvent + 120); - // DeltaV - end init NextEventComp + // Begin DeltaV Additions: init NextEventComp if (TryComp(uid, out var nextEventComponent) - && _event.TryGenerateRandomEvent(component.ScheduledGameRules, out string? firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent)) - && firstEvent != null) + && _event.TryGenerateRandomEvent(component.ScheduledGameRules, TimeSpan.FromSeconds(component.TimeUntilNextEvent)) is {} firstEvent) { _chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", firstEvent), ("seconds", (int)component.TimeUntilNextEvent))); _next.UpdateNextEvent(nextEventComponent, firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent)); } - // DeltaV - end init NextEventComp + // End DeltaV Additions } protected override void Ended(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule, @@ -73,22 +72,24 @@ public override void Update(float frameTime) continue; } - // DeltaV events using NextEventComponent + // Begin DeltaV Additions: events using NextEventComponent if (TryComp(uid, out var nextEventComponent)) // If there is a nextEventComponent use the stashed event instead of running it directly. { ResetTimer(eventScheduler); // Time needs to be reset ahead of time since we need to chose events based on the next time it will run. var nextEventTime = _timing.CurTime + TimeSpan.FromSeconds(eventScheduler.TimeUntilNextEvent); - if (!_event.TryGenerateRandomEvent(eventScheduler.ScheduledGameRules, out string? generatedEvent, nextEventTime)) + if (_event.TryGenerateRandomEvent(eventScheduler.ScheduledGameRules, nextEventTime) is not {} generatedEvent) continue; + _chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", generatedEvent), ("seconds", (int)eventScheduler.TimeUntilNextEvent))); // Cycle the stashed event with the new generated event and time. - string? storedEvent = _next.UpdateNextEvent(nextEventComponent, generatedEvent, nextEventTime); + var storedEvent = _next.UpdateNextEvent(nextEventComponent, generatedEvent, nextEventTime); if (string.IsNullOrEmpty(storedEvent)) //If there was no stored event don't try to run it. continue; + GameTicker.AddGameRule(storedEvent); continue; } - // DeltaV end events using NextEventComponent + // End DeltaV Additions: events using NextEventComponent _event.RunRandomEvent(eventScheduler.ScheduledGameRules); ResetTimer(eventScheduler); diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index eadacdbbadf..b865b9a34c9 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -11,8 +11,7 @@ using Content.Shared.EntityTable.EntitySelectors; using Content.Shared.EntityTable; using Content.Server.Psionics.Glimmer; // DeltaV -using Content.Shared.Psionics.Glimmer; -using System.Diagnostics.CodeAnalysis; // DeltaV +using Content.Shared.Psionics.Glimmer; // DeltaV namespace Content.Server.StationEvents; @@ -60,67 +59,51 @@ public void RunRandomEvent() /// public void RunRandomEvent(EntityTableSelector limitedEventsTable) { - if (TryGenerateRandomEvent(limitedEventsTable, out string? randomLimitedEvent)) // DeltaV - seperated into own method + if (TryGenerateRandomEvent(limitedEventsTable) is {} randomLimitedEvent) // DeltaV - seperated into own method GameTicker.AddGameRule(randomLimitedEvent); } - // DeltaV - overloaded for backwards compatiblity - public bool TryGenerateRandomEvent(EntityTableSelector limitedEventsTable, [NotNullWhen(true)] out string? randomLimitedEvent) - { - return TryGenerateRandomEvent(limitedEventsTable, out randomLimitedEvent, null); - } - // DeltaV - end overloaded for backwards compatiblity - - // DeltaV - separate event generation method /// - /// Returns a random event from the list of events given that can be run at a given time. + /// DeltaV: Returns a random event from the list of events given that can be run at a given time. /// /// The list of events that can be chosen. - /// Generated event /// The time to use for checking time restrictions. Uses current time if null. - /// - public bool TryGenerateRandomEvent(EntityTableSelector limitedEventsTable, [NotNullWhen(true)] out string? randomLimitedEvent, TimeSpan? eventRunTime) + /// The generated event id + /// + /// This is taken out of RunRandomEvent. + /// + public EntProtoId? TryGenerateRandomEvent(EntityTableSelector limitedEventsTable, TimeSpan? eventRunTime = null) { - randomLimitedEvent = null; if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents, eventRunTime)) { Log.Warning("Provided event table could not build dict!"); - return false; + return null; } - randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the GetSpawns to do it, but that will be a major rebalancing fuck. - // DeltaV - randomLimitedEvent declared by enclosing method + var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the GetSpawns to do it, but that will be a major rebalancing fuck. if (randomLimitedEvent == null) { Log.Warning("The selected random event is null!"); - return false; + return null; } - if (!_prototype.TryIndex(randomLimitedEvent, out _)) + if (!_prototype.HasIndex(randomLimitedEvent)) { Log.Warning("A requested event is not available!"); - return false; + return null; } - return true; + return randomLimitedEvent; } - // DeltaV - end separate event generation method - - // DeltaV - overloaded for backwards compatiblity - public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary limitedEvents) - { - return TryBuildLimitedEvents(limitedEventsTable, out limitedEvents, null); - } - // DeltaV - end overloaded for backwards compatiblity /// /// Returns true if the provided EntityTableSelector gives at least one prototype with a StationEvent comp. /// - public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary limitedEvents, TimeSpan? eventRunTime) // DeltaV - Add a time overide + public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary limitedEvents, TimeSpan? eventRunTime = null) // DeltaV - Add a time overide { limitedEvents = new Dictionary(); // DeltaV - Overide time for stashing events - var availableEvents = AvailableEvents(eventRunTime); // handles the player counts and individual event restrictions + var availableEvents = AvailableEvents(eventRunTime: eventRunTime); // handles the player counts and individual event restrictions if (availableEvents.Count == 0) { Log.Warning("No events were available to run!"); @@ -206,16 +189,6 @@ public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Di return null; } - // DeltaV - overloaded for backwards compatiblity - public Dictionary AvailableEvents( - bool ignoreEarliestStart = false, - int? playerCountOverride = null, - TimeSpan? currentTimeOverride = null) - { - return AvailableEvents(null, ignoreEarliestStart, playerCountOverride, currentTimeOverride); - } - // DeltaV - end overloaded for backwards compatiblity - /// /// Gets the events that have met their player count, time-until start, etc. /// @@ -223,20 +196,17 @@ public Dictionary AvailableEvents( /// Override for round time, if using this to simulate events rather than in an actual round. /// public Dictionary AvailableEvents( - TimeSpan? eventRunTime, bool ignoreEarliestStart = false, int? playerCountOverride = null, - TimeSpan? currentTimeOverride = null) - { + TimeSpan? currentTimeOverride = null, + TimeSpan? eventRunTime = null) // DeltaV + { var playerCount = playerCountOverride ?? _playerManager.PlayerCount; // playerCount does a lock so we'll just keep the variable here - var currentTime = currentTimeOverride ?? ( - (!ignoreEarliestStart - ? eventRunTime // DeltaV - Use eventRunTime instead of RoundDuration if provided - ?? GameTicker.RoundDuration() - : TimeSpan.Zero) - ); + var currentTime = currentTimeOverride ?? (!ignoreEarliestStart + ? eventRunTime ?? GameTicker.RoundDuration() // DeltaV - Use eventRunTime instead of RoundDuration if provided + : TimeSpan.Zero); var result = new Dictionary(); diff --git a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs index 67c8f9fb5d4..9585b3b824a 100644 --- a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs @@ -43,15 +43,14 @@ protected override void Started(EntityUid uid, RampingStationEventSchedulerCompo PickNextEventTime(uid, component); - // DeltaV - end init NextEventComp + // Begin DeltaV Additions: init NextEventComp if (TryComp(uid, out var nextEventComponent) - && _event.TryGenerateRandomEvent(component.ScheduledGameRules, out string? firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent)) - && firstEvent != null) + && _event.TryGenerateRandomEvent(component.ScheduledGameRules, TimeSpan.FromSeconds(component.TimeUntilNextEvent)) is {} firstEvent) { _chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", firstEvent), ("seconds", (int)component.TimeUntilNextEvent))); _next.UpdateNextEvent(nextEventComponent, firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent)); } - // DeltaV - end init NextEventComp + // End DeltaV Additions: init NextEventComp } public override void Update(float frameTime) @@ -73,22 +72,24 @@ public override void Update(float frameTime) continue; } - // DeltaV events using NextEventComponent + // Begin DeltaV Additions: events using NextEventComponent if (TryComp(uid, out var nextEventComponent)) // If there is a nextEventComponent use the stashed event instead of running it directly. { PickNextEventTime(uid, scheduler); var nextEventTime = _timing.CurTime + TimeSpan.FromSeconds(scheduler.TimeUntilNextEvent); - if (!_event.TryGenerateRandomEvent(scheduler.ScheduledGameRules, out string? generatedEvent, nextEventTime) || generatedEvent == null) + if (_event.TryGenerateRandomEvent(scheduler.ScheduledGameRules, nextEventTime) is not {} generatedEvent) continue; + _chatManager.SendAdminAlert(Loc.GetString("station-event-system-run-event-delayed", ("eventName", generatedEvent), ("seconds", (int)scheduler.TimeUntilNextEvent))); // Cycle the stashed event with the new generated event and time. string? storedEvent = _next.UpdateNextEvent(nextEventComponent, generatedEvent, nextEventTime); if (string.IsNullOrEmpty(storedEvent)) //If there was no stored event don't try to run it. continue; + GameTicker.AddGameRule(storedEvent); continue; } - // DeltaV end events using NextEventComponent + // End DeltaV Additions: events using NextEventComponent PickNextEventTime(uid, scheduler); _event.RunRandomEvent(scheduler.ScheduledGameRules); diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index 011a17c018f..7555e682b66 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -2,7 +2,7 @@ using System.Numerics; using Content.Server.Cargo.Systems; using Content.Server.Power.EntitySystems; -using Content.Server.Stunnable; +using Content.Server.Stunnable; // DeltaV using Content.Server.Temperature.Systems; // DeltaV Heat Change system using Content.Server.Weapons.Ranged.Components; using Content.Shared.Damage; @@ -220,9 +220,10 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid? if (hitscan.StaminaDamage > 0f) _stamina.TakeProjectileStaminaDamage(hitEntity, hitscan.StaminaDamage, source: user); // DeltaV - Cope with hitscan not being an entity - // DeltaV: Changes the target's temperature by this amount when hit + // Begin DeltaV Additions: Changes the target's temperature by this amount when hit if (hitscan.HeatChange != 0f) - _temperature.ChangeHeat(hitEntity, hitscan.HeatChange, true); + _temperature.ChangeHeat(hitEntity, hitscan.HeatChange, true); + // End DeltaV Additions var dmg = hitscan.Damage; diff --git a/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionPowerComponent.cs b/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionPowerComponent.cs index 26ecf48f7aa..6f5f36086c6 100644 --- a/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionPowerComponent.cs +++ b/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionPowerComponent.cs @@ -1,17 +1,15 @@ using Content.Shared.DoAfter; using Robust.Shared.Audio; +using Robust.Shared.GameStates; using Robust.Shared.Prototypes; namespace Content.Shared.Abilities.Psionics; -[RegisterComponent] +[RegisterComponent, NetworkedComponent] public sealed partial class PrecognitionPowerComponent : Component { [DataField] - public float RandomResultChance = 0.2F; - - [DataField] - public Dictionary AllResults; + public float RandomResultChance = 0.2f; [DataField] public SoundSpecifier VisionSound = new SoundPathSpecifier("/Audio/DeltaV/Effects/clang2.ogg"); diff --git a/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionResultComponent.cs b/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionResultComponent.cs index 34a8979f4fa..059ada567ff 100644 --- a/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionResultComponent.cs +++ b/Content.Shared/DeltaV/Abilities/Psionics/PrecognitionResultComponent.cs @@ -1,10 +1,13 @@ namespace Content.Shared.Abilities.Psionics; +/// +/// Component added to game rules that lets it be shown with the precognition psionic power. +/// [RegisterComponent] public sealed partial class PrecognitionResultComponent : Component { - [DataField] - public string Message = default!; + [DataField(required: true)] + public LocId Message; [DataField] public float Weight = 1; diff --git a/Content.Shared/DeltaV/Psionics/Events.cs b/Content.Shared/DeltaV/Psionics/Events.cs new file mode 100644 index 00000000000..ce5b680a118 --- /dev/null +++ b/Content.Shared/DeltaV/Psionics/Events.cs @@ -0,0 +1,10 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.Psionics.Events; + +[Serializable, NetSerializable] +public sealed partial class PrecognitionDoAfterEvent : SimpleDoAfterEvent; + +[Serializable, NetSerializable] +public sealed partial class GlimmerWispDrainDoAfterEvent : SimpleDoAfterEvent; diff --git a/Content.Shared/Nyanotrasen/Psionics/Events.cs b/Content.Shared/Nyanotrasen/Psionics/Events.cs index 3837e3d0ee9..c54dc48de8d 100644 --- a/Content.Shared/Nyanotrasen/Psionics/Events.cs +++ b/Content.Shared/Nyanotrasen/Psionics/Events.cs @@ -1,48 +1,21 @@ -using Robust.Shared.Serialization; using Content.Shared.DoAfter; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; -namespace Content.Shared.Psionics.Events -{ - [Serializable, NetSerializable] - public sealed partial class PsionicRegenerationDoAfterEvent : DoAfterEvent - { - [DataField("startedAt", required: true)] - public TimeSpan StartedAt; - - private PsionicRegenerationDoAfterEvent() - { - } - - public PsionicRegenerationDoAfterEvent(TimeSpan startedAt) - { - StartedAt = startedAt; - } +namespace Content.Shared.Psionics.Events; - public override DoAfterEvent Clone() => this; - } +[Serializable, NetSerializable] +public sealed partial class PsionicRegenerationDoAfterEvent : SimpleDoAfterEvent +{ + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan StartedAt; - // DeltaV Precognition - [Serializable, NetSerializable] - public sealed partial class PrecognitionDoAfterEvent : SimpleDoAfterEvent + private PsionicRegenerationDoAfterEvent() { - [DataField("startedAt", required: true)] - public TimeSpan StartedAt; - - private PrecognitionDoAfterEvent() - { - } - - public PrecognitionDoAfterEvent(TimeSpan startedAt) - { - StartedAt = startedAt; - } - - public override DoAfterEvent Clone() => this; } - // DeltaV End Precognition - [Serializable, NetSerializable] - public sealed partial class GlimmerWispDrainDoAfterEvent : SimpleDoAfterEvent + public PsionicRegenerationDoAfterEvent(TimeSpan startedAt) { + StartedAt = startedAt; } } diff --git a/Resources/Locale/en-US/deltav/abilities/psionic.ftl b/Resources/Locale/en-US/deltav/abilities/psionic.ftl index 677c0b19def..8d6ab750383 100644 --- a/Resources/Locale/en-US/deltav/abilities/psionic.ftl +++ b/Resources/Locale/en-US/deltav/abilities/psionic.ftl @@ -9,7 +9,7 @@ psionic-power-precognition-fugitive-result-message = You see hounds around every psionic-power-precognition-syndicate-recruiter-result-message = You see someone cutting ties on a chain-link fence and reforging its now disparate parts under a new oath of blood. psionic-power-precognition-synthesis-specialist-result-message = You smell a dangerous mixture of chemicals in the air; the distant sound of a small plasma engine roars to life. psionic-power-precognition-cargo-gifts-base-result-message = You see a vision of yourself, gathered for a time-old tradition of receiving gifts. You didn't ask for these, but you must pretend to appreciate nonetheless. -psionic-power-precognition-anomoly-spawn-result-message = You attempt to look forward, but the future is distorted by a blast of noöspheric energies converging on a single point. +psionic-power-precognition-anomaly-spawn-result-message = You attempt to look forward, but the future is distorted by a blast of noöspheric energies converging on a single point. psionic-power-precognition-bluespace-artifact-result-message = You attempt to look forward but are blinded by noöspheric energies coalescing into an object beyond comprehension. psionic-power-precognition-bluespace-locker-result-message = You attempt to look forward, but the noösphere seems distorted by a constantly shifting bluespace energy. psionic-power-precognition-breaker-flip-result-message = You see torches snuff around you and keepers rekindling the lost flames. @@ -18,14 +18,14 @@ psionic-power-precognition-clerical-error-result-message = You see faces you onc psionic-power-precognition-closet-skeleton-result-message = You hear a crackling laugh echo and clinking bones in the dusty recesses of the station. psionic-power-precognition-dragon-spawn-result-message = Reality around you bulges and breaks as a great beast cries for war. The smell of salty sea and blood fills the air. psionic-power-precognition-ninja-spawn-result-message = You see a vision of shadows brought to life, hounds of war howling their cries as they chase it through dark corners of the station. -psionic-power-precognition-revenant-spawn-result-message = The shadows around you grow threefold taller and threefold darker. Something lurks within them, a predator stalking you in the darkness. +psionic-power-precognition-revenant-spawn-result-message = The shadows around you grow threefold taller and threefold darker. Something lurks within them, a predator stalking you in the darkness. psionic-power-precognition-gas-leak-result-message = For but a moment, it feels as if you cannot breathe. With a blink, everything returns to normal. psionic-power-precognition-kudzu-growth-result-message = Leaves and vines pierce through the dusty tiles of the station, crawling about your ankles, trying to drag you down with them. psionic-power-precognition-power-grid-check-result-message = You see torches snuff around you only to spontaneously ignite moments later. psionic-power-precognition-solar-flare-result-message = The stars look beautiful tonight, shrinking and growing and shooting great bolts like fireworks into the sky. psionic-power-precognition-vent-clog-result-message = You smell something horrific on the artificial breeze of the station, for a moment your eyes fill with fog. When you blink it away, the smell is gone. psionic-power-precognition-slimes-spawn-result-message = Something lurks deep within the darkest corners of the station, crying for blood. Soft squelches and bubbling howls accompany the call. -psionic-power-precognition-snake-spawn-result-message = Something lurks deep within the darkest corners of the station, crying for blood. The sounds of hissing growls accompany the call. +psionic-power-precognition-snake-spawn-result-message = Something lurks deep within the darkest corners of the station, crying for blood. The sounds of hissing growls accompany the call. psionic-power-precognition-spider-spawn-result-message = Something lurks deep within the darkest corners of the station, crying for blood. A symphony of clicks and chitters accompanies the call. psionic-power-precognition-spider-clown-spawn-result-message = Something lurks deep within the darkest corners of the station, crying for blood. An unholy mass of honks accompanies the call. psionic-power-precognition-zombie-outbreak-result-message = Your coworker lies on the cold ground before you; skull ripped open, eyes blank. You think you see the body twitch. diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index c368a5c69c5..e1f7f29be3b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -448,7 +448,6 @@ - MiniSyringe - WeaponColdCannon - WeaponBeamCannon - # End DeltaV additions - type: entity diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 849a9418be8..b345120c10f 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -84,7 +84,7 @@ weight: 12 # DeltaV - was 8 duration: 35 - type: PrecognitionResult # DeltaV - Precogniton - message: psionic-power-precognition-anomoly-spawn-result-message + message: psionic-power-precognition-anomaly-spawn-result-message - type: AnomalySpawnRule - type: entity From 3204e46c1007bebdef1f92823b39896e34c53bdd Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:34:18 +0000 Subject: [PATCH 4/4] fix vent critters rarely spawning anything (#2517) * update events to use entity tables * change Entries to Table in the component * update rule and add log --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Psionics/PrecognitionPowerSystem.cs | 2 +- .../Components/VentCrittersRuleComponent.cs | 12 +++- .../StationEvents/Events/VentCrittersRule.cs | 5 +- .../Prototypes/DeltaV/GameRules/events.yml | 40 +++++------ Resources/Prototypes/GameRules/events.yml | 34 ++++----- Resources/Prototypes/GameRules/pests.yml | 71 +++++++++---------- 6 files changed, 81 insertions(+), 83 deletions(-) diff --git a/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs b/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs index 60d574192e1..79a56066e31 100644 --- a/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs +++ b/Content.Server/DeltaV/Abilities/Psionics/PrecognitionPowerSystem.cs @@ -148,7 +148,7 @@ private void OnDoAfter(EntityUid uid, PrecognitionPowerComponent component, Prec var msg = Loc.GetString(locId); _chat.ChatMessageToOne(ChatChannel.Server, msg, - Loc.GetString("chat-manager-server-wrap-message", ("message", message)), + Loc.GetString("chat-manager-server-wrap-message", ("message", msg)), uid, false, mindComponent.Session.Channel, diff --git a/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs b/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs index a575075632e..7ec6e3d54ac 100644 --- a/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs +++ b/Content.Server/StationEvents/Components/VentCrittersRuleComponent.cs @@ -1,4 +1,5 @@ using Content.Server.StationEvents.Events; +using Content.Shared.EntityTable.EntitySelectors; using Content.Shared.Storage; using Robust.Shared.Map; // DeltaV @@ -7,8 +8,15 @@ namespace Content.Server.StationEvents.Components; [RegisterComponent, Access(typeof(VentCrittersRule))] public sealed partial class VentCrittersRuleComponent : Component { - [DataField("entries")] - public List Entries = new(); + // DeltaV: Replaced by Table + //[DataField("entries")] + //public List Entries = new(); + + /// + /// DeltaV: Table of possible entities to spawn. + /// + [DataField(required: true)] + public EntityTableSelector Table = default!; /// /// At least one special entry is guaranteed to spawn diff --git a/Content.Server/StationEvents/Events/VentCrittersRule.cs b/Content.Server/StationEvents/Events/VentCrittersRule.cs index 20143a77591..90c0cc262dc 100644 --- a/Content.Server/StationEvents/Events/VentCrittersRule.cs +++ b/Content.Server/StationEvents/Events/VentCrittersRule.cs @@ -2,6 +2,7 @@ using Content.Server.GameTicking.Rules.Components; using Content.Server.Pinpointer; using Content.Server.StationEvents.Components; +using Content.Shared.EntityTable; using Content.Shared.GameTicking.Components; using Content.Shared.Station.Components; using Content.Shared.Storage; @@ -26,6 +27,7 @@ public sealed class VentCrittersRule : StationEventSystem