New psionic ablility: Precognition (#2131)
* TESTING enable events for dev enviroment * Add NextEventComponent * Check for schedulers NextEventComponent * Seperate gernateing event to its own method * Add NextEventSystem and use in BasicStationEventSchedulerSystem * TESTING: Override time and player restrictions * Stash events in NextEventComponent (#1) * Add NextEventComponent * Check for schedulers NextEventComponent * Seperate gernateing event to its own method * Add NextEventSystem and use in BasicStationEventSchedulerSystem * Format code * Add nextEvent time perdiction * Use RunTime instead of float minutes * Bug fixes * Add NextEvent to Ramping and Meteors * Fix timing on BasticStationEvents * initialize NextEventComponent when created * Event scheduler caching (#2) * Check for schedulers NextEventComponent * Seperate gernateing event to its own method * Add NextEventSystem and use in BasicStationEventSchedulerSystem * Format code * Add nextEvent time perdiction * Use RunTime instead of float minutes * Bug fixes * Add NextEvent to Ramping and Meteors * Fix timing on BasticStationEvents * initialize NextEventComponent when created --------- Signed-off-by: SolStar <44028047+ewokswagger@users.noreply.github.com> * Revert "Event scheduler caching (#2)" This reverts commitbf9cd26ed4. * Revert "Merge branch 'seer' into stash-next-event" This reverts commit656ca26173, reversing changes made to36f45be10e. * Revert "Caching next exent" This reverts commit9f1bee4131, reversing changes made to82678d9c18. * Reapply "Event scheduler caching (#2)" This reverts commit82678d9c18. * More merge conflict nonsence * oops * oops 2 * Oops 3 * Precognition Psionic ability (#3) * Precognition ability added * Precog get next event * Get soonest event and display * update prototypes with precog results * Add random * Use Timespan for UseDelay * Damage breaks doafter * typo * fix localization * fix do after * Add effects durring do after * Revert "TESTING enable events for dev enviroment" This reverts commit03453133bd. * Revert testing changes * add deltav comments * Cleaning up! * Move NextEvent to server space * Fix NextEventId init value * Reverted upstream file to block scoped namespace * Add precognitnon result messages * reverting testing changes for real * Add admin alert for upcoming events * Add sound effect * make alert more subtule * extended max window size * fix message mixup * yaml fixes * more yaml fixes * Delta Changes * totaly a yaml error trust * remove unsessesary weights --------- Signed-off-by: SolStar <44028047+ewokswagger@users.noreply.github.com>
This commit is contained in:
parent
6e72bdebb6
commit
d5716a8d41
|
|
@ -0,0 +1,232 @@
|
|||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.DeltaV.StationEvents.NextEvent;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Mind;
|
||||
using Content.Shared.Abilities.Psionics;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Eye.Blinding.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Psionics.Events;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.Stunnable;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Abilities.Psionics;
|
||||
|
||||
public sealed class PrecognitionPowerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = 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 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 IRobustRandom _random = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<PrecognitionPowerComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<PrecognitionPowerComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<PrecognitionPowerComponent, PrecognitionPowerActionEvent>(OnPowerUsed);
|
||||
SubscribeLocalEvent<PrecognitionPowerComponent, PrecognitionDoAfterEvent>(OnDoAfter);
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<PrecognitionPowerComponent> 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<PsionicComponent>(ent, out var psionic) && psionic.PsionicAbility == null)
|
||||
{
|
||||
psionic.PsionicAbility = ent.Comp.PrecognitionActionEntity;
|
||||
psionic.ActivePowers.Add(ent.Comp);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, PrecognitionPowerComponent component, ComponentShutdown args)
|
||||
{
|
||||
_actions.RemoveAction(uid, component.PrecognitionActionEntity);
|
||||
if (TryComp<PsionicComponent>(uid, out var psionic))
|
||||
psionic.ActivePowers.Remove(component);
|
||||
}
|
||||
|
||||
private void OnPowerUsed(EntityUid uid, PrecognitionPowerComponent component, PrecognitionPowerActionEvent args)
|
||||
{
|
||||
var ev = new PrecognitionDoAfterEvent(_gameTiming.CurTime);
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, uid, component.UseDelay, ev, uid)
|
||||
{
|
||||
BreakOnDamage = true
|
||||
};
|
||||
|
||||
// A custom shader for seeing visions would be nice but this will do for now.
|
||||
_statusEffects.TryAddStatusEffect<TemporaryBlindnessComponent>(uid, "TemporaryBlindness", component.UseDelay, true);
|
||||
_statusEffects.TryAddStatusEffect<SlowedDownComponent>(uid, "SlowedDown", component.UseDelay, true);
|
||||
|
||||
_doAfterSystem.TryStartDoAfter(doAfterArgs, out var doAfterId);
|
||||
component.DoAfter = doAfterId;
|
||||
|
||||
var player = _audio.PlayGlobal(component.VisionSound, Filter.Entities(uid), true);
|
||||
if (player != null)
|
||||
component.SoundStream = player.Value.Entity;
|
||||
_psionics.LogPowerUsed(uid, "Precognition");
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upon completion will send a message to the user corrosponding to the next station event to occour.
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="component"></param>
|
||||
/// <param name="args"></param>
|
||||
private void OnDoAfter(EntityUid uid, PrecognitionPowerComponent component, PrecognitionDoAfterEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (args.Cancelled)
|
||||
{
|
||||
// Need to clean up the applied effects in case of cancel and alert the player.
|
||||
component.SoundStream = _audio.Stop(component.SoundStream);
|
||||
_statusEffects.TryRemoveStatusEffect(uid, "TemporaryBlindness");
|
||||
_statusEffects.TryRemoveStatusEffect(uid, "SlowedDown");
|
||||
|
||||
_popups.PopupEntity(
|
||||
Loc.GetString("psionic-power-precognition-failure-by-damage"),
|
||||
uid,
|
||||
uid,
|
||||
PopupType.SmallCaution);
|
||||
|
||||
if (_actions.TryGetActionData(component.PrecognitionActionEntity, out var actionData))
|
||||
// If canceled give a short delay before being able to try again
|
||||
actionData.Cooldown =
|
||||
(_gameTicker.RoundDuration(),
|
||||
_gameTicker.RoundDuration() + TimeSpan.FromSeconds(15));
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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.
|
||||
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);
|
||||
|
||||
component.DoAfter = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the precognition result message corosponding to the passed event id.
|
||||
/// </summary>
|
||||
/// <returns>message string corosponding to the event id passed</returns>
|
||||
private string GetResultMessage(EntProtoId? eventId, PrecognitionPowerComponent component)
|
||||
{
|
||||
foreach (var (eventProto, precognitionResult) in component.AllResults)
|
||||
{
|
||||
if (eventProto.ID == eventId && precognitionResult != null)
|
||||
return precognitionResult.Message;
|
||||
}
|
||||
Log.Error($"Prototype {eventId} does not have an associated precognitionResult!");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <returns>The localized string of a weighted randomly chosen precognition result</returns>
|
||||
public string? GetRandomResult()
|
||||
{
|
||||
var precognitionResults = GetAllPrecognitionResults();
|
||||
var sumOfWeights = 0;
|
||||
foreach (var precognitionResult in precognitionResults.Values)
|
||||
sumOfWeights += (int)precognitionResult.Weight;
|
||||
|
||||
sumOfWeights = _random.Next(sumOfWeights);
|
||||
foreach (var precognitionResult in precognitionResults.Values)
|
||||
{
|
||||
sumOfWeights -= (int)precognitionResult.Weight;
|
||||
|
||||
if (sumOfWeights <= 0)
|
||||
return precognitionResult.Message;
|
||||
}
|
||||
|
||||
Log.Error("Result was not found after weighted pick process!");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the soonest nextEvent to occur within the window.
|
||||
/// </summary>
|
||||
/// <param name="minDetectWindow"></param> The earliest reletive time that will be return a nextEvent
|
||||
/// <param name="maxDetectWindow"></param> The latest reletive latest time that will be return a nextEvent
|
||||
/// <returns>Component for the next event to occour if one exists in the window.</returns>
|
||||
private NextEventComponent? FindEarliestNextEvent(TimeSpan minDetectWindow, TimeSpan maxDetectWindow)
|
||||
{
|
||||
TimeSpan? earliestNextEventTime = null;
|
||||
NextEventComponent? earliestNextEvent = null;
|
||||
var query = EntityQueryEnumerator<NextEventComponent>();
|
||||
while (query.MoveNext(out var nextEventComponent))
|
||||
{
|
||||
// Update if the event is the most recent event that isnt too close or too far from happening to be of use
|
||||
if (nextEventComponent.NextEventTime > _gameTicker.RoundDuration() + minDetectWindow
|
||||
&& nextEventComponent.NextEventTime < _gameTicker.RoundDuration() + maxDetectWindow
|
||||
&& earliestNextEvent == null
|
||||
|| nextEventComponent.NextEventTime < earliestNextEventTime)
|
||||
earliestNextEvent ??= nextEventComponent;
|
||||
}
|
||||
return earliestNextEvent;
|
||||
}
|
||||
|
||||
public Dictionary<EntityPrototype, PrecognitionResultComponent> GetAllPrecognitionResults()
|
||||
{
|
||||
var allEvents = new Dictionary<EntityPrototype, PrecognitionResultComponent>();
|
||||
foreach (var prototype in _prototype.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (prototype.Abstract)
|
||||
continue;
|
||||
|
||||
if (!prototype.TryGetComponent<PrecognitionResultComponent>(out var precognitionResult, _factory))
|
||||
continue;
|
||||
|
||||
allEvents.Add(prototype, precognitionResult);
|
||||
}
|
||||
|
||||
return allEvents;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.DeltaV.StationEvents.NextEvent;
|
||||
|
||||
[RegisterComponent, Access(typeof(NextEventSystem))]
|
||||
public sealed partial class NextEventComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of the next event that will be run by EventManagerSystem.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId? NextEventId;
|
||||
|
||||
/// <summary>
|
||||
/// Round time of the scheduler's next station event.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan NextEventTime;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using Content.Server.DeltaV.StationEvents.NextEvent;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.DeltaV.StationEvents.NextEvent;
|
||||
|
||||
public sealed class NextEventSystem : EntitySystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the NextEventComponent with the provided id and time and returns the previously stored id.
|
||||
/// </summary>
|
||||
public EntProtoId? UpdateNextEvent(NextEventComponent component, EntProtoId newEventId, TimeSpan newEventTime)
|
||||
{
|
||||
EntProtoId? oldEventId = component.NextEventId; // Store components current NextEventId for return
|
||||
component.NextEventId = newEventId;
|
||||
component.NextEventTime = newEventTime;
|
||||
return oldEventId;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Chat.Managers; // DeltaV
|
||||
using Content.Server.DeltaV.StationEvents.NextEvent; // DeltaV
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.StationEvents.Components;
|
||||
|
|
@ -9,6 +11,7 @@ using Content.Shared.GameTicking.Components;
|
|||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing; // DeltaV
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
|
|
@ -21,14 +24,27 @@ namespace Content.Server.StationEvents
|
|||
[UsedImplicitly]
|
||||
public sealed class BasicStationEventSchedulerSystem : GameRuleSystem<BasicStationEventSchedulerComponent>
|
||||
{
|
||||
[Dependency] private readonly IChatManager _chatManager = default!; // DeltaV
|
||||
[Dependency] private readonly IGameTiming _timing = default!; // DeltaV
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly EventManagerSystem _event = default!;
|
||||
[Dependency] private readonly NextEventSystem _next = default!; // DeltaV
|
||||
|
||||
protected override void Started(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
|
||||
GameRuleStartedEvent args)
|
||||
{
|
||||
// A little starting variance so schedulers dont all proc at once.
|
||||
component.TimeUntilNextEvent = RobustRandom.NextFloat(component.MinimumTimeUntilFirstEvent, component.MinimumTimeUntilFirstEvent + 120);
|
||||
|
||||
// DeltaV - end init NextEventComp
|
||||
if (TryComp<NextEventComponent>(uid, out var nextEventComponent)
|
||||
&& _event.TryGenerateRandomEvent(component.ScheduledGameRules, out string? firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent))
|
||||
&& firstEvent != null)
|
||||
{
|
||||
_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
|
||||
}
|
||||
|
||||
protected override void Ended(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
|
||||
|
|
@ -57,6 +73,23 @@ namespace Content.Server.StationEvents
|
|||
continue;
|
||||
}
|
||||
|
||||
// DeltaV events using NextEventComponent
|
||||
if (TryComp<NextEventComponent>(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))
|
||||
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);
|
||||
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
|
||||
|
||||
_event.RunRandomEvent(eventScheduler.ScheduledGameRules);
|
||||
ResetTimer(eventScheduler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ using Robust.Shared.Random;
|
|||
using Content.Shared.EntityTable.EntitySelectors;
|
||||
using Content.Shared.EntityTable;
|
||||
using Content.Server.Psionics.Glimmer; // DeltaV
|
||||
using Content.Shared.Psionics.Glimmer; // DeltaV
|
||||
using Content.Shared.Psionics.Glimmer;
|
||||
using System.Diagnostics.CodeAnalysis; // DeltaV
|
||||
|
||||
namespace Content.Server.StationEvents;
|
||||
|
||||
|
|
@ -59,37 +60,67 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
/// </summary>
|
||||
public void RunRandomEvent(EntityTableSelector limitedEventsTable)
|
||||
{
|
||||
if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents))
|
||||
if (TryGenerateRandomEvent(limitedEventsTable, out string? 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
|
||||
/// <summary>
|
||||
/// Returns a random event from the list of events given that can be run at a given time.
|
||||
/// </summary>
|
||||
/// <param name="limitedEventsTable">The list of events that can be chosen.</param>
|
||||
/// <param name="randomLimitedEvent">Generated event</param>
|
||||
/// <param name="eventRunTime">The time to use for checking time restrictions. Uses current time if null.</param>
|
||||
/// <returns></returns>
|
||||
public bool TryGenerateRandomEvent(EntityTableSelector limitedEventsTable, [NotNullWhen(true)] out string? randomLimitedEvent, TimeSpan? eventRunTime)
|
||||
{
|
||||
randomLimitedEvent = null;
|
||||
if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents, eventRunTime))
|
||||
{
|
||||
Log.Warning("Provided event table could not build dict!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
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.
|
||||
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
|
||||
if (randomLimitedEvent == null)
|
||||
{
|
||||
Log.Warning("The selected random event is null!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_prototype.TryIndex(randomLimitedEvent, out _))
|
||||
{
|
||||
Log.Warning("A requested event is not available!");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
GameTicker.AddGameRule(randomLimitedEvent);
|
||||
return true;
|
||||
}
|
||||
// DeltaV - end separate event generation method
|
||||
|
||||
// DeltaV - overloaded for backwards compatiblity
|
||||
public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary<EntityPrototype, StationEventComponent> limitedEvents)
|
||||
{
|
||||
return TryBuildLimitedEvents(limitedEventsTable, out limitedEvents, null);
|
||||
}
|
||||
// DeltaV - end overloaded for backwards compatiblity
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the provided EntityTableSelector gives at least one prototype with a StationEvent comp.
|
||||
/// </summary>
|
||||
public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary<EntityPrototype, StationEventComponent> limitedEvents)
|
||||
public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary<EntityPrototype, StationEventComponent> limitedEvents, TimeSpan? eventRunTime) // DeltaV - Add a time overide
|
||||
{
|
||||
limitedEvents = new Dictionary<EntityPrototype, StationEventComponent>();
|
||||
|
||||
var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions
|
||||
|
||||
// DeltaV - Overide time for stashing events
|
||||
var availableEvents = AvailableEvents(eventRunTime); // handles the player counts and individual event restrictions
|
||||
if (availableEvents.Count == 0)
|
||||
{
|
||||
Log.Warning("No events were available to run!");
|
||||
|
|
@ -175,6 +206,16 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
return null;
|
||||
}
|
||||
|
||||
// DeltaV - overloaded for backwards compatiblity
|
||||
public Dictionary<EntityPrototype, StationEventComponent> AvailableEvents(
|
||||
bool ignoreEarliestStart = false,
|
||||
int? playerCountOverride = null,
|
||||
TimeSpan? currentTimeOverride = null)
|
||||
{
|
||||
return AvailableEvents(null, ignoreEarliestStart, playerCountOverride, currentTimeOverride);
|
||||
}
|
||||
// DeltaV - end overloaded for backwards compatiblity
|
||||
|
||||
/// <summary>
|
||||
/// Gets the events that have met their player count, time-until start, etc.
|
||||
/// </summary>
|
||||
|
|
@ -182,6 +223,7 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
/// <param name="currentTimeOverride">Override for round time, if using this to simulate events rather than in an actual round.</param>
|
||||
/// <returns></returns>
|
||||
public Dictionary<EntityPrototype, StationEventComponent> AvailableEvents(
|
||||
TimeSpan? eventRunTime,
|
||||
bool ignoreEarliestStart = false,
|
||||
int? playerCountOverride = null,
|
||||
TimeSpan? currentTimeOverride = null)
|
||||
|
|
@ -189,9 +231,12 @@ public sealed class EventManagerSystem : EntitySystem
|
|||
var playerCount = playerCountOverride ?? _playerManager.PlayerCount;
|
||||
|
||||
// playerCount does a lock so we'll just keep the variable here
|
||||
var currentTime = currentTimeOverride ?? (!ignoreEarliestStart
|
||||
? GameTicker.RoundDuration()
|
||||
: TimeSpan.Zero);
|
||||
var currentTime = currentTimeOverride ?? (
|
||||
(!ignoreEarliestStart
|
||||
? eventRunTime // DeltaV - Use eventRunTime instead of RoundDuration if provided
|
||||
?? GameTicker.RoundDuration()
|
||||
: TimeSpan.Zero)
|
||||
);
|
||||
|
||||
var result = new Dictionary<EntityPrototype, StationEventComponent>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
using Content.Server.Chat.Managers; // DeltaV
|
||||
using Content.Server.DeltaV.StationEvents.NextEvent; // DeltaV
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing; // DeltaV
|
||||
|
||||
namespace Content.Server.StationEvents;
|
||||
|
||||
public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingStationEventSchedulerComponent>
|
||||
{
|
||||
[Dependency] private readonly IChatManager _chatManager = default!; // DeltaV
|
||||
[Dependency] private readonly IGameTiming _timing = default!; // DeltaV
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly EventManagerSystem _event = default!;
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
[Dependency] private readonly NextEventSystem _next = default!; // DeltaV
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ChaosModifier which increases as round time increases to a point.
|
||||
|
|
@ -36,6 +42,16 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
|||
component.StartingChaos = component.MaxChaos / 10;
|
||||
|
||||
PickNextEventTime(uid, component);
|
||||
|
||||
// DeltaV - end init NextEventComp
|
||||
if (TryComp<NextEventComponent>(uid, out var nextEventComponent)
|
||||
&& _event.TryGenerateRandomEvent(component.ScheduledGameRules, out string? firstEvent, TimeSpan.FromSeconds(component.TimeUntilNextEvent))
|
||||
&& firstEvent != null)
|
||||
{
|
||||
_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
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
|
|
@ -57,6 +73,23 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
|||
continue;
|
||||
}
|
||||
|
||||
// DeltaV events using NextEventComponent
|
||||
if (TryComp<NextEventComponent>(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)
|
||||
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
|
||||
|
||||
PickNextEventTime(uid, scheduler);
|
||||
_event.RunRandomEvent(scheduler.ScheduledGameRules);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Abilities.Psionics;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class PrecognitionPowerComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float RandomResultChance = 0.2F;
|
||||
|
||||
[DataField]
|
||||
public Dictionary<EntityPrototype, PrecognitionResultComponent> AllResults;
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier VisionSound = new SoundPathSpecifier("/Audio/DeltaV/Effects/clang2.ogg");
|
||||
|
||||
[DataField]
|
||||
public EntityUid? SoundStream;
|
||||
|
||||
[DataField]
|
||||
public DoAfterId? DoAfter;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan UseDelay = TimeSpan.FromSeconds(8.35); // The length of the sound effect
|
||||
|
||||
[DataField]
|
||||
public EntProtoId PrecognitionActionId = "ActionPrecognition";
|
||||
|
||||
[DataField]
|
||||
public EntityUid? PrecognitionActionEntity;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
namespace Content.Shared.Abilities.Psionics;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class PrecognitionResultComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public string Message = default!;
|
||||
|
||||
[DataField]
|
||||
public float Weight = 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
public sealed partial class PrecognitionPowerActionEvent : InstantActionEvent;
|
||||
|
|
@ -21,6 +21,26 @@ namespace Content.Shared.Psionics.Events
|
|||
public override DoAfterEvent Clone() => this;
|
||||
}
|
||||
|
||||
// DeltaV Precognition
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class PrecognitionDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
[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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
psionic-power-precognition-failure-by-damage = Your concentration was broken! You fail to decipher anything of use.
|
||||
psionic-power-precognition-no-event-result-message = You see a vision of an undisturbed lake.
|
||||
|
||||
psionic-power-precognition-xeno-vents-result-message = You see a vision, peering around a corner you see a strange, squelching beast tear at the insides of one of your coworkers as they let out a bloodcurdling scream.
|
||||
psionic-power-precognition-mothroach-spawn-result-message = You see a hungering mass of newborns, chittering and screeching as they sink their mandibles into the station's knitwork.
|
||||
psionic-power-precognition-listening-post-result-message = you hear a cacophony of foreign voices speaking over radio static; you wake with a creeping sense of paranoia.
|
||||
psionic-power-precognition-paradox-anomaly-result-message = You see your coworker splitting in two. Where there was one, there are now two. You are unsure which of the beings is truly your coworker.
|
||||
psionic-power-precognition-fugitive-result-message = You see hounds around every corner all hunting for someone who does not belong.
|
||||
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-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.
|
||||
psionic-power-precognition-bureaucratic-error-result-message = You see a vision of yourself trapped in a room, trying to solve a puzzle with both missing and duplicate pieces.
|
||||
psionic-power-precognition-clerical-error-result-message = You see faces you once knew being obscured in a fog of static, identities lost.
|
||||
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-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-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.
|
||||
psionic-power-precognition-lone-ops-spawn-result-message = You see a vision of a beast with a blood-red carapace, laughing as it eats through the station, bite by bite.
|
||||
psionic-power-precognition-sleeper-agents-result-message = You see a vision of life through the eyes of a non-descript coworker, a soft but dangerous buzzing accompanies you at the base of their skull. It sounds like radio static.
|
||||
psionic-power-precognition-mass-hallucinations-result-message = You attempt to see a vision of the future, but all you see is a phantasmagoria of chaotic shapes.
|
||||
psionic-power-precognition-ion-storm-result-message = You see a vision of the rigid being destroyed and reshaped into something new and wrong.
|
||||
psionic-power-precognition-meteor-swarm-result-message = You see a fiery vision of shooting stars falling from the sky, colorful trails shooting through the station you call home.
|
||||
psionic-power-precognition-game-rule-urist-swarm-result-message = You see a fiery vision of... PEOPLE falling from the sky! colorful trails shooting through the station you call home.
|
||||
psionic-power-precognition-immovable-rod-spawn-result-message = You see a fiery vision of a MASSIVE star falling from the sky! colorful trails shooting through the station you call home.
|
||||
psionic-power-precognition-mouse-migration-result-message = You see a vision of living as a simplistic creature, scurrying underfoot of creatures beyond your comprehension.
|
||||
psionic-power-precognition-king-rat-migration-result-message = You see a vision of living as a simplistic creature, scurrying underfoot of creatures beyond your comprehension.
|
||||
psionic-power-precognition-cockroach-migration-result-message = You see a vision of living as a simplistic creature, scurrying underfoot of creatures beyond your comprehension.
|
||||
psionic-power-precognition-snail-migration-result-message = You see a vision of living as a simplistic creature, scurrying underfoot of creatures beyond your comprehension.
|
||||
psionic-power-precognition-random-sentience-result-message = Something bright and beautiful sparks to life within your third eye. Nothing brings wonder quite like new life.
|
||||
psionic-power-precognition-unknown-shuttle-cargo-lost-result-message = You see a vision of a simple ship of old Terra, adrift of the sea, far away from home.
|
||||
psionic-power-precognition-unknown-shuttle-traveling-cuisine-result-message = You see a vision of peace, a cozy meal sizzling on a warm stove. A delicious smells wafts through the air.
|
||||
psionic-power-precognition-unknown-shuttle-disaster-evac-pod-result-message = You see a vision of death and blood, of a destruction so complete only few survive, drifting through the coldness of space.
|
||||
|
|
@ -0,0 +1 @@
|
|||
station-event-system-run-event-delayed = Running event {$eventName} in {$seconds} seconds
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
- type: entity
|
||||
- type: entity
|
||||
id: ActionOpenRadioImplant
|
||||
name: Open Radio Implant
|
||||
description: Opens the bluespace key compartment of the radio implant embedded in your skull.
|
||||
|
|
@ -34,3 +34,17 @@
|
|||
sprite: Structures/Furniture/Tables/generic.rsi
|
||||
state: full
|
||||
event: !type:ToggleCrawlingStateEvent
|
||||
|
||||
- type: entity
|
||||
id: ActionPrecognition
|
||||
name: Precognition
|
||||
description: See into the future to get a hint about the next random event.
|
||||
components:
|
||||
- type: InstantAction
|
||||
icon:
|
||||
sprite: DeltaV/Interface/Actions/actions_psionics.rsi
|
||||
state: precognition
|
||||
useDelay: 240
|
||||
checkCanInteract: false
|
||||
checkConsciousness: false
|
||||
event: !type:PrecognitionPowerActionEvent
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
params:
|
||||
volume: -4
|
||||
duration: null #ending is handled by MeteorSwarmRule
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-meteor-swarm-result-message
|
||||
- type: MeteorSwarmRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -44,6 +46,8 @@
|
|||
minimumPlayers: 20
|
||||
weight: 1
|
||||
duration: 60
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-xeno-vents-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobXeno
|
||||
|
|
@ -72,6 +76,8 @@
|
|||
minimumPlayers: 15
|
||||
weight: 4
|
||||
duration: 60
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-mothroach-spawn-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobMothroach
|
||||
|
|
@ -87,6 +93,8 @@
|
|||
minimumPlayers: 25
|
||||
maxOccurrences: 1
|
||||
duration: null
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-listening-post-result-message
|
||||
- type: RuleGrids
|
||||
- type: LoadFarGridRule
|
||||
path: /Maps/Shuttles/DeltaV/listening_post.yml
|
||||
|
|
@ -146,6 +154,8 @@
|
|||
components:
|
||||
- type: StationEvent
|
||||
duration: null
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-paradox-anomaly-result-message
|
||||
- type: ParadoxClonerRule
|
||||
- type: AntagObjectives
|
||||
objectives:
|
||||
|
|
@ -169,6 +179,8 @@
|
|||
- type: StationEvent
|
||||
minimumPlayers: 40 # it's really easy to find fugitives on lowpop
|
||||
duration: null
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-fugitive-result-message
|
||||
- type: FugitiveRule
|
||||
- type: AntagLoadProfileRule
|
||||
- type: AntagObjectives
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
parent: BaseGameRule
|
||||
id: GlimmerEventScheduler
|
||||
components:
|
||||
- type: NextEvent
|
||||
- type: BasicStationEventScheduler
|
||||
minMaxEventTiming:
|
||||
min: 300
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
minimumPlayers: 20
|
||||
maxOccurrences: 1
|
||||
duration: null
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-syndicate-recruiter-result-message
|
||||
- type: RuleGrids
|
||||
- type: LoadMapRule
|
||||
preloadedGrid: SyndieRecruiterShip
|
||||
|
|
@ -56,6 +58,8 @@
|
|||
minimumPlayers: 20
|
||||
maxOccurrences: 1
|
||||
duration: null
|
||||
- type: PrecognitionResult
|
||||
message: psionic-power-precognition-synthesis-specialist-result-message
|
||||
- type: RuleGrids
|
||||
- type: LoadMapRule
|
||||
preloadedGrid: SyndieSynthesisShip
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
delay:
|
||||
min: 10
|
||||
max: 10
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-cargo-gifts-base-result-message
|
||||
- type: StationEvent
|
||||
startColor: "#18abf5"
|
||||
startAudio:
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@
|
|||
path: /Audio/Announcements/announce.ogg
|
||||
weight: 12 # DeltaV - was 8
|
||||
duration: 35
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-anomoly-spawn-result-message
|
||||
- type: AnomalySpawnRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -99,6 +101,8 @@
|
|||
path: /Audio/Announcements/announce.ogg
|
||||
weight: 8
|
||||
duration: 35
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-bluespace-artifact-result-message
|
||||
- type: BluespaceArtifactRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -110,6 +114,8 @@
|
|||
reoccurrenceDelay: 5
|
||||
earliestStart: 1
|
||||
duration: 1
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-bluespace-locker-result-message
|
||||
- type: BluespaceLockerRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -120,6 +126,8 @@
|
|||
weight: 10
|
||||
duration: 1
|
||||
minimumPlayers: 15
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-breaker-flip-result-message
|
||||
- type: BreakerFlipRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -133,6 +141,8 @@
|
|||
minimumPlayers: 25
|
||||
weight: 5
|
||||
duration: 1
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-bureaucratic-error-result-message
|
||||
- type: BureaucraticErrorRule
|
||||
ignoredJobs:
|
||||
- StationAi
|
||||
|
|
@ -146,6 +156,8 @@
|
|||
minimumPlayers: 15
|
||||
weight: 5
|
||||
duration: 1
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-clerical-error-result-message
|
||||
- type: ClericalErrorRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -156,6 +168,8 @@
|
|||
weight: 8 # DeltaV - was 10
|
||||
duration: 1
|
||||
minimumPlayers: 10
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-closet-skeleton-result-message
|
||||
- type: RandomEntityStorageSpawnRule
|
||||
prototype: MobSkeletonCloset
|
||||
|
||||
|
|
@ -169,6 +183,8 @@
|
|||
reoccurrenceDelay: 20
|
||||
minimumPlayers: 45 # DeltaV - was 20
|
||||
duration: null
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-dragon-spawn-result-message
|
||||
- type: SpaceSpawnRule
|
||||
spawnDistance: 0
|
||||
- type: AntagSpawner
|
||||
|
|
@ -198,6 +214,8 @@
|
|||
earliestStart: 30
|
||||
reoccurrenceDelay: 60 # DeltaV - was 20
|
||||
minimumPlayers: 40 # DeltaV - was 30
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-ninja-spawn-result-message
|
||||
- type: SpaceSpawnRule
|
||||
- type: AntagLoadProfileRule
|
||||
- type: AntagObjectives
|
||||
|
|
@ -253,6 +271,8 @@
|
|||
duration: 1
|
||||
earliestStart: 45
|
||||
minimumPlayers: 20
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-revenant-spawn-result-message
|
||||
- type: RandomSpawnRule
|
||||
prototype: MobRevenant
|
||||
|
||||
|
|
@ -277,6 +297,8 @@
|
|||
path: /Audio/Announcements/gas_leak.ogg # DeltaV - custom announcer
|
||||
endAnnouncement: station-event-gas-leak-end-announcement
|
||||
weight: 10 # DeltaV - was 8
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-gas-leak-result-message
|
||||
- type: GasLeakRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -288,6 +310,8 @@
|
|||
minimumPlayers: 10 # DeltaV - Was 15
|
||||
weight: 5 # DeltaV - was 7
|
||||
duration: 240
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-kudzu-growth-result-message
|
||||
- type: KudzuGrowthRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -304,6 +328,8 @@
|
|||
volume: -4
|
||||
duration: 60
|
||||
maxDuration: 120
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-power-grid-check-result-message
|
||||
- type: PowerGridCheckRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -318,6 +344,8 @@
|
|||
path: /Audio/Announcements/attention.ogg
|
||||
duration: 120
|
||||
maxDuration: 240
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-solar-flare-result-message
|
||||
- type: SolarFlareRule
|
||||
onlyJamHeadsets: true
|
||||
affectedChannels:
|
||||
|
|
@ -346,6 +374,8 @@
|
|||
minimumPlayers: 15
|
||||
weight: 7.5 # DeltaV - was 5
|
||||
duration: 60
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-vent-clog-result-message
|
||||
- type: VentClogRule
|
||||
|
||||
- type: entity
|
||||
|
|
@ -360,6 +390,8 @@
|
|||
minimumPlayers: 15
|
||||
weight: 5
|
||||
duration: 60
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-slimes-spawn-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobAdultSlimesBlueAngry
|
||||
|
|
@ -381,6 +413,8 @@
|
|||
minimumPlayers: 15
|
||||
weight: 5
|
||||
duration: 60
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-snake-spawn-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobPurpleSnake
|
||||
|
|
@ -402,6 +436,8 @@
|
|||
minimumPlayers: 15
|
||||
weight: 5
|
||||
duration: 60
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-spider-spawn-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobGiantSpiderAngry
|
||||
|
|
@ -419,6 +455,8 @@
|
|||
minimumPlayers: 30 # DeltaV - was 20
|
||||
weight: 1 # DeltaV - was 1.5
|
||||
duration: 60
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-spider-clown-spawn-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobClownSpider
|
||||
|
|
@ -433,6 +471,8 @@
|
|||
minimumPlayers: 40
|
||||
weight: 1 # Zombies was happening basically every single survival round, so now it's super rare
|
||||
duration: 1
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-zombie-outbreak-result-message
|
||||
- type: ZombieRule
|
||||
- type: AntagSelection
|
||||
definitions:
|
||||
|
|
@ -467,6 +507,8 @@
|
|||
minimumPlayers: 30 # DeltaV - was 20
|
||||
reoccurrenceDelay: 30
|
||||
duration: 1
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-lone-ops-spawn-result-message
|
||||
- type: RuleGrids
|
||||
- type: LoadMapRule
|
||||
mapPath: /Maps/Shuttles/ShuttleEvent/striker.yml
|
||||
|
|
@ -507,6 +549,8 @@
|
|||
path: /Audio/Announcements/attention.ogg # DeltaV - Use the generic announcement sound
|
||||
duration: null # the rule has to last the whole round not 1 second
|
||||
occursDuringRoundEnd: false
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-sleeper-agents-result-message
|
||||
- type: AlertLevelInterceptionRule
|
||||
- type: AntagSelection
|
||||
definitions:
|
||||
|
|
@ -529,6 +573,8 @@
|
|||
weight: 10
|
||||
duration: 150
|
||||
maxDuration: 300
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-mass-hallucinations-result-message
|
||||
- type: MassHallucinationsRule
|
||||
minTimeBetweenIncidents: 30 # DeltaV - was 0.1
|
||||
maxTimeBetweenIncidents: 300
|
||||
|
|
@ -544,6 +590,8 @@
|
|||
weight: 10
|
||||
reoccurrenceDelay: 30 #DeltaV - Was 20 #20 mins feels too short, and can scramble borgs way too much
|
||||
duration: 1
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-ion-storm-result-message
|
||||
- type: IonStormRule
|
||||
|
||||
# DeltaV - Disable Mimic event. It causes a ton of heisentests, and does practially nothing in game
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
parent: BaseGameRule
|
||||
id: MeteorSwarmScheduler
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: GameRule
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 600 # 10 min
|
||||
|
|
@ -68,6 +69,7 @@
|
|||
parent: BaseGameRule
|
||||
id: MeteorSwarmMildScheduler
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: GameRule
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 600 # 10 min
|
||||
|
|
@ -82,6 +84,7 @@
|
|||
parent: BaseGameRule
|
||||
id: KesslerSyndromeScheduler
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event
|
||||
- type: GameRule
|
||||
- type: RampingStationEventScheduler
|
||||
scheduledGameRules: !type:NestedSelector
|
||||
|
|
@ -99,6 +102,8 @@
|
|||
reoccurrenceDelay: 1
|
||||
earliestStart: 12
|
||||
minimumPlayers: 25
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-meteor-swarm-result-message
|
||||
- type: MeteorSwarm
|
||||
|
||||
- type: entity
|
||||
|
|
@ -184,6 +189,8 @@
|
|||
components:
|
||||
- type: StationEvent
|
||||
weight: 0.05
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-game-rule-urist-swarm-result-message
|
||||
- type: MeteorSwarm
|
||||
announcement: station-event-meteor-urist-start-announcement
|
||||
announcementSound: /Audio/Announcements/attention.ogg
|
||||
|
|
@ -209,6 +216,8 @@
|
|||
duration: 1
|
||||
earliestStart: 30
|
||||
minimumPlayers: 25
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-immovable-rod-spawn-result-message
|
||||
- type: ImmovableRodRule
|
||||
rodPrototypes:
|
||||
- id: ImmovableRodKeepTilesStill
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
earliestStart: 15
|
||||
weight: 6
|
||||
duration: 50
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-mouse-migration-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobMouse
|
||||
|
|
@ -52,6 +54,8 @@
|
|||
weight: 6
|
||||
duration: 50
|
||||
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
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobMouse
|
||||
|
|
@ -76,6 +80,8 @@
|
|||
path: /Audio/Announcements/attention.ogg
|
||||
weight: 6
|
||||
duration: 50
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-cockroach-migration-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobCockroach
|
||||
|
|
@ -93,6 +99,8 @@
|
|||
path: /Audio/Announcements/attention.ogg
|
||||
weight: 6
|
||||
duration: 50
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-snail-migration-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobSnail
|
||||
|
|
@ -114,6 +122,8 @@
|
|||
weight: 6
|
||||
duration: 50
|
||||
minimumPlayers: 30
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-snail-migration-result-message
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobSnail
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
maxOccurrences: 1 # this event has diminishing returns on interesting-ness, so we cap it
|
||||
startAudio:
|
||||
path: /Audio/Announcements/attention.ogg
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-random-sentience-result-message
|
||||
- type: RandomSentienceRule
|
||||
minSentiences: 2
|
||||
maxSentiences: 5
|
||||
|
|
@ -22,4 +24,4 @@
|
|||
id: RandomSentienceEventStrength
|
||||
values:
|
||||
prefix: random-sentience-event-strength-
|
||||
count: 8
|
||||
count: 8
|
||||
|
|
|
|||
|
|
@ -313,6 +313,7 @@
|
|||
id: BasicStationEventScheduler
|
||||
parent: BaseGameRule
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event for precognition
|
||||
- type: BasicStationEventScheduler
|
||||
minMaxEventTiming: # DeltaV
|
||||
min: 300 # DeltaV - 5 mins, was 3
|
||||
|
|
@ -324,6 +325,7 @@
|
|||
id: RampingStationEventScheduler
|
||||
parent: BaseGameRule
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event for precognition
|
||||
- type: RampingStationEventScheduler
|
||||
averageChaos: 4.5 # DeltaV
|
||||
averageEndTime: 180 # DeltaV
|
||||
|
|
@ -334,6 +336,7 @@
|
|||
id: SpaceTrafficControlEventScheduler # iff we make a selector for EntityTables that can respect StationEventComp restrictions, or somehow impliment them otherwise in said tables,
|
||||
parent: BaseGameRule # we can remerge this with the other schedulers, but it will silently fail due to that limitation without a separate scheduler to balance atm.
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event for precognition
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 2700 # 45 mins #shows up like half way through shift.
|
||||
minMaxEventTiming:
|
||||
|
|
@ -346,6 +349,7 @@
|
|||
id: SpaceTrafficControlFriendlyEventScheduler
|
||||
parent: BaseGameRule
|
||||
components:
|
||||
- type: NextEvent # DeltaV: Queue Event for precognition
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 1200 # 20 mins
|
||||
minMaxEventTiming:
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@
|
|||
components:
|
||||
- type: StationEvent
|
||||
maxOccurrences: 2 # should be the same as [copies] in shuttle_incoming_event.yml
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-unknown-shuttle-cargo-lost-result-message
|
||||
- type: LoadMapRule
|
||||
preloadedGrid: ShuttleCargoLost
|
||||
|
||||
|
|
@ -69,6 +71,8 @@
|
|||
- type: StationEvent
|
||||
startAnnouncement: station-event-unknown-shuttle-incoming
|
||||
maxOccurrences: 2 # should be the same as [copies] in shuttle_incoming_event.yml
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-unknown-shuttle-traveling-cuisine-result-message
|
||||
- type: LoadMapRule
|
||||
preloadedGrid: TravelingCuisine
|
||||
|
||||
|
|
@ -79,6 +83,8 @@
|
|||
- type: StationEvent
|
||||
startAnnouncement: station-event-unknown-shuttle-incoming
|
||||
maxOccurrences: 3 # should be the same as [copies] in shuttle_incoming_event.yml
|
||||
- type: PrecognitionResult # DeltaV - Precogniton
|
||||
message: psionic-power-precognition-unknown-shuttle-disaster-evac-pod-result-message
|
||||
- type: LoadMapRule
|
||||
preloadedGrid: DisasterEvacPod
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
DispelPower: 1
|
||||
TelegnosisPower: 1
|
||||
PsionicRegenerationPower: 1
|
||||
PrecognitionPower: 1 # DeltaV
|
||||
MassSleepPower: 0.3
|
||||
NoosphericZapPower: 0.3
|
||||
# PsionicInvisibilityPower: 0.15
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-4.0",
|
||||
"copyright": "Sprited by chamomileteatime on Discord for DeltaV",
|
||||
"size": {
|
||||
"x": 64,
|
||||
"y": 64
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "precognition"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Loading…
Reference in New Issue