Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Refactor Ramping Event Scheduler (#592)" #644

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,38 @@
public sealed partial class RampingStationEventSchedulerComponent : Component
{
/// <summary>
/// Multiplies the End Time of the Ramping Event curve. Lower this number for shorter, hectic shifts, increase this number for longer shifts.
/// The maximum number by which the event rate will be multiplied when shift time reaches the end time.
/// </summary>
[DataField]
public float ShiftChaosModifier = 1f;
public float ChaosModifier = 3f;

/// <summary>
/// The number by which all event delays will be multiplied. Unlike chaos, remains constant throughout the shift.
/// The minimum number by which the event rate will be multiplied when the shift has just begun.
/// </summary>
[DataField]
public float EventDelayModifier = 1f;

public float StartingChaosRatio = 0.1f;

/// <summary>
/// Shift Length(in Minutes) is directly reduced by this value.
/// </summary>
[DataField]
public float ShiftLengthOffset = 0f;

/// <summary>
/// Minimum time between events is decreased by this value.
/// The number by which all event delays will be multiplied. Unlike chaos, remains constant throughout the shift.
/// </summary>
[DataField]
public float MinimumEventTimeOffset = 0f;
public float EventDelayModifier = 1f;

/// <summary>
/// Maximum time between events is decreased by this value.
/// The number by which average expected shift length is multiplied. Higher values lead to slower chaos growth.
/// </summary>

[DataField]
public float MaximumEventTimeOffset = 0f;

[DataField]
public bool IgnoreMinimumTimes = false;
public float ShiftLengthModifier = 1f;

// Everything below is overridden in the RampingStationEventSchedulerSystem based on CVars
[DataField]
[DataField("endTime"), ViewVariables(VVAccess.ReadWrite)]
public float EndTime;

[DataField]
[DataField("maxChaos"), ViewVariables(VVAccess.ReadWrite)]
public float MaxChaos;

[DataField]
[DataField("startingChaos"), ViewVariables(VVAccess.ReadWrite)]
public float StartingChaos;

[DataField]
[DataField("timeUntilNextEvent"), ViewVariables(VVAccess.ReadWrite)]
public float TimeUntilNextEvent;
}
65 changes: 23 additions & 42 deletions Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.StationEvents.Components;
using Content.Server.StationEvents.Events;
using Content.Shared.CCVar;
using Robust.Shared.Configuration;
using Robust.Shared.Random;
using Robust.Shared.Utility;

namespace Content.Server.StationEvents;

Expand All @@ -16,35 +16,30 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
[Dependency] private readonly EventManagerSystem _event = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;

/// <summary>
/// A <see href="https://www.desmos.com/calculator/87huunvoxq">logistic curve equation</see> used to smooth out the transition between event times at shift start, vs. shift end.
/// Depending on the settings used, the end time might not necessarily be the point at which timers hit the floor.
/// It is after all, an asymptote.
/// </summary>
/// <param name="component"></param>
/// <param name="startTime"></param>
/// <param name="endTimeOffset"></param>
/// <returns></returns>
public float RampingEventTimeEquation(RampingStationEventSchedulerComponent component, float startTime, float endTimeOffset = 0)
public float GetChaosModifier(EntityUid uid, RampingStationEventSchedulerComponent component)
{
var endTime = Math.Clamp(endTimeOffset, 0.1f, startTime - 1);
var shiftLength = Math.Max(1, _cfg.GetCVar(CCVars.EventsRampingAverageEndTime) - component.ShiftLengthOffset);
return 2 * endTime
/ (1
+ MathF.Exp(_cfg.GetCVar(CCVars.EventsRampingAverageChaos)
* component.ShiftChaosModifier
/ shiftLength
* endTime
* (float) _gameTicker.RoundDuration().TotalSeconds
/ 60))
+ (startTime - endTime);
var roundTime = (float) _gameTicker.RoundDuration().TotalSeconds;
if (roundTime > component.EndTime)
return component.MaxChaos;

return component.MaxChaos / component.EndTime * roundTime + component.StartingChaos;
}

protected override void Started(EntityUid uid, RampingStationEventSchedulerComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);

PickNextEventTime(component);
var avgChaos = _cfg.GetCVar(CCVars.EventsRampingAverageChaos) * component.ChaosModifier;
var avgTime = _cfg.GetCVar(CCVars.EventsRampingAverageEndTime) * component.ShiftLengthModifier;

// Worlds shittiest probability distribution
// Got a complaint? Send them to
component.MaxChaos = avgChaos * _random.NextFloat(0.75f, 1.25f);
// This is in minutes, so *60 for seconds (for the chaos calc)
component.EndTime = avgTime * _random.NextFloat(0.75f, 1.25f) * 60f;
component.StartingChaos = component.MaxChaos * component.StartingChaosRatio;

PickNextEventTime(uid, component);
}

public override void Update(float frameTime)
Expand All @@ -66,31 +61,17 @@ public override void Update(float frameTime)
return;
}

PickNextEventTime(scheduler);
PickNextEventTime(uid, scheduler);
_event.RunRandomEvent();
}
}

private void PickNextEventTime(RampingStationEventSchedulerComponent component)
private void PickNextEventTime(EntityUid uid, RampingStationEventSchedulerComponent component)
{
// In case of server hosts being silly and setting maximum time to be lower than minimum time, sanity check the scheduler inputs and sort them by Min/Max
var minimumTime = MathF.Min(_cfg.GetCVar(CCVars.GameEventsRampingMinimumTime)
- _cfg.GetCVar(CCVars.GameEventsRampingMinimumTimeOffset)
- component.MinimumEventTimeOffset, _cfg.GetCVar(CCVars.GameEventsRampingMaximumTime)
- _cfg.GetCVar(CCVars.GameEventsRampingMaximumTimeOffset)
- component.MaximumEventTimeOffset);

var maximumTime = MathF.Max(_cfg.GetCVar(CCVars.GameEventsRampingMinimumTime)
- _cfg.GetCVar(CCVars.GameEventsRampingMinimumTimeOffset)
- component.MinimumEventTimeOffset, _cfg.GetCVar(CCVars.GameEventsRampingMaximumTime)
- _cfg.GetCVar(CCVars.GameEventsRampingMaximumTimeOffset)
- component.MaximumEventTimeOffset);

// Just in case someone messed up their math, set it to between 6 and 12 seconds. This absolutely isn't ideal
component.TimeUntilNextEvent = _random.NextFloat(
RampingEventTimeEquation(component, MathF.Max(0.1f, minimumTime)),
RampingEventTimeEquation(component, MathF.Max(0.2f, maximumTime)));
_cfg.GetCVar(CCVars.GameEventsRampingMinimumTime),
_cfg.GetCVar(CCVars.GameEventsRampingMaximumTime));

component.TimeUntilNextEvent *= component.EventDelayModifier;
component.TimeUntilNextEvent *= component.EventDelayModifier / GetChaosModifier(uid, component);
}
}
27 changes: 7 additions & 20 deletions Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public static readonly CVarDef<float>
/// Max chaos chosen for a round will deviate from this
/// </summary>
public static readonly CVarDef<float>
EventsRampingAverageChaos = CVarDef.Create("events.ramping_average_chaos", 0.8f, CVar.ARCHIVE | CVar.SERVERONLY);
EventsRampingAverageChaos = CVarDef.Create("events.ramping_average_chaos", 6f, CVar.ARCHIVE | CVar.SERVERONLY);

/*
* Game
Expand Down Expand Up @@ -186,29 +186,16 @@ public static readonly CVarDef<int> // 25 Minutes
GameEventsBasicMaximumTime = CVarDef.Create("game.events_basic_maximum_time", 1500, CVar.SERVERONLY);

/// <summary>
/// Minimum time between Ramping station events in minutes
/// Minimum time between Ramping station events in seconds
/// </summary>
public static readonly CVarDef<float> // 8 Minutes
GameEventsRampingMinimumTime = CVarDef.Create("game.events_ramping_minimum_time", 8f, CVar.SERVERONLY);
public static readonly CVarDef<int> // 4 Minutes
GameEventsRampingMinimumTime = CVarDef.Create("game.events_ramping_minimum_time", 240, CVar.SERVERONLY);

/// <summary>
/// After the shift's desired "Endpoint" is reached, the minimum time between events is RampingMinimumTime - Offset.
/// Maximum time between Ramping station events in seconds
/// </summary>

public static readonly CVarDef<float>
GameEventsRampingMinimumTimeOffset = CVarDef.Create("game.events_ramping_minimum_time_offset", 6f, CVar.SERVERONLY);

/// <summary>
/// Maximum time between Ramping station events in minutes
/// </summary>
public static readonly CVarDef<float> // 16 Minutes
GameEventsRampingMaximumTime = CVarDef.Create("game.events_ramping_maximum_time", 16f, CVar.SERVERONLY);

/// <summary>
/// After the shift's desired "Endpoint" is reached, the maximum time between events is RampingMaximumTime - Offset.
/// </summary>
public static readonly CVarDef<float>
GameEventsRampingMaximumTimeOffset = CVarDef.Create("game.events_ramping_maximum_time_offset", 10f, CVar.SERVERONLY);
public static readonly CVarDef<int> // 12 Minutes
GameEventsRampingMaximumTime = CVarDef.Create("game.events_ramping_maximum_time", 720, CVar.SERVERONLY);

/// <summary>
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,3 @@ survival-description = No internal threats, but how long can the station survive

hellshift-title = Hellshift
hellshift-description = The station rolled a "one" in a luck check. Can the crew make it to the end?

longsurvival-title = Long Survival
longsurvival-description = Survival, but two hours longer. Event growth is stretched over a vastly greater length of time.
12 changes: 3 additions & 9 deletions Resources/Prototypes/GameRules/roundstart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,15 @@
components:
- type: RampingStationEventScheduler

- type: entity
id: LongSurvivalStationEventScheduler
parent: BaseGameRule
noSpawn: true
components:
- type: RampingStationEventScheduler
shiftLengthOffset: -120

- type: entity
id: HellshiftStationEventScheduler
parent: BaseGameRule
noSpawn: true
components:
- type: RampingStationEventScheduler
shiftChaosModifier: 4 #30 minute HELL SHIFT
chaosModifier: 4 # By default, one event each 30-10 seconds after two hours. Changing CVars will cause this to deviate.
startingChaosRatio: 0.025 # Starts as slow as survival, but quickly ramps up
shiftLengthModifier: 2.5

# variation passes
- type: entity
Expand Down
11 changes: 0 additions & 11 deletions Resources/Prototypes/game_presets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@
- HellshiftStationEventScheduler
- BasicRoundstartVariation

- type: gamePreset
id: SurvivalLonger
alias:
- longsurvival
showInVote: true
name: longsurvival-title
description: longsurvival-description
rules:
- LongSurvivalStationEventScheduler
- BasicRoundstartVariation

- type: gamePreset
id: AllAtOnce
name: all-at-once-title
Expand Down
Loading