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

refactor event schedulers to use explicit game rules #29320

Merged
merged 39 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4bf1181
works, still has testing values, im sure I did stupid shit.
IProduceWidgets Jun 21, 2024
cbe3c89
shitvent crapfactor
IProduceWidgets Jun 21, 2024
d3aace9
snap extra word out of existence
IProduceWidgets Jun 21, 2024
4556659
shit I died of old
IProduceWidgets Jun 21, 2024
5938150
remove useless inaccurate design comments
IProduceWidgets Jun 21, 2024
4e44d6b
Oopsie, handle requirement params in RandomRuleSystem too
IProduceWidgets Jun 22, 2024
2660633
I'm a slash slinging hasher
IProduceWidgets Jun 22, 2024
d2e71a2
Address reviews, add admin alerts I forgor
IProduceWidgets Jun 22, 2024
f92e6a4
EntityMan saves the day
IProduceWidgets Jun 24, 2024
d44e076
address reviews 1
IProduceWidgets Jul 2, 2024
5d23be6
eh, I actually don't care about the cargo gifts thing.
IProduceWidgets Jul 2, 2024
28329bb
started
IProduceWidgets Jul 2, 2024
7c9a8eb
Do reviews
IProduceWidgets Jul 20, 2024
63d3c19
you actually meant 1.2 lmao
IProduceWidgets Jul 20, 2024
b1e31a1
dependency inheritance is a fickle bitch
IProduceWidgets Jul 20, 2024
e5a559a
I have no idea.
IProduceWidgets Jul 20, 2024
423af3b
Threads are for sheets not computers.
IProduceWidgets Jul 20, 2024
d21551e
Merge branch 'master' into gamerulerefactors
IProduceWidgets Jul 20, 2024
fe9b37b
fix traitor rule test
IProduceWidgets Jul 20, 2024
9d502aa
fix round type tattling
IProduceWidgets Jul 21, 2024
a3345f2
break things
IProduceWidgets Aug 12, 2024
60c5523
Merge branch 'master' into gamerulerefactors
IProduceWidgets Aug 12, 2024
a08f08c
It worky
IProduceWidgets Aug 12, 2024
9a50348
Toolshed makes we want to drink depresso.
IProduceWidgets Aug 13, 2024
83a0e26
Finished?
IProduceWidgets Aug 13, 2024
047b8fa
remove debug values
IProduceWidgets Aug 13, 2024
03aeec7
timings
IProduceWidgets Aug 13, 2024
3779b7f
use defaults
IProduceWidgets Aug 13, 2024
601ec24
alphabetize
IProduceWidgets Aug 13, 2024
0f22edf
bobby drop tables
IProduceWidgets Aug 13, 2024
7e5cf24
Float required fr fr
IProduceWidgets Aug 13, 2024
0897b66
continue
IProduceWidgets Aug 13, 2024
e9eb54b
more continence
IProduceWidgets Aug 13, 2024
3ad5151
uno mas
IProduceWidgets Aug 13, 2024
ba56c16
obsolution
IProduceWidgets Aug 13, 2024
97cd0a3
cleanup and documentations
IProduceWidgets Aug 13, 2024
57d9f79
Yell at self
IProduceWidgets Aug 13, 2024
132f2de
use the right value defaults
IProduceWidgets Aug 13, 2024
d75148b
housekeeping
IProduceWidgets Aug 13, 2024
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
25 changes: 25 additions & 0 deletions Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Content.Shared.Storage;

namespace Content.Server.GameTicking.Rules.Components;

[RegisterComponent, Access(typeof(RandomRuleSystem))]
public sealed partial class RandomRuleComponent : Component
{
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
/// <summary>
/// The gamerules that get added at random.
/// </summary>
[DataField(required: true)]
public List<EntitySpawnEntry> SelectableGameRules = new();

/// <summary>
/// The maximum gamerules that get added at a time.
/// </summary>
[DataField]
public int MaxRules = 1;

/// <summary>
/// The minimum gamerules that get added at a time.
/// </summary>
[DataField]
public int MinRules = 1;
}
79 changes: 79 additions & 0 deletions Content.Server/GameTicking/Rules/RandomRuleSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Content.Server.Administration.Logs;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.StationEvents;
using Content.Shared.GameTicking.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Content.Shared.Storage;
using Content.Server.StationEvents.Components;

namespace Content.Server.GameTicking.Rules;

public sealed class RandomRuleSystem : GameRuleSystem<RandomRuleComponent>
{
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IComponentFactory _compFact = default!;
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
[Dependency] private readonly EventManagerSystem _event = default!;

private string _ruleCompName = default!;
public override void Initialize()
{
base.Initialize();
}

IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
protected override void Added(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
{
var selectedRules = EntitySpawnCollection.GetSpawns(component.SelectableGameRules, _random);

Random rnd = new Random();
int ruleQuant = rnd.Next(component.MinRules, component.MaxRules);

IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
for (int i = 0; i < ruleQuant; i++)
{
var availableEvents = _event.AvailableEvents(); // handles the player counts and individual event restrictions, we need to do it each i incase it changes
string? slag = null;

foreach (var rule in selectedRules)
{
if (selectedRules == null)
return;
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
// If the station is already initialized, just start the rule, otherwise let that happen at the start of round.
if (GameTicker.RunLevel <= GameRunLevel.InRound)
{
GameTicker.AddGameRule(rule);
}
else
{
_prototypeManager.TryIndex(rule, out var ruleEnt);
if (ruleEnt == null)
{
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
Log.Warning("The selected random rule is null!");
continue;
}

if (ruleEnt.TryGetComponent<StationEventComponent>(out _, _compFact))
{
if (!availableEvents.ContainsKey(ruleEnt))
{
Log.Warning("The selected random rule is not available!");
continue;
}
GameTicker.StartGameRule(rule);
}
}
slag = rule;
}

// prevents same gamerule twice in one run.
if (!string.IsNullOrEmpty(slag))
{
selectedRules.RemoveAt(selectedRules.IndexOf(slag));
}
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ public sealed class BasicStationEventSchedulerSystem : GameRuleSystem<BasicStati
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly EventManagerSystem _event = default!;

public const float MinEventTime = 60 * 3;
public const float MaxEventTime = 60 * 10;
// someome yell at me if I forget to change this back, I need to test it without dying of old
public const float MinEventTime = 60 * 3; // 60 * 3;
public const float MaxEventTime = 60 * 10; // 60 * 10;
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved

protected override void Ended(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
GameRuleEndedEvent args)
Expand All @@ -37,7 +38,7 @@ public override void Update(float frameTime)
{
base.Update(frameTime);

if (!_event.EventsEnabled)
if (!_event.EventsEnabled) // comment for testing
return;

var query = EntityQueryEnumerator<BasicStationEventSchedulerComponent, GameRuleComponent>();
Expand All @@ -52,7 +53,7 @@ public override void Update(float frameTime)
return;
}

_event.RunRandomEvent();
_event.RunLimitedEvent(eventScheduler.ScheduledGameRules);
ResetTimer(eventScheduler);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
namespace Content.Server.StationEvents.Components;
using Content.Shared.Storage;

namespace Content.Server.StationEvents.Components;

[RegisterComponent, Access(typeof(BasicStationEventSchedulerSystem))]
public sealed partial class BasicStationEventSchedulerComponent : Component
{
public const float MinimumTimeUntilFirstEvent = 300;
public const float MinimumTimeUntilFirstEvent = 300; // Someone yell at me if I dont change this back to 300, I need to test it without dying of old

IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
/// <summary>
/// How long until the next check for an event runs
/// </summary>
/// Default value is how long until first event is allowed
[ViewVariables(VVAccess.ReadWrite)]
public float TimeUntilNextEvent = MinimumTimeUntilFirstEvent;

/// <summary>
/// The gamerules that the scheduler can choose from
/// </summary>
[DataField(required: true)]
public List<EntitySpawnEntry> ScheduledGameRules = new();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Content.Server.StationEvents.Components;
using Content.Shared.Storage;

namespace Content.Server.StationEvents.Components;

[RegisterComponent, Access(typeof(RampingStationEventSchedulerSystem))]
public sealed partial class RampingStationEventSchedulerComponent : Component
Expand All @@ -14,4 +16,10 @@ public sealed partial class RampingStationEventSchedulerComponent : Component

[DataField("timeUntilNextEvent"), ViewVariables(VVAccess.ReadWrite)]
public float TimeUntilNextEvent;

/// <summary>
/// The gamerules that the scheduler can choose from
/// </summary>
[DataField(required: true)]
public List<EntitySpawnEntry> ScheduledGameRules = new();
}
70 changes: 69 additions & 1 deletion Content.Server/StationEvents/EventManagerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
Expand All @@ -7,11 +8,13 @@
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Content.Shared.Storage;

namespace Content.Server.StationEvents;

public sealed class EventManagerSystem : EntitySystem
{
[Dependency] private readonly IComponentFactory _compFac = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
Expand Down Expand Up @@ -44,7 +47,7 @@ public string RunRandomEvent()
}

var ent = GameTicker.AddGameRule(randomEvent);
var str = Loc.GetString("station-event-system-run-event",("eventName", ToPrettyString(ent)));
var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ent)));
_chat.SendAdminAlert(str);
Log.Info(str);
return str;
Expand All @@ -60,6 +63,71 @@ public string RunRandomEvent()
return FindEvent(availableEvents);
}

/// <summary>
/// Randomly runs an event from provided EntitySpawnCollection.
/// </summary>
public string? RunLimitedEvent(List<EntitySpawnEntry>? limitedEventsList)
{
if (limitedEventsList != null)
{
var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions

if (availableEvents.Count == 0)
{
Log.Warning("No events were available to run!");
return null;
}
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved

var selectedEvents = EntitySpawnCollection.GetSpawns(limitedEventsList, _random); // storage function for game rules, smh my head.
// fuck it though, it works and gives us all the random selection utility we want.

Log.Info($"Picking from {limitedEventsList.Count} subsetted events");

var limitedEvents = new Dictionary<EntityPrototype, StationEventComponent>();
foreach (var eventid in selectedEvents)
{
if (!_prototype.TryIndex(eventid, out var eventproto))
{
Log.Warning("An event ID has no prototype index!");
continue;
}

if (eventproto.Abstract)
continue;

if (!eventproto.TryGetComponent<StationEventComponent>(out var stationEvent, _compFac))
continue;

if (!availableEvents.ContainsKey(eventproto))
continue;

limitedEvents.Add(eventproto, stationEvent);
}

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 null;
}

if (!_prototype.TryIndex(randomLimitedEvent, out _))
{
Log.Warning("A requested event is not available!");
return null;
}

var ent = GameTicker.AddGameRule(randomLimitedEvent);
var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ent)));
_chat.SendAdminAlert(str);
Log.Info(str);
return str;
}
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
Log.Warning("A scheduler has requested null as event!");
return null;
}

IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Pick a random event from the available events at this time, also considering their weightings.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Content.Server.GameTicking;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.StationEvents.Components;
Expand Down Expand Up @@ -63,7 +63,7 @@ public override void Update(float frameTime)
}

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

Expand Down
39 changes: 39 additions & 0 deletions Resources/Prototypes/GameRules/cargo_gifts.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
# Add your new event to this RandomRule if you want it to happen via the basic/ramping schedulers.
- type: entity
parent: BaseGameRule
id: RandomCargoGiftsRule
components:
- type: RandomRule
selectableGameRules:
# Make the probability sum to 1 or I will remove your fingernails with toothpicks.
IProduceWidgets marked this conversation as resolved.
Show resolved Hide resolved
- id: GiftsPizzaPartySmall
prob: 0.1
orGroup: Gifts
- id: GiftsPizzaPartyLarge
prob: 0.1
orGroup: Gifts
- id: GiftsEngineering
prob: 0.1
orGroup: Gifts
- id: GiftsVendingRestock
prob: 0.1
orGroup: Gifts
- id: GiftsJanitor
prob: 0.1
orGroup: Gifts
- id: GiftsMedical
prob: 0.1
orGroup: Gifts
- id: GiftsSpacingSupplies
prob: 0.1
orGroup: Gifts
- id: GiftsFireProtection
prob: 0.1
orGroup: Gifts
- id: GiftsSecurityGuns
prob: 0.1
orGroup: Gifts
- id: GiftsSecurityRiot
prob: 0.1
orGroup: Gifts

- type: entity
id: CargoGiftsBase
parent: BaseGameRule
Expand Down
Loading
Loading