From 672aff891c794abcb89bde847e2774efcd49edaf Mon Sep 17 00:00:00 2001 From: deBurboun <131053044+deBurboun@users.noreply.github.com> Date: Sun, 7 Dec 2025 13:27:37 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=BC=D0=BF=D0=BB=D0=B0=D0=BD=D1=82=20?= =?UTF-8?q?=D0=BB=D0=BE=D1=8F=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_Fish/Implants/LoyaltyImplantSystem.cs | 71 +++++++++++++++++++ .../_Fish/Implants/LoyaltyImplantComponent.cs | 23 ++++++ .../ru-RU/_fish/Implants/loyalty_implant.ftl | 21 ++++++ .../Devices/Implants/loyalty_implant.yml | 28 ++++++++ 4 files changed, 143 insertions(+) create mode 100644 Content.Server/_Fish/Implants/LoyaltyImplantSystem.cs create mode 100644 Content.Shared/_Fish/Implants/LoyaltyImplantComponent.cs create mode 100644 Resources/Locale/ru-RU/_fish/Implants/loyalty_implant.ftl create mode 100644 Resources/Prototypes/_Fish/Entities/Objects/Devices/Implants/loyalty_implant.yml diff --git a/Content.Server/_Fish/Implants/LoyaltyImplantSystem.cs b/Content.Server/_Fish/Implants/LoyaltyImplantSystem.cs new file mode 100644 index 0000000000..47189a329c --- /dev/null +++ b/Content.Server/_Fish/Implants/LoyaltyImplantSystem.cs @@ -0,0 +1,71 @@ +using Content.Shared.Implants.Components; +using Robust.Shared.Random; +using Robust.Shared.Timing; +using Content.Shared.Chat; +using Content.Server.Chat.Managers; +using Robust.Shared.Player; +using Content.Shared.Popups; +using Content.Shared.Implants; +using Content.Shared.Interaction.Events; +using Content.Server.NPC.Systems; +using Content.Shared.Mindshield.Components; + +namespace Content.Server.Implants; + +public sealed class LoyaltyImplantSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IChatManager _chatManager = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnImplanted); + } + + private void OnInit(Entity ent, ref ComponentInit args) + { + ent.Comp.NextMessageTime = _timing.CurTime + TimeSpan.FromSeconds(ent.Comp.Interval); + } + + private void OnImplanted(Entity ent, ref ImplantImplantedEvent args) + { + var implanted = args.Implanted; + + if (!TryComp(implanted, out var actor)) + return; + + var message = Loc.GetString("loyalty-implant-initial-message"); + + _popup.PopupEntity(message, implanted, implanted, PopupType.Large); + _chatManager.ChatMessageToOne(ChatChannel.Local, message, message, default, false, actor.PlayerSession.Channel); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var loyalty, out var subdermal)) + { + if (_timing.CurTime < loyalty.NextMessageTime) + continue; + + loyalty.NextMessageTime = _timing.CurTime + TimeSpan.FromSeconds(loyalty.Interval); + + if (subdermal.ImplantedEntity is not { } implanted) + continue; + + if (!TryComp(implanted, out var actor)) + continue; + + var messageIndex = _random.Next(1, 11); + var message = Loc.GetString($"loyalty-implant-message-{messageIndex}"); + + _chatManager.ChatMessageToOne(ChatChannel.Local, message, message, default, false, actor.PlayerSession.Channel); + } + } +} diff --git a/Content.Shared/_Fish/Implants/LoyaltyImplantComponent.cs b/Content.Shared/_Fish/Implants/LoyaltyImplantComponent.cs new file mode 100644 index 0000000000..c4405a1d4f --- /dev/null +++ b/Content.Shared/_Fish/Implants/LoyaltyImplantComponent.cs @@ -0,0 +1,23 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Implants.Components; + +/// +/// Component for the Loyalty Implant. +/// Periodically sends loyalty-affirming messages to the implanted entity. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class LoyaltyImplantComponent : Component +{ + /// + /// The time interval between messages in seconds. + /// + [DataField("interval")] + public float Interval = 300f; // 5 minutes default + + /// + /// The next time a message will be sent. + /// + [DataField("nextMessageTime")] + public TimeSpan NextMessageTime; +} diff --git a/Resources/Locale/ru-RU/_fish/Implants/loyalty_implant.ftl b/Resources/Locale/ru-RU/_fish/Implants/loyalty_implant.ftl new file mode 100644 index 0000000000..a71daf2444 --- /dev/null +++ b/Resources/Locale/ru-RU/_fish/Implants/loyalty_implant.ftl @@ -0,0 +1,21 @@ +loyalty-implant-message-1 = Вы уверены, что НаноТрейзен - лучшая корпорация во всей Вселенной! +loyalty-implant-message-2 = Вы считаете, что Стандартный порядок действий - это величайшая процедура, которая когда-либо существовала! +loyalty-implant-message-3 = Вы готовы отдать свою жизнь во славу НаноТрейзен! +loyalty-implant-message-4 = Вы уверены в том, что все действия НаноТрейзен приведут к всеобщему благу! +loyalty-implant-message-5 = Вы уверены, что НаноТрейзен - это не работа, это стиль жизни, который нельзя покинуть! +loyalty-implant-message-6 = Вы считаете, что все ваши мысли принадлежат НаноТрейзен - и это так успокаивает! +loyalty-implant-message-7 = Вы считаете, что ваша жизнь без НаноТрейзен была бы настолько скучной, что вы бы её и не вспомнили! +loyalty-implant-message-8 = Вы убеждены, что НаноТрейзен заботится о вас так же, как вы заботитесь о своей любимой кружке! +loyalty-implant-message-9 = Вы считаете, что работать в НаноТрейзен - это лучшее, что могло с вами случиться! +loyalty-implant-message-10 = Вы считаете, что ваш трудовой договор с НаноТрейзен - это пожизненная гарантия приключений! + +ent-LoyaltyImplant = имплант лояльности + .desc = Имплант, обеспечивающий абсолютную лояльность НаноТрейзен. + +ent-LoyaltyImplanter = имплантер лояльности + .desc = Одноразовый шприц, специально разработанный для введения подкожных имплантов. + +ent-LoyaltyImplantCase = кейс импланта лояльности + .desc = Надежный кейс, содержащий импланты лояльности. + +loyalty-implant-initial-message = В вас был введен имплант лояльности. Ваша воля подавлена. Вы теперь полностью лояльны НаноТрейзен. Вы не должны причинять вред корпорации. diff --git a/Resources/Prototypes/_Fish/Entities/Objects/Devices/Implants/loyalty_implant.yml b/Resources/Prototypes/_Fish/Entities/Objects/Devices/Implants/loyalty_implant.yml new file mode 100644 index 0000000000..c9b512dd8f --- /dev/null +++ b/Resources/Prototypes/_Fish/Entities/Objects/Devices/Implants/loyalty_implant.yml @@ -0,0 +1,28 @@ +- type: entity + parent: BaseSubdermalImplant + id: LoyaltyImplant + components: + - type: SubdermalImplant + - type: MindShieldImplant + - type: LoyaltyImplant + - type: Tag + tags: + - SubdermalImplant + +- type: entity + id: LoyaltyImplanter + parent: BaseImplantOnlyImplanter + components: + - type: Implanter + implant: LoyaltyImplant + +- type: entity + parent: Lockbox + id: LoyaltyImplantCase + components: + - type: StorageFill + contents: + - id: LoyaltyImplanter + amount: 4 + - type: AccessReader + access: [ [ "HeadOfSecurity" ], [ "Captain" ] ]