diff --git a/Content.Client/Revolutionary/UI/DeconvertedEui.cs b/Content.Client/Revolutionary/UI/DeconvertedEui.cs
new file mode 100644
index 0000000000..33495f8a97
--- /dev/null
+++ b/Content.Client/Revolutionary/UI/DeconvertedEui.cs
@@ -0,0 +1,25 @@
+using Content.Client.Eui;
+
+namespace Content.Client.Revolutionary.UI;
+
+public sealed class DeconvertedEui : BaseEui
+{
+ private readonly DeconvertedMenu _menu;
+
+ public DeconvertedEui()
+ {
+ _menu = new DeconvertedMenu();
+ }
+
+ public override void Opened()
+ {
+ _menu.OpenCentered();
+ }
+
+ public override void Closed()
+ {
+ base.Closed();
+
+ _menu.Close();
+ }
+}
diff --git a/Content.Client/Revolutionary/UI/DeconvertedMenu.xaml b/Content.Client/Revolutionary/UI/DeconvertedMenu.xaml
new file mode 100644
index 0000000000..14b31c1950
--- /dev/null
+++ b/Content.Client/Revolutionary/UI/DeconvertedMenu.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/Content.Client/Revolutionary/UI/DeconvertedMenu.xaml.cs b/Content.Client/Revolutionary/UI/DeconvertedMenu.xaml.cs
new file mode 100644
index 0000000000..ed32473a88
--- /dev/null
+++ b/Content.Client/Revolutionary/UI/DeconvertedMenu.xaml.cs
@@ -0,0 +1,16 @@
+using Content.Client.UserInterface.Controls;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Revolutionary.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class DeconvertedMenu : FancyWindow
+{
+ public DeconvertedMenu()
+ {
+ RobustXamlLoader.Load(this);
+
+ ConfirmButton.OnPressed += _ => Close();
+ }
+}
diff --git a/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs b/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs
index d8d3177267..869bd128fd 100644
--- a/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs
+++ b/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs
@@ -2,12 +2,14 @@ using System.Linq;
using Content.Server.Administration.Logs;
using Content.Server.Antag;
using Content.Server.Chat.Managers;
+using Content.Server.EUI;
using Content.Server.Flash;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Mind;
using Content.Server.NPC.Components;
using Content.Server.NPC.Systems;
using Content.Server.Popups;
+using Content.Server.Revolutionary;
using Content.Server.Revolutionary.Components;
using Content.Server.Roles;
using Content.Server.RoundEnd;
@@ -16,6 +18,7 @@ using Content.Shared.Database;
using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement;
using Content.Shared.Mind;
+using Content.Shared.Mind.Components;
using Content.Shared.Mindshield.Components;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
@@ -39,6 +42,7 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem();
- while (rev.MoveNext(out var uid, out _))
+ var rev = AllEntityQuery();
+ while (rev.MoveNext(out var uid, out _, out var mc))
{
- if (!HasComp(uid))
- {
- _npcFaction.RemoveFaction(uid, RevolutionaryNpcFaction);
- _stun.TryParalyze(uid, stunTime, true);
- RemCompDeferred(uid);
- _popup.PopupEntity(Loc.GetString("rev-break-control", ("name", Identity.Entity(uid, EntityManager))), uid);
- _adminLogManager.Add(LogType.Mind, LogImpact.Medium, $"{ToPrettyString(uid)} was deconverted due to all Head Revolutionaries dying.");
- }
+ if (HasComp(uid))
+ continue;
+
+ _npcFaction.RemoveFaction(uid, RevolutionaryNpcFaction);
+ _stun.TryParalyze(uid, stunTime, true);
+ RemCompDeferred(uid);
+ _popup.PopupEntity(Loc.GetString("rev-break-control", ("name", Identity.Entity(uid, EntityManager))), uid);
+ _adminLogManager.Add(LogType.Mind, LogImpact.Medium, $"{ToPrettyString(uid)} was deconverted due to all Head Revolutionaries dying.");
+
+ if (!_mind.TryGetMind(uid, out var mindId, out var mind, mc))
+ continue;
+
+ // remove their antag role
+ _role.MindTryRemoveRole(mindId);
+
+ // make it very obvious to the rev they've been deconverted since
+ // they may not see the popup due to antag and/or new player tunnel vision
+ if (_mind.TryGetSession(mindId, out var session))
+ _euiMan.OpenEui(new DeconvertedEui(), session);
}
return true;
}
diff --git a/Content.Server/Revolutionary/DeconvertedEui.cs b/Content.Server/Revolutionary/DeconvertedEui.cs
new file mode 100644
index 0000000000..5dfed2f08f
--- /dev/null
+++ b/Content.Server/Revolutionary/DeconvertedEui.cs
@@ -0,0 +1,8 @@
+using Content.Server.EUI;
+
+namespace Content.Server.Revolutionary;
+
+public sealed class DeconvertedEui : BaseEui
+{
+ // serverside it does nothing since its just to inform the player
+}
diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl
index 4ace8f96d2..5fb1d40b3d 100644
--- a/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl
+++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-revolutionary.ftl
@@ -64,3 +64,12 @@ rev-headrev-name = [color=#5e9cff]{$name}[/color] converted {$count} {$count ->
[one] person
*[other] people
}
+
+## Deconverted window
+
+rev-deconverted-title = Deconverted!
+rev-deconverted-text =
+ As the last headrev has died, the revolution is over.
+
+ You are no longer a revolutionary, so be nice.
+rev-deconverted-confirm = Confirm