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

zombie gamemode semi rework #2194

Merged
merged 3 commits into from
Nov 26, 2024
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
@@ -0,0 +1,46 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Server.DeltaV.GameTicking.Rules.Components;

/// <summary>
/// Delays adding components to the antags of a gamerule until some time has passed.
/// </summary>
/// <remarks>
/// This is used for the zombies gamemode so that new players don't hit the funny button immediately and ruin anyone else's plans.
/// </remarks>
[RegisterComponent, Access(typeof(DelayedRuleSystem))]
[AutoGenerateComponentPause]
public sealed partial class DelayedRuleComponent : Component
{
/// <summary>
/// The players must wait this length of time before <see cref="DelayedComponents"/> gets added.
/// If they are somehow found out and get gibbed/cremated/etc before this delay is up they will not turn.
/// </summary>
[DataField(required: true)]
public TimeSpan Delay;

/// <summary>
/// Whether to skip the delay if there is only 1 antag selected.
/// </summary>
[DataField]
public bool IgnoreSolo;

/// <summary>
/// When the <see cref="Delay"/> will end.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan DelayEnds;

/// <summary>
/// The components to add to each player's mob once the delay ends.
/// </summary>
[DataField(required: true)]
public ComponentRegistry DelayedComponents = new();

/// <summary>
/// Popup to show when the delay ends.
/// </summary>
[DataField(required: true)]
public LocId EndedPopup;
}
58 changes: 58 additions & 0 deletions Content.Server/DeltaV/GameTicking/Rules/DelayedRuleSystem.cs
Original file line number Diff line number Diff line change
@@ -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<DelayedRuleComponent>
{
[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));
}

/// <summary>
/// Checks if the delay has ended.
/// </summary>
private void CheckDelay(Entity<DelayedRuleComponent> ent)
{
if (!TryComp<AntagSelectionComponent>(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<MindComponent>(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<DelayedRuleComponent>(ent);
}
}
Original file line number Diff line number Diff line change
@@ -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!
20 changes: 16 additions & 4 deletions Resources/Prototypes/GameRules/roundstart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]
Expand All @@ -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

Expand Down
Loading