diff --git a/Content.Server/_WH14K/Altar/AltarComponent.cs b/Content.Server/_WH14K/Altar/AltarComponent.cs new file mode 100644 index 00000000000..84f55575a81 --- /dev/null +++ b/Content.Server/_WH14K/Altar/AltarComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Server._WH14K.Altar; + +[RegisterComponent] +public sealed partial class AltarComponent : Component +{ + // TODO: this is shit, remake it soon + [DataField] + public bool Exploded = false; +} diff --git a/Content.Server/_WH14K/Altar/AltarSystem.cs b/Content.Server/_WH14K/Altar/AltarSystem.cs new file mode 100644 index 00000000000..b43a98398b0 --- /dev/null +++ b/Content.Server/_WH14K/Altar/AltarSystem.cs @@ -0,0 +1,18 @@ +using Content.Server._WH14K.GameTicking.Rules; + +namespace Content.Server._WH14K.Altar; + +public sealed partial class AltarSystem : EntitySystem +{ + [Dependency] private readonly PlanetaryWarfareRuleSystem _pw = default!; + public override void Initialize() + { + base.Initialize(); + } + + private void AltarExploded(AltarComponent component) + { + component.Exploded = true; + _pw.CheckRoundShouldEnd(); + } +} diff --git a/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/CommandIGComponent.cs b/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/CommandIGComponent.cs new file mode 100644 index 00000000000..5cbb07d31dc --- /dev/null +++ b/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/CommandIGComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Server._WH14K.GameTicking.Rules; + +[RegisterComponent] +public sealed partial class CommandIGComponent : Component +{ + +} diff --git a/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/PlanetaryWarfareRuleComponent.cs b/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/PlanetaryWarfareRuleComponent.cs new file mode 100644 index 00000000000..927f971fb6a --- /dev/null +++ b/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/PlanetaryWarfareRuleComponent.cs @@ -0,0 +1,16 @@ +namespace Content.Server._WH14K.GameTicking.Rules; + +[RegisterComponent, Access(typeof(PlanetaryWarfareRuleSystem))] +public sealed partial class PlanetaryWarfareRuleComponent : Component +{ + [DataField] + public WinTypePW WinTypePW = WinTypePW.Neutral; +} + +public enum WinTypePW : byte +{ + AllCommandDead, + WarpStormSummoned, + Neutral, + AllAltarExploded +} diff --git a/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/PlanetaryWarfareRuleSystem.cs b/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/PlanetaryWarfareRuleSystem.cs new file mode 100644 index 00000000000..63a0ee95126 --- /dev/null +++ b/Content.Server/_WH14K/GameTicking/Rules/PlanetaryWarfare/PlanetaryWarfareRuleSystem.cs @@ -0,0 +1,138 @@ +using Content.Server.Antag; +using Content.Server.Communications; +using Content.Server.GameTicking; +using Content.Server.GameTicking.Rules; +using Content.Server.RoundEnd; +using Content.Server.GameTicking.Rules.Components; +using Content.Server.Popups; +using Content.Server._WH14K.WarpShtorm; +using Content.Server._WH14K.Altar; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.GameTicking.Components; +using Robust.Shared.Utility; +using Robust.Shared.Map.Components; +using Content.Shared.Mind; +using Robust.Server.Player; + +namespace Content.Server._WH14K.GameTicking.Rules; + +public sealed partial class PlanetaryWarfareRuleSystem : GameRuleSystem +{ + [Dependency] private readonly RoundEndSystem _roundEndSystem = default!; + [Dependency] private readonly IPlayerManager _player = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnComponentRemove); + SubscribeLocalEvent(OnMobStateChanged); + } + + protected override void AppendRoundEndText(EntityUid uid, PlanetaryWarfareRuleComponent component, GameRuleComponent gameRule, ref RoundEndTextAppendEvent args) + { + switch (component.WinTypePW) + { + case WinTypePW.WarpStormSummoned: + args.AddLine(Loc.GetString("pw-chaos-win")); + args.AddLine(Loc.GetString("pw-warp-storm-summoned-desc")); + break; + case WinTypePW.AllCommandDead: + args.AddLine(Loc.GetString("pw-chaos-win")); + args.AddLine(Loc.GetString("pw-all-command-dead-desc")); + break; + case WinTypePW.AllAltarExploded: + args.AddLine(Loc.GetString("pw-ig-win")); + args.AddLine(Loc.GetString("pw-all-altars-exploded-desc")); + break; + default: + break; + } + + var igCommand = EntityQuery(true); + foreach (var (ig, mind) in igCommand) + { + if (mind is null || mind.CharacterName is null || mind.OriginalOwnerUserId is null) + return; + + _player.TryGetPlayerData(mind.OriginalOwnerUserId.Value, out var data); + + if (data == null) + return; + args.AddLine(Loc.GetString("ig-command-list-start")); + + args.AddLine(Loc.GetString("ig-command-list-name-user", ("name", mind.CharacterName), ("user", data.UserName))); + } + } + + private void OnComponentRemove(EntityUid uid, CommandIGComponent component, ComponentRemove args) + { + CheckRoundShouldEnd(); + } + + private void OnMobStateChanged(EntityUid uid, CommandIGComponent component, MobStateChangedEvent ev) + { + if (ev.NewMobState == MobState.Dead) + CheckRoundShouldEnd(); + } + + public void CheckRoundShouldEnd() + { + var query = QueryActiveRules(); + while (query.MoveNext(out var uid, out _, out var pw, out _)) + { + WarpStormSummoned((uid, pw)); + AllCommandDead((uid, pw)); + AllAltarExploded((uid, pw)); + } + } + + private void AllCommandDead(Entity ent) + { + var igCommand = EntityQuery(true); + + foreach (var (ig, igMobState) in igCommand) + { + if (igMobState.CurrentState == MobState.Alive) + { + return; + } + } + + ent.Comp.WinTypePW = WinTypePW.AllCommandDead; + _roundEndSystem.EndRound(); + } + + private void AllAltarExploded(Entity ent) + { + var altars = EntityQuery(true); + + foreach (var altar in altars) + { + if (!altar.Exploded) + { + return; + } + } + + ent.Comp.WinTypePW = WinTypePW.AllAltarExploded; + _roundEndSystem.EndRound(); + } + + private void WarpStormSummoned(Entity ent) + { + var warpStorms = EntityQuery(); + foreach (var warpStorm in warpStorms) + { + var mapQuery = EntityQueryEnumerator(); + while (mapQuery.MoveNext(out var uid, out var map)) + { + map.AmbientLightColor = Color.FromHex("#e82a2a"); + Dirty(uid, map); + } + + ent.Comp.WinTypePW = WinTypePW.WarpStormSummoned; + _roundEndSystem.EndRound(); + } + } +} diff --git a/Content.Server/_WH14K/WarpShtorm/WarpStormComponent.cs b/Content.Server/_WH14K/WarpShtorm/WarpStormComponent.cs new file mode 100644 index 00000000000..28c9e4b617c --- /dev/null +++ b/Content.Server/_WH14K/WarpShtorm/WarpStormComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Server._WH14K.WarpShtorm; + +[RegisterComponent] +public sealed partial class WarpStormComponent : Component +{ +} diff --git a/Content.Server/_WH14K/WarpShtorm/WarpStormSystem.cs b/Content.Server/_WH14K/WarpShtorm/WarpStormSystem.cs new file mode 100644 index 00000000000..3ec035b4b65 --- /dev/null +++ b/Content.Server/_WH14K/WarpShtorm/WarpStormSystem.cs @@ -0,0 +1,17 @@ +using Content.Server._WH14K.GameTicking.Rules; + +namespace Content.Server._WH14K.WarpShtorm; + +public sealed partial class WarpStormSystem : EntitySystem +{ + [Dependency] private readonly PlanetaryWarfareRuleSystem _pw = default!; + public override void Initialize() + { + base.Initialize(); + } + + private void Summon() + { + _pw.CheckRoundShouldEnd(); + } +} diff --git a/Resources/Locale/en-US/_WH14K/pw.ftl b/Resources/Locale/en-US/_WH14K/pw.ftl new file mode 100644 index 00000000000..43b6e2c1cc0 --- /dev/null +++ b/Resources/Locale/en-US/_WH14K/pw.ftl @@ -0,0 +1,11 @@ +pw-title = Планетарное Сражение +pw-description = режим + +pw-ig-win = [color=gold][font size=16][bold]Победа Империума[/bold][/font][/color] +pw-chaos-win = [color=#9B2D30][font size=16][bold]Победа Хаоса[/bold][/font][/color] + +pw-all-command-dead-desc = Хаос смог захватить крейсер Имперской Гвардии, что вкупе с орудиями планетарной обороны позволит еретикам укрепить свое влияние в секторе. +pw-all-altars-exploded-desc = Силы Империума сумели уничтожить все алтари Темных Богов, предотвратив Варп-Шторм. Это спасло миллиарды жизней, но это только одна из тысяч планет под угрозой. +pw-warp-storm-summoned-desc = Катастрофа космического масштаба, разразившаяся в центре этой планеты, погубила триллионы жизней + +ig-command-list-start = Командирами Империума были: diff --git a/Resources/Prototypes/_WH14K/GameRules/roundstart.yml b/Resources/Prototypes/_WH14K/GameRules/roundstart.yml new file mode 100644 index 00000000000..0157f2f961b --- /dev/null +++ b/Resources/Prototypes/_WH14K/GameRules/roundstart.yml @@ -0,0 +1,5 @@ +- type: entity + parent: BaseGameRule + id: PlanetaryWarfareRule + components: + - type: PlanetaryWarfareRule diff --git a/Resources/Prototypes/_WH14K/game_presets.yml b/Resources/Prototypes/_WH14K/game_presets.yml new file mode 100644 index 00000000000..010a055ed51 --- /dev/null +++ b/Resources/Prototypes/_WH14K/game_presets.yml @@ -0,0 +1,7 @@ +- type: gamePreset + id: PlanetaryWarfare + name: pw-title + showInVote: true + description: pw-description + rules: + - PlanetaryWarfareRule