From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Sun, 14 Dec 2025 02:04:28 +0000 (+0100) Subject: Killsign cleanup (#41845) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=40ae49bb8502ef7dddc63efa74f9daf7425eef16;p=space-station-14.git Killsign cleanup (#41845) * init * rsi * review * scale * it * cat, dog, nerd * rsi * I just microbalanced animation speed * raider, stinky resprite * review * HideFromOwner * hidden smite * copyright * Apply suggestions from code review --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- diff --git a/Content.Client/Administration/Systems/KillSignSystem.cs b/Content.Client/Administration/Systems/KillSignSystem.cs index f15cfe6442..f17c384c1e 100644 --- a/Content.Client/Administration/Systems/KillSignSystem.cs +++ b/Content.Client/Administration/Systems/KillSignSystem.cs @@ -1,46 +1,77 @@ using System.Numerics; using Content.Shared.Administration.Components; using Robust.Client.GameObjects; -using Robust.Shared.Utility; +using Robust.Client.Player; namespace Content.Client.Administration.Systems; public sealed class KillSignSystem : EntitySystem { [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private readonly IPlayerManager _player = default!; public override void Initialize() { SubscribeLocalEvent(KillSignAdded); SubscribeLocalEvent(KillSignRemoved); + SubscribeLocalEvent(AfterAutoHandleState); } - private void KillSignRemoved(EntityUid uid, KillSignComponent component, ComponentShutdown args) + private void KillSignRemoved(Entity ent, ref ComponentShutdown args) { - if (!TryComp(uid, out var sprite)) - return; + RemoveKillsign(ent); + } - if (!_sprite.LayerMapTryGet((uid, sprite), KillSignKey.Key, out var layer, false)) - return; + private void KillSignAdded(Entity ent, ref ComponentStartup args) + { + AddKillsign(ent); + } - _sprite.RemoveLayer((uid, sprite), layer); + private void AfterAutoHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + { + // After receiving a new state for the component, we remove the old killsign and build a new one. + // This is so changes to the sprite can be displayed live and allowing them to be edited via ViewVariables. + // This could just update an existing sprite, but this is both easier and runs rarely anyway. + RemoveKillsign(ent); + AddKillsign(ent); } - private void KillSignAdded(EntityUid uid, KillSignComponent component, ComponentStartup args) + private void AddKillsign(Entity ent) { - if (!TryComp(uid, out var sprite)) + // If we hide from owner and we ARE the owner, don't add a killsign. + // This could use session specific networking to FULLY hide it, but I am too lazy right now. + if (ent.Comp.HideFromOwner && _player.LocalEntity == ent) + return; + + if (!TryComp(ent, out var sprite)) return; - if (_sprite.LayerMapTryGet((uid, sprite), KillSignKey.Key, out var _, false)) + if (_sprite.LayerMapTryGet((ent, sprite), KillSignKey.Key, out var _, false)) return; - var adj = _sprite.GetLocalBounds((uid, sprite)).Height / 2 + ((1.0f / 32) * 6.0f); + if (ent.Comp.Sprite == null) + return; - var layer = _sprite.AddLayer((uid, sprite), new SpriteSpecifier.Rsi(new ResPath("Objects/Misc/killsign.rsi"), "sign")); - _sprite.LayerMapSet((uid, sprite), KillSignKey.Key, layer); + var adj = _sprite.GetLocalBounds((ent, sprite)).Height / 2 + ((1.0f / 32) * 6.0f); + + var layer = _sprite.AddLayer((ent, sprite), ent.Comp.Sprite); + _sprite.LayerMapSet((ent, sprite), KillSignKey.Key, layer); + _sprite.LayerSetScale((ent, sprite), layer, ent.Comp.Scale); + _sprite.LayerSetOffset((ent, sprite), layer, ent.Comp.DoOffset ? new Vector2(0.0f, adj) : new Vector2(0.0f, 0.0f)); + + if (ent.Comp.ForceUnshaded) + sprite.LayerSetShader(layer, "unshaded"); + } + + private void RemoveKillsign(Entity ent) + { + if (!TryComp(ent, out var sprite)) + return; + + if (!_sprite.LayerMapTryGet((ent, sprite), KillSignKey.Key, out var layer, false)) + return; - _sprite.LayerSetOffset((uid, sprite), layer, new Vector2(0.0f, adj)); - sprite.LayerSetShader(layer, "unshaded"); + _sprite.RemoveLayer((ent, sprite), layer); } private enum KillSignKey diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs index b7f88e6c3c..f367acbd79 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs @@ -573,13 +573,32 @@ public sealed partial class AdminVerbSystem Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Misc/killsign.rsi"), "icon"), Act = () => { - EnsureComp(args.Target); + EnsureComp(args.Target, out var comp); + comp.HideFromOwner = false; // We set it to false anyway, in case the hidden smite was used beforehand. + Dirty(args.Target, comp); }, Impact = LogImpact.Extreme, Message = string.Join(": ", killSignName, Loc.GetString("admin-smite-kill-sign-description")) }; args.Verbs.Add(killSign); + var hiddenKillSignName = Loc.GetString("admin-smite-kill-sign-hidden-name").ToLowerInvariant(); + Verb hiddenKillSign = new() + { + Text = hiddenKillSignName, + Category = VerbCategory.Smite, + Icon = new SpriteSpecifier.Rsi(new("/Textures/Objects/Misc/killsign.rsi"), "icon-hidden"), + Act = () => + { + EnsureComp(args.Target, out var comp); + comp.HideFromOwner = true; + Dirty(args.Target, comp); + }, + Impact = LogImpact.Extreme, + Message = string.Join(": ", hiddenKillSignName, Loc.GetString("admin-smite-kill-sign-hidden-description")) + }; + args.Verbs.Add(hiddenKillSign); + var cluwneName = Loc.GetString("admin-smite-cluwne-name").ToLowerInvariant(); Verb cluwne = new() { diff --git a/Content.Shared/Administration/Components/KillSignComponent.cs b/Content.Shared/Administration/Components/KillSignComponent.cs index 34c36759cc..796a98a71d 100644 --- a/Content.Shared/Administration/Components/KillSignComponent.cs +++ b/Content.Shared/Administration/Components/KillSignComponent.cs @@ -1,6 +1,43 @@ -using Robust.Shared.GameStates; +using System.Numerics; +using Robust.Shared.GameStates; +using Robust.Shared.Utility; namespace Content.Shared.Administration.Components; -[RegisterComponent, NetworkedComponent] -public sealed partial class KillSignComponent : Component; +/// +/// Displays a sprite above an entity. +/// By default a huge sign saying "KILL". +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(raiseAfterAutoHandleState: true)] +public sealed partial class KillSignComponent : Component +{ + /// + /// The sprite show above the entity. + /// + [DataField, AutoNetworkedField] + public SpriteSpecifier? Sprite = new SpriteSpecifier.Rsi(new ResPath("Objects/Misc/killsign.rsi"), "kill"); + + /// + /// Whether the granted layer should always be forced to be unshaded. + /// + [DataField, AutoNetworkedField] + public bool ForceUnshaded = true; + + /// + /// Whether the granted layer should be offset to be above the entity. + /// + [DataField, AutoNetworkedField] + public bool DoOffset = true; + + /// + /// Prevents the sign from displaying to the owner of the component, allowing everyone but them to see it. + /// + [DataField, AutoNetworkedField] + public bool HideFromOwner = false; + + /// + /// The scale of the sprite. + /// + [DataField, AutoNetworkedField] + public Vector2 Scale = Vector2.One; +} diff --git a/Resources/Locale/en-US/administration/smites.ftl b/Resources/Locale/en-US/administration/smites.ftl index e8dfbd2055..0702afb33c 100644 --- a/Resources/Locale/en-US/administration/smites.ftl +++ b/Resources/Locale/en-US/administration/smites.ftl @@ -58,6 +58,7 @@ admin-smite-vomit-organs-name = Vomit Organs admin-smite-ghostkick-name = Ghost Kick admin-smite-nyanify-name = Cat Ears admin-smite-kill-sign-name = Kill Sign +admin-smite-kill-sign-hidden-name = Hidden Kill Sign admin-smite-omni-accent-name = Omni-Accent admin-smite-crawler-name = Crawler admin-smite-homing-rod-name = Homing Rod @@ -82,6 +83,7 @@ admin-smite-become-bread-description = It turns them into bread. Really, that's admin-smite-ghostkick-description = Silently kicks the user, dropping their connection. admin-smite-nyanify-description = Forcibly add cat ears, there is no escape. admin-smite-kill-sign-description = Marks a player for death by their fellows. +admin-smite-kill-sign-hidden-description = Marks a player for death by their fellows. Hidden from the targeted player. admin-smite-cluwne-description = Cluwnes them. The suit cannot be removed and the station's crew may murder them freely. admin-smite-anger-pointing-arrows-description = Angers the pointing arrows, causing them to assault this entity explosively. admin-smite-dust-description = Reduces the target to a small pile of ash. diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/bald.png b/Resources/Textures/Objects/Misc/killsign.rsi/bald.png new file mode 100644 index 0000000000..f821c632b4 Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/bald.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/cat.png b/Resources/Textures/Objects/Misc/killsign.rsi/cat.png new file mode 100644 index 0000000000..29ec8a251b Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/cat.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/dog.png b/Resources/Textures/Objects/Misc/killsign.rsi/dog.png new file mode 100644 index 0000000000..3e648e69cc Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/dog.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/furry.png b/Resources/Textures/Objects/Misc/killsign.rsi/furry.png new file mode 100644 index 0000000000..82597e87f9 Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/furry.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/icon-hidden.png b/Resources/Textures/Objects/Misc/killsign.rsi/icon-hidden.png new file mode 100644 index 0000000000..443177e07b Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/icon-hidden.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/it.png b/Resources/Textures/Objects/Misc/killsign.rsi/it.png new file mode 100644 index 0000000000..fd33d95ec5 Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/it.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/sign.png b/Resources/Textures/Objects/Misc/killsign.rsi/kill.png similarity index 100% rename from Resources/Textures/Objects/Misc/killsign.rsi/sign.png rename to Resources/Textures/Objects/Misc/killsign.rsi/kill.png diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/meta.json b/Resources/Textures/Objects/Misc/killsign.rsi/meta.json index f756df4139..f75f8d65d0 100644 --- a/Resources/Textures/Objects/Misc/killsign.rsi/meta.json +++ b/Resources/Textures/Objects/Misc/killsign.rsi/meta.json @@ -1,25 +1,119 @@ { "version": 1, "license": "CC-BY-NC-SA-3.0", - "copyright": "Created by github user @moonheart08", + "copyright": "Created by github user @moonheart08 | bald, cat, dog, furry, it, nerd, peak, raider, stinky and icon-hidden states edited by ScarKy0(Github)", "size": { "x": 32, "y": 32 }, "states": [ { - "name": "sign", + "name": "bald", "directions": 1, "delays": [ [ - 0.1, - 0.1 + 0.15, + 0.15 + ] + ] + }, + { + "name": "cat", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "dog", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "furry", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "it", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "kill", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "nerd", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "peak", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "raider", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 + ] + ] + }, + { + "name": "stinky", + "directions": 1, + "delays": [ + [ + 0.15, + 0.15 ] ] }, { "name": "icon", "directions": 1 + }, + { + "name": "icon-hidden", + "directions": 1 } ] } diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/nerd.png b/Resources/Textures/Objects/Misc/killsign.rsi/nerd.png new file mode 100644 index 0000000000..0829fe7bf7 Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/nerd.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/peak.png b/Resources/Textures/Objects/Misc/killsign.rsi/peak.png new file mode 100644 index 0000000000..165c6c56e5 Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/peak.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/raider.png b/Resources/Textures/Objects/Misc/killsign.rsi/raider.png new file mode 100644 index 0000000000..278d2a3d9e Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/raider.png differ diff --git a/Resources/Textures/Objects/Misc/killsign.rsi/stinky.png b/Resources/Textures/Objects/Misc/killsign.rsi/stinky.png new file mode 100644 index 0000000000..1924bd354d Binary files /dev/null and b/Resources/Textures/Objects/Misc/killsign.rsi/stinky.png differ