* - 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:
Aviu00
2024-07-28 16:54:32 +00:00
committed by GitHub
parent 2a9344f616
commit edf9f243a1
48 changed files with 514 additions and 150 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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!";
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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} &&

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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";

View File

@@ -0,0 +1,8 @@
namespace Content.Shared._White.Cult.Components;
[RegisterComponent]
public sealed partial class DeleteOnDropAttemptComponent : Component
{
[DataField]
public string Message = string.Empty;
}

View File

@@ -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]

View File

@@ -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;

View File

@@ -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));
}

View File

@@ -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));
}
}

View File

@@ -34,8 +34,8 @@ ent-InstantActionSummonCultDagger = Призыв Ритуального Кинж
ent-InstantActionBloodRites = Кровавые Обряды
.desc = Высасывает кровь и исцеляет вас.
ent-ActionCultStun = Оглушение
.desc = Сильное заклинание, которое оглушает и обезмолвливает жертв. Не работает на цели со священным оружием в руках или с чипом защиты разума.
ent-InstantActionCultStun = Оглушение
.desc = Сильное заклинание, которое оглушает и обезмолвливает жертв. Не работает на цели со священным оружием в руках. При наличии пентаграммы над головой эффект сильно ослабевает.
ent-ActionCultShadowShackles = Теневые Узы
.desc = Бесшумное заклинание, которое наложит на человека теневые наручники и заставит вашу жертву замолчать на 10 секунд.

View File

@@ -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]

View File

@@ -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 = Руны

View File

@@ -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 культист.

View File

@@ -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 = Кровь за кровь.

View File

@@ -0,0 +1,3 @@
cult-stun-component-extra-message = [color=darkgray]Выбросите ауру, чтобы навсегда избавиться от неё.[/color]
cult-magic-holy = Сила священного предмета в руках цели препятствует магии!
cult-magic-no-empty-hand = Вам нужна свободная рука для использования заклинания!

View File

@@ -43,6 +43,7 @@ arcane-barrage-no-empty-hand = Вам нужна свободная рука д
mindswap-success = Ваш разум подменили!
mindswap-borer-failed = Его разумом кто-то управляет.
mindswap-cultist-failed = Нечестивая сила препятствует подмене сознания.
store-currency-display-spell-point = Очки заклинаний

View File

@@ -1442,7 +1442,7 @@
- type: Projectile
damage:
types:
Piercing: 25
Piercing: 20
- type: entity
name: arcane bolt

View File

@@ -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

View File

@@ -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

View File

@@ -24,6 +24,8 @@
proto: BloodBolt
capacity: 25
- type: BoltBarrage
- type: DeleteOnDropAttempt
message: bolt-barrage-component-extra-message
- type: GiftIgnore
- type: CultItem
canPickUp: false

View File

@@ -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

View File

@@ -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

View File

@@ -165,4 +165,5 @@
- type: CultRuneBase
invokePhrase: "TOK-LYR RQA-NAP G'OLT-ULOFT!"
cultistGatheringRange: 1.5
invokeChatType: Speak
- type: CultRuneApocalypse

View File

@@ -19,7 +19,7 @@
- 0.30,0.40
density: 20
mask:
- ItemMask
- BulletImpassable
restitution: 0.3
friction: 0.2
- type: Sharp

View File

@@ -65,7 +65,7 @@
types:
Heat: 18
- type: Item
size: Normal
size: Ginormous
sprite: White/Objects/Weapons/Chaplain/godhand.rsi
- type: Unremoveable
deleteOnDrop: true

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

View 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
]
]
}
]
}