diff --git a/Content.Server/_CP14/MapEvents/CPMapEventsSchedulerComponent.cs b/Content.Server/_CP14/MapEvents/CPMapEventsSchedulerComponent.cs new file mode 100644 index 0000000000..c9f6791990 --- /dev/null +++ b/Content.Server/_CP14/MapEvents/CPMapEventsSchedulerComponent.cs @@ -0,0 +1,33 @@ +using Robust.Shared.Map; +using Robust.Shared.Prototypes; + +namespace Content.Server.CrystallPunk.MapEvents; + +/// +/// +/// + +[RegisterComponent, Access(typeof(CPMapEventsSchedulerSystem))] +public sealed partial class CPMapEventsSchedulerComponent : Component +{ + public MapId Map; + + [DataField] + public float MinimumTimeUntilFirstEvent = 300f; + + [DataField] + public float MinimumTimeBetweenEvents = 30f; + + [DataField] + public float MaximumTimeBetweenEvents = 300f; + + [DataField(required: true)] + public List WhitelistedEvents = new(); + + + /// + /// How long until the next check for an event runs + /// + [DataField] + public TimeSpan NextEventTime; +} diff --git a/Content.Server/_CP14/MapEvents/CPMapEventsSchedulerSystem.cs b/Content.Server/_CP14/MapEvents/CPMapEventsSchedulerSystem.cs new file mode 100644 index 0000000000..1e0b49a756 --- /dev/null +++ b/Content.Server/_CP14/MapEvents/CPMapEventsSchedulerSystem.cs @@ -0,0 +1,47 @@ +using Content.Server.GameTicking; +using Content.Server.GameTicking.Rules; +using Content.Server.GameTicking.Rules.Components; +using Content.Server.StationEvents; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.CrystallPunk.MapEvents; + +public sealed class CPMapEventsSchedulerSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] public readonly GameTicker GameTicker = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSchedulerInit); + } + + private void OnSchedulerInit(Entity scheduler, ref MapInitEvent args) + { + scheduler.Comp.NextEventTime = _timing.CurTime + TimeSpan.FromSeconds(scheduler.Comp.MinimumTimeUntilFirstEvent); + scheduler.Comp.Map = Transform(scheduler).MapID; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var scheduler)) + { + if (_timing.CurTime < scheduler.NextEventTime) + continue; + + var randomEvent = _random.Pick(scheduler.WhitelistedEvents); + + //var ent = GameTicker.AddGameRule(randomEvent); + GameTicker.StartGameRule(randomEvent); + + scheduler.NextEventTime = _timing.CurTime + TimeSpan.FromSeconds(_random.NextFloat(scheduler.MinimumTimeBetweenEvents, scheduler.MaximumTimeBetweenEvents)); + } + } +} diff --git a/Content.Server/_CP14/MapEvents/Components/CPWeatherRuleComponent.cs b/Content.Server/_CP14/MapEvents/Components/CPWeatherRuleComponent.cs new file mode 100644 index 0000000000..215e1b83c4 --- /dev/null +++ b/Content.Server/_CP14/MapEvents/Components/CPWeatherRuleComponent.cs @@ -0,0 +1,21 @@ +using Content.Shared.Weather; +using Robust.Shared.Prototypes; + +namespace Content.Server.CrystallPunk.MapEvents; + +/// +/// +/// + +[RegisterComponent, Access(typeof(CPWeatherRule))] +public sealed partial class CPWeatherRuleComponent : Component +{ + [DataField(required: true)] + public ProtoId Weather = "Storm"; + + [DataField] + public float MinimumLength = 60f; + + [DataField] + public float MaximumLength = 300f; +} diff --git a/Content.Server/_CP14/MapEvents/Events/CPWeatherRule.cs b/Content.Server/_CP14/MapEvents/Events/CPWeatherRule.cs new file mode 100644 index 0000000000..ba8de3add6 --- /dev/null +++ b/Content.Server/_CP14/MapEvents/Events/CPWeatherRule.cs @@ -0,0 +1,29 @@ +using Content.Server.GameTicking.Rules.Components; +using Content.Server.Station.Systems; +using Content.Server.StationEvents.Events; +using Content.Server.Weather; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.CrystallPunk.MapEvents; + + +public sealed class CPWeatherRule : StationEventSystem +{ + + [Dependency] private readonly WeatherSystem _weather = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; + protected override void Started(EntityUid uid, CPWeatherRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) + { + base.Started(uid, component, gameRule, args); + + + var mapId = GameTicker.DefaultMap; + var duration = _random.NextFloat(component.MinimumLength, component.MaximumLength); + + _weather.SetWeather(mapId, _proto.Index(component.Weather), _timing.CurTime + TimeSpan.FromSeconds(duration)); + } +} diff --git a/Resources/Maps/CrystallPunk/dev_map.yml b/Resources/Maps/CrystallPunk/dev_map.yml index b88833ef8f..a41be683a6 100644 --- a/Resources/Maps/CrystallPunk/dev_map.yml +++ b/Resources/Maps/CrystallPunk/dev_map.yml @@ -391,6 +391,14 @@ entities: - type: GridTree - type: MovedGrids - type: MapLight + - type: CPMapEventsScheduler + minimumTimeUntilFirstEvent: 5 + minimumTimeBetweenEvents: 50 + maximumTimeBetweenEvents: 120 + whitelistedEvents: + - CPWeatherRain + - CPWeatherStorm + - CPWeatherAshfallHeavy - type: DayCycle timeEntries: - startColor: "#754a4a" #Рассвет diff --git a/Resources/Prototypes/_CP14/Entities/GameRules/weather.yml b/Resources/Prototypes/_CP14/Entities/GameRules/weather.yml new file mode 100644 index 0000000000..b08f4221b3 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/GameRules/weather.yml @@ -0,0 +1,29 @@ +- type: entity + id: CPWeatherStorm + parent: BaseGameRule + noSpawn: true + components: + - type: CPWeatherRule + weather: Storm + minimumLength: 30 + maximumLength: 120 + +- type: entity + id: CPWeatherRain + parent: BaseGameRule + noSpawn: true + components: + - type: CPWeatherRule + weather: Rain + minimumLength: 30 + maximumLength: 120 + +- type: entity + id: CPWeatherAshfallHeavy + parent: BaseGameRule + noSpawn: true + components: + - type: CPWeatherRule + weather: AshfallHeavy + minimumLength: 30 + maximumLength: 120 \ No newline at end of file