From 921a0e26fd6b46231dd84f18da9cfc7859e2f0b8 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:23:26 +0000 Subject: [PATCH] zombie gamemode semi rework (#2194) * zombie gamemode semi rework * remove 1 --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Rules/Components/DelayedRuleComponent.cs | 46 +++++++++++++++ .../GameTicking/Rules/DelayedRuleSystem.cs | 58 +++++++++++++++++++ .../game-presets/preset-zombies.ftl | 2 + Resources/Prototypes/GameRules/roundstart.yml | 20 +++++-- 4 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 Content.Server/DeltaV/GameTicking/Rules/Components/DelayedRuleComponent.cs create mode 100644 Content.Server/DeltaV/GameTicking/Rules/DelayedRuleSystem.cs create mode 100644 Resources/Locale/en-US/deltav/game-ticking/game-presets/preset-zombies.ftl diff --git a/Content.Server/DeltaV/GameTicking/Rules/Components/DelayedRuleComponent.cs b/Content.Server/DeltaV/GameTicking/Rules/Components/DelayedRuleComponent.cs new file mode 100644 index 00000000000..64f90f135e0 --- /dev/null +++ b/Content.Server/DeltaV/GameTicking/Rules/Components/DelayedRuleComponent.cs @@ -0,0 +1,46 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.DeltaV.GameTicking.Rules.Components; + +/// +/// Delays adding components to the antags of a gamerule until some time has passed. +/// +/// +/// This is used for the zombies gamemode so that new players don't hit the funny button immediately and ruin anyone else's plans. +/// +[RegisterComponent, Access(typeof(DelayedRuleSystem))] +[AutoGenerateComponentPause] +public sealed partial class DelayedRuleComponent : Component +{ + /// + /// The players must wait this length of time before gets added. + /// If they are somehow found out and get gibbed/cremated/etc before this delay is up they will not turn. + /// + [DataField(required: true)] + public TimeSpan Delay; + + /// + /// Whether to skip the delay if there is only 1 antag selected. + /// + [DataField] + public bool IgnoreSolo; + + /// + /// When the will end. + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] + public TimeSpan DelayEnds; + + /// + /// The components to add to each player's mob once the delay ends. + /// + [DataField(required: true)] + public ComponentRegistry DelayedComponents = new(); + + /// + /// Popup to show when the delay ends. + /// + [DataField(required: true)] + public LocId EndedPopup; +} diff --git a/Content.Server/DeltaV/GameTicking/Rules/DelayedRuleSystem.cs b/Content.Server/DeltaV/GameTicking/Rules/DelayedRuleSystem.cs new file mode 100644 index 00000000000..ca64ebf45e0 --- /dev/null +++ b/Content.Server/DeltaV/GameTicking/Rules/DelayedRuleSystem.cs @@ -0,0 +1,58 @@ +using Content.Server.Antag.Components; +using Content.Server.GameTicking.Rules; +using Content.Server.DeltaV.GameTicking.Rules.Components; +using Content.Shared.GameTicking.Components; +using Content.Shared.Mind; +using Content.Shared.Popups; + +namespace Content.Server.DeltaV.GameTicking.Rules; + +public sealed class DelayedRuleSystem : GameRuleSystem +{ + [Dependency] private readonly SharedPopupSystem _popup = default!; + + protected override void Started(EntityUid uid, DelayedRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) + { + base.Started(uid, component, gameRule, args); + + component.DelayEnds = Timing.CurTime + component.Delay; + } + + protected override void ActiveTick(EntityUid uid, DelayedRuleComponent component, GameRuleComponent gameRule, float frameTime) + { + base.ActiveTick(uid, component, gameRule, frameTime); + + CheckDelay((uid, component)); + } + + /// + /// Checks if the delay has ended. + /// + private void CheckDelay(Entity ent) + { + if (!TryComp(ent, out var selection)) + return; + + // skip the delay if it's just 1 player, theres no plan to ruin if you are the only one + var ends = ent.Comp.DelayEnds; + if (ent.Comp.IgnoreSolo && selection.SelectedMinds.Count < 2) + ends = Timing.CurTime; + + if (Timing.CurTime < ends) + return; + + var comps = ent.Comp.DelayedComponents; + foreach (var (mindId, _) in selection.SelectedMinds) + { + // using OriginalOwnedEntity as the player might have ghosted to try become an evil ghost antag + if (!TryComp(mindId, out var mind) || !TryGetEntity(mind.OriginalOwnedEntity, out var mob)) + continue; + + var uid = mob.Value; + _popup.PopupEntity(Loc.GetString(ent.Comp.EndedPopup), uid, uid, PopupType.LargeCaution); + EntityManager.AddComponents(uid, comps); + } + + RemCompDeferred(ent); + } +} diff --git a/Resources/Locale/en-US/deltav/game-ticking/game-presets/preset-zombies.ftl b/Resources/Locale/en-US/deltav/game-ticking/game-presets/preset-zombies.ftl new file mode 100644 index 00000000000..1bc0332154b --- /dev/null +++ b/Resources/Locale/en-US/deltav/game-ticking/game-presets/preset-zombies.ftl @@ -0,0 +1,2 @@ +zombie-bioterrorist-role-greeting = You are a syndicate sponsored bioterrorist sent to overtake the station by use of the Romerol virus. Coordinate with your team, get supplies and prepare for your eventual transformation. Death to nanotrasen! +zombie-bioterrorist-romerol-active = The romerol in your blood is now active, you are ready to transform! diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 8359a2fbd94..50de7c4b746 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -248,6 +248,13 @@ min: 600 max: 900 - type: ZombieRule + - type: DelayedRule # DeltaV: Grace period of 5 minutes before you can turn, to avoid a random passenger ruining your plan + delay: 300 + delayedComponents: + - type: PendingZombie + - type: ZombifyOnDeath + - type: IncurableZombie + endedPopup: zombie-bioterrorist-romerol-active - type: AntagSelection definitions: - prefRoles: [ InitialInfected ] @@ -258,14 +265,19 @@ - ZombieImmune - AntagImmune briefing: - text: zombie-patientzero-role-greeting + text: zombie-bioterrorist-role-greeting # DeltaV: Different greeting color: Plum sound: "/Audio/Ambience/Antag/zombie_start.ogg" components: - - type: PendingZombie - - type: ZombifyOnDeath - - type: IncurableZombie + # Begin DeltaV Removals: Moved to DelayedRule above + #- type: PendingZombie + #- type: ZombifyOnDeath + #- type: IncurableZombie + # End DeltaV Removals - type: InitialInfected + - type: AutoImplant # DeltaV: Let them communicate to come up with a plan of action + implants: + - SyndicateRadioImplant mindRoles: - MindRoleInitialInfected