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

Prevent willful deconversion of Revolutionaries #24391

Closed
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
15 changes: 11 additions & 4 deletions Content.Server/Implants/ImplanterSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,17 @@ private void OnImplanterAfterInteract(EntityUid uid, ImplanterComponent componen
if (implant == null)
return;

// show popup to the user saying implant failed
var name = Identity.Name(target, EntityManager, args.User);
var msg = Loc.GetString("implanter-component-implant-failed", ("implant", implant), ("target", name));
_popup.PopupEntity(msg, target, args.User);
// optionally, show popup to explain why the implant failed
var ev = new PopupAfterFailedImplantEvent(args.User, target, implant.Value);
RaiseLocalEvent(target, ev);
if (!ev.Handled)
{
// show generic popup saying the implant failed
var name = Identity.Name(target, EntityManager, args.User);
var msg = Loc.GetString("implanter-component-implant-failed", ("implant", implant), ("target", name));
_popup.PopupEntity(msg, target, args.User);
}

// prevent further interaction since popup was shown
args.Handled = true;
return;
Expand Down
15 changes: 15 additions & 0 deletions Content.Shared/Implants/SharedImplanterSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,18 @@ public AddImplantAttemptEvent(EntityUid user, EntityUid target, EntityUid implan
Implanter = implanter;
}
}

public sealed class PopupAfterFailedImplantEvent : CancellableEntityEventArgs
{
public readonly EntityUid User;
public readonly EntityUid Target;
public readonly EntityUid Implant;
public bool Handled = false;

public PopupAfterFailedImplantEvent(EntityUid user, EntityUid target, EntityUid implant)
{
User = user;
Target = target;
Implant = implant;
}
}
39 changes: 39 additions & 0 deletions Content.Shared/Revolutionary/SharedRevolutionarySystem.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,61 @@
using Content.Shared.IdentityManagement;
using Content.Shared.Implants;
using Content.Shared.Mindshield.Components;
using Content.Shared.Popups;
using Content.Shared.Revolutionary.Components;
using Content.Shared.Stunnable;
using Content.Shared.Tag;

namespace Content.Shared.Revolutionary;

public sealed class SharedRevolutionarySystem : EntitySystem
{
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedStunSystem _sharedStun = default!;
[Dependency] private readonly TagSystem _tag = default!;

[ValidatePrototypeId<TagPrototype>]
public const string MindShieldTag = "MindShield";

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RevolutionaryComponent, AddImplantAttemptEvent>(PreventSelfDeconvert);
SubscribeLocalEvent<RevolutionaryComponent, PopupAfterFailedImplantEvent>(InformTargetWasSelf);
SubscribeLocalEvent<MindShieldComponent, MapInitEvent>(MindShieldImplanted);
}

/// <summary>
/// Prevents Revs from attempting to implant themselves with a mindshield.
/// </summary>
public void PreventSelfDeconvert(EntityUid uid, RevolutionaryComponent comp, ref AddImplantAttemptEvent ev)
{
if (IsMindshieldTargetSelf(ev.User, ev.Target, ev.Implant))
{
ev.Cancel();
}
}

/// <summary>
/// Informs the Rev why the implant failed.
/// </summary>
public void InformTargetWasSelf(EntityUid uid, RevolutionaryComponent comp, ref PopupAfterFailedImplantEvent ev)
{
if (IsMindshieldTargetSelf(ev.User, ev.Target, ev.Implant))
{
_popupSystem.PopupEntity(Loc.GetString("rev-fail-self-mindshield"), ev.User);
ev.Handled = true;
}
}

/// <summary>
/// Checks if a Rev is attempting to implant themselves with a mindshield.
/// </summary>
public bool IsMindshieldTargetSelf(EntityUid user, EntityUid target, EntityUid implant)
{
return _tag.HasTag(implant, MindShieldTag) && HasComp<RevolutionaryComponent>(user) && !HasComp<HeadRevolutionaryComponent>(user) && user == target;
}

/// <summary>
/// When the mindshield is implanted in the rev it will popup saying they were deconverted. In Head Revs it will remove the mindshield component.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ rev-role-greeting =

rev-briefing = Help your head revolutionaries kill every head to take over the station.

rev-fail-self-mindshield = You cannot bring yourself to betray the revolution!

## General

rev-title = Revolutionaries
Expand Down
Loading