Blood and more (#516)
* - tweak: Teleport only works on cultists. * - add: Better twisted construction. * - tweak: Free engivend.
This commit is contained in:
@@ -8,14 +8,9 @@ using Content.Server._White.Cult.UI;
|
|||||||
using Content.Server._White.Wizard.Magic;
|
using Content.Server._White.Wizard.Magic;
|
||||||
using Content.Server.Chat.Systems;
|
using Content.Server.Chat.Systems;
|
||||||
using Content.Shared._White.Chaplain;
|
using Content.Shared._White.Chaplain;
|
||||||
using Content.Shared.Chemistry.Components;
|
|
||||||
using Content.Shared.Damage;
|
|
||||||
using Content.Shared.Damage.Prototypes;
|
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
using Content.Shared.Fluids.Components;
|
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.Stacks;
|
using Content.Shared.Stacks;
|
||||||
using Content.Shared.StatusEffect;
|
|
||||||
using Content.Shared.Stunnable;
|
using Content.Shared.Stunnable;
|
||||||
using Content.Shared._White.Cult.Actions;
|
using Content.Shared._White.Cult.Actions;
|
||||||
using Content.Shared._White.Cult.Components;
|
using Content.Shared._White.Cult.Components;
|
||||||
@@ -25,8 +20,8 @@ using Content.Shared.Actions;
|
|||||||
using Content.Shared.Cuffs;
|
using Content.Shared.Cuffs;
|
||||||
using Content.Shared.Cuffs.Components;
|
using Content.Shared.Cuffs.Components;
|
||||||
using Content.Shared.DoAfter;
|
using Content.Shared.DoAfter;
|
||||||
|
using Content.Shared.Doors.Components;
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
using Content.Shared.Mindshield.Components;
|
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
@@ -72,6 +67,21 @@ public partial class CultSystem
|
|||||||
SubscribeLocalEvent<CultistComponent, CultStunActionEvent>(OnStun);
|
SubscribeLocalEvent<CultistComponent, CultStunActionEvent>(OnStun);
|
||||||
SubscribeLocalEvent<CultistComponent, ActionGettingRemovedEvent>(OnActionRemoved);
|
SubscribeLocalEvent<CultistComponent, ActionGettingRemovedEvent>(OnActionRemoved);
|
||||||
SubscribeLocalEvent<CultistComponent, ShacklesEvent>(OnShackles);
|
SubscribeLocalEvent<CultistComponent, ShacklesEvent>(OnShackles);
|
||||||
|
SubscribeLocalEvent<CultistComponent, TwistedConstructionEvent>(OnTwistedConstruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTwistedConstruction(Entity<CultistComponent> ent, ref TwistedConstructionEvent args)
|
||||||
|
{
|
||||||
|
if (args.Cancelled)
|
||||||
|
QueueDel(GetEntity(args.Effect));
|
||||||
|
|
||||||
|
if (args.Handled || args.Cancelled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Handled = true;
|
||||||
|
|
||||||
|
Del(args.Target);
|
||||||
|
Spawn(args.RunicDoor, GetCoordinates(args.Location));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnShackles(Entity<CultistComponent> ent, ref ShacklesEvent args)
|
private void OnShackles(Entity<CultistComponent> ent, ref ShacklesEvent args)
|
||||||
@@ -115,22 +125,14 @@ public partial class CultSystem
|
|||||||
!TryComp<ActorComponent>(uid, out var actor))
|
!TryComp<ActorComponent>(uid, out var actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_holyWeapon.IsHoldingHolyWeapon(args.Target))
|
if (!HasComp<CultistComponent>(args.Target))
|
||||||
{
|
{
|
||||||
_popupSystem.PopupEntity(Loc.GetString("cult-magic-holy"), args.Performer, args.Performer,
|
_popupSystem.PopupEntity("Цель должна быть культистом.", args.Performer, args.Performer,
|
||||||
PopupType.MediumCaution);
|
PopupType.MediumCaution);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HasComp<CultistComponent>(args.Target) && !HasComp<ConstructComponent>(args.Target) &&
|
_bloodstreamSystem.TryModifyBloodLevel(uid, -7, bloodstream, createPuddle: false);
|
||||||
_actionBlocker.CanInteract(args.Target, null))
|
|
||||||
{
|
|
||||||
_popupSystem.PopupEntity("Цель должна быть культистом, быть скованной или парализованной.", args.Performer,
|
|
||||||
args.Performer, PopupType.MediumCaution);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_bloodstreamSystem.TryModifyBloodLevel(uid, -5, bloodstream, createPuddle: false);
|
|
||||||
|
|
||||||
var eui = new CultTeleportSpellEui(args.Performer, args.Target);
|
var eui = new CultTeleportSpellEui(args.Performer, args.Target);
|
||||||
_euiManager.OpenEui(eui, actor.PlayerSession);
|
_euiManager.OpenEui(eui, actor.PlayerSession);
|
||||||
@@ -367,13 +369,47 @@ public partial class CultSystem
|
|||||||
if (!TryComp(args.Target, out CuffableComponent? cuffs) || cuffs.Container.ContainedEntities.Count > 0)
|
if (!TryComp(args.Target, out CuffableComponent? cuffs) || cuffs.Container.ContainedEntities.Count > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.Performer, TimeSpan.FromSeconds(2),
|
var doAfterArgs = new DoAfterArgs(EntityManager, args.Performer, TimeSpan.FromSeconds(2), new ShacklesEvent(),
|
||||||
new ShacklesEvent(), args.Performer, args.Target)
|
args.Performer, args.Target)
|
||||||
{
|
{
|
||||||
BreakOnMove = true,
|
BreakOnMove = true,
|
||||||
BreakOnDamage = true
|
BreakOnDamage = true
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (!_doAfterSystem.TryStartDoAfter(doAfterArgs))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Speak(args);
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConvertDoor(EntityUid uid, EntityUid target, BloodstreamComponent bloodstream,
|
||||||
|
CultTwistedConstructionActionEvent args)
|
||||||
|
{
|
||||||
|
var meta = MetaData(target);
|
||||||
|
if (meta.EntityPrototype?.ID == args.RunicDoor.Id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var xform = Transform(target);
|
||||||
|
if (!xform.Anchored)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var effect = Spawn(args.Effect, xform.Coordinates);
|
||||||
|
var ev = new TwistedConstructionEvent(GetNetEntity(effect), args.RunicDoor, GetNetCoordinates(xform.Coordinates));
|
||||||
|
var doAfterArgs = new DoAfterArgs(EntityManager, uid, args.Delay, ev, uid, target)
|
||||||
|
{
|
||||||
|
BreakOnDamage = true,
|
||||||
|
BreakOnMove = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!_doAfterSystem.TryStartDoAfter(doAfterArgs))
|
||||||
|
{
|
||||||
|
QueueDel(effect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_audio.PlayPvs(args.Sound, xform.Coordinates);
|
||||||
|
_bloodstreamSystem.TryModifyBloodLevel(uid, -12, bloodstream, createPuddle: false);
|
||||||
Speak(args);
|
Speak(args);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
@@ -389,6 +425,12 @@ public partial class CultSystem
|
|||||||
if (!TryComp<BloodstreamComponent>(args.Performer, out var bloodstreamComponent))
|
if (!TryComp<BloodstreamComponent>(args.Performer, out var bloodstreamComponent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (HasComp<DoorComponent>(args.Target))
|
||||||
|
{
|
||||||
|
ConvertDoor(uid, args.Target, bloodstreamComponent, args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_entityManager.TryGetComponent<StackComponent>(args.Target, out var stack))
|
if (!_entityManager.TryGetComponent<StackComponent>(args.Target, out var stack))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Content.Shared.Actions;
|
using Content.Shared.Actions;
|
||||||
using Content.Shared.Magic;
|
using Content.Shared.Magic;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Shared._White.Cult.Actions;
|
namespace Content.Shared._White.Cult.Actions;
|
||||||
|
|
||||||
@@ -7,6 +9,21 @@ public sealed partial class CultTwistedConstructionActionEvent : EntityTargetAct
|
|||||||
{
|
{
|
||||||
[DataField("speech")]
|
[DataField("speech")]
|
||||||
public string? Speech { get; private set; }
|
public string? Speech { get; private set; }
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public EntProtoId RunicDoor = "AirlockGlassCult";
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public EntProtoId Effect = "EffectConstructRed";
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public TimeSpan Delay = TimeSpan.FromSeconds(4);
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public SoundSpecifier? Sound = new SoundPathSpecifier("/Audio/Machines/airlock_creaking.ogg")
|
||||||
|
{
|
||||||
|
Params = AudioParams.Default.WithVolume(-3f),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent, ISpeakSpell
|
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent, ISpeakSpell
|
||||||
|
|||||||
30
Content.Shared/_White/Cult/Actions/CultEvents.cs
Normal file
30
Content.Shared/_White/Cult/Actions/CultEvents.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Content.Shared.DoAfter;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared._White.Cult.Actions;
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed partial class ShacklesEvent : SimpleDoAfterEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed partial class TwistedConstructionEvent : DoAfterEvent
|
||||||
|
{
|
||||||
|
public NetEntity Effect { get; private set; }
|
||||||
|
|
||||||
|
public EntProtoId RunicDoor { get; private set; }
|
||||||
|
|
||||||
|
public NetCoordinates Location { get; private set; }
|
||||||
|
|
||||||
|
public TwistedConstructionEvent(NetEntity effect, EntProtoId runicDoor, NetCoordinates location)
|
||||||
|
{
|
||||||
|
Effect = effect;
|
||||||
|
RunicDoor = runicDoor;
|
||||||
|
Location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DoAfterEvent Clone() => this;
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using Content.Shared.DoAfter;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
|
|
||||||
namespace Content.Shared._White.Cult.Actions;
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed partial class ShacklesEvent : SimpleDoAfterEvent
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -20,10 +20,10 @@ juggernaut-create-wall-action-name = Щит
|
|||||||
juggernaut-create-wall-action-description = Это заклинание создает временное невидимое силовое поле для защиты себя и союзников от подавляющего огня.
|
juggernaut-create-wall-action-description = Это заклинание создает временное невидимое силовое поле для защиты себя и союзников от подавляющего огня.
|
||||||
|
|
||||||
ent-ActionCultTwistedConstruction = Искажённое Воздействие
|
ent-ActionCultTwistedConstruction = Искажённое Воздействие
|
||||||
.desc = Зловещее заклинание, которое используют для превращения металла в рунический металл.
|
.desc = Зловещее заклинание, которое используют для превращения металла в рунический металл и обычных дверей в рунические.
|
||||||
|
|
||||||
ent-ActionCultTeleport = Телепорт
|
ent-ActionCultTeleport = Телепорт
|
||||||
.desc = Полезное заклинание, которое телепортирует цель на выбранную руну телепотрации. Цель должна являются культистом или быть парализованной.
|
.desc = Полезное заклинание, которое телепортирует культиста на выбранную руну телепотрации.
|
||||||
|
|
||||||
ent-ActionCultSummonCombatEquipment = Призыв Боевого Снаряжения
|
ent-ActionCultSummonCombatEquipment = Призыв Боевого Снаряжения
|
||||||
.desc = Важное заклинание, которое позволяет вам вызвать полный набор боевого снаряжения.
|
.desc = Важное заклинание, которое позволяет вам вызвать полный набор боевого снаряжения.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: EffectRCDBase
|
id: EffectRCDBase
|
||||||
abstract: true
|
abstract: true
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
|
|||||||
@@ -766,6 +766,7 @@
|
|||||||
normalState: normal-unshaded
|
normalState: normal-unshaded
|
||||||
ejectState: eject-unshaded
|
ejectState: eject-unshaded
|
||||||
denyState: deny-unshaded
|
denyState: deny-unshaded
|
||||||
|
priceMultiplier: 0.0
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Machines/VendingMachines/engivend.rsi
|
sprite: Structures/Machines/VendingMachines/engivend.rsi
|
||||||
layers:
|
layers:
|
||||||
|
|||||||
@@ -118,3 +118,13 @@
|
|||||||
duration: 0.5
|
duration: 0.5
|
||||||
- type: TimedDespawn
|
- type: TimedDespawn
|
||||||
lifetime: 0.5
|
lifetime: 0.5
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: EffectRCDBase
|
||||||
|
id: EffectConstructRed
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
state: construct_red
|
||||||
|
- type: TimedDespawn
|
||||||
|
lifetime: 5.2
|
||||||
|
|||||||
BIN
Resources/Textures/Effects/rcd.rsi/construct_red.png
Normal file
BIN
Resources/Textures/Effects/rcd.rsi/construct_red.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
@@ -201,6 +201,65 @@
|
|||||||
0.1
|
0.1
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "construct_red",
|
||||||
|
"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,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
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": "deconstruct2",
|
"name": "deconstruct2",
|
||||||
|
|||||||
Reference in New Issue
Block a user