Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using Content.Server._White.Wizard.SpellBlade;
|
||||
using Content.Server.Temperature.Components;
|
||||
using Content.Server.Temperature.Systems;
|
||||
using Content.Shared.Changeling;
|
||||
@@ -10,6 +11,7 @@ namespace Content.Server._White.ChangeTemperatureOnCollide;
|
||||
public sealed class LowTemperatureSlowdownSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
|
||||
[Dependency] private readonly SpellBladeSystem _spellBlade = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -22,7 +24,8 @@ public sealed class LowTemperatureSlowdownSystem : EntitySystem
|
||||
private void OnMoveSpeedRefresh(EntityUid uid, TemperatureComponent component,
|
||||
RefreshMovementSpeedModifiersEvent args)
|
||||
{
|
||||
var modifier = HasComp<GodmodeComponent>(uid) || HasComp<VoidAdaptationComponent>(uid) || !component.Slowdown
|
||||
var modifier = _spellBlade.IsHoldingItemWithComponent<FrostAspectComponent>(uid) ||
|
||||
HasComp<GodmodeComponent>(uid) || HasComp<VoidAdaptationComponent>(uid) || !component.Slowdown
|
||||
? 1f
|
||||
: GetSpeedModifier(component.CurrentTemperature);
|
||||
args.ModifySpeed(modifier, modifier);
|
||||
@@ -32,7 +35,7 @@ public sealed class LowTemperatureSlowdownSystem : EntitySystem
|
||||
OnTemperatureChangeEvent args)
|
||||
{
|
||||
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||
if(GetSpeedModifier(args.LastTemperature) == GetSpeedModifier(args.CurrentTemperature))
|
||||
if (GetSpeedModifier(args.LastTemperature) == GetSpeedModifier(args.CurrentTemperature))
|
||||
return;
|
||||
|
||||
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid, component);
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._White.Cult;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ConstructComponent : Component
|
||||
{
|
||||
[DataField("actions")]
|
||||
public List<EntProtoId> Actions = new();
|
||||
|
||||
[ViewVariables]
|
||||
public List<EntityUid?> ActionEntities = new();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server._White.Cult.Items.Components;
|
||||
using Content.Server._White.Cult.TimedProduction;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Pylon;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using Content.Server.Atmos.Piping.Other.Components;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Interaction;
|
||||
|
||||
@@ -148,7 +148,7 @@ public partial class CultSystem
|
||||
|
||||
_bloodstreamSystem.TryModifyBloodLevel(uid, -5, bloodstream, createPuddle: false);
|
||||
|
||||
var eui = new TeleportSpellEui(args.Performer, args.Target);
|
||||
var eui = new CultTeleportSpellEui(args.Performer, args.Target);
|
||||
_euiManager.OpenEui(eui, actor.PlayerSession);
|
||||
eui.StateDirty();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
|
||||
namespace Content.Server._White.Cult.Runes.Systems;
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Runes;
|
||||
using Content.Shared._White.Cult.UI;
|
||||
using Content.Shared.Cuffs;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Mindshield.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
@@ -597,13 +596,14 @@ public sealed partial class CultSystem : EntitySystem
|
||||
|
||||
private bool AddCultistBuff(EntityUid target, EntityUid user)
|
||||
{
|
||||
if (HasComp<CultBuffComponent>(target))
|
||||
if (TryComp<CultBuffComponent>(target, out var buff) && buff.BuffTime > buff.BuffLimit)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("cult-buff-already-buffed"), user, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
EnsureComp<CultBuffComponent>(target);
|
||||
buff = EnsureComp<CultBuffComponent>(target);
|
||||
buff.BuffTime = buff.StartingBuffTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -631,6 +631,18 @@ public sealed partial class CultSystem : EntitySystem
|
||||
}
|
||||
|
||||
private bool Teleport(EntityUid rune, EntityUid user, List<EntityUid>? victims = null)
|
||||
{
|
||||
if (!OpenTeleportUi(user, rune))
|
||||
return false;
|
||||
|
||||
_entityManager.EnsureComponent<CultTeleportRuneProviderComponent>(user, out var providerComponent);
|
||||
providerComponent.Targets = victims;
|
||||
providerComponent.BaseRune = rune;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool OpenTeleportUi(EntityUid user, EntityUid? exceptRune = null)
|
||||
{
|
||||
var runesQuery = EntityQueryEnumerator<CultRuneTeleportComponent>();
|
||||
var list = new List<int>();
|
||||
@@ -641,7 +653,7 @@ public sealed partial class CultSystem : EntitySystem
|
||||
if (teleportComponent.Label == null)
|
||||
continue;
|
||||
|
||||
if (runeUid == rune)
|
||||
if (runeUid == exceptRune)
|
||||
continue;
|
||||
|
||||
if (!int.TryParse(runeUid.ToString(), out var intValue))
|
||||
@@ -665,10 +677,6 @@ public sealed partial class CultSystem : EntitySystem
|
||||
return false;
|
||||
}
|
||||
|
||||
_entityManager.EnsureComponent<CultTeleportRuneProviderComponent>(user, out var providerComponent);
|
||||
providerComponent.Targets = victims;
|
||||
providerComponent.BaseRune = rune;
|
||||
|
||||
_ui.SetUiState(ui, new TeleportRunesListWindowBUIState(list, labels));
|
||||
|
||||
if (_ui.IsUiOpen(user, ui.UiKey))
|
||||
@@ -868,7 +876,10 @@ public sealed partial class CultSystem : EntitySystem
|
||||
return false;
|
||||
|
||||
if (!_mobState.IsDead(target, mobState))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("cult-revive-rune-already-alive"), user, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
var airlossGroup = _prototypeManager.Index<DamageGroupPrototype>("Airloss");
|
||||
|
||||
@@ -878,7 +889,10 @@ public sealed partial class CultSystem : EntitySystem
|
||||
{
|
||||
var afterHeal = damageable.TotalDamage - toHeal;
|
||||
if (deadThreshold <= afterHeal)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("cult-revive-rune-too-damaged"), user, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
var asphyxType = _prototypeManager.Index<DamageTypePrototype>("Asphyxiation");
|
||||
var bloodlossType = _prototypeManager.Index<DamageTypePrototype>("Bloodloss");
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Content.Server._White.Cult.Structures;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class RunicDoorComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
using Content.Server.Cuffs;
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Doors;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Prying.Components;
|
||||
using Content.Shared.Weapons.Melee.Components;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
|
||||
|
||||
namespace Content.Server._White.Cult.Structures;
|
||||
|
||||
public sealed class RunicDoorSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DoorSystem _doorSystem = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly OccluderSystem _occluder = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly CuffableSystem _cuffable = default!;
|
||||
[Dependency] private readonly HolyWeaponSystem _holyWeapon = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RunicDoorComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
|
||||
SubscribeLocalEvent<RunicDoorComponent, BeforeDoorClosedEvent>(OnBeforeDoorClosed);
|
||||
// SubscribeLocalEvent<RunicDoorComponent, AttackedEvent>(OnGetAttacked);
|
||||
SubscribeLocalEvent<RunicDoorComponent, ConcealEvent>(OnConceal);
|
||||
SubscribeLocalEvent<RunicDoorComponent, BeforePryEvent>(OnBeforePry);
|
||||
}
|
||||
|
||||
private void OnBeforePry(Entity<RunicDoorComponent> ent, ref BeforePryEvent args)
|
||||
{
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnConceal(Entity<RunicDoorComponent> ent, ref ConcealEvent args)
|
||||
{
|
||||
if (!TryComp(ent, out MetaDataComponent? meta))
|
||||
return;
|
||||
|
||||
if (TryComp(ent, out PhysicsComponent? physics))
|
||||
_occluder.SetEnabled(ent, args.Conceal && physics.CanCollide, meta: meta);
|
||||
|
||||
if (TryComp(ent, out DoorComponent? door))
|
||||
{
|
||||
door.Occludes = args.Conceal;
|
||||
Dirty(ent, door, meta);
|
||||
}
|
||||
|
||||
if (!TryComp(ent, out MeleeSoundComponent? meleeSound) || meleeSound.SoundGroups == null)
|
||||
return;
|
||||
|
||||
meleeSound.SoundGroups["Brute"] = args.Conceal
|
||||
? new SoundPathSpecifier("/Audio/Weapons/smash.ogg")
|
||||
: new SoundCollectionSpecifier("GlassSmash");
|
||||
|
||||
Dirty(ent, meleeSound, meta);
|
||||
}
|
||||
|
||||
private void OnGetAttacked(Entity<RunicDoorComponent> ent, ref AttackedEvent args)
|
||||
{
|
||||
if (!HasComp<HolyWeaponComponent>(args.Used) || !TryComp<DoorComponent>(ent, out var doorComp) ||
|
||||
doorComp.State is not DoorState.Closed)
|
||||
return;
|
||||
|
||||
_audio.PlayPvs(new SoundPathSpecifier("/Audio/Magic/knock.ogg"), ent);
|
||||
|
||||
_doorSystem.StartOpening(ent, doorComp);
|
||||
}
|
||||
|
||||
private void OnBeforeDoorOpened(EntityUid uid, RunicDoorComponent component, BeforeDoorOpenedEvent args)
|
||||
{
|
||||
args.Uncancel();
|
||||
|
||||
if (!args.User.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Process(uid, args.User.Value))
|
||||
{
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeforeDoorClosed(EntityUid uid, RunicDoorComponent component, BeforeDoorClosedEvent args)
|
||||
{
|
||||
args.Uncancel();
|
||||
|
||||
if (!args.User.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Process(uid, args.User.Value))
|
||||
{
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private bool Process(EntityUid airlock, EntityUid user)
|
||||
{
|
||||
if (HasComp<CultistComponent>(user) || HasComp<ConstructComponent>(user))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// _doorSystem.Deny(airlock);
|
||||
|
||||
if (!HasComp<HumanoidAppearanceComponent>(user) || _holyWeapon.IsHoldingHolyWeapon(user) ||
|
||||
TryComp(airlock, out ConcealableComponent? concealable) && concealable.Concealed)
|
||||
return false;
|
||||
|
||||
var direction = Transform(user).MapPosition.Position - Transform(airlock).MapPosition.Position;
|
||||
var impulseVector = direction * 2000;
|
||||
|
||||
_physics.ApplyLinearImpulse(user, impulseVector);
|
||||
|
||||
_stunSystem.TryParalyze(user, TimeSpan.FromSeconds(3), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanBumpOpen(EntityUid uid, EntityUid otherUid)
|
||||
{
|
||||
return !HasComp<RunicDoorComponent>(uid) || !HasComp<ConstructComponent>(otherUid) &&
|
||||
(!HasComp<CultistComponent>(otherUid) || !_mobState.IsAlive(otherUid) ||
|
||||
TryComp(otherUid, out CuffableComponent? cuffable) && _cuffable.GetAllCuffs(cuffable).Count > 0);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._White.Cult.UI;
|
||||
|
||||
public sealed class TeleportSpellEui : BaseEui
|
||||
public sealed class CultTeleportSpellEui : BaseEui
|
||||
{
|
||||
[Dependency] private readonly EntityManager _entityManager = default!;
|
||||
private readonly SharedTransformSystem _transformSystem;
|
||||
@@ -22,7 +22,7 @@ public sealed class TeleportSpellEui : BaseEui
|
||||
|
||||
private bool _used;
|
||||
|
||||
public TeleportSpellEui(EntityUid performer, EntityUid target)
|
||||
public CultTeleportSpellEui(EntityUid performer, EntityUid target)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
@@ -39,7 +39,7 @@ public sealed class TeleportSpellEui : BaseEui
|
||||
public override EuiStateBase GetNewState()
|
||||
{
|
||||
var runesQuery = _entityManager.EntityQueryEnumerator<CultRuneTeleportComponent>();
|
||||
var state = new TeleportSpellEuiState();
|
||||
var state = new CultTeleportSpellEuiState();
|
||||
|
||||
while (runesQuery.MoveNext(out var runeUid, out var rune))
|
||||
{
|
||||
@@ -110,4 +110,4 @@ public sealed class TeleportSpellEui : BaseEui
|
||||
_transformSystem.SetCoordinates(_target, runeTransform.Coordinates);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using Content.Server._White.Cult.Structures;
|
||||
using Content.Shared._White.Cult.Structures;
|
||||
using Content.Shared._White.Keyhole.Components;
|
||||
using Content.Shared._White.Keyhole;
|
||||
using Content.Shared.DoAfter;
|
||||
@@ -120,4 +120,4 @@ public sealed class KeyholeSystem : EntitySystem
|
||||
_popupSystem.PopupEntity(Loc.GetString("key-pressed-in-keyform-message", ("user", user), ("key", uid)), uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
||||
if (!TryComp(msg.Performer, out ActorComponent? actor))
|
||||
return;
|
||||
|
||||
var eui = new TeleportSpellEui(msg.Performer);
|
||||
var eui = new WizardTeleportSpellEui(msg.Performer);
|
||||
_euiManager.OpenEui(eui, actor.PlayerSession);
|
||||
eui.StateDirty();
|
||||
|
||||
@@ -736,7 +736,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
||||
RaiseLocalEvent(uid, new EnergyDomeClothesTurnOffEvent());
|
||||
}
|
||||
|
||||
private bool CanCast(BaseActionEvent msg)
|
||||
public bool CanCast(BaseActionEvent msg)
|
||||
{
|
||||
return !msg.Handled && CheckRequirements(msg.Action, msg.Performer) &&
|
||||
!_statusEffectsSystem.HasStatusEffect(msg.Performer, "Incorporeal");
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Content.Server._White.Wizard.SpellBlade;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class FireAspectComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Content.Shared.Atmos;
|
||||
|
||||
namespace Content.Server._White.Wizard.SpellBlade;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class FrostAspectComponent : Component
|
||||
{
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float TemperatureOnHit = 100;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float MinTemperature = Atmospherics.TCMB;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Content.Server._White.Wizard.SpellBlade;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class LightningAspectComponent : Component
|
||||
{
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float Range = 2f;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public int BoltCount = 3;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public string LightningPrototype = "WeakWizardLightning";
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public int ArcDepth = 2;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan ShockRate = TimeSpan.FromSeconds(10);
|
||||
|
||||
public TimeSpan NextShock;
|
||||
}
|
||||
79
Content.Server/_White/Wizard/SpellBlade/SpellBladeSystem.cs
Normal file
79
Content.Server/_White/Wizard/SpellBlade/SpellBladeSystem.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Lightning;
|
||||
using Content.Server.Temperature.Components;
|
||||
using Content.Server.Temperature.Systems;
|
||||
using Content.Shared._White.Wizard.SpellBlade;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._White.Wizard.SpellBlade;
|
||||
|
||||
public sealed class SpellBladeSystem : SharedSpellBladeSystem
|
||||
{
|
||||
[Dependency] private readonly TemperatureSystem _temperature = default!;
|
||||
[Dependency] private readonly LightningSystem _lightning = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<FrostAspectComponent, MeleeHitEvent>(OnFrostMeleeHit);
|
||||
SubscribeLocalEvent<LightningAspectComponent, MeleeHitEvent>(OnLightningMeleeHit);
|
||||
}
|
||||
|
||||
private void OnLightningMeleeHit(Entity<LightningAspectComponent> ent, ref MeleeHitEvent args)
|
||||
{
|
||||
if (args.Direction != null || args.HitEntities.Count != 1)
|
||||
return;
|
||||
|
||||
if (ent.Comp.NextShock > _timing.CurTime)
|
||||
return;
|
||||
|
||||
ent.Comp.NextShock = _timing.CurTime + ent.Comp.ShockRate;
|
||||
|
||||
_lightning.ShootRandomLightnings(args.HitEntities[0], ent.Comp.Range, ent.Comp.BoltCount,
|
||||
ent.Comp.LightningPrototype, ent.Comp.ArcDepth, false, args.User);
|
||||
}
|
||||
|
||||
private void OnFrostMeleeHit(Entity<FrostAspectComponent> ent, ref MeleeHitEvent args)
|
||||
{
|
||||
var temp = ent.Comp.TemperatureOnHit;
|
||||
if (args.Direction != null) // Heavy attack
|
||||
temp *= 0.5f;
|
||||
|
||||
foreach (var entity in args.HitEntities)
|
||||
{
|
||||
if (!TryComp<TemperatureComponent>(entity, out var temperature))
|
||||
continue;
|
||||
|
||||
var curTemp = temperature.CurrentTemperature;
|
||||
var newTemp = curTemp - temp;
|
||||
|
||||
newTemp = curTemp < ent.Comp.MinTemperature
|
||||
? MathF.Min(curTemp, newTemp)
|
||||
: Math.Max(newTemp, ent.Comp.MinTemperature);
|
||||
|
||||
_temperature.ForceChangeTemperature(entity, newTemp, temperature);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ApplyFireAspect(EntityUid uid)
|
||||
{
|
||||
var ignite = EnsureComp<IgniteOnMeleeHitComponent>(uid);
|
||||
ignite.FireStacks = 2f;
|
||||
EnsureComp<FireAspectComponent>(uid);
|
||||
}
|
||||
|
||||
protected override void ApplyFrostAspect(EntityUid uid)
|
||||
{
|
||||
var ignite = EnsureComp<IgniteOnMeleeHitComponent>(uid);
|
||||
ignite.FireStacks = -5f;
|
||||
EnsureComp<FrostAspectComponent>(uid);
|
||||
}
|
||||
|
||||
protected override void ApplyLightningAspect(EntityUid uid)
|
||||
{
|
||||
EnsureComp<LightningAspectComponent>(uid);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
using Content.Server.Pinpointer;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.Warps;
|
||||
using Content.Shared.Coordinates.Helpers;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Physics;
|
||||
|
||||
namespace Content.Server._White.Wizard.Teleport;
|
||||
|
||||
public sealed class TeleportLocationSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly TurfSystem _turf = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -20,10 +26,30 @@ public sealed class TeleportLocationSystem : EntitySystem
|
||||
if (!TryComp(ent, out WarpPointComponent? warpPoint) || warpPoint.Location == null)
|
||||
return;
|
||||
|
||||
var newEnt = Spawn(null, Transform(ent).Coordinates);
|
||||
var xForm = EnsureComp<TransformComponent>(newEnt);
|
||||
_transformSystem.AttachToGridOrMap(newEnt, xForm);
|
||||
var xForm = Transform(ent);
|
||||
|
||||
if (!CanTeleport(ent, xForm))
|
||||
return;
|
||||
|
||||
var newEnt = Spawn(null, xForm.Coordinates);
|
||||
var newXForm = EnsureComp<TransformComponent>(newEnt);
|
||||
_transformSystem.AttachToGridOrMap(newEnt, newXForm);
|
||||
var location = EnsureComp<TeleportLocationComponent>(newEnt);
|
||||
location.Location = warpPoint.Location;
|
||||
}
|
||||
|
||||
public bool CanTeleport(EntityUid uid, TransformComponent xForm)
|
||||
{
|
||||
var station = _station.GetOwningStation(uid, xForm);
|
||||
|
||||
if (!HasComp<TeleportLocationTargetStationComponent>(station))
|
||||
return false;
|
||||
|
||||
var turf = xForm.Coordinates.SnapToGrid(EntityManager).GetTileRef(EntityManager);
|
||||
|
||||
if (turf == null)
|
||||
return false;
|
||||
|
||||
return !_turf.IsTileBlocked(turf.Value, CollisionGroup.Impassable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Content.Server._White.Wizard.Teleport;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class TeleportLocationTargetStationComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using Content.Server.EUI;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared._White.Wizard.Teleport;
|
||||
using Content.Shared.Eui;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._White.Wizard.Teleport;
|
||||
|
||||
public sealed class WizardTeleportSpellEui : BaseEui
|
||||
{
|
||||
[Dependency] private readonly EntityManager _entityManager = default!;
|
||||
private readonly SharedTransformSystem _transformSystem;
|
||||
private readonly TeleportLocationSystem _teleportLocation;
|
||||
private readonly PopupSystem _popupSystem;
|
||||
|
||||
private readonly EntityUid _performer;
|
||||
|
||||
private bool _used;
|
||||
|
||||
public WizardTeleportSpellEui(EntityUid performer)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_transformSystem = _entityManager.System<SharedTransformSystem>();
|
||||
_teleportLocation = _entityManager.System<TeleportLocationSystem>();
|
||||
_popupSystem = _entityManager.System<PopupSystem>();
|
||||
|
||||
_performer = performer;
|
||||
|
||||
Timer.Spawn(TimeSpan.FromSeconds(60), Close);
|
||||
}
|
||||
|
||||
public override EuiStateBase GetNewState()
|
||||
{
|
||||
var locationQuery = _entityManager.EntityQueryEnumerator<TeleportLocationComponent, TransformComponent>();
|
||||
var state = new WizardTeleportSpellEuiState();
|
||||
|
||||
while (locationQuery.MoveNext(out var locationUid, out var locationComponent, out var transformComponent))
|
||||
{
|
||||
if (_teleportLocation.CanTeleport(locationUid, transformComponent))
|
||||
state.Locations.Add((int) locationUid, locationComponent.Location);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
public override void HandleMessage(EuiMessageBase msg)
|
||||
{
|
||||
base.HandleMessage(msg);
|
||||
|
||||
if (_used)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg is not TeleportSpellTargetLocationSelected cast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var transform = _entityManager.GetComponent<TransformComponent>(_performer);
|
||||
var oldCoords = transform.Coordinates;
|
||||
|
||||
TransformComponent? locationTransform = null;
|
||||
|
||||
var teleportLocationQuery = _entityManager
|
||||
.EntityQueryEnumerator<TeleportLocationComponent, TransformComponent>();
|
||||
while (teleportLocationQuery.MoveNext(out var locationUid, out _, out var transformComponent))
|
||||
{
|
||||
if (locationUid == new EntityUid(cast.LocationUid))
|
||||
{
|
||||
locationTransform = transformComponent;
|
||||
}
|
||||
}
|
||||
|
||||
if (locationTransform is null)
|
||||
{
|
||||
_popupSystem.PopupEntity("Can't teleport", _performer, _performer);
|
||||
DoStateUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
_used = true;
|
||||
|
||||
var coords = locationTransform.Coordinates;
|
||||
|
||||
_transformSystem.SetCoordinates(_performer, coords);
|
||||
_transformSystem.AttachToGridOrMap(_performer, transform);
|
||||
|
||||
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", oldCoords);
|
||||
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", coords);
|
||||
|
||||
Close();
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ public sealed partial class WizardRuleComponent : Component
|
||||
{
|
||||
public readonly List<EntityUid> WizardMinds = new();
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[ViewVariables]
|
||||
public EntityUid? TargetStation;
|
||||
|
||||
[DataField("minPlayers")]
|
||||
|
||||
@@ -310,7 +310,7 @@ public sealed class WizardRuleSystem : GameRuleSystem<WizardRuleComponent>
|
||||
if (meta.EntityPrototype?.ID != component.SpawnPointProto.Id)
|
||||
continue;
|
||||
|
||||
if (xform.ParentUid != component.ShuttleMap)
|
||||
if (xform.MapUid != component.ShuttleMap)
|
||||
continue;
|
||||
|
||||
spawn = xform.Coordinates;
|
||||
|
||||
Reference in New Issue
Block a user