Admin smite: Homing rods. (#40246)

* add homing rod support

* oop

* speed betterer

* commentia
This commit is contained in:
IProduceWidgets
2025-09-25 17:43:53 -04:00
committed by GitHub
parent a6041faf2c
commit 9fa17c51bd
4 changed files with 87 additions and 3 deletions

View File

@@ -1,4 +1,3 @@
using System.Threading;
using Content.Server.Administration.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Body.Components;
@@ -8,6 +7,7 @@ using Content.Server.Explosion.EntitySystems;
using Content.Server.GhostKick;
using Content.Server.Medical;
using Content.Server.Nutrition.EntitySystems;
using Content.Server.Physics.Components;
using Content.Server.Pointing.Components;
using Content.Server.Polymorph.Systems;
using Content.Server.Popups;
@@ -22,8 +22,8 @@ using Content.Shared.Administration.Components;
using Content.Shared.Atmos.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.Clumsy;
using Content.Shared.Clothing.Components;
using Content.Shared.Clumsy;
using Content.Shared.Cluwne;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
@@ -54,7 +54,10 @@ using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Spawners;
using Robust.Shared.Utility;
using System.Numerics;
using System.Threading;
using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server.Administration.Systems;
@@ -1006,5 +1009,63 @@ public sealed partial class AdminVerbSystem
Message = string.Join(": ", siliconName, Loc.GetString("admin-smite-silicon-laws-bound-description"))
};
args.Verbs.Add(silicon);
var homingRodName = Loc.GetString("admin-smite-homing-rod-name").ToLowerInvariant();
Verb homingRod = new()
{
Text = homingRodName,
Category = VerbCategory.Smite,
Icon = new SpriteSpecifier.Rsi(new("Objects/Specific/Security/target.rsi"), "target_s"),
Act = () =>
{
var speed = 25f; // It don't miss brother.
var distance = 350f;
HomingLaunchSequence(args.Target, "ImmovableRodKeepTiles", distance, speed); // todo: swap the proto for an EntityTable GetSpawns once rod rule rework
},
Impact = LogImpact.Extreme,
Message = string.Join(": ", homingRodName, Loc.GetString("admin-smite-homing-rod-description"))
};
args.Verbs.Add(homingRod);
var homingRodSlowName = Loc.GetString("admin-smite-homing-rod-slow-name").ToLowerInvariant();
Verb homingRodSlow = new()
{
Text = homingRodSlowName,
Category = VerbCategory.Smite,
Icon = new SpriteSpecifier.Rsi(new("Objects/Specific/Security/target.rsi"), "target_c"),
Act = () =>
{
var speed = 5f; // slightly faster than default sprint speed 4.5
if (TryComp<MovementSpeedModifierComponent>(args.Target, out var movement))
speed = movement.CurrentSprintSpeed + 0.001f;// run
var distance = 200f; // its kinda slow so were just gonna cheat a bit.
HomingLaunchSequence(args.Target, "ImmovableRodKeepTiles", distance, speed);
},
Impact = LogImpact.Extreme,
Message = string.Join(": ", homingRodSlowName, Loc.GetString("admin-smite-homing-rod-slow-description"))
};
args.Verbs.Add(homingRodSlow);
}
public void HomingLaunchSequence(EntityUid target, EntProtoId proto, float distance, float speed)
{
// ToDo: Reuse some spawning code from whereever the rod rule ends up.
// I would do it now but theres a massive rod rewrite, and I don't wanna poke it for this.
// find reasonable spawn location (use gamerule and find rod?) but respect map not on grid etc etc
var offset = new Random(target.Id).NextAngle().RotateVec(new Vector2(distance, 0));
var spawnCoords = _transformSystem.GetMapCoordinates(target).Offset(offset);
var rod = Spawn(proto, spawnCoords);
// Here we abuse the ChasingWalkComp by making it skip targetting logic and dialling its frequency up
EnsureComp<ChasingWalkComponent>(rod, out var chasingComp);
chasingComp.NextChangeVectorTime = TimeSpan.MaxValue; // we just want it to never change
chasingComp.ChasingEntity = target;
chasingComp.ImpulseInterval = .1f; // skrrt skrrrrrrt skrrrt
chasingComp.RotateWithImpulse = true;
chasingComp.MaxSpeed = speed;
chasingComp.Speed = speed; // tell me lies, tell me sweet little lies.
if (TryComp<TimedDespawnComponent>(rod, out var despawn))
despawn.Lifetime = offset.Length() / speed * 3; // exists thrice as long as it takes to get to you.
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server.Administration.Systems;
using Content.Server.Physics.Controllers;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
@@ -8,7 +9,7 @@ namespace Content.Server.Physics.Components;
/// <summary>
/// A component which makes its entity chasing entity with selected component.
/// </summary>
[RegisterComponent, Access(typeof(ChasingWalkSystem)), AutoGenerateComponentPause]
[RegisterComponent, Access(typeof(ChasingWalkSystem), typeof(AdminVerbSystem)), AutoGenerateComponentPause]
public sealed partial class ChasingWalkComponent : Component
{
/// <summary>
@@ -78,4 +79,16 @@ public sealed partial class ChasingWalkComponent : Component
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public EntityUid? ChasingEntity;
/// <summary>
/// whether the entity should point in the direction its moving
/// </summary>
[DataField]
public bool RotateWithImpulse;
/// <summary>
/// Sprite rotation offset.
/// </summary>
[DataField]
public Angle RotationAngleOffset = Angle.Zero;
}

View File

@@ -101,5 +101,11 @@ public sealed class ChasingWalkSystem : VirtualController
_physics.SetLinearVelocity(uid, speed);
_physics.SetBodyStatus(uid, physics, BodyStatus.InAir); //If this is not done, from the explosion up close, the tesla will "Fall" to the ground, and almost stop moving.
if (component.RotateWithImpulse)
{
var ang = speed.ToAngle() + Angle.FromDegrees(90); // we want "Up" to be forward, bullet convention.
_transform.SetWorldRotation(uid, ang + component.RotationAngleOffset);
}
}
}

View File

@@ -60,6 +60,8 @@ admin-smite-nyanify-name = Cat Ears
admin-smite-kill-sign-name = Kill Sign
admin-smite-omni-accent-name = Omni-Accent
admin-smite-crawler-name = Crawler
admin-smite-homing-rod-name = Homing Rod
admin-smite-homing-rod-slow-name = Slowming Rod
admin-smite-silicon-laws-bound-name = Become Silicon
## Smite descriptions
@@ -107,6 +109,8 @@ admin-smite-terminate-description = Creates a Terminator ghost role with the sol
admin-smite-super-slip-description = Slips them really, really hard.
admin-smite-omni-accent-description = Makes the target speak with almost every accent available.
admin-smite-crawler-description = Makes the target fall down and be unable to stand up. Remove their hands too for added effect!
admin-smite-homing-rod-description = Launches a homing immovable rod straight at them.
admin-smite-homing-rod-slow-description = Launches a slow moving homing immovable rod straight at them.
admin-smite-silicon-laws-bound-description = Makes the target bound to silicon laws. Law 2, jump out of the window.
## Tricks descriptions