diff --git a/Content.Shared/KillTome/KillTomeComponent.cs b/Content.Shared/KillTome/KillTomeComponent.cs deleted file mode 100644 index 266ff1a8f8..0000000000 --- a/Content.Shared/KillTome/KillTomeComponent.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Content.Shared.Damage; -using Content.Shared.Damage.Prototypes; -using Content.Shared.FixedPoint; -using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; - -namespace Content.Shared.KillTome; - -/// -/// Paper with that component is KillTome. -/// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -public sealed partial class KillTomeComponent : Component -{ - /// - /// if delay is not specified, it will use this default value - /// - [DataField, AutoNetworkedField] - public TimeSpan DefaultKillDelay = TimeSpan.FromSeconds(40); - - /// - /// Damage specifier that will be used to kill the target. - /// - [DataField, AutoNetworkedField] - public DamageSpecifier Damage = new() - { - DamageDict = new Dictionary - { - { "Blunt", 200 } - } - }; - - /// - /// to keep a track of already killed people so they won't be killed again - /// - [DataField] - public HashSet KilledEntities = []; -} diff --git a/Content.Shared/KillTome/KillTomeSystem.cs b/Content.Shared/KillTome/KillTomeSystem.cs deleted file mode 100644 index bd49c483d9..0000000000 --- a/Content.Shared/KillTome/KillTomeSystem.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using Content.Shared.Administration.Logs; -using Content.Shared.Damage; -using Content.Shared.Database; -using Content.Shared.Humanoid; -using Content.Shared.Mobs; -using Content.Shared.Mobs.Components; -using Content.Shared.NameModifier.EntitySystems; -using Content.Shared.Paper; -using Content.Shared.Popups; -using Robust.Shared.Timing; -using Robust.Shared.Utility; - -namespace Content.Shared.KillTome; - -/// -/// This handles KillTome functionality. -/// - -/// Kill Tome Rules: -// 1. The humanoid whose name is written in this note shall die. -// 2. If the name is shared by multiple humanoids, a random humanoid with that name will die. -// 3. Each name shall be written on a new line. -// 4. Names must be written in the format: "Name, Delay (in seconds)" (e.g., John Doe, 40). -// 5. A humanoid can be killed by the same Kill Tome only once. -public sealed class KillTomeSystem : EntitySystem -{ - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly SharedPopupSystem _popupSystem = default!; - [Dependency] private readonly DamageableSystem _damageSystem = default!; - [Dependency] private readonly ISharedAdminLogManager _adminLogs = default!; - [Dependency] private readonly NameModifierSystem _nameModifierSystem = default!; - - /// - public override void Initialize() - { - SubscribeLocalEvent(OnPaperAfterWriteInteract); - } - - public override void Update(float frameTime) - { - // Getting all the entities that are targeted by Kill Tome and checking if their kill time has passed. - // If it has, we kill them and remove the KillTomeTargetComponent. - var query = EntityQueryEnumerator(); - - while (query.MoveNext(out var uid, out var targetComp)) - { - if (_gameTiming.CurTime < targetComp.KillTime) - continue; - - // The component doesn't get removed fast enough and the update loop will run through it a few more times. - // This check is here to ensure it will not spam popups or kill you several times over. - if (targetComp.Dead) - continue; - - Kill(uid, targetComp); - - _popupSystem.PopupPredicted(Loc.GetString("killtome-death"), - Loc.GetString("killtome-death-others", ("target", uid)), - uid, - uid, - PopupType.LargeCaution); - - targetComp.Dead = true; - - RemCompDeferred(uid); - } - } - - private void OnPaperAfterWriteInteract(Entity ent, ref PaperAfterWriteEvent args) - { - // if the entity is not a paper, we don't do anything - if (!TryComp(ent.Owner, out var paper)) - return; - - var content = paper.Content; - - var lines = content.Split('\n', StringSplitOptions.RemoveEmptyEntries); - - var showPopup = false; - - foreach (var line in lines) - { - if (string.IsNullOrEmpty(line)) - continue; - - var parts = line.Split(',', 2, StringSplitOptions.RemoveEmptyEntries); - - var name = parts[0].Trim(); - - var delay = ent.Comp.DefaultKillDelay; - - if (parts.Length == 2 && Parse.TryInt32(parts[1].Trim(), out var parsedDelay) && parsedDelay > 0) - delay = TimeSpan.FromSeconds(parsedDelay); - - if (!CheckIfEligible(name, ent.Comp, out var uid)) - { - continue; - } - - // Compiler will complain if we don't check for null here. - if (uid is not { } realUid) - continue; - - showPopup = true; - - EnsureComp(realUid, out var targetComp); - - targetComp.KillTime = _gameTiming.CurTime + delay; - targetComp.Damage = ent.Comp.Damage; - - Dirty(realUid, targetComp); - - ent.Comp.KilledEntities.Add(realUid); - - Dirty(ent); - - _adminLogs.Add(LogType.Chat, - LogImpact.High, - $"{ToPrettyString(args.Actor)} has written {ToPrettyString(uid)}'s name in Kill Tome."); - } - - // If we have written at least one eligible name, we show the popup (So the player knows death note worked). - if (showPopup) - _popupSystem.PopupEntity(Loc.GetString("killtome-kill-success"), ent.Owner, args.Actor, PopupType.Large); - } - - // A person to be killed by KillTome must: - // 1. be with the name - // 2. have HumanoidAppearanceComponent (so it targets only humanoids, obv) - // 3. not be already dead - // 4. not be already killed by Kill Tome - - // If all these conditions are met, we return true and the entityUid of the person to kill. - private bool CheckIfEligible(string name, KillTomeComponent comp, [NotNullWhen(true)] out EntityUid? entityUid) - { - if (!TryFindEntityByName(name, out var uid) || - !TryComp(uid, out var mob)) - { - entityUid = null; - return false; - } - - if (uid is not { } realUid) - { - entityUid = null; - return false; - } - - if (comp.KilledEntities.Contains(realUid)) - { - entityUid = null; - return false; - } - - if (mob.CurrentState == MobState.Dead) - { - entityUid = null; - return false; - } - - entityUid = uid; - return true; - } - - private bool TryFindEntityByName(string name, [NotNullWhen(true)] out EntityUid? entityUid) - { - var query = EntityQueryEnumerator(); - - while (query.MoveNext(out var uid, out _)) - { - if (!_nameModifierSystem.GetBaseName(uid).Equals(name, StringComparison.OrdinalIgnoreCase)) - continue; - - entityUid = uid; - return true; - } - - entityUid = null; - return false; - } - - private void Kill(EntityUid uid, KillTomeTargetComponent comp) - { - _damageSystem.TryChangeDamage(uid, comp.Damage, true); - } -} diff --git a/Content.Shared/KillTome/KillTomeTargetComponent.cs b/Content.Shared/KillTome/KillTomeTargetComponent.cs deleted file mode 100644 index 14a573b75f..0000000000 --- a/Content.Shared/KillTome/KillTomeTargetComponent.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Content.Shared.Damage; -using Content.Shared.FixedPoint; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; - -namespace Content.Shared.KillTome; - -/// -/// Entity with this component is a Kill Tome target. -/// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] -public sealed partial class KillTomeTargetComponent : Component -{ - /// - /// Damage that will be dealt to the target. - /// - [DataField, AutoNetworkedField] - public DamageSpecifier Damage = new() - { - DamageDict = new Dictionary - { - { "Blunt", 200 } - } - }; - - /// - /// The time when the target is killed. - /// - [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] - [AutoPausedField] - public TimeSpan KillTime = TimeSpan.Zero; - - /// - /// Indicates this target has been killed by the killtome. - /// - [DataField, AutoNetworkedField] - public bool Dead; - - // Disallows cheat clients from seeing who is about to die to the killtome. - public override bool SendOnlyToOwner => true; -} diff --git a/Content.Shared/Paper/PaperSystem.cs b/Content.Shared/Paper/PaperSystem.cs index 6a181e4ae9..75496d93b4 100644 --- a/Content.Shared/Paper/PaperSystem.cs +++ b/Content.Shared/Paper/PaperSystem.cs @@ -187,7 +187,6 @@ public sealed class PaperSystem : EntitySystem { var ev = new PaperWriteAttemptEvent(entity.Owner); RaiseLocalEvent(args.Actor, ref ev); - if (ev.Cancelled) return; @@ -212,9 +211,6 @@ public sealed class PaperSystem : EntitySystem entity.Comp.Mode = PaperAction.Read; UpdateUserInterface(entity); - - var writeAfterEv = new PaperAfterWriteEvent(args.Actor); - RaiseLocalEvent(entity.Owner, ref writeAfterEv); } private void OnRandomPaperContentMapInit(Entity ent, ref MapInitEvent args) @@ -323,14 +319,6 @@ public record struct PaperWriteEvent(EntityUid User, EntityUid Paper); /// /// Cancellable event for attempting to write on a piece of paper. /// -/// The paper that the writing will take place on. +/// The paper that the writing will take place on. [ByRefEvent] public record struct PaperWriteAttemptEvent(EntityUid Paper, string? FailReason = null, bool Cancelled = false); - -/// -/// Event raised on paper after it was written on by someone. -/// -/// Entity that wrote something on the paper. -[ByRefEvent] -public readonly record struct PaperAfterWriteEvent(EntityUid Actor); - diff --git a/Resources/Locale/en-US/killtome.ftl b/Resources/Locale/en-US/killtome.ftl deleted file mode 100644 index 2a45db41ff..0000000000 --- a/Resources/Locale/en-US/killtome.ftl +++ /dev/null @@ -1,11 +0,0 @@ -killtome-rules = - Kill Tome Rules: - 1. The humanoid whose name is written in this note shall die. - 2. If the name is shared by multiple humanoids, a random humanoid with that name will die. - 3. Each name shall be written on a new line. - 4. Names must be written in the format: "Name, Delay (in seconds)" (e.g., John Doe, 40). - 5. A humanoid can be killed by the same Kill Tome only once. - -killtome-kill-success = The name is written. The countdown begins. -killtome-death = You feel sudden pain in your chest! -killtome-death-others = {CAPITALIZE($target)} grabs onto {POSS-ADJ($target)} chest and falls to the ground! diff --git a/Resources/Prototypes/Entities/Objects/Misc/killtome.yml b/Resources/Prototypes/Entities/Objects/Misc/killtome.yml deleted file mode 100644 index 41339a9281..0000000000 --- a/Resources/Prototypes/Entities/Objects/Misc/killtome.yml +++ /dev/null @@ -1,24 +0,0 @@ -- type: entity - name: black tome - parent: BasePaper - id: KillTome - suffix: KillTome, Admeme # To stay true to the lore, please never make this accessible outside of divine intervention (admeme). - description: A worn black tome. It smells like old paper. - components: - - type: Sprite - sprite: Objects/Misc/killtome.rsi - state: icon - - type: KillTome - defaultKillDelay: 40 - damage: - types: - Blunt: 200 - - type: Paper - content: killtome-rules - - type: ActivatableUI - key: enum.PaperUiKey.Key - requiresComplex: false - - type: UserInterface - interfaces: - enum.PaperUiKey.Key: - type: PaperBoundUserInterface diff --git a/Resources/Textures/Objects/Misc/killtome.rsi/icon.png b/Resources/Textures/Objects/Misc/killtome.rsi/icon.png deleted file mode 100644 index b3f5427ebe..0000000000 Binary files a/Resources/Textures/Objects/Misc/killtome.rsi/icon.png and /dev/null differ diff --git a/Resources/Textures/Objects/Misc/killtome.rsi/meta.json b/Resources/Textures/Objects/Misc/killtome.rsi/meta.json deleted file mode 100644 index b418b2056f..0000000000 --- a/Resources/Textures/Objects/Misc/killtome.rsi/meta.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "alexmactep", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" - } - ] -}