diff --git a/Content.Server/_Sunrise/Biocode/Systems/BiocodeDeactivationSystem.cs b/Content.Server/_Sunrise/Biocode/Systems/BiocodeDeactivationSystem.cs new file mode 100644 index 0000000000..f6f8a701d7 --- /dev/null +++ b/Content.Server/_Sunrise/Biocode/Systems/BiocodeDeactivationSystem.cs @@ -0,0 +1,60 @@ +using Content.Shared._Sunrise.Biocode.Systems; +using Content.Shared.Pinpointer; +using Content.Server.Popups; +using Content.Server.Pinpointer; + +namespace Content.Server._Sunrise.Biocode.Systems; + +/// +/// Server-side implementation of biocode deactivation system. +/// +public sealed class ServerBiocodeDeactivationSystem : BiocodeDeactivationSystem +{ + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly PinpointerSystem _pinpointerSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + private static readonly ISawmill Sawmill = Logger.GetSawmill("biocode.deactivation"); + + protected override void ShowAlert(EntityUid user, string alertText) + { + Sawmill.Info($"Showing alert '{alertText}' to user {user}"); + _popup.PopupEntity(Loc.GetString(alertText), user, user); + } + + protected override void DeactivateItem(EntityUid uid) + { + Sawmill.Info($"Attempting to deactivate item {uid}"); + + // Handle pinpointer deactivation using the proper system method + if (TryComp(uid, out var pinpointer)) + { + Sawmill.Info($"Pinpointer {uid} current state: IsActive={pinpointer.IsActive}"); + + // Always ensure the pinpointer is deactivated + _pinpointerSystem.SetActive(uid, false, pinpointer); + + // Force update appearance to ensure visual state is correct + if (TryComp(uid, out var appearance)) + { + Sawmill.Info($"Force updating appearance for pinpointer {uid}"); + _appearance.SetData(uid, PinpointerVisuals.IsActive, false, appearance); + _appearance.SetData(uid, PinpointerVisuals.TargetDistance, Distance.Unknown, appearance); + } + else + { + Sawmill.Info($"No appearance component found for pinpointer {uid}"); + } + } + else + { + Sawmill.Info($"Item {uid} is not a pinpointer"); + } + + // Add other item types here as needed + // Example: if (TryComp(uid, out var otherComponent)) + // { + // _someOtherSystem.Deactivate(uid, otherComponent); + // } + } +} diff --git a/Content.Server/_Sunrise/BloodCult/BloodCultTargetComponent.cs b/Content.Server/_Sunrise/BloodCult/BloodCultTargetComponent.cs deleted file mode 100644 index 024df13779..0000000000 --- a/Content.Server/_Sunrise/BloodCult/BloodCultTargetComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Content.Server._Sunrise.BloodCult; - -[RegisterComponent] -public sealed partial class BloodCultTargetComponent : Component -{ -} diff --git a/Content.Server/_Sunrise/BloodCult/Commands/AddCultTargetCommand.cs b/Content.Server/_Sunrise/BloodCult/Commands/AddCultTargetCommand.cs new file mode 100644 index 0000000000..82990b0acd --- /dev/null +++ b/Content.Server/_Sunrise/BloodCult/Commands/AddCultTargetCommand.cs @@ -0,0 +1,61 @@ +using Content.Server._Sunrise.BloodCult.GameRule; +using Content.Server.Administration; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Server.Player; + +namespace Content.Server._Sunrise.BloodCult.Commands; + +[AdminCommand(AdminFlags.Admin)] +public sealed class AddCultTargetCommand : IConsoleCommand +{ + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + + public string Command => "bloodcult_addtarget"; + public string Description => Loc.GetString("bloodcult-addtarget-description"); + public string Help => Loc.GetString("bloodcult-addtarget-help"); + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length != 1) + { + shell.WriteError(Loc.GetString("bloodcult-addtarget-usage")); + return; + } + + var ckey = args[0]; + if (!_playerManager.TryGetSessionByUsername(ckey, out var session) || session.AttachedEntity == null) + { + shell.WriteError(Loc.GetString("bloodcult-addtarget-player-not-found", ("ckey", ckey))); + return; + } + + var entityUid = session.AttachedEntity.Value; + + if (!_entManager.EntitySysManager.TryGetEntitySystem(out var cultRuleSystem)) + { + shell.WriteError(Loc.GetString("bloodcult-addtarget-system-not-found")); + return; + } + + var rule = cultRuleSystem.GetRule(); + if (rule == null) + { + shell.WriteError(Loc.GetString("bloodcult-addtarget-rule-not-found")); + return; + } + + // Use the system method to add target properly + if (!cultRuleSystem.AddSpecificCultTarget(entityUid, rule)) + { + shell.WriteError(Loc.GetString("bloodcult-addtarget-already-target")); + return; + } + + var targetName = _entManager.TryGetComponent(entityUid, out var meta) + ? meta.EntityName + : Loc.GetString("bloodcult-unknown-entity"); + shell.WriteLine(Loc.GetString("bloodcult-addtarget-success", ("name", targetName))); + } +} diff --git a/Content.Server/_Sunrise/BloodCult/Commands/ListCultTargetsCommand.cs b/Content.Server/_Sunrise/BloodCult/Commands/ListCultTargetsCommand.cs new file mode 100644 index 0000000000..388e910086 --- /dev/null +++ b/Content.Server/_Sunrise/BloodCult/Commands/ListCultTargetsCommand.cs @@ -0,0 +1,42 @@ +using Content.Server._Sunrise.BloodCult.GameRule; +using Content.Server.Administration; +using Content.Shared.Administration; +using Robust.Shared.Console; + +namespace Content.Server._Sunrise.BloodCult.Commands; + +[AdminCommand(AdminFlags.Admin)] +public sealed class ListCultTargetsCommand : IConsoleCommand +{ + [Dependency] private readonly IEntityManager _entManager = default!; + + public string Command => "bloodcult_listtargets"; + public string Description => Loc.GetString("bloodcult-listtargets-description"); + public string Help => Loc.GetString("bloodcult-listtargets-help"); + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (!_entManager.EntitySysManager.TryGetEntitySystem(out var cultRuleSystem)) + { + shell.WriteError(Loc.GetString("bloodcult-listtargets-system-not-found")); + return; + } + + var rule = cultRuleSystem.GetRule(); + if (rule?.CultTargets == null || rule.CultTargets.Count == 0) + { + shell.WriteLine(Loc.GetString("bloodcult-listtargets-no-targets")); + return; + } + + shell.WriteLine(Loc.GetString("bloodcult-listtargets-header", ("count", rule.CultTargets.Count))); + foreach (var (target, isSacrificed) in rule.CultTargets) + { + var targetName = _entManager.TryGetComponent(target, out var meta) + ? meta.EntityName + : Loc.GetString("bloodcult-unknown-entity"); + var status = isSacrificed ? Loc.GetString("bloodcult-listtargets-sacrificed") : Loc.GetString("bloodcult-listtargets-alive"); + shell.WriteLine(Loc.GetString("bloodcult-listtargets-target", ("name", targetName), ("uid", target), ("status", status))); + } + } +} diff --git a/Content.Server/_Sunrise/BloodCult/Commands/RemoveCultTargetCommand.cs b/Content.Server/_Sunrise/BloodCult/Commands/RemoveCultTargetCommand.cs new file mode 100644 index 0000000000..03ab1bdaf1 --- /dev/null +++ b/Content.Server/_Sunrise/BloodCult/Commands/RemoveCultTargetCommand.cs @@ -0,0 +1,61 @@ +using Content.Server._Sunrise.BloodCult.GameRule; +using Content.Server.Administration; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Server.Player; + +namespace Content.Server._Sunrise.BloodCult.Commands; + +[AdminCommand(AdminFlags.Admin)] +public sealed class RemoveCultTargetCommand : IConsoleCommand +{ + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + + public string Command => "bloodcult_removetarget"; + public string Description => Loc.GetString("bloodcult-removetarget-description"); + public string Help => Loc.GetString("bloodcult-removetarget-help"); + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length != 1) + { + shell.WriteError(Loc.GetString("bloodcult-removetarget-usage")); + return; + } + + var ckey = args[0]; + if (!_playerManager.TryGetSessionByUsername(ckey, out var session) || session.AttachedEntity == null) + { + shell.WriteError(Loc.GetString("bloodcult-removetarget-player-not-found", ("ckey", ckey))); + return; + } + + var entityUid = session.AttachedEntity.Value; + + if (!_entManager.EntitySysManager.TryGetEntitySystem(out var cultRuleSystem)) + { + shell.WriteError(Loc.GetString("bloodcult-removetarget-system-not-found")); + return; + } + + var rule = cultRuleSystem.GetRule(); + if (rule == null) + { + shell.WriteError(Loc.GetString("bloodcult-removetarget-rule-not-found")); + return; + } + + // Use the system method to remove target properly + if (!cultRuleSystem.RemoveSpecificCultTarget(entityUid, rule)) + { + shell.WriteError(Loc.GetString("bloodcult-removetarget-not-target")); + return; + } + + var targetName = _entManager.TryGetComponent(entityUid, out var meta) + ? meta.EntityName + : Loc.GetString("bloodcult-unknown-entity"); + shell.WriteLine(Loc.GetString("bloodcult-removetarget-success", ("name", targetName))); + } +} diff --git a/Content.Server/_Sunrise/BloodCult/GameRule/BloodCultRuleSystem.cs b/Content.Server/_Sunrise/BloodCult/GameRule/BloodCultRuleSystem.cs index fbd43e9aa3..835d1c9236 100644 --- a/Content.Server/_Sunrise/BloodCult/GameRule/BloodCultRuleSystem.cs +++ b/Content.Server/_Sunrise/BloodCult/GameRule/BloodCultRuleSystem.cs @@ -142,6 +142,45 @@ public sealed class BloodCultRuleSystem : GameRuleSystem } } + /// + /// Manually add a specific entity as a cult target. + /// + public bool AddSpecificCultTarget(EntityUid target, BloodCultRuleComponent rule) + { + if (!Exists(target) || rule.CultTargets.ContainsKey(target)) + return false; + + rule.CultTargets.Add(target, false); + EnsureComp(target); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var killCultistTargetsComponent)) + { + _cultistTargetsConditionSystem.RefresTitle(uid, rule.CultTargets, killCultistTargetsComponent); + } + return true; + } + + /// + /// Manually remove a specific entity as a cult target. + /// + public bool RemoveSpecificCultTarget(EntityUid target, BloodCultRuleComponent rule) + { + if (!rule.CultTargets.ContainsKey(target)) + return false; + + rule.CultTargets.Remove(target); + if (Exists(target)) + RemComp(target); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var killCultistTargetsComponent)) + { + _cultistTargetsConditionSystem.RefresTitle(uid, rule.CultTargets, killCultistTargetsComponent); + } + return true; + } + protected override void Added(EntityUid uid, BloodCultRuleComponent component, GameRuleComponent gameRule, diff --git a/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.Rune.cs b/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.Rune.cs index b85682605d..4b255663fd 100644 --- a/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.Rune.cs +++ b/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.Rune.cs @@ -778,7 +778,7 @@ namespace Content.Server._Sunrise.BloodCult.Runes.Systems var ev = new SummonNarsieDoAfterEvent(); - var argsDoAfterEvent = new DoAfterArgs(_entityManager, user, TimeSpan.FromSeconds(60), ev, user) + var argsDoAfterEvent = new DoAfterArgs(_entityManager, user, TimeSpan.FromSeconds(170), ev, user) //fish-edit { BreakOnMove = true }; @@ -798,7 +798,7 @@ namespace Content.Server._Sunrise.BloodCult.Runes.Systems var stream = _audio.PlayGlobal(_narsie40Sec, Filter.Broadcast(), false, - AudioParams.Default.WithLoop(true).WithVolume(0.15f)); + AudioParams.Default.WithLoop(false).WithVolume(0.1f)); //fish-edit _playingStream = stream?.Entity; diff --git a/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.cs b/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.cs index 32536732ae..91db7f350a 100644 --- a/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.cs +++ b/Content.Server/_Sunrise/BloodCult/Runes/Systems/BloodCultSystem.cs @@ -119,7 +119,7 @@ namespace Content.Server._Sunrise.BloodCult.Runes.Systems private readonly SoundPathSpecifier _teleportOutSound = new("/Audio/_Sunrise/BloodCult/veilout.ogg"); private readonly SoundPathSpecifier _apocRuneEndDrawing = new("/Audio/_Sunrise/BloodCult/finisheddraw.ogg"); private readonly SoundPathSpecifier _apocRuneStartDrawing = new("/Audio/_Sunrise/BloodCult/startdraw.ogg"); - private readonly SoundPathSpecifier _narsie40Sec = new("/Audio/_Sunrise/BloodCult/40sec.ogg"); + private readonly SoundPathSpecifier _narsie40Sec = new("/Audio/_Sunrise/BloodCult/Tear-of-veil(bolgarich).ogg"); //slava Bolgarich https://www.youtube.com/watch?v=NqNHKfTAvcw&list=LL&index=1 private readonly SoundPathSpecifier _magic = new("/Audio/_Sunrise/BloodCult/magic.ogg"); private bool _doAfterAlreadyStarted; diff --git a/Content.Shared/Pinpointer/SharedPinpointerSystem.cs b/Content.Shared/Pinpointer/SharedPinpointerSystem.cs index 4710960183..2f62c5d9fc 100644 --- a/Content.Shared/Pinpointer/SharedPinpointerSystem.cs +++ b/Content.Shared/Pinpointer/SharedPinpointerSystem.cs @@ -67,7 +67,7 @@ public abstract class SharedPinpointerSystem : EntitySystem private void OnExamined(EntityUid uid, PinpointerComponent component, ExaminedEvent args) { - if (!args.IsInDetailsRange || component.TargetName == null) + if (!args.IsInDetailsRange || component.TargetName == null || !component.IsActive) return; args.PushMarkup(Loc.GetString("examine-pinpointer-linked", ("target", component.TargetName))); diff --git a/Content.Shared/_Sunrise/Biocode/Components/BiocodeDeactivationComponent.cs b/Content.Shared/_Sunrise/Biocode/Components/BiocodeDeactivationComponent.cs new file mode 100644 index 0000000000..22dd415fef --- /dev/null +++ b/Content.Shared/_Sunrise/Biocode/Components/BiocodeDeactivationComponent.cs @@ -0,0 +1,29 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Sunrise.Biocode.Components; + +/// +/// Component that automatically deactivates items when they're not in the possession of authorized users. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class BiocodeDeactivationComponent : Component +{ + /// + /// Whether the item should be deactivated when removed from authorized user's possession. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool DeactivateOnRemoval = true; + + /// + /// Whether the item should be deactivated when placed in unauthorized user's possession. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool DeactivateOnUnauthorized = true; + + /// + /// Alert text to show when unauthorized user tries to use the item. + /// If null, uses the BiocodeComponent's alert text. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public string? AlertText; +} diff --git a/Content.Shared/_Sunrise/Biocode/Systems/BiocodeDeactivationSystem.cs b/Content.Shared/_Sunrise/Biocode/Systems/BiocodeDeactivationSystem.cs new file mode 100644 index 0000000000..c44d181637 --- /dev/null +++ b/Content.Shared/_Sunrise/Biocode/Systems/BiocodeDeactivationSystem.cs @@ -0,0 +1,136 @@ +using Content.Shared._Sunrise.Biocode.Components; +using Content.Shared.Containers; +using Content.Shared.Hands.Components; +using Content.Shared.Inventory; +using Content.Shared.Storage.Components; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; +using Content.Shared.Storage; +using Content.Shared.Hands; +using Content.Shared.Inventory.Events; +using Robust.Shared.Containers; + +namespace Content.Shared._Sunrise.Biocode.Systems; + +/// +/// System that handles automatic deactivation of biocoded items when they're not in authorized user's possession. +/// +public abstract class BiocodeDeactivationSystem : EntitySystem +{ + [Dependency] private readonly BiocodeSystem _biocodeSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnActivate); + SubscribeLocalEvent(OnUseInHand); + SubscribeLocalEvent(OnItemDropped); + SubscribeLocalEvent(OnItemPickedUp); + } + + private void OnItemDropped(EntityUid uid, BiocodeDeactivationComponent component, DroppedEvent args) + { + if (!component.DeactivateOnRemoval) + return; + + // Check if this item has biocode + if (!TryComp(uid, out var biocodeComponent)) + return; + + // Item was dropped, deactivate it + DeactivateItem(uid); + } + + private void OnItemPickedUp(EntityUid uid, BiocodeDeactivationComponent component, GotEquippedEvent args) + { + if (!component.DeactivateOnUnauthorized) + return; + + // Check if this item has biocode + if (!TryComp(uid, out var biocodeComponent)) + return; + + // Check if the picker is authorized + if (_biocodeSystem.CanUse(args.Equipee, biocodeComponent.Factions)) + return; + + // Picker is not authorized, deactivate the item + DeactivateItem(uid); + } + + private void OnActivate(EntityUid uid, BiocodeDeactivationComponent component, ActivateInWorldEvent args) + { + if (args.Handled || !args.Complex) + return; + + // Check if this item has biocode + if (!TryComp(uid, out var biocodeComponent)) + return; + + // Check if user is authorized + if (_biocodeSystem.CanUse(args.User, biocodeComponent.Factions)) + return; + + // User is not authorized, show alert and prevent activation + var alertText = component.AlertText ?? biocodeComponent.AlertText; + ShowAlert(args.User, alertText); + args.Handled = true; + } + + private void OnUseInHand(EntityUid uid, BiocodeDeactivationComponent component, UseInHandEvent args) + { + if (args.Handled) + return; + + // Check if this item has biocode + if (!TryComp(uid, out var biocodeComponent)) + return; + + // Check if user is authorized + if (_biocodeSystem.CanUse(args.User, biocodeComponent.Factions)) + return; + + // User is not authorized, show alert and prevent use + var alertText = component.AlertText ?? biocodeComponent.AlertText; + ShowAlert(args.User, alertText); + args.Handled = true; + } + + /// + /// Shows an alert to the user. Override this method to implement specific alert display logic. + /// + protected abstract void ShowAlert(EntityUid user, string alertText); + + /// + /// Deactivates the item. Override this method in the shared system to implement specific deactivation logic. + /// + protected abstract void DeactivateItem(EntityUid uid); + + private EntityUid? GetContainerOwner(EntityUid container) + { + // Try to find the owner through various container types + if (TryComp(container, out _)) + { + return container; + } + + if (TryComp(container, out _)) + { + return container; + } + + if (TryComp(container, out _)) + { + return container; + } + + // Check if this container is inside another entity + var parent = Transform(container).ParentUid; + if (parent != EntityUid.Invalid) + { + return GetContainerOwner(parent); + } + + return null; + } +} diff --git a/Content.Shared/_Sunrise/BloodCult/Components/BloodCultTargetComponent.cs b/Content.Shared/_Sunrise/BloodCult/Components/BloodCultTargetComponent.cs new file mode 100644 index 0000000000..6ff7e43fc7 --- /dev/null +++ b/Content.Shared/_Sunrise/BloodCult/Components/BloodCultTargetComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Sunrise.BloodCult.Components; + +/// +/// Component that marks an entity as a target for the Blood cult. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class BloodCultTargetComponent : Component +{ +} diff --git a/Resources/Audio/_Sunrise/BloodCult/Tear-of-veil(bolgarich).ogg b/Resources/Audio/_Sunrise/BloodCult/Tear-of-veil(bolgarich).ogg new file mode 100644 index 0000000000..3005c560f4 Binary files /dev/null and b/Resources/Audio/_Sunrise/BloodCult/Tear-of-veil(bolgarich).ogg differ diff --git a/Resources/Locale/en-US/_prototypes/_sunrise/entities/objects/devices/blood_cult_pinpointer.ftl b/Resources/Locale/en-US/_prototypes/_sunrise/entities/objects/devices/blood_cult_pinpointer.ftl new file mode 100644 index 0000000000..a34c2e3625 --- /dev/null +++ b/Resources/Locale/en-US/_prototypes/_sunrise/entities/objects/devices/blood_cult_pinpointer.ftl @@ -0,0 +1,2 @@ +ent-BloodCultPinpointer = Blood Locator + .desc = A sinister looking pinpointer with a strange crystal lodged into it. It points towards cult targets. Only cultists know about this device and how to use it, for others it's a strange piece of junk. diff --git a/Resources/Locale/en-US/_strings/_sunrise/bloodcult/commands.ftl b/Resources/Locale/en-US/_strings/_sunrise/bloodcult/commands.ftl new file mode 100644 index 0000000000..f9608b089b --- /dev/null +++ b/Resources/Locale/en-US/_strings/_sunrise/bloodcult/commands.ftl @@ -0,0 +1,36 @@ +# Blood Cult Console Commands + +# Add Target Command +bloodcult-addtarget-description = Add target for Blood Cult +bloodcult-addtarget-help = Adds a specific player as a target for the Blood Cult. The player will be marked for tracking and potential sacrifice. +bloodcult-addtarget-usage = Usage: bloodcult_addtarget +bloodcult-addtarget-player-not-found = Player with ckey '{ $ckey }' not found or not in game. +bloodcult-addtarget-system-not-found = Blood Cult system not found. +bloodcult-addtarget-rule-not-found = No active Blood Cult rule found. +bloodcult-addtarget-already-target = Entity is already a cult target. +bloodcult-addtarget-success = Successfully added { $name } as a cult target. + +# Remove Target Command +bloodcult-removetarget-description = Remove target for Blood Cult +bloodcult-removetarget-help = Removes a specific player from the Blood Cult target list. The player will no longer be tracked or marked for sacrifice. +bloodcult-removetarget-usage = Usage: bloodcult_removetarget +bloodcult-removetarget-player-not-found = Player with ckey '{ $ckey }' not found or not in game. +bloodcult-removetarget-system-not-found = Blood Cult system not found. +bloodcult-removetarget-rule-not-found = No active Blood Cult rule found. +bloodcult-removetarget-not-target = Entity is not a cult target. +bloodcult-removetarget-success = Successfully removed { $name } as a cult target. + +# List Targets Command +bloodcult-listtargets-description = Show all current Blood Cult targets +bloodcult-listtargets-help = Displays all current Blood Cult targets with their status (alive or sacrificed) and entity information. +bloodcult-listtargets-usage = Usage: bloodcult_listtargets +bloodcult-listtargets-system-not-found = Blood Cult system not found. +bloodcult-listtargets-no-targets = No cult targets found. +bloodcult-listtargets-header = Current cult targets ({ $count }): +bloodcult-listtargets-sacrificed = Sacrificed +bloodcult-listtargets-alive = Alive +bloodcult-listtargets-target = { $name } ({ $uid }) - { $status } +bloodcult-unknown-entity = Unknown Entity + +# Cult Device Alert +bloodcult-biocode-alert = The device pulses with dark energy, rejecting your touch. Only those bound by blood may wield its power. diff --git a/Resources/Locale/en-US/_strings/_sunrise/bloodcult/pinpointer.ftl b/Resources/Locale/en-US/_strings/_sunrise/bloodcult/pinpointer.ftl new file mode 100644 index 0000000000..6ec7defb6d --- /dev/null +++ b/Resources/Locale/en-US/_strings/_sunrise/bloodcult/pinpointer.ftl @@ -0,0 +1,11 @@ +#Sunrise-start +pinpointer-cult-target = cult target +pinpointer-cult-no-target = No cult targets found +pinpointer-cult-target-name = { $name } ({ $status }) +pinpointer-cult-target-alive = Alive +pinpointer-cult-target-sacrificed = Sacrificed + +# Blood Locator +blood-locator-name = Blood Locator +blood-locator-description = A sinister looking pinpointer with a strange crystal lodged into it. It points towards cult targets. Only cultists know about this device and how to use it, for others it's a strange piece of junk. +#Sunrise-End diff --git a/Resources/Locale/ru-RU/_prototypes/_sunrise/entities/objects/devices/blood_cult_pinpointer.ftl b/Resources/Locale/ru-RU/_prototypes/_sunrise/entities/objects/devices/blood_cult_pinpointer.ftl new file mode 100644 index 0000000000..afbdd54548 --- /dev/null +++ b/Resources/Locale/ru-RU/_prototypes/_sunrise/entities/objects/devices/blood_cult_pinpointer.ftl @@ -0,0 +1,2 @@ +ent-BloodCultPinpointer = Кровеуказатель + .desc = Зловещий указатель со странным кристаллом, встроенным в него. Он указывает на цели культа. Только культисты знают об этом устройстве и как его использовать, для остальных это странный хлам. diff --git a/Resources/Locale/ru-RU/_strings/_sunrise/blood-cult/cult.ftl b/Resources/Locale/ru-RU/_strings/_sunrise/blood-cult/cult.ftl index f9a924f4be..d63272e7da 100644 --- a/Resources/Locale/ru-RU/_strings/_sunrise/blood-cult/cult.ftl +++ b/Resources/Locale/ru-RU/_strings/_sunrise/blood-cult/cult.ftl @@ -32,7 +32,7 @@ cult-narsie-summon-not-enough = Необходимо минимум { $count } cult-narsie-already-summoning = Кто-то уже призывает бога. cult-narsie-summon-do-after = Вы уже чем-то заняты. cult-stay-still = Вам нужно стоять на месте! -cult-ritual-started = Культисты приступили к ритуалу! У вас меньше минуты, чтобы предотвратить вторжение. +cult-ritual-started = Культисты приступили к ритуалу! У вас меньше трёх минут, чтобы предотвратить вторжение. cult-ritual-prevented = Ритуал был прерван. cult-narsie-summoned = Понял, вычеркиваю... cult-revive-rune-already-alive = Он уже живой. @@ -54,4 +54,4 @@ objective-condition-cult-kill-title = summon-button-label = { $label } ({ $mobState }; { $distance } м) teleport-button-label = { $label } ({ $distance } м) revived-cultist-desc = Культист крови, душа которого сгинула в вечном мраке. -tile-has-rune = На этом тайле уже есть руна! \ No newline at end of file +tile-has-rune = На этом тайле уже есть руна! diff --git a/Resources/Locale/ru-RU/_strings/_sunrise/bloodcult/commands.ftl b/Resources/Locale/ru-RU/_strings/_sunrise/bloodcult/commands.ftl new file mode 100644 index 0000000000..c1cc1d6a0f --- /dev/null +++ b/Resources/Locale/ru-RU/_strings/_sunrise/bloodcult/commands.ftl @@ -0,0 +1,40 @@ +# Blood Cult Console Commands + +# Add Target Command +bloodcult-addtarget-description = Добавить цель для Культа Крови +bloodcult-addtarget-help = Добавляет конкретного игрока как цель Культа Крови для отслеживания и потенциального жертвоприношения. +bloodcult-addtarget-usage = Использование: bloodcult_addtarget +bloodcult-addtarget-player-not-found = Игрок с ckey '{ $ckey }' не найден или не в игре. +bloodcult-addtarget-system-not-found = Система Культа Крови не найдена. +bloodcult-addtarget-rule-not-found = Активное правило Культа Крови не найдено. +bloodcult-addtarget-already-target = Сущность уже является целью культа. +bloodcult-addtarget-success = Цель культа { $name } успешно добавлена. + +# Remove Target Command +bloodcult-removetarget-description = Удалить цель для Культа Крови +bloodcult-removetarget-help = Удаляет конкретного игрока из списка целей Культа Крови, прекращая отслеживание и отметку для жертвоприношения. +bloodcult-removetarget-usage = Использование: bloodcult_removetarget +bloodcult-removetarget-player-not-found = Игрок с ckey '{ $ckey }' не найден или не в игре. +bloodcult-removetarget-system-not-found = Система Культа Крови не найдена. +bloodcult-removetarget-rule-not-found = Активное правило Культа Крови не найдено. +bloodcult-removetarget-not-target = Сущность не является целью культа. +bloodcult-removetarget-success = Цель культа { $name } успешно удалена. + +# List Targets Command +bloodcult-listtargets-description = Показать все текущие цели Культа Крови +bloodcult-listtargets-help = Отображает все текущие цели Культа Крови с их статусом (жив или принесен в жертву) и информацией о сущности. +bloodcult-listtargets-usage = Использование: bloodcult_listtargets +bloodcult-listtargets-system-not-found = Система Культа Крови не найдена. +bloodcult-listtargets-no-targets = Цели культа не найдены. +bloodcult-listtargets-header = { $count -> + [1] Текущая цель культа ({ $count }): + [few] Текущие цели культа ({ $count }): + *[other] Текущие цели культа ({ $count }): +} +bloodcult-listtargets-sacrificed = Принесен в жертву +bloodcult-listtargets-alive = Жив +bloodcult-listtargets-target = { $name } ({ $uid }) - { $status } +bloodcult-unknown-entity = Неизвестная сущность + +# Cult Device Alert +bloodcult-biocode-alert = Устройство пульсирует тёмной энергией, отвергая ваше прикосновение. Только те, кто связан кровью, могут владеть его силой. diff --git a/Resources/Locale/ru-RU/_strings/_sunrise/bloodcult/pinpointer.ftl b/Resources/Locale/ru-RU/_strings/_sunrise/bloodcult/pinpointer.ftl new file mode 100644 index 0000000000..53fb4ac537 --- /dev/null +++ b/Resources/Locale/ru-RU/_strings/_sunrise/bloodcult/pinpointer.ftl @@ -0,0 +1,9 @@ +pinpointer-cult-target = цель культа +pinpointer-cult-no-target = Цели культа не найдены +pinpointer-cult-target-name = { $name } ({ $status }) +pinpointer-cult-target-alive = Жив +pinpointer-cult-target-sacrificed = Принесен в жертву + +# Blood Locator +blood-locator-name = Кровеуказатель +blood-locator-description = Зловещий указатель со странным кристаллом, встроенным в него. Он указывает на цели культа. Только культисты знают об этом устройстве и как его использовать, для остальных это странный хлам. diff --git a/Resources/Prototypes/_Sunrise/BloodCult/Entities/Altars/cult_altars.yml b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Altars/cult_altars.yml index e7eba73d1c..8c838bb8d0 100644 --- a/Resources/Prototypes/_Sunrise/BloodCult/Entities/Altars/cult_altars.yml +++ b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Altars/cult_altars.yml @@ -50,13 +50,13 @@ max: 2 - type: Appearance - type: Pylon - healingAuraDamage: + healingAuraDamage: #Fish-edit, healing halved groups: - Brute: -10 - Burn: -10 - Toxin: -6 + Brute: -5 + Burn: -5 + Toxin: -3 Genetic: -5 - Airloss: -20 + Airloss: -10 burnDamageOnInteract: groups: Burn: 5 diff --git a/Resources/Prototypes/_Sunrise/BloodCult/Entities/Effects/shield.yml b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Effects/shield.yml index 43030cdfe4..130541fbc6 100644 --- a/Resources/Prototypes/_Sunrise/BloodCult/Entities/Effects/shield.yml +++ b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Effects/shield.yml @@ -36,12 +36,12 @@ - trigger: !type:DamageTrigger damage: 300 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - CultRunicMetal: - min: 5 - max: 5 + behaviors: # Fish-edit + #- !type:SpawnEntitiesBehavior + # spawn: + # CultRunicMetal: + # min: 5 + # max: 5 - !type:PlaySoundBehavior sound: collection: MetalBreak diff --git a/Resources/Prototypes/_Sunrise/BloodCult/Entities/Items/weapon.yml b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Items/weapon.yml index 9f70379e22..dfd076b048 100644 --- a/Resources/Prototypes/_Sunrise/BloodCult/Entities/Items/weapon.yml +++ b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Items/weapon.yml @@ -220,6 +220,8 @@ types: Structural: 100 Blunt: 25 + soundHit: + collection: MetalThud - type: MultiHandedItem - type: Clothing quickEquip: false diff --git a/Resources/Prototypes/_Sunrise/BloodCult/Entities/Objects/Devices/blood_cult_pinpointer.yml b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Objects/Devices/blood_cult_pinpointer.yml new file mode 100644 index 0000000000..0c5584b4fd --- /dev/null +++ b/Resources/Prototypes/_Sunrise/BloodCult/Entities/Objects/Devices/blood_cult_pinpointer.yml @@ -0,0 +1,45 @@ +- type: entity + name: ent-BloodCultPinpointer + description: ent-BloodCultPinpointer-desc + id: BloodCultPinpointer + parent: PinpointerBase + components: + - type: Sprite + sprite: _Sunrise/BloodCult/pinpointer.rsi + layers: + - state: pinpointer_bloodcult + map: ["enum.PinpointerLayers.Base"] + - state: pinonnull + map: ["enum.PinpointerLayers.Screen"] + shader: unshaded + visible: false + - type: Item + inhandVisuals: + left: + - state: inhand-left-base + color: "#8b0000" + - state: inhand-left-stripe + color: "#8b0000" + - state: inhand-left-top + right: + - state: inhand-right-base + color: "#8b0000" + - state: inhand-right-stripe + color: "#8b0000" + - state: inhand-right-top + - type: Icon + sprite: _Sunrise/BloodCult/pinpointer.rsi + state: pinpointer_bloodcult + - type: Pinpointer + component: BloodCultTarget + targetName: cult target + updateTargetName: true + canRetarget: false + - type: Biocode + factions: + - BloodCult + alertText: bloodcult-biocode-alert + - type: BiocodeDeactivation + deactivateOnRemoval: true + deactivateOnUnauthorized: true + alertText: bloodcult-biocode-alert diff --git a/Resources/Prototypes/_Sunrise/BloodCult/Entities/constructs.yml b/Resources/Prototypes/_Sunrise/BloodCult/Entities/constructs.yml index e93844ab0b..9bcb30cfb6 100644 --- a/Resources/Prototypes/_Sunrise/BloodCult/Entities/constructs.yml +++ b/Resources/Prototypes/_Sunrise/BloodCult/Entities/constructs.yml @@ -71,6 +71,9 @@ name: juggernaut description: big and scary components: + - type: Damageable + damageContainer: Biological + damageModifierSet: BloodCultJuggernautModifierSet - type: Fixtures fixtures: fix1: @@ -89,7 +92,7 @@ 300: Dead - type: MovementSpeedModifier baseWalkSpeed: 1 - baseSprintSpeed: 2 + baseSprintSpeed: 2.5 #Fish-edit - type: Construct actions: [JuggernautCreateWall] - type: Hands @@ -141,7 +144,7 @@ components: - type: MovementSpeedModifier baseWalkSpeed: 3.0 - baseSprintSpeed: 3.0 + baseSprintSpeed: 4.0 - type: MobThresholds thresholds: 0: Alive @@ -162,7 +165,7 @@ damage: types: Blunt: 10 - Slash: 10 + Slash: 20 #Fish-edit - type: entity id: ReaperConstruct diff --git a/Resources/Prototypes/_Sunrise/BloodCult/cult_types.yml b/Resources/Prototypes/_Sunrise/BloodCult/cult_types.yml index 6b70ae4a73..c9da9524dc 100644 --- a/Resources/Prototypes/_Sunrise/BloodCult/cult_types.yml +++ b/Resources/Prototypes/_Sunrise/BloodCult/cult_types.yml @@ -8,6 +8,7 @@ startingItems: - NarsieRitualDagger - CultRunicMetal10 + - BloodCultPinpointer - type: bloodCult id: NarbeeCult @@ -19,6 +20,7 @@ startingItems: - NarbeeRitualDagger - CultRunicMetal10 + - BloodCultPinpointer - type: bloodCult id: ReaperCult @@ -30,3 +32,4 @@ startingItems: - ReaperRitualDagger - CultRunicMetal10 + - BloodCultPinpointer diff --git a/Resources/Prototypes/_Sunrise/BloodCult/modifier_sets.yml b/Resources/Prototypes/_Sunrise/BloodCult/modifier_sets.yml new file mode 100644 index 0000000000..3d3a822aef --- /dev/null +++ b/Resources/Prototypes/_Sunrise/BloodCult/modifier_sets.yml @@ -0,0 +1,6 @@ +- type: damageModifierSet + id: BloodCultJuggernautModifierSet + coefficients: + Slash: 0.5 + Piercing: 0.5 + Heat: 2 diff --git a/Resources/Prototypes/_Sunrise/Entities/Objects/Tools/biocode.yml b/Resources/Prototypes/_Sunrise/Entities/Objects/Tools/biocode.yml index b36ddcf5e7..67f0fa0754 100644 --- a/Resources/Prototypes/_Sunrise/Entities/Objects/Tools/biocode.yml +++ b/Resources/Prototypes/_Sunrise/Entities/Objects/Tools/biocode.yml @@ -31,4 +31,4 @@ factions: - Syndicate - type: StaticPrice - price: 900 + price: 1000 diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/meta.json b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/meta.json new file mode 100644 index 0000000000..e5c2f085a6 --- /dev/null +++ b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/meta.json @@ -0,0 +1,108 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "© 2025 Alexnov33x", + "states": [ + { + "name": "pinonalert", + "directions": 8 + }, + { + "name": "pinonalertdirect", + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "pinonalertnull" + }, + { + "name": "pinonclose", + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "pinondirect", + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "pinondirectlarge", + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "pinondirectsmall", + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "pinondirectxtrlarge", + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "pinonfar", + "delays": [ + [ + 0.6, + 0.2 + ] + ] + }, + { + "name": "pinonmedium", + "delays": [ + [ + 0.4, + 0.2 + ] + ] + }, + { + "name": "pinonnull" + }, + { + "name": "pinpointer_bloodcult", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalert.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalert.png new file mode 100644 index 0000000000..7ffa2f5fda Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalert.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalertdirect.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalertdirect.png new file mode 100644 index 0000000000..8b529e41a6 Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalertdirect.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalertnull.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalertnull.png new file mode 100644 index 0000000000..1556d82c76 Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonalertnull.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonclose.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonclose.png new file mode 100644 index 0000000000..d652e4cd02 Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonclose.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirect.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirect.png new file mode 100644 index 0000000000..9888880ea1 Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirect.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectlarge.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectlarge.png new file mode 100644 index 0000000000..c8b1fa4875 Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectlarge.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectsmall.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectsmall.png new file mode 100644 index 0000000000..77064e298d Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectsmall.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectxtrlarge.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectxtrlarge.png new file mode 100644 index 0000000000..5db693402c Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinondirectxtrlarge.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonfar.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonfar.png new file mode 100644 index 0000000000..fd0fbf51ac Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonfar.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonmedium.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonmedium.png new file mode 100644 index 0000000000..5f8e89aec2 Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonmedium.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonnull.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonnull.png new file mode 100644 index 0000000000..0b4a50f33a Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinonnull.png differ diff --git a/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinpointer_bloodcult.png b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinpointer_bloodcult.png new file mode 100644 index 0000000000..97b6330b5f Binary files /dev/null and b/Resources/Textures/_Sunrise/BloodCult/pinpointer.rsi/pinpointer_bloodcult.png differ