From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com>
Date: Mon, 18 Dec 2023 19:39:23 +0000 (+0200)
Subject: Super Bonk Smite (#22413)
X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=bf2b441192036e34b4bf2c325c4c678cf8e8531c;p=space-station-14.git
Super Bonk Smite (#22413)
* Added the Super Bonk smite. It teleports the player from table to table
in the game and bonk their head into them. Also smashes them into glass
tables.
* Stopped using a timer and now instead use Comp + System. Also added proper logging impact.
* Fixed name inconsistency
* Admin CL which I forgot
* Made it funnier
* Moved basically all logic to the system and added a light version that stops when you die
* Hopefully made YAML Linter stop bullying me
* Removed fun(Glass tables no longer get smashed when the target is bonked over them)
General opinion seems that it would cause too much collateral damage. I kinda agree.
* Adressed reviews
---
diff --git a/Content.Server/Administration/Components/SuperBonkComponent.cs b/Content.Server/Administration/Components/SuperBonkComponent.cs
new file mode 100644
index 0000000000..868d232e60
--- /dev/null
+++ b/Content.Server/Administration/Components/SuperBonkComponent.cs
@@ -0,0 +1,48 @@
+using Content.Server.Administration.Systems;
+using Content.Shared.Climbing.Components;
+
+namespace Content.Server.Administration.Components;
+
+///
+/// Component to track the timer for the SuperBonk smite.
+///
+[RegisterComponent, Access(typeof(SuperBonkSystem))]
+public sealed partial class SuperBonkComponent: Component
+{
+ ///
+ /// Entity being Super Bonked.
+ ///
+ [DataField]
+ public EntityUid Target;
+
+ ///
+ /// All of the tables the target will be bonked on.
+ ///
+ [DataField]
+ public Dictionary.Enumerator Tables;
+
+ ///
+ /// Value used to reset the timer once it expires.
+ ///
+ [DataField]
+ public float InitialTime = 0.10f;
+
+ ///
+ /// Timer till the next bonk.
+ ///
+ [DataField]
+ public float TimeRemaining = 0.10f;
+
+ ///
+ /// Whether to remove the clumsy component from the target after SuperBonk is done.
+ ///
+ [DataField]
+ public bool RemoveClumsy = true;
+
+ ///
+ /// Whether to stop Super Bonk on the target once he dies. Otherwise it will continue until no other tables are left
+ /// or the target is gibbed.
+ ///
+ [DataField]
+ public bool StopWhenDead = true;
+}
diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs
index c2f07320b5..10a001be8b 100644
--- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs
+++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs
@@ -40,7 +40,6 @@ using Content.Shared.Popups;
using Content.Shared.Tabletop.Components;
using Content.Shared.Tools.Systems;
using Content.Shared.Verbs;
-using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
@@ -77,6 +76,7 @@ public sealed partial class AdminVerbSystem
[Dependency] private readonly WeldableSystem _weldableSystem = default!;
[Dependency] private readonly SharedContentEyeSystem _eyeSystem = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
+ [Dependency] private readonly SuperBonkSystem _superBonkSystem = default!;
// All smite verbs have names so invokeverb works.
private void AddSmiteVerbs(GetVerbsEvent args)
@@ -793,5 +793,32 @@ public sealed partial class AdminVerbSystem
Message = Loc.GetString("admin-smite-super-speed-description"),
};
args.Verbs.Add(superSpeed);
+ //Bonk
+ Verb superBonkLite = new()
+ {
+ Text = "Super Bonk Lite",
+ Category = VerbCategory.Smite,
+ Icon = new SpriteSpecifier.Rsi(new("Structures/Furniture/Tables/glass.rsi"), "full"),
+ Act = () =>
+ {
+ _superBonkSystem.StartSuperBonk(args.Target, stopWhenDead: true);
+ },
+ Message = Loc.GetString("admin-smite-super-bonk-lite-description"),
+ Impact = LogImpact.Extreme,
+ };
+ args.Verbs.Add(superBonkLite);
+ Verb superBonk= new()
+ {
+ Text = "Super Bonk",
+ Category = VerbCategory.Smite,
+ Icon = new SpriteSpecifier.Rsi(new("Structures/Furniture/Tables/generic.rsi"), "full"),
+ Act = () =>
+ {
+ _superBonkSystem.StartSuperBonk(args.Target);
+ },
+ Message = Loc.GetString("admin-smite-super-bonk-description"),
+ Impact = LogImpact.Extreme,
+ };
+ args.Verbs.Add(superBonk);
}
}
diff --git a/Content.Server/Administration/Systems/SuperBonkSystem.cs b/Content.Server/Administration/Systems/SuperBonkSystem.cs
new file mode 100644
index 0000000000..5488a8d6f4
--- /dev/null
+++ b/Content.Server/Administration/Systems/SuperBonkSystem.cs
@@ -0,0 +1,107 @@
+using Content.Server.Administration.Components;
+using Content.Shared.Climbing.Components;
+using Content.Shared.Climbing.Events;
+using Content.Shared.Climbing.Systems;
+using Content.Shared.Interaction.Components;
+using Content.Shared.Mobs;
+using Content.Shared.Mobs.Components;
+
+namespace Content.Server.Administration.Systems;
+
+public sealed class SuperBonkSystem: EntitySystem
+{
+ [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
+ [Dependency] private readonly BonkSystem _bonkSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnBonkShutdown);
+ SubscribeLocalEvent(OnMobStateChanged);
+ }
+
+ public void StartSuperBonk(EntityUid target, float delay = 0.1f, bool stopWhenDead = false )
+ {
+
+ //The other check in the code to stop when the target dies does not work if the target is already dead.
+ if (stopWhenDead && TryComp(target, out var mState))
+ {
+ if (mState.CurrentState == MobState.Dead)
+ return;
+ }
+
+
+ var hadClumsy = EnsureComp(target, out _);
+
+ var tables = EntityQueryEnumerator();
+ var bonks = new Dictionary();
+ // This is done so we don't crash if something like a new table is spawned.
+ while (tables.MoveNext(out var uid, out var comp))
+ {
+ bonks.Add(uid, comp);
+ }
+
+ var sComp = new SuperBonkComponent
+ {
+ Target = target,
+ Tables = bonks.GetEnumerator(),
+ RemoveClumsy = !hadClumsy,
+ StopWhenDead = stopWhenDead,
+ };
+
+ AddComp(target, sComp);
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ var comps = EntityQueryEnumerator();
+
+ while (comps.MoveNext(out var uid, out var comp))
+ {
+ comp.TimeRemaining -= frameTime;
+ if (!(comp.TimeRemaining <= 0))
+ continue;
+
+ Bonk(comp);
+
+ if (!(comp.Tables.MoveNext()))
+ {
+ RemComp(comp.Target);
+ continue;
+ }
+
+ comp.TimeRemaining = comp.InitialTime;
+ }
+ }
+
+ private void Bonk(SuperBonkComponent comp)
+ {
+ var uid = comp.Tables.Current.Key;
+ var bonkComp = comp.Tables.Current.Value;
+
+ // It would be very weird for something without a transform component to have a bonk component
+ // but just in case because I don't want to crash the server.
+ if (!HasComp(uid))
+ return;
+
+ _transformSystem.SetCoordinates(comp.Target, Transform(uid).Coordinates);
+
+ _bonkSystem.TryBonk(comp.Target, uid, bonkComp);
+ }
+
+ private void OnMobStateChanged(EntityUid uid, SuperBonkComponent comp, MobStateChangedEvent args)
+ {
+ if (comp.StopWhenDead && args.NewMobState == MobState.Dead)
+ {
+ RemComp(uid);
+ }
+ }
+
+ private void OnBonkShutdown(EntityUid uid, SuperBonkComponent comp, ComponentShutdown ev)
+ {
+ if (comp.RemoveClumsy)
+ RemComp(comp.Target);
+ }
+}
diff --git a/Resources/Changelog/Admin.yml b/Resources/Changelog/Admin.yml
index 4e0beb10e7..d537cd4d7a 100644
--- a/Resources/Changelog/Admin.yml
+++ b/Resources/Changelog/Admin.yml
@@ -70,3 +70,7 @@ Entries:
changes:
- {message: 'The respawn verb now respawns the targeted player instead of the admin', type: Fix}
time: '2023-11-22T16:39:00.0000000+00:00'
+- author: nikthechampiongr
+ changes:
+ - {message: 'The Super Bonk smite is now available. Targets will bonk their head on every single table.', type: Add}
+ time: '2023-12-12T11:54:00.0000000+00:00'
diff --git a/Resources/Locale/en-US/administration/smites.ftl b/Resources/Locale/en-US/administration/smites.ftl
index e8f9dcded5..e6b0f92b7a 100644
--- a/Resources/Locale/en-US/administration/smites.ftl
+++ b/Resources/Locale/en-US/administration/smites.ftl
@@ -55,7 +55,8 @@ admin-smite-lung-removal-description = Removes their lungs, drowning them.
admin-smite-remove-hand-description = Removes only one of their hands instead of all of them.
admin-smite-disarm-prone-description = Makes them get disarmed 100% of the time and cuffed instantly.
admin-smite-garbage-can-description = Turn them into a garbage bin to emphasize what they remind you of.
-
+admin-smite-super-bonk-description = Slams them on every single table on the Station and beyond.
+admin-smite-super-bonk-lite-description= Slams them on every single table on the Station and beyond. Stops when the target is dead.
## Tricks descriptions