Blood (#507)
* - tweak: Nerf spear. * - tweak: Blood bolt barrage. * - add: Cult stuff. * - fix: Cult fixes. * - remove: Garbage. * - fix: Multiple pylons. * - fix: Pylon placement fix. * - add: Lots of cult stuff.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Content.Client.Administration.Managers;
|
||||
using Content.Client.Ghost;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Changeling;
|
||||
using Content.Shared.Chat;
|
||||
@@ -54,7 +55,8 @@ namespace Content.Client.Chat.Managers
|
||||
|
||||
case ChatSelectChannel.Cult:
|
||||
var localEnt = _player.LocalPlayer != null ? _player.LocalPlayer.ControlledEntity : null;
|
||||
if (_entityManager.TryGetComponent(localEnt, out CultistComponent? comp))
|
||||
if (_entityManager.HasComponent<CultistComponent>(localEnt) ||
|
||||
_entityManager.HasComponent<ConstructComponent>(localEnt))
|
||||
_consoleHost.ExecuteCommand($"csay \"{CommandParsing.Escape(text)}\"");
|
||||
break;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ using Content.Shared.Damage.ForceSay;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared._White;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Utils;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Robust.Client.Graphics;
|
||||
@@ -235,8 +236,8 @@ public sealed class ChatUIController : UIController
|
||||
_input.SetInputCommand(ContentKeyFunctions.CycleChatChannelBackward,
|
||||
InputCmdHandler.FromDelegate(_ => CycleChatChannel(false)));
|
||||
|
||||
SubscribeLocalEvent<ChangelingUserStart>(OnUpdateChangelingChat);
|
||||
// WD EDIT
|
||||
SubscribeLocalEvent<ChangelingUserStart>(OnUpdateChangelingChat);
|
||||
SubscribeLocalEvent<EventCultistComponentState>(OnUpdateCultState);
|
||||
// WD EDIT END
|
||||
|
||||
@@ -563,7 +564,7 @@ public sealed class ChatUIController : UIController
|
||||
|
||||
// WD EDIT
|
||||
var localEnt = _player.LocalEntity;
|
||||
if (_entities.HasComponent<CultistComponent>(localEnt))
|
||||
if (_entities.HasComponent<CultistComponent>(localEnt) || _entities.HasComponent<ConstructComponent>(localEnt))
|
||||
{
|
||||
FilterableChannels |= ChatChannel.Cult;
|
||||
CanSendChannels |= ChatSelectChannel.Cult;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
@@ -29,7 +28,7 @@ public sealed class ShowCultHudSystem : EntitySystem
|
||||
_overlay = new CultHudOverlay(EntityManager);
|
||||
}
|
||||
|
||||
private void OnComponentInit(EntityUid uid, ShowCultHudComponent component, ComponentInit args)
|
||||
private void OnComponentInit<T>(EntityUid uid, T component, ComponentInit args)
|
||||
{
|
||||
if (_player.LocalSession?.AttachedEntity != uid)
|
||||
return;
|
||||
@@ -38,7 +37,7 @@ public sealed class ShowCultHudSystem : EntitySystem
|
||||
|
||||
}
|
||||
|
||||
private void OnComponentRemoved(EntityUid uid, ShowCultHudComponent component, ComponentRemove args)
|
||||
private void OnComponentRemoved<T>(EntityUid uid, T component, ComponentRemove args)
|
||||
{
|
||||
if (_player.LocalSession?.AttachedEntity != uid)
|
||||
return;
|
||||
@@ -47,7 +46,7 @@ public sealed class ShowCultHudSystem : EntitySystem
|
||||
|
||||
}
|
||||
|
||||
private void OnPlayerAttached(EntityUid uid, ShowCultHudComponent component, PlayerAttachedEvent args)
|
||||
private void OnPlayerAttached<T>(EntityUid uid, T component, PlayerAttachedEvent args)
|
||||
{
|
||||
if (_player.LocalSession != args.Player)
|
||||
return;
|
||||
@@ -55,7 +54,7 @@ public sealed class ShowCultHudSystem : EntitySystem
|
||||
_overlayManager.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void OnPlayerDetached(EntityUid uid, ShowCultHudComponent component, PlayerDetachedEvent args)
|
||||
private void OnPlayerDetached<T>(EntityUid uid, T component, PlayerDetachedEvent args)
|
||||
{
|
||||
if (_player.LocalSession != args.Player)
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Construction;
|
||||
using Content.Shared._White.Cult.Pylon;
|
||||
using Content.Shared.Construction.Prototypes;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Client.Placement;
|
||||
@@ -8,60 +9,33 @@ using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Client._White.Cult.UI.StructureRadial;
|
||||
|
||||
public sealed class CultPylonPlacementHijack : PlacementHijack
|
||||
public sealed class CultPylonPlacementHijack(ConstructionPrototype? prototype, IEntityManager entMan, EntityUid player)
|
||||
: PlacementHijack
|
||||
{
|
||||
private readonly ConstructionSystem _constructionSystem;
|
||||
private readonly IEntityManager _entMan;
|
||||
private readonly ConstructionPrototype? _prototype;
|
||||
private readonly EntityUid _player;
|
||||
private readonly ConstructionSystem _constructionSystem = entMan.System<ConstructionSystem>();
|
||||
|
||||
public override bool CanRotate { get; }
|
||||
|
||||
public CultPylonPlacementHijack(ConstructionPrototype? prototype, IEntityManager entMan, EntityUid player)
|
||||
{
|
||||
_prototype = prototype;
|
||||
_entMan = entMan;
|
||||
_player = player;
|
||||
_constructionSystem = entMan.System<ConstructionSystem>();
|
||||
CanRotate = prototype?.CanRotate ?? true;
|
||||
}
|
||||
public override bool CanRotate { get; } = prototype?.CanRotate ?? true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HijackPlacementRequest(EntityCoordinates coordinates)
|
||||
{
|
||||
if (_prototype == null)
|
||||
if (prototype == null)
|
||||
return true;
|
||||
|
||||
if (CheckForStructure(coordinates))
|
||||
if (SharedPylonComponent.CheckForStructure(coordinates, entMan, 10f))
|
||||
{
|
||||
var popup = _entMan.System<SharedPopupSystem>();
|
||||
popup.PopupClient(Loc.GetString("cult-structure-craft-another-structure-nearby"), _player, _player);
|
||||
var popup = entMan.System<SharedPopupSystem>();
|
||||
popup.PopupClient(Loc.GetString("cult-structure-craft-another-structure-nearby"), player, player);
|
||||
return true;
|
||||
}
|
||||
|
||||
_constructionSystem.ClearAllGhosts();
|
||||
var dir = Manager.Direction;
|
||||
_constructionSystem.SpawnGhost(_prototype, coordinates, dir);
|
||||
_constructionSystem.SpawnGhost(prototype, coordinates, dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CheckForStructure(EntityCoordinates coordinates)
|
||||
{
|
||||
var lookupSystem = _entMan.System<EntityLookupSystem>();
|
||||
var entities = lookupSystem.GetEntitiesInRange(coordinates, 10f);
|
||||
foreach (var ent in entities)
|
||||
{
|
||||
if (!_entMan.TryGetComponent<MetaDataComponent>(ent, out var metadata))
|
||||
continue;
|
||||
|
||||
if (metadata.EntityPrototype?.ID is "CultPylon")
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HijackDeletion(EntityUid entity)
|
||||
{
|
||||
@@ -77,6 +51,6 @@ public sealed class CultPylonPlacementHijack : PlacementHijack
|
||||
public override void StartHijack(PlacementManager manager)
|
||||
{
|
||||
base.StartHijack(manager);
|
||||
manager.CurrentTextures = _prototype?.Layers.Select(sprite => sprite.DirFrame0()).ToList();
|
||||
manager.CurrentTextures = prototype?.Layers.Select(sprite => sprite.DirFrame0()).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Enums;
|
||||
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
|
||||
@@ -35,7 +36,8 @@ namespace Content.Server.Chat.Commands
|
||||
|
||||
var entityManager = IoCManager.Resolve<EntityManager>();
|
||||
|
||||
if (!entityManager.HasComponent<CultistComponent>(entity))
|
||||
if (!entityManager.HasComponent<CultistComponent>(entity) &&
|
||||
!entityManager.HasComponent<ConstructComponent>(entity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Server.Damage.Components;
|
||||
using Content.Server.Weapons.Ranged.Systems;
|
||||
using Content.Shared.Camera;
|
||||
using Content.Server._White.Crossbow;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Events;
|
||||
using Content.Shared.Damage.Systems;
|
||||
@@ -30,7 +31,8 @@ namespace Content.Server.Damage.Systems
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<DamageOtherOnHitComponent, ThrowDoHitEvent>(OnDoHit,
|
||||
before: new[] {typeof(MeleeThrowOnHitSystem)}); // WD EDIT
|
||||
before: new[] {typeof(MeleeThrowOnHitSystem)},
|
||||
after: new[] {typeof(BloodSpearSystem)}); // WD EDIT
|
||||
SubscribeLocalEvent<DamageOtherOnHitComponent, DamageExamineEvent>(OnDamageExamine);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ public sealed partial class CultRuleComponent : Component
|
||||
public List<ConstructComponent> Constructs = new();
|
||||
|
||||
public CultWinCondition WinCondition = CultWinCondition.Draw;
|
||||
|
||||
public CultStage Stage = CultStage.Normal;
|
||||
}
|
||||
|
||||
public enum CultWinCondition : byte
|
||||
@@ -59,4 +61,11 @@ public enum CultWinCondition : byte
|
||||
Failure,
|
||||
}
|
||||
|
||||
public enum CultStage : byte
|
||||
{
|
||||
Normal,
|
||||
RedEyes,
|
||||
Pentagram,
|
||||
}
|
||||
|
||||
public sealed class CultNarsieSummoned : EntityEventArgs;
|
||||
|
||||
@@ -6,6 +6,7 @@ using Content.Server.Bible.Components;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Objectives.Components;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.RoundEnd;
|
||||
@@ -53,6 +54,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
[Dependency] private readonly GulagSystem _gulag = default!;
|
||||
[Dependency] private readonly BloodSpearSystem _bloodSpear = default!;
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
[Dependency] private readonly HandsSystem _hands = default!;
|
||||
|
||||
private const int PlayerPerCultist = 10;
|
||||
private int _minStartingCultists;
|
||||
@@ -175,6 +177,8 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
if (TryComp<ActorComponent>(uid, out var actor))
|
||||
{
|
||||
cult.CultistsCache.TryAdd(name, actor.PlayerSession.Name);
|
||||
_mindSystem.TryGetMind(actor.PlayerSession.UserId, out var mind);
|
||||
component.OriginalMind = mind;
|
||||
}
|
||||
|
||||
UpdateCultistsAppearance(cult);
|
||||
@@ -339,7 +343,12 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
var cultistsCount = cultRuleComponent.CurrentCultists.Count;
|
||||
var constructsCount = cultRuleComponent.Constructs.Count;
|
||||
var totalCultMembers = cultistsCount + constructsCount;
|
||||
if (totalCultMembers < cultRuleComponent.ReadEyeThreshold)
|
||||
if (totalCultMembers >= cultRuleComponent.PentagramThreshold)
|
||||
cultRuleComponent.Stage = CultStage.Pentagram;
|
||||
else if (totalCultMembers >= cultRuleComponent.ReadEyeThreshold && cultRuleComponent.Stage == CultStage.Normal)
|
||||
cultRuleComponent.Stage = CultStage.RedEyes;
|
||||
|
||||
if (cultRuleComponent.Stage == CultStage.Normal)
|
||||
return;
|
||||
|
||||
foreach (var cultistComponent in cultRuleComponent.CurrentCultists)
|
||||
@@ -350,7 +359,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
Dirty(cultistComponent.Owner, appearanceComponent);
|
||||
}
|
||||
|
||||
if (totalCultMembers < cultRuleComponent.PentagramThreshold)
|
||||
if (cultRuleComponent.Stage != CultStage.Pentagram)
|
||||
return;
|
||||
|
||||
EnsureComp<PentagramComponent>(cultistComponent.Owner);
|
||||
@@ -458,6 +467,13 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
_container.Remove(container.ContainedEntity.Value, container, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in _hands.EnumerateHeld(uid))
|
||||
{
|
||||
if (TryComp(item, out CultItemComponent? cultItem) && !cultItem.CanPickUp &&
|
||||
!_hands.TryDrop(uid, item, null, false, false))
|
||||
QueueDel(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void TransferRole(EntityUid transferFrom, EntityUid transferTo)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Content.Server._White.Cult.Items.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CultStunHandComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan Duration = TimeSpan.FromSeconds(16);
|
||||
|
||||
[DataField]
|
||||
public TimeSpan HaloDuration = TimeSpan.FromSeconds(1.5);
|
||||
|
||||
[DataField]
|
||||
public TimeSpan MuteDuration = TimeSpan.FromSeconds(12);
|
||||
|
||||
[DataField]
|
||||
public TimeSpan HaloMuteDuration = TimeSpan.FromSeconds(1);
|
||||
|
||||
[DataField]
|
||||
public string Speech = "Fuu ma'jin!";
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Content.Server._White.Cult.Items.Components;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Stunnable;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
|
||||
namespace Content.Server._White.Cult.Items.Systems;
|
||||
|
||||
public sealed class CultStunHandSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly StunSystem _stun = default!;
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly HolyWeaponSystem _holyWeapon = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly BloodstreamSystem _bloodstream = default!;
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CultStunHandComponent, MeleeHitEvent>(OnHit);
|
||||
}
|
||||
|
||||
private void OnHit(Entity<CultStunHandComponent> ent, ref MeleeHitEvent args)
|
||||
{
|
||||
if (args.HitEntities.Count == 0)
|
||||
return;
|
||||
|
||||
var target = args.HitEntities[0];
|
||||
var (uid, comp) = ent;
|
||||
|
||||
QueueDel(uid);
|
||||
Spawn("CultStunFlashEffect", Transform(target).Coordinates);
|
||||
_chat.TrySendInGameICMessage(args.User, comp.Speech, InGameICChatType.Whisper, false);
|
||||
if (TryComp(args.User, out BloodstreamComponent? bloodstream))
|
||||
_bloodstream.TryModifyBloodLevel(args.User, -10, bloodstream, createPuddle: false);
|
||||
|
||||
if (_holyWeapon.IsHoldingHolyWeapon(target))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("cult-magic-holy"), args.User, args.User, PopupType.MediumCaution);
|
||||
return;
|
||||
}
|
||||
|
||||
var halo = HasComp<PentagramComponent>(args.User);
|
||||
|
||||
_statusEffects.TryAddStatusEffect(target, "Muted", halo ? comp.HaloMuteDuration : comp.MuteDuration, true,
|
||||
"Muted");
|
||||
_stun.TryParalyze(target, halo ? comp.HaloDuration : comp.Duration, true);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Atmos.Piping.Other.Components;
|
||||
using Content.Server.Body.Components;
|
||||
@@ -61,6 +61,15 @@ public sealed class PylonSystem : EntitySystem
|
||||
|
||||
private void OnInit(EntityUid uid, SharedPylonComponent component, ComponentInit args)
|
||||
{
|
||||
var coords = Transform(uid).Coordinates;
|
||||
if (SharedPylonComponent.CheckForStructure(coords, EntityManager, 9f, uid))
|
||||
{
|
||||
QueueDel(uid);
|
||||
_popupSystem.PopupCoordinates(Loc.GetString("cult-structure-craft-another-structure-nearby"),
|
||||
coords, PopupType.MediumCaution);
|
||||
Spawn("CultRunicMetal4", coords);
|
||||
return;
|
||||
}
|
||||
UpdateAppearance(uid, component);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Content.Server.Chat.Systems;
|
||||
|
||||
namespace Content.Server._White.Cult.Runes.Comps;
|
||||
|
||||
[RegisterComponent]
|
||||
@@ -14,4 +16,7 @@ public sealed partial class CultRuneBaseComponent : Component
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("invokePhrase")]
|
||||
public string InvokePhrase = "";
|
||||
|
||||
[DataField]
|
||||
public InGameICChatType InvokeChatType = InGameICChatType.Whisper;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Emp;
|
||||
using Content.Server.EUI;
|
||||
using Content.Server._White.Cult.UI;
|
||||
using Content.Server._White.Wizard.Magic;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Damage;
|
||||
@@ -50,6 +52,7 @@ public partial class CultSystem
|
||||
[Dependency] private readonly PhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly HolyWeaponSystem _holyWeapon = default!;
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||
[Dependency] private readonly WizardSpellsSystem _spells = default!;
|
||||
|
||||
private const string TileId = "CultFloor";
|
||||
private const string ConcealedTileId = "CultFloorConcealed";
|
||||
@@ -66,7 +69,7 @@ public partial class CultSystem
|
||||
SubscribeLocalEvent<CultistComponent, CultBloodRitesInstantActionEvent>(OnBloodRites);
|
||||
SubscribeLocalEvent<CultistComponent, CultBloodSpearRecallInstantActionEvent>(OnBloodSpearRecall);
|
||||
SubscribeLocalEvent<CultistComponent, CultTeleportTargetActionEvent>(OnTeleport);
|
||||
SubscribeLocalEvent<CultistComponent, CultStunTargetActionEvent>(OnStunTarget);
|
||||
SubscribeLocalEvent<CultistComponent, CultStunActionEvent>(OnStun);
|
||||
SubscribeLocalEvent<CultistComponent, ActionGettingRemovedEvent>(OnActionRemoved);
|
||||
SubscribeLocalEvent<CultistComponent, ShacklesEvent>(OnShackles);
|
||||
}
|
||||
@@ -84,6 +87,11 @@ public partial class CultSystem
|
||||
if (_cuffable.TryAddNewCuffs(args.Target.Value, args.User, cuffs, cuffable, handcuffComponent))
|
||||
{
|
||||
SharedCuffableSystem.SetUsed(handcuffComponent, true);
|
||||
if (_statusEffectsSystem.TryAddStatusEffect(args.Target.Value, "Muted", TimeSpan.FromSeconds(10),
|
||||
true, "Muted"))
|
||||
{
|
||||
_popupSystem.PopupEntity("Цель обезмолвлена.", args.User, args.User);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -96,32 +104,16 @@ public partial class CultSystem
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
private void OnStunTarget(EntityUid uid, CultistComponent component, CultStunTargetActionEvent args)
|
||||
private void OnStun(EntityUid uid, CultistComponent component, CultStunActionEvent args)
|
||||
{
|
||||
if (args.Target == uid || !TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) ||
|
||||
!TryComp<StatusEffectsComponent>(args.Target, out var status))
|
||||
return;
|
||||
|
||||
if (_holyWeapon.IsHoldingHolyWeapon(args.Target))
|
||||
var entity = Spawn("StunHand", Transform(uid).Coordinates);
|
||||
if (!_handsSystem.TryPickupAnyHand(uid, entity))
|
||||
{
|
||||
_popupSystem.PopupEntity("Сила священного оружия препятствует магии.", args.Performer, args.Performer,
|
||||
PopupType.MediumCaution);
|
||||
_popupSystem.PopupEntity(Loc.GetString("cult-magic-no-empty-hand"), uid, uid);
|
||||
QueueDel(entity);
|
||||
_actionsSystem.SetCooldown(args.Action, TimeSpan.FromSeconds(1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasComp<MindShieldComponent>(args.Target))
|
||||
{
|
||||
_popupSystem.PopupEntity("Он имплантирован чипом защиты разума.", args.Performer, args.Performer,
|
||||
PopupType.MediumCaution);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(6), true, status) &
|
||||
!_statusEffectsSystem.TryAddStatusEffect(args.Target, "Muted", TimeSpan.FromSeconds(12), true, "Muted",
|
||||
status))
|
||||
return;
|
||||
|
||||
_bloodstreamSystem.TryModifyBloodLevel(uid, -10, bloodstream, createPuddle: false);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -133,7 +125,7 @@ public partial class CultSystem
|
||||
|
||||
if (_holyWeapon.IsHoldingHolyWeapon(args.Target))
|
||||
{
|
||||
_popupSystem.PopupEntity("Сила священного оружия препятствует магии.", args.Performer, args.Performer,
|
||||
_popupSystem.PopupEntity(Loc.GetString("cult-magic-holy"), args.Performer, args.Performer,
|
||||
PopupType.MediumCaution);
|
||||
return;
|
||||
}
|
||||
@@ -152,6 +144,7 @@ public partial class CultSystem
|
||||
_euiManager.OpenEui(eui, actor.PlayerSession);
|
||||
eui.StateDirty();
|
||||
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -210,6 +203,7 @@ public partial class CultSystem
|
||||
_popupSystem.PopupEntity(Loc.GetString("verb-blood-rites-message", ("blood", component.RitesBloodAmount)), uid,
|
||||
uid);
|
||||
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -342,6 +336,7 @@ public partial class CultSystem
|
||||
_audio.PlayPvs(conceal ? "/Audio/White/Cult/smoke.ogg" : "/Audio/White/Cult/enter_blood.ogg", uid,
|
||||
AudioParams.Default.WithMaxDistance(5f));
|
||||
_bloodstreamSystem.TryModifyBloodLevel(uid, -2, bloodstream, createPuddle: false);
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -420,6 +415,7 @@ public partial class CultSystem
|
||||
|
||||
_empSystem.EmpPulse(_transform.GetMapCoordinates(uid), 5, 100000, 10f);
|
||||
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -430,13 +426,6 @@ public partial class CultSystem
|
||||
|
||||
_bloodstreamSystem.TryModifyBloodLevel(uid, -5, bloodstream, createPuddle: false);
|
||||
|
||||
if (!_holyWeapon.IsHoldingHolyWeapon(args.Target) &&
|
||||
_statusEffectsSystem.TryAddStatusEffect(args.Target, "Muted", TimeSpan.FromSeconds(10), true, "Muted"))
|
||||
{
|
||||
_popupSystem.PopupEntity("Цель обезмолвлена.", args.Performer, args.Performer);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
if (!TryComp(args.Target, out CuffableComponent? cuffs) || cuffs.Container.ContainedEntities.Count > 0)
|
||||
return;
|
||||
|
||||
@@ -447,6 +436,7 @@ public partial class CultSystem
|
||||
BreakOnDamage = true
|
||||
});
|
||||
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -482,6 +472,7 @@ public partial class CultSystem
|
||||
stackNew.Count = count;
|
||||
|
||||
_popupSystem.PopupEntity("Конвертируем сталь в руинический металл!", args.Performer, args.Performer);
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -498,6 +489,12 @@ public partial class CultSystem
|
||||
|
||||
_bloodstreamSystem.TryModifyBloodLevel(args.Performer, -10, bloodstreamComponent, false);
|
||||
_handsSystem.TryPickupAnyHand(args.Performer, dagger);
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void Speak(BaseActionEvent args)
|
||||
{
|
||||
_spells.Speak(args, InGameICChatType.Whisper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ using Content.Server.Chemistry.Components;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Fluids.Components;
|
||||
using Content.Server.Ghost;
|
||||
using Content.Server.Pinpointer;
|
||||
using Content.Server.Revenant.Components;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
@@ -51,6 +52,7 @@ using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
|
||||
|
||||
namespace Content.Server._White.Cult.Runes.Systems;
|
||||
@@ -77,6 +79,7 @@ public sealed partial class CultSystem : EntitySystem
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly MobThresholdSystem _thresholdSystem = default!;
|
||||
[Dependency] private readonly NavMapSystem _navMap = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -404,7 +407,7 @@ public sealed partial class CultSystem : EntitySystem
|
||||
|
||||
foreach (var cultist in cultists)
|
||||
{
|
||||
_chat.TrySendInGameICMessage(cultist, component.InvokePhrase, InGameICChatType.Speak, false, false, null,
|
||||
_chat.TrySendInGameICMessage(cultist, component.InvokePhrase, component.InvokeChatType, false, false, null,
|
||||
null, null, false);
|
||||
}
|
||||
}
|
||||
@@ -1347,11 +1350,8 @@ public sealed partial class CultSystem : EntitySystem
|
||||
}
|
||||
|
||||
damage = 40;
|
||||
var pos = _transform.GetMapCoordinates(uid, transComp);
|
||||
var x = (int) pos.X;
|
||||
var y = (int) pos.Y;
|
||||
var posText = $"(x = {x}, y = {y})";
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-narsie-summon-drawn-position", ("posText", posText)),
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-narsie-summon-drawn-position",
|
||||
("location", FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((uid, transComp))))),
|
||||
"CULT", true, _apocRuneEndDrawing, colorOverride: Color.DarkRed);
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +174,12 @@ public sealed class WizardSpellsSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasComp<CultistComponent>(target))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("mindswap-cultist-failed"), uid, uid, PopupType.MediumCaution);
|
||||
return;
|
||||
}
|
||||
|
||||
var userHasMind = _mindSystem.TryGetMind(uid, out var mindId, out var mind);
|
||||
var targetHasMind = _mindSystem.TryGetMind(target, out var targetMindId, out var targetMind);
|
||||
|
||||
@@ -183,8 +189,6 @@ public sealed class WizardSpellsSystem : EntitySystem
|
||||
SwapComponent<WizardComponent>(uid, target);
|
||||
SwapComponent<RevolutionaryComponent>(uid, target);
|
||||
SwapComponent<HeadRevolutionaryComponent>(uid, target);
|
||||
SwapComponent<PentagramComponent>(uid, target);
|
||||
SwapComponent<CultistComponent>(uid, target);
|
||||
SwapComponent<GlobalAntagonistComponent>(uid, target);
|
||||
|
||||
_mindSystem.TransferTo(mindId, target, mind: mind);
|
||||
@@ -854,13 +858,12 @@ public sealed class WizardSpellsSystem : EntitySystem
|
||||
!_statusEffectsSystem.HasStatusEffect(msg.Performer, "Incorporeal");
|
||||
}
|
||||
|
||||
private void Speak(BaseActionEvent args)
|
||||
public void Speak(BaseActionEvent args, InGameICChatType type = InGameICChatType.Speak)
|
||||
{
|
||||
if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech))
|
||||
return;
|
||||
|
||||
_chat.TrySendInGameICMessage(args.Performer, Loc.GetString(speak.Speech),
|
||||
InGameICChatType.Speak, false);
|
||||
_chat.TrySendInGameICMessage(args.Performer, Loc.GetString(speak.Speech), type, false);
|
||||
}
|
||||
|
||||
private void SetCooldown(EntityUid action, ActionUseType useType)
|
||||
|
||||
@@ -101,7 +101,7 @@ public abstract partial class SharedHandsSystem : EntitySystem
|
||||
if (TryComp(session?.AttachedEntity, out HandsComponent? hands) && hands.ActiveHand != null)
|
||||
// WD EDIT START
|
||||
{
|
||||
if (HasComp<BoltBarrageComponent>(hands.ActiveHandEntity))
|
||||
if (HasComp<DeleteOnDropAttemptComponent>(hands.ActiveHandEntity))
|
||||
{
|
||||
if (_net.IsServer)
|
||||
QueueDel(hands.ActiveHandEntity.Value);
|
||||
|
||||
@@ -116,6 +116,9 @@ public abstract partial class SharedProjectileSystem : EntitySystem
|
||||
return;
|
||||
|
||||
// WD START
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (component is {Penetrate: true, PenetratedUid: null} &&
|
||||
TryComp(args.Target, out PenetratedComponent? penetrated) &&
|
||||
penetrated is {ProjectileUid: null, IsPinned: false} &&
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -62,19 +63,31 @@ public sealed partial class MeleeWeaponComponent : Component
|
||||
public bool Attacking = false;
|
||||
|
||||
// WD START
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public bool CanHeavyAttack = true;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public bool CanAttackSelf = true;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public bool CanMiss = true;
|
||||
|
||||
[DataField]
|
||||
public EntityWhitelist? AttackWhitelist;
|
||||
|
||||
[DataField]
|
||||
public EntityWhitelist? AttackBlacklist;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public bool IgnoreResistances;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public float HeavyAttackStaminaCost = 8;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public EntProtoId MissAnimation = "WeaponArcPunch";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public EntProtoId DisarmAnimation = "WeaponArcDisarm";
|
||||
// WD END
|
||||
|
||||
|
||||
@@ -365,6 +365,30 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (weaponUid == lightTarget)
|
||||
return false;
|
||||
|
||||
// WD START
|
||||
if (user == lightTarget && !weapon.CanAttackSelf)
|
||||
return false;
|
||||
|
||||
if (lightTarget == null)
|
||||
{
|
||||
if (weapon.CanMiss)
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (weapon.AttackWhitelist != null)
|
||||
{
|
||||
if (!weapon.AttackWhitelist.IsValid(lightTarget.Value, EntityManager))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (weapon.AttackBlacklist != null)
|
||||
{
|
||||
if (weapon.AttackBlacklist.IsValid(lightTarget.Value, EntityManager))
|
||||
return false;
|
||||
}
|
||||
// WD END
|
||||
|
||||
break;
|
||||
case DisarmAttackEvent disarm:
|
||||
var disarmTarget = GetEntity(disarm.Target);
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Magic;
|
||||
|
||||
namespace Content.Shared._White.Cult.Actions;
|
||||
|
||||
public sealed partial class CultTwistedConstructionActionEvent : EntityTargetActionEvent
|
||||
public sealed partial class CultTwistedConstructionActionEvent : EntityTargetActionEvent, ISpeakSpell
|
||||
{
|
||||
[DataField("speech")]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
|
||||
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent, ISpeakSpell
|
||||
{
|
||||
[DataField("speech")]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
|
||||
public sealed partial class CultStunActionEvent : InstantActionEvent
|
||||
{
|
||||
}
|
||||
|
||||
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent
|
||||
public sealed partial class CultTeleportTargetActionEvent : EntityTargetActionEvent, ISpeakSpell
|
||||
{
|
||||
[DataField("speech")]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
|
||||
public sealed partial class CultStunTargetActionEvent : EntityTargetActionEvent
|
||||
public sealed partial class CultElectromagneticPulseInstantActionEvent : InstantActionEvent, ISpeakSpell
|
||||
{
|
||||
[DataField("speech")]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
|
||||
public sealed partial class CultTeleportTargetActionEvent : EntityTargetActionEvent
|
||||
{
|
||||
}
|
||||
|
||||
public sealed partial class CultElectromagneticPulseInstantActionEvent : InstantActionEvent
|
||||
{
|
||||
}
|
||||
|
||||
public sealed partial class CultShadowShacklesTargetActionEvent : EntityTargetActionEvent
|
||||
public sealed partial class CultShadowShacklesTargetActionEvent : EntityTargetActionEvent, ISpeakSpell
|
||||
{
|
||||
[DataField("speech")]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
|
||||
public sealed partial class CultSummonCombatEquipmentTargetActionEvent : EntityTargetActionEvent
|
||||
@@ -31,8 +42,10 @@ public sealed partial class CultSummonCombatEquipmentTargetActionEvent : EntityT
|
||||
}
|
||||
|
||||
[Virtual]
|
||||
public partial class CultConcealPresenceInstantActionEvent : InstantActionEvent
|
||||
public partial class CultConcealPresenceInstantActionEvent : InstantActionEvent, ISpeakSpell
|
||||
{
|
||||
[DataField("speech")]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
|
||||
public sealed partial class CultConcealInstantActionEvent : CultConcealPresenceInstantActionEvent
|
||||
@@ -43,8 +56,10 @@ public sealed partial class CultRevealInstantActionEvent : CultConcealPresenceIn
|
||||
{
|
||||
}
|
||||
|
||||
public sealed partial class CultBloodRitesInstantActionEvent : InstantActionEvent
|
||||
public sealed partial class CultBloodRitesInstantActionEvent : InstantActionEvent, ISpeakSpell
|
||||
{
|
||||
[DataField("speech")]
|
||||
public string? Speech { get; private set; }
|
||||
}
|
||||
|
||||
public sealed partial class CultBloodSpearRecallInstantActionEvent : InstantActionEvent
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Content.Shared._White.Cult.Components;
|
||||
/// This is used for tagging a mob as a cultist.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class CultistComponent : ShowCultHudComponent
|
||||
public sealed partial class CultistComponent : Component
|
||||
{
|
||||
[DataField("greetSound", customTypeSerializer: typeof(SoundSpecifierTypeSerializer))]
|
||||
public SoundSpecifier? CultistGreetSound = new SoundPathSpecifier("/Audio/CultSounds/fart.ogg");
|
||||
@@ -41,7 +41,7 @@ public sealed partial class CultistComponent : ShowCultHudComponent
|
||||
|
||||
public static string CultSummonCombatEquipmentAction = "ActionCultSummonCombatEquipment";
|
||||
|
||||
public static string CultStunAction = "ActionCultStun";
|
||||
public static string CultStunAction = "InstantActionCultStun";
|
||||
|
||||
public static string CultShadowShacklesAction = "ActionCultShadowShackles";
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Content.Shared._White.Cult.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class DeleteOnDropAttemptComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public string Message = string.Empty;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._White.Cult.Pylon;
|
||||
@@ -64,6 +65,25 @@ public sealed partial class SharedPylonComponent : Component
|
||||
|
||||
[DataField("wallConvertEffect")]
|
||||
public string WallConvertEffect = "CultWallGlow";
|
||||
|
||||
public static bool CheckForStructure(EntityCoordinates coordinates, IEntityManager entMan, float range, EntityUid? pylon = null)
|
||||
{
|
||||
var lookupSystem = entMan.System<EntityLookupSystem>();
|
||||
var entities = lookupSystem.GetEntitiesInRange(coordinates, range);
|
||||
foreach (var ent in entities)
|
||||
{
|
||||
if (ent == pylon)
|
||||
continue;
|
||||
|
||||
if (!entMan.TryGetComponent<MetaDataComponent>(ent, out var metadata))
|
||||
continue;
|
||||
|
||||
if (metadata.EntityPrototype?.ID is "CultPylon")
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Projectiles;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared.Throwing;
|
||||
@@ -15,6 +17,7 @@ public sealed class BloodSpearSystem : EntitySystem
|
||||
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly HolyWeaponSystem _holy = default!;
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
|
||||
public override void Initialize()
|
||||
@@ -23,7 +26,8 @@ public sealed class BloodSpearSystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<BloodSpearComponent, ComponentRemove>(OnRemove);
|
||||
SubscribeLocalEvent<BloodSpearComponent, GotEquippedHandEvent>(OnEquip);
|
||||
SubscribeLocalEvent<BloodSpearComponent, ThrowDoHitEvent>(OnThrowDoHit);
|
||||
SubscribeLocalEvent<BloodSpearComponent, ThrowDoHitEvent>(OnThrowDoHit,
|
||||
before: new[] {typeof(SharedProjectileSystem)});
|
||||
SubscribeLocalEvent<BloodSpearComponent, ExaminedEvent>(OnExamine);
|
||||
}
|
||||
|
||||
@@ -34,11 +38,20 @@ public sealed class BloodSpearSystem : EntitySystem
|
||||
|
||||
private void OnThrowDoHit(Entity<BloodSpearComponent> ent, ref ThrowDoHitEvent args)
|
||||
{
|
||||
if (HasComp<CultistComponent>(args.Target) || HasComp<ConstructComponent>(args.Target))
|
||||
{
|
||||
args.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryComp(args.Target, out StatusEffectsComponent? status))
|
||||
return;
|
||||
|
||||
if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(6), true, status))
|
||||
return;
|
||||
if (!_holy.IsHoldingHolyWeapon(args.Target))
|
||||
{
|
||||
if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(4), true, status))
|
||||
return;
|
||||
}
|
||||
|
||||
if (_net.IsClient)
|
||||
return;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Content.Shared._White.Cult.Components;
|
||||
|
||||
namespace Content.Shared._White.Cult.Systems;
|
||||
|
||||
/// <summary>
|
||||
@@ -9,16 +11,18 @@ public sealed class CultistSystem : EntitySystem
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<Components.CultistComponent, ComponentStartup>(OnInit);
|
||||
SubscribeLocalEvent<Components.CultistComponent, ComponentShutdown>(OnRemove);
|
||||
SubscribeLocalEvent<ConstructComponent, ComponentStartup>(OnInit);
|
||||
SubscribeLocalEvent<ConstructComponent, ComponentShutdown>(OnRemove);
|
||||
SubscribeLocalEvent<CultistComponent, ComponentStartup>(OnInit);
|
||||
SubscribeLocalEvent<CultistComponent, ComponentShutdown>(OnRemove);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, Components.CultistComponent component, ComponentStartup args)
|
||||
private void OnInit<T>(EntityUid uid, T component, ComponentStartup args)
|
||||
{
|
||||
RaiseLocalEvent(new EventCultistComponentState(true));
|
||||
}
|
||||
|
||||
private void OnRemove(EntityUid uid, Components.CultistComponent component, ComponentShutdown args)
|
||||
private void OnRemove<T>(EntityUid uid, T component, ComponentShutdown args)
|
||||
{
|
||||
RaiseLocalEvent(new EventCultistComponentState(false));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared.Examine;
|
||||
|
||||
namespace Content.Shared._White.Cult.Systems;
|
||||
|
||||
public sealed class DeleteOnDropAttemptSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DeleteOnDropAttemptComponent, ExaminedEvent>(OnExamine);
|
||||
}
|
||||
|
||||
private void OnExamine(Entity<DeleteOnDropAttemptComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString(ent.Comp.Message));
|
||||
}
|
||||
}
|
||||
@@ -34,8 +34,8 @@ ent-InstantActionSummonCultDagger = Призыв Ритуального Кинж
|
||||
ent-InstantActionBloodRites = Кровавые Обряды
|
||||
.desc = Высасывает кровь и исцеляет вас.
|
||||
|
||||
ent-ActionCultStun = Оглушение
|
||||
.desc = Сильное заклинание, которое оглушает и обезмолвливает жертв. Не работает на цели со священным оружием в руках или с чипом защиты разума.
|
||||
ent-InstantActionCultStun = Оглушение
|
||||
.desc = Сильное заклинание, которое оглушает и обезмолвливает жертв. Не работает на цели со священным оружием в руках. При наличии пентаграммы над головой эффект сильно ослабевает.
|
||||
|
||||
ent-ActionCultShadowShackles = Теневые Узы
|
||||
.desc = Бесшумное заклинание, которое наложит на человека теневые наручники и заставит вашу жертву замолчать на 10 секунд.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
bolt-barrage-component-no-empty-hand = Вам нужно иметь свободную руку, чтобы стрелять.
|
||||
bolt-barrage-component-not-cultist = Вы не умеете пользоваться магией.
|
||||
bolt-barrage-component-extra-desc = [color=darkgray]Для стрельбы залпом необходимо иметь свободную руку. Вобросите залп, чтобы навсегда избавиться от него.[/color]
|
||||
bolt-barrage-component-extra-desc = [color=darkgray]Для стрельбы залпом необходимо иметь свободную руку.[/color]
|
||||
bolt-barrage-component-extra-message = [color=darkgray]Выбросите залп, чтобы навсегда избавиться от него.[/color]
|
||||
|
||||
@@ -32,7 +32,7 @@ cult-blood-boil-rune-need-minimum = Необходимо минимум 3 кул
|
||||
cult-blood-boil-rune-no-blood = Кому-то из культистов не хватает крови.
|
||||
cult-blood-boil-rune-no-targets = Нет целей.
|
||||
cult-teleport-rune-default-label = безымянная метка
|
||||
cult-narsie-summon-drawn-position = Культ закончил рисовать руну ритуала разрыва измерений! Координаты: { $posText }
|
||||
cult-narsie-summon-drawn-position = Культ закончил рисовать руну ритуала разрыва измерений! Локация: { $location }
|
||||
cult-cant-draw-rune = Нельзя рисовать руну в космосе.
|
||||
|
||||
runes-window-title = Руны
|
||||
|
||||
@@ -5,11 +5,11 @@ ent-SoulShardGhost = камень душ
|
||||
.desc = Мистический светящийся осколок.
|
||||
.suffix = Роль призраков
|
||||
|
||||
ent-WetStone = точильный камень
|
||||
.desc = Используется для заточки кромок стальных инструментов.
|
||||
ent-StunHand = оглушающая аура
|
||||
.desc = Оглушит и обезмолвит жертву при ударе.
|
||||
|
||||
ent-CultSharpener = древний точильный камень
|
||||
.desc = Используется для заточки кромок стальных инструментов.
|
||||
ent-ShadowShackles = теневые оковы
|
||||
.desc = Оковы, сковывающие запястья с помощью зловещей магии.
|
||||
|
||||
ent-CultRunicMetal = рунический металл
|
||||
.desc = Необычный лист металла с пульсирующей руной.
|
||||
@@ -19,10 +19,17 @@ ent-CultRunicMetal1 = рунический металл
|
||||
.desc = Необычный лист металла с пульсирующей руной.
|
||||
.suffix = Один
|
||||
|
||||
ent-CultRunicMetal4 = рунический металл
|
||||
.desc = Необычный лист металла с пульсирующей руной.
|
||||
.suffix = 4
|
||||
|
||||
ent-CultRunicMetal20 = рунический металл
|
||||
.desc = Необычный лист металла с пульсирующей руной.
|
||||
.suffix = 20
|
||||
|
||||
ent-AltarTome = архивы
|
||||
.desc = Стол, заваленный тайными рукописями и книгами на неизвестных языках.
|
||||
|
||||
ent-CultBloodAltar = алтарь
|
||||
.desc = Кровавый алтарь, посвященный какому-то существу.
|
||||
|
||||
@@ -38,9 +45,6 @@ ent-AirlockGlassCult = рунический шлюз
|
||||
ent-WallForceCult = светящаяся стена
|
||||
.desc = Нечестивый щит, блокирующий все атаки.
|
||||
|
||||
ent-CultClothingBlindfold = повязка Зилота
|
||||
.desc = Повязка, наделенная странной силой.
|
||||
|
||||
ent-OfferingRune = руна предпонесения
|
||||
.desc = Мгновенно превращает обычного члена экипажа в культиста, для чего требуется 2 культиста вокруг руны. Члена экипажа с имплантом защиты разума нельзя перевоплотить, можно только принести в жертву, для чего нужно 3 культиста, которые встанут вокруг руны. Если цель мертва, то она будет принесена в жертву, для чего требуется 1 культист.
|
||||
|
||||
|
||||
@@ -2,9 +2,6 @@ cultist-factory-charging = { $name } будут заряжаться ещё { $s
|
||||
cultist-factory-create = Создать { $itemName }
|
||||
cultist-factory-too-far = Слишком далеко
|
||||
|
||||
ent-AltarTome = архивы
|
||||
.desc = Стол, заваленный тайными рукописями и книгами на неизвестных языках.
|
||||
|
||||
ent-CultRobeModify = одеяние флагелланта
|
||||
.desc = Какая-то религиозная роба.
|
||||
|
||||
@@ -13,9 +10,18 @@ ent-CultMirrorShield = зеркальный щит
|
||||
|
||||
ent-CultOuterArmor = бронированная мантия
|
||||
.desc = С первого взгляда кажется, что это простая мантия, но на ней имеется элементы брони.
|
||||
ent-ShadowShackles = теневые оковы
|
||||
.desc = Оковы, сковывающие запястья с помощью зловещей магии.
|
||||
|
||||
ent-WetStone = точильный камень
|
||||
.desc = Используется для заточки кромок стальных инструментов.
|
||||
|
||||
ent-CultSharpener = древний точильный камень
|
||||
.desc = Используется для заточки кромок стальных инструментов.
|
||||
|
||||
ent-CultClothingBlindfold = повязка Зилота
|
||||
.desc = Повязка, наделенная странной силой.
|
||||
|
||||
ent-BloodSpear = кровавое копьё
|
||||
.desc = Ужасающее копьё, полностью состоящее из кристаллизованной крови.
|
||||
|
||||
ent-BloodBarrage = залп кровавых снарядов
|
||||
.desc = Кровь за кровь.
|
||||
|
||||
3
Resources/Locale/ru-RU/_white/cult/messages.ftl
Normal file
3
Resources/Locale/ru-RU/_white/cult/messages.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
cult-stun-component-extra-message = [color=darkgray]Выбросите ауру, чтобы навсегда избавиться от неё.[/color]
|
||||
cult-magic-holy = Сила священного предмета в руках цели препятствует магии!
|
||||
cult-magic-no-empty-hand = Вам нужна свободная рука для использования заклинания!
|
||||
@@ -43,6 +43,7 @@ arcane-barrage-no-empty-hand = Вам нужна свободная рука д
|
||||
|
||||
mindswap-success = Ваш разум подменили!
|
||||
mindswap-borer-failed = Его разумом кто-то управляет.
|
||||
mindswap-cultist-failed = Нечестивая сила препятствует подмене сознания.
|
||||
|
||||
store-currency-display-spell-point = Очки заклинаний
|
||||
|
||||
|
||||
@@ -1442,7 +1442,7 @@
|
||||
- type: Projectile
|
||||
damage:
|
||||
types:
|
||||
Piercing: 25
|
||||
Piercing: 20
|
||||
|
||||
- type: entity
|
||||
name: arcane bolt
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
sprite: /Textures/Objects/Materials/Sheets/metal.rsi
|
||||
state: steel
|
||||
event: !type:CultTwistedConstructionActionEvent
|
||||
speech: "Ethra p'ni dedol!"
|
||||
itemIconStyle: BigAction
|
||||
charges: 1
|
||||
temporary: true
|
||||
@@ -31,6 +32,7 @@
|
||||
sprite: /Textures/White/Cult/actions_cult.rsi
|
||||
state: teleport
|
||||
event: !type:CultTeleportTargetActionEvent
|
||||
speech: "Sas'so c'arta forbici!"
|
||||
itemIconStyle: BigAction
|
||||
charges: 1
|
||||
temporary: true
|
||||
@@ -58,20 +60,16 @@
|
||||
removeOnNoCharges: true
|
||||
|
||||
- type: entity
|
||||
id: ActionCultStun
|
||||
id: InstantActionCultStun
|
||||
name: Stun
|
||||
description: A potent spell that will stun and mute victims.
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: EntityTargetAction
|
||||
whitelist:
|
||||
components:
|
||||
- HumanoidAppearance
|
||||
canTargetSelf: false
|
||||
- type: InstantAction
|
||||
icon:
|
||||
sprite: /Textures/White/Cult/actions_cult.rsi
|
||||
state: stun
|
||||
event: !type:CultStunTargetActionEvent
|
||||
event: !type:CultStunActionEvent
|
||||
itemIconStyle: BigAction
|
||||
charges: 1
|
||||
temporary: true
|
||||
@@ -92,6 +90,7 @@
|
||||
sprite: /Textures/White/Cult/actions_cult.rsi
|
||||
state: shackles
|
||||
event: !type:CultShadowShacklesTargetActionEvent
|
||||
speech: "In'totum Lig'abis!"
|
||||
itemIconStyle: BigAction
|
||||
charges: 4
|
||||
temporary: true
|
||||
@@ -108,6 +107,7 @@
|
||||
sprite: /Textures/White/Cult/interface.rsi
|
||||
state: icon
|
||||
event: !type:CultSummonDaggerActionEvent
|
||||
speech: "Wur d'dai leev'mai k'sagan!"
|
||||
charges: 1
|
||||
temporary: true
|
||||
removeOnNoCharges: true
|
||||
@@ -123,6 +123,7 @@
|
||||
sprite: /Textures/White/Cult/actions_cult.rsi
|
||||
state: blood_rites
|
||||
event: !type:CultBloodRitesInstantActionEvent
|
||||
speech: "Fel'th Dol Ab'orod!"
|
||||
charges: 5
|
||||
temporary: true
|
||||
removeOnNoCharges: true
|
||||
@@ -138,6 +139,7 @@
|
||||
sprite: /Textures/White/Cult/actions_cult.rsi
|
||||
state: emp
|
||||
event: !type:CultElectromagneticPulseInstantActionEvent
|
||||
speech: "Ta'gh fara'qha fel d'amar det!"
|
||||
charges: 1
|
||||
temporary: true
|
||||
removeOnNoCharges: true
|
||||
@@ -153,12 +155,15 @@
|
||||
sprite: /Textures/White/Cult/actions_cult.rsi
|
||||
state: gone
|
||||
event: !type:CultConcealInstantActionEvent
|
||||
speech: "Kla'atu barada nikt'o!"
|
||||
charges: 10
|
||||
temporary: true
|
||||
removeOnNoCharges: true
|
||||
- type: ConcealPresenceSpell
|
||||
concealEvent: !type:CultConcealInstantActionEvent
|
||||
speech: "Kla'atu barada nikt'o!"
|
||||
revealEvent: !type:CultRevealInstantActionEvent
|
||||
speech: "Kla'atu barada nikt'o!"
|
||||
concealIcon:
|
||||
sprite: /Textures/White/Cult/actions_cult.rsi
|
||||
state: gone
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- type: entity
|
||||
- type: entity
|
||||
id: CultTileSpawnEffect
|
||||
name: Sparkle
|
||||
placement:
|
||||
@@ -103,3 +103,18 @@
|
||||
drawdepth: Effects
|
||||
- type: PointLight
|
||||
color: "#FF0000"
|
||||
|
||||
- type: entity
|
||||
id: CultStunFlashEffect
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
radius: 5
|
||||
energy: 8
|
||||
netsync: false
|
||||
color: Red
|
||||
- type: LightFade
|
||||
duration: 0.5
|
||||
- type: TimedDespawn
|
||||
lifetime: 0.5
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
proto: BloodBolt
|
||||
capacity: 25
|
||||
- type: BoltBarrage
|
||||
- type: DeleteOnDropAttempt
|
||||
message: bolt-barrage-component-extra-message
|
||||
- type: GiftIgnore
|
||||
- type: CultItem
|
||||
canPickUp: false
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: StunHand
|
||||
name: stunning aura
|
||||
description: Will stun and mute a weak-minded victim on hit.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: White/Cult/Entities/stun.rsi
|
||||
state: icon
|
||||
- type: Item
|
||||
size: Ginormous
|
||||
sprite: White/Cult/Entities/stun.rsi
|
||||
- type: MeleeWeapon
|
||||
canHeavyAttack: false
|
||||
canAttackSelf: false
|
||||
canMiss: false
|
||||
attackWhitelist:
|
||||
components:
|
||||
- StatusEffects
|
||||
attackBlacklist:
|
||||
components:
|
||||
- Cultist
|
||||
- Construct
|
||||
wideAnimationRotation: 180
|
||||
damage:
|
||||
types:
|
||||
Heat: 0
|
||||
- type: CultStunHand
|
||||
- type: DeleteOnDropAttempt
|
||||
message: cult-stun-component-extra-message
|
||||
- type: Unremoveable
|
||||
deleteOnDrop: true
|
||||
- type: CultItem
|
||||
canPickUp: false
|
||||
@@ -187,6 +187,16 @@
|
||||
- type: Stack
|
||||
count: 1
|
||||
|
||||
- type: entity
|
||||
parent: CultRunicMetal
|
||||
id: CultRunicMetal4
|
||||
suffix: 4
|
||||
components:
|
||||
- type: Sprite
|
||||
state: runic
|
||||
- type: Stack
|
||||
count: 4
|
||||
|
||||
- type: entity
|
||||
parent: CultRunicMetal
|
||||
id: CultRunicMetal20
|
||||
|
||||
@@ -165,4 +165,5 @@
|
||||
- type: CultRuneBase
|
||||
invokePhrase: "TOK-LYR RQA-NAP G'OLT-ULOFT!"
|
||||
cultistGatheringRange: 1.5
|
||||
invokeChatType: Speak
|
||||
- type: CultRuneApocalypse
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
- 0.30,0.40
|
||||
density: 20
|
||||
mask:
|
||||
- ItemMask
|
||||
- BulletImpassable
|
||||
restitution: 0.3
|
||||
friction: 0.2
|
||||
- type: Sharp
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
types:
|
||||
Heat: 18
|
||||
- type: Item
|
||||
size: Normal
|
||||
size: Ginormous
|
||||
sprite: White/Objects/Weapons/Chaplain/godhand.rsi
|
||||
- type: Unremoveable
|
||||
deleteOnDrop: true
|
||||
|
||||
@@ -133,5 +133,7 @@
|
||||
- type: BasicEntityAmmoProvider
|
||||
proto: ArcaneBolt
|
||||
capacity: 30
|
||||
- type: DeleteOnDropAttempt
|
||||
message: bolt-barrage-component-extra-message
|
||||
- type: BoltBarrage
|
||||
- type: GiftIgnore
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 489 B |
BIN
Resources/Textures/White/Cult/Entities/stun.rsi/icon.png
Normal file
BIN
Resources/Textures/White/Cult/Entities/stun.rsi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Resources/Textures/White/Cult/Entities/stun.rsi/inhand-left.png
Normal file
BIN
Resources/Textures/White/Cult/Entities/stun.rsi/inhand-left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 845 B |
BIN
Resources/Textures/White/Cult/Entities/stun.rsi/inhand-right.png
Normal file
BIN
Resources/Textures/White/Cult/Entities/stun.rsi/inhand-right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 843 B |
66
Resources/Textures/White/Cult/Entities/stun.rsi/meta.json
Normal file
66
Resources/Textures/White/Cult/Entities/stun.rsi/meta.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/pull/49264/commits/d0dffe7ca643db2624424fdcebf45863f85c0448",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "icon"
|
||||
},
|
||||
{
|
||||
"name": "inhand-left",
|
||||
"directions": 4,
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inhand-right",
|
||||
"directions": 4,
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user