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 882d841b24f..f70ce468ab4 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.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/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index b22bc621c80..1d6bebb6963 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