More magic (#338)
* - tweak: Magic tweaks. * - add: Rework some spells. * - fix: Some bugfixes. * - tweak: Less requirements. * - add: Loc.
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
using Content.Shared._White.Wizard;
|
using Content.Shared._White.Wizard;
|
||||||
using Content.Shared._White.Wizard.Charging;
|
using Content.Shared._White.Wizard.Charging;
|
||||||
using Content.Shared.Actions;
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Mobs.Systems;
|
||||||
|
using Content.Shared.StatusEffect;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Input;
|
using Robust.Client.Input;
|
||||||
@@ -24,6 +26,8 @@ public sealed class ChargeActionSystem : SharedChargingSystem
|
|||||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||||
|
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||||
|
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
|
||||||
|
|
||||||
private ActionUIController? _controller;
|
private ActionUIController? _controller;
|
||||||
|
|
||||||
@@ -55,6 +59,9 @@ public sealed class ChargeActionSystem : SharedChargingSystem
|
|||||||
if (_playerManager.LocalEntity is not { } user)
|
if (_playerManager.LocalEntity is not { } user)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!_mobState.IsAlive(user) || _statusEffects.HasStatusEffect(user, "Incorporeal"))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!_timing.IsFirstTimePredicted || _controller == null || _controller.SelectingTargetFor is not { } actionId)
|
if (!_timing.IsFirstTimePredicted || _controller == null || _controller.SelectingTargetFor is not { } actionId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Server.Beam.Components;
|
using Content.Server.Beam.Components;
|
||||||
|
using Content.Server.Electrocution;
|
||||||
using Content.Shared.Beam;
|
using Content.Shared.Beam;
|
||||||
using Content.Shared.Beam.Components;
|
using Content.Shared.Beam.Components;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
@@ -65,7 +66,7 @@ public sealed class BeamSystem : SharedBeamSystem
|
|||||||
/// <param name="controller"> The virtual beam controller that this beam will use. If one doesn't exist it will be created here.</param>
|
/// <param name="controller"> The virtual beam controller that this beam will use. If one doesn't exist it will be created here.</param>
|
||||||
/// <param name="bodyState">Optional sprite state for the <see cref="prototype"/> if it needs a dynamic one</param>
|
/// <param name="bodyState">Optional sprite state for the <see cref="prototype"/> if it needs a dynamic one</param>
|
||||||
/// <param name="shader">Optional shader for the <see cref="prototype"/> and <see cref="bodyState"/> if it needs something other than default</param>
|
/// <param name="shader">Optional shader for the <see cref="prototype"/> and <see cref="bodyState"/> if it needs something other than default</param>
|
||||||
private void CreateBeam(string prototype,
|
private IEnumerable<EntityUid> CreateBeam(string prototype,
|
||||||
Angle userAngle,
|
Angle userAngle,
|
||||||
Vector2 calculatedDistance,
|
Vector2 calculatedDistance,
|
||||||
MapCoordinates beamStartPos,
|
MapCoordinates beamStartPos,
|
||||||
@@ -78,8 +79,10 @@ public sealed class BeamSystem : SharedBeamSystem
|
|||||||
var ent = Spawn(prototype, beamSpawnPos);
|
var ent = Spawn(prototype, beamSpawnPos);
|
||||||
var shape = new EdgeShape(distanceCorrection, new Vector2(0,0));
|
var shape = new EdgeShape(distanceCorrection, new Vector2(0,0));
|
||||||
|
|
||||||
|
yield return ent;
|
||||||
|
|
||||||
if (!TryComp<PhysicsComponent>(ent, out var physics) || !TryComp<BeamComponent>(ent, out var beam))
|
if (!TryComp<PhysicsComponent>(ent, out var physics) || !TryComp<BeamComponent>(ent, out var beam))
|
||||||
return;
|
yield break;
|
||||||
|
|
||||||
FixturesComponent? manager = null;
|
FixturesComponent? manager = null;
|
||||||
_fixture.TryCreateFixture(
|
_fixture.TryCreateFixture(
|
||||||
@@ -120,6 +123,7 @@ public sealed class BeamSystem : SharedBeamSystem
|
|||||||
{
|
{
|
||||||
beamSpawnPos = beamSpawnPos.Offset(calculatedDistance.Normalized());
|
beamSpawnPos = beamSpawnPos.Offset(calculatedDistance.Normalized());
|
||||||
var newEnt = Spawn(prototype, beamSpawnPos);
|
var newEnt = Spawn(prototype, beamSpawnPos);
|
||||||
|
yield return newEnt;
|
||||||
|
|
||||||
var ev = new BeamVisualizerEvent(GetNetEntity(newEnt), distanceLength, userAngle, bodyState, shader);
|
var ev = new BeamVisualizerEvent(GetNetEntity(newEnt), distanceLength, userAngle, bodyState, shader);
|
||||||
RaiseNetworkEvent(ev);
|
RaiseNetworkEvent(ev);
|
||||||
@@ -139,10 +143,10 @@ public sealed class BeamSystem : SharedBeamSystem
|
|||||||
/// <param name="bodyState">Optional sprite state for the <see cref="bodyPrototype"/> if a default one is not given</param>
|
/// <param name="bodyState">Optional sprite state for the <see cref="bodyPrototype"/> if a default one is not given</param>
|
||||||
/// <param name="shader">Optional shader for the <see cref="bodyPrototype"/> if a default one is not given</param>
|
/// <param name="shader">Optional shader for the <see cref="bodyPrototype"/> if a default one is not given</param>
|
||||||
/// <param name="controller"></param>
|
/// <param name="controller"></param>
|
||||||
public void TryCreateBeam(EntityUid user, EntityUid target, string bodyPrototype, string? bodyState = null, string shader = "unshaded", EntityUid? controller = null)
|
public IEnumerable<EntityUid> TryCreateBeam(EntityUid user, EntityUid target, string bodyPrototype, string? bodyState = null, string shader = "unshaded", EntityUid? controller = null)
|
||||||
{
|
{
|
||||||
if (Deleted(user) || Deleted(target))
|
if (Deleted(user) || Deleted(target))
|
||||||
return;
|
yield break;
|
||||||
|
|
||||||
var userMapPos = Transform(user).MapPosition;
|
var userMapPos = Transform(user).MapPosition;
|
||||||
var targetMapPos = Transform(target).MapPosition;
|
var targetMapPos = Transform(target).MapPosition;
|
||||||
@@ -152,14 +156,14 @@ public sealed class BeamSystem : SharedBeamSystem
|
|||||||
var userAngle = calculatedDistance.ToWorldAngle();
|
var userAngle = calculatedDistance.ToWorldAngle();
|
||||||
|
|
||||||
if (userMapPos.MapId != targetMapPos.MapId)
|
if (userMapPos.MapId != targetMapPos.MapId)
|
||||||
return;
|
yield break;
|
||||||
|
|
||||||
//Where the start of the beam will spawn
|
//Where the start of the beam will spawn
|
||||||
var beamStartPos = userMapPos.Offset(calculatedDistance.Normalized());
|
var beamStartPos = userMapPos.Offset(calculatedDistance.Normalized());
|
||||||
|
|
||||||
//Don't divide by zero
|
//Don't divide by zero
|
||||||
if (calculatedDistance.Length() == 0)
|
if (calculatedDistance.Length() == 0)
|
||||||
return;
|
yield break;
|
||||||
|
|
||||||
if (controller != null && TryComp<BeamComponent>(controller, out var controllerBeamComp))
|
if (controller != null && TryComp<BeamComponent>(controller, out var controllerBeamComp))
|
||||||
{
|
{
|
||||||
@@ -169,7 +173,12 @@ public sealed class BeamSystem : SharedBeamSystem
|
|||||||
|
|
||||||
var distanceCorrection = calculatedDistance - calculatedDistance.Normalized();
|
var distanceCorrection = calculatedDistance - calculatedDistance.Normalized();
|
||||||
|
|
||||||
CreateBeam(bodyPrototype, userAngle, calculatedDistance, beamStartPos, distanceCorrection, controller, bodyState, shader);
|
var ents = CreateBeam(bodyPrototype, userAngle, calculatedDistance, beamStartPos, distanceCorrection, controller, bodyState, shader);
|
||||||
|
|
||||||
|
foreach (var ent in ents)
|
||||||
|
{
|
||||||
|
yield return ent;
|
||||||
|
}
|
||||||
|
|
||||||
var ev = new CreateBeamSuccessEvent(user, target);
|
var ev = new CreateBeamSuccessEvent(user, target);
|
||||||
RaiseLocalEvent(user, ev);
|
RaiseLocalEvent(user, ev);
|
||||||
|
|||||||
@@ -85,4 +85,11 @@ public sealed partial class ElectrifiedComponent : Component
|
|||||||
|
|
||||||
[DataField("shockVolume")]
|
[DataField("shockVolume")]
|
||||||
public float ShockVolume = 20;
|
public float ShockVolume = 20;
|
||||||
|
|
||||||
|
// WD EDIT START
|
||||||
|
[DataField]
|
||||||
|
public bool IgnoreInsulation;
|
||||||
|
|
||||||
|
public EntityUid? Caster;
|
||||||
|
// WD EDIT END
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
|
|||||||
_appearance.SetData(uid, ElectrifiedVisuals.IsPowered, true);
|
_appearance.SetData(uid, ElectrifiedVisuals.IsPowered, true);
|
||||||
|
|
||||||
siemens *= electrified.SiemensCoefficient;
|
siemens *= electrified.SiemensCoefficient;
|
||||||
if (!DoCommonElectrocutionAttempt(targetUid, uid, ref siemens) || siemens <= 0)
|
if (targetUid != electrified.Caster && !DoCommonElectrocutionAttempt(targetUid, uid, ref siemens, electrified.IgnoreInsulation) || siemens <= 0) // WD EDIT
|
||||||
return false; // If electrocution would fail, do nothing.
|
return false; // If electrocution would fail, do nothing.
|
||||||
|
|
||||||
var targets = new List<(EntityUid entity, int depth)>();
|
var targets = new List<(EntityUid entity, int depth)>();
|
||||||
@@ -230,13 +230,19 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
|
|||||||
for (var i = targets.Count - 1; i >= 0; i--)
|
for (var i = targets.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var (entity, depth) = targets[i];
|
var (entity, depth) = targets[i];
|
||||||
|
|
||||||
|
if (entity == electrified.Caster) // WD
|
||||||
|
continue;
|
||||||
|
|
||||||
lastRet = TryDoElectrocution(
|
lastRet = TryDoElectrocution(
|
||||||
entity,
|
entity,
|
||||||
uid,
|
uid,
|
||||||
(int) (electrified.ShockDamage * MathF.Pow(RecursiveDamageMultiplier, depth)),
|
(int) (electrified.ShockDamage * MathF.Pow(RecursiveDamageMultiplier, depth)),
|
||||||
TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth)),
|
TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth)),
|
||||||
true,
|
true,
|
||||||
electrified.SiemensCoefficient
|
electrified.SiemensCoefficient,
|
||||||
|
null, // WD EDIT START
|
||||||
|
electrified.IgnoreInsulation // WD EDIT END
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,4 +524,4 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
|
|||||||
|
|
||||||
_audio.PlayPvs(electrified.ShockNoises, targetUid, AudioParams.Default.WithVolume(electrified.ShockVolume));
|
_audio.PlayPvs(electrified.ShockNoises, targetUid, AudioParams.Default.WithVolume(electrified.ShockVolume));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Beam;
|
using Content.Server.Beam;
|
||||||
using Content.Server.Beam.Components;
|
using Content.Server.Beam.Components;
|
||||||
|
using Content.Server.Electrocution;
|
||||||
using Content.Server.Lightning.Components;
|
using Content.Server.Lightning.Components;
|
||||||
using Content.Shared.Lightning;
|
using Content.Shared.Lightning;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
@@ -45,10 +46,16 @@ public sealed class LightningSystem : SharedLightningSystem
|
|||||||
/// <param name="target">Where the lightning fires to</param>
|
/// <param name="target">Where the lightning fires to</param>
|
||||||
/// <param name="lightningPrototype">The prototype for the lightning to be created</param>
|
/// <param name="lightningPrototype">The prototype for the lightning to be created</param>
|
||||||
/// <param name="triggerLightningEvents">if the lightnings being fired should trigger lightning events.</param>
|
/// <param name="triggerLightningEvents">if the lightnings being fired should trigger lightning events.</param>
|
||||||
public void ShootLightning(EntityUid user, EntityUid target, string lightningPrototype = "Lightning", bool triggerLightningEvents = true)
|
public void ShootLightning(EntityUid user, EntityUid target, string lightningPrototype = "Lightning", bool triggerLightningEvents = true, EntityUid? caster = null) // WD EDIT
|
||||||
{
|
{
|
||||||
var spriteState = LightningRandomizer();
|
var spriteState = LightningRandomizer();
|
||||||
_beam.TryCreateBeam(user, target, lightningPrototype, spriteState);
|
var ents = _beam.TryCreateBeam(user, target, lightningPrototype, spriteState); // WD EDIT START
|
||||||
|
foreach (var ent in ents)
|
||||||
|
{
|
||||||
|
if (TryComp(ent, out ElectrifiedComponent? electrified))
|
||||||
|
electrified.Caster = caster;
|
||||||
|
}
|
||||||
|
// WD EDIT END
|
||||||
|
|
||||||
if (triggerLightningEvents) // we don't want certain prototypes to trigger lightning level events
|
if (triggerLightningEvents) // we don't want certain prototypes to trigger lightning level events
|
||||||
{
|
{
|
||||||
@@ -66,7 +73,7 @@ public sealed class LightningSystem : SharedLightningSystem
|
|||||||
/// <param name="lightningPrototype">The prototype for the lightning to be created</param>
|
/// <param name="lightningPrototype">The prototype for the lightning to be created</param>
|
||||||
/// <param name="arcDepth">how many times to recursively fire lightning bolts from the target points of the first shot.</param>
|
/// <param name="arcDepth">how many times to recursively fire lightning bolts from the target points of the first shot.</param>
|
||||||
/// <param name="triggerLightningEvents">if the lightnings being fired should trigger lightning events.</param>
|
/// <param name="triggerLightningEvents">if the lightnings being fired should trigger lightning events.</param>
|
||||||
public void ShootRandomLightnings(EntityUid user, float range, int boltCount, string lightningPrototype = "Lightning", int arcDepth = 0, bool triggerLightningEvents = true)
|
public void ShootRandomLightnings(EntityUid user, float range, int boltCount, string lightningPrototype = "Lightning", int arcDepth = 0, bool triggerLightningEvents = true, EntityUid? caster = null) // WD EDIT
|
||||||
{
|
{
|
||||||
//To Do: add support to different priority target tablem for different lightning types
|
//To Do: add support to different priority target tablem for different lightning types
|
||||||
//To Do: Remove Hardcode LightningTargetComponent (this should be a parameter of the SharedLightningComponent)
|
//To Do: Remove Hardcode LightningTargetComponent (this should be a parameter of the SharedLightningComponent)
|
||||||
@@ -89,10 +96,10 @@ public sealed class LightningSystem : SharedLightningSystem
|
|||||||
if (!_random.Prob(curTarget.HitProbability)) //Chance to ignore target
|
if (!_random.Prob(curTarget.HitProbability)) //Chance to ignore target
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ShootLightning(user, targets[count].Owner, lightningPrototype, triggerLightningEvents);
|
ShootLightning(user, targets[count].Owner, lightningPrototype, triggerLightningEvents, caster); // WD EDIT
|
||||||
if (arcDepth - targets[count].LightningResistance > 0)
|
if (arcDepth - targets[count].LightningResistance > 0)
|
||||||
{
|
{
|
||||||
ShootRandomLightnings(targets[count].Owner, range, 1, lightningPrototype, arcDepth - targets[count].LightningResistance, triggerLightningEvents);
|
ShootRandomLightnings(targets[count].Owner, range, 1, lightningPrototype, arcDepth - targets[count].LightningResistance, triggerLightningEvents, caster); // WD EDIT
|
||||||
}
|
}
|
||||||
shootCount++;
|
shootCount++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.Singularity.Components;
|
using Content.Server.Singularity.Components;
|
||||||
|
using Content.Server.Stunnable;
|
||||||
using Content.Shared.Ghost;
|
using Content.Shared.Ghost;
|
||||||
using Content.Shared.Singularity.EntitySystems;
|
using Content.Shared.Singularity.EntitySystems;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
@@ -24,6 +25,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
|
[Dependency] private readonly StunSystem _stun = default!; // WD EDIT
|
||||||
#endregion Dependencies
|
#endregion Dependencies
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -141,10 +143,10 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
/// <param name="baseRadialDeltaV">The base radial velocity that will be added to entities within range towards the center of the gravitational pulse.</param>
|
/// <param name="baseRadialDeltaV">The base radial velocity that will be added to entities within range towards the center of the gravitational pulse.</param>
|
||||||
/// <param name="baseTangentialDeltaV">The base tangential velocity that will be added to entities within countrclockwise around the center of the gravitational pulse.</param>
|
/// <param name="baseTangentialDeltaV">The base tangential velocity that will be added to entities within countrclockwise around the center of the gravitational pulse.</param>
|
||||||
/// <param name="xform">(optional) The transform of the entity at the epicenter of the gravitational pulse.</param>
|
/// <param name="xform">(optional) The transform of the entity at the epicenter of the gravitational pulse.</param>
|
||||||
public void GravPulse(EntityUid uid, float maxRange, float minRange, float baseRadialDeltaV = 0.0f, float baseTangentialDeltaV = 0.0f, TransformComponent? xform = null)
|
public void GravPulse(EntityUid uid, float maxRange, float minRange, float baseRadialDeltaV = 0.0f, float baseTangentialDeltaV = 0.0f, TransformComponent? xform = null, float stunTime = 0f, List<EntityUid>? ignore = null)
|
||||||
{
|
{
|
||||||
if (Resolve(uid, ref xform))
|
if (Resolve(uid, ref xform))
|
||||||
GravPulse(xform.Coordinates, maxRange, minRange, baseRadialDeltaV, baseTangentialDeltaV);
|
GravPulse(xform.Coordinates, maxRange, minRange, baseRadialDeltaV, baseTangentialDeltaV, stunTime, ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -165,8 +167,8 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
/// <param name="minRange">The minimum distance at which entities can be affected by the gravity pulse.</param>
|
/// <param name="minRange">The minimum distance at which entities can be affected by the gravity pulse.</param>
|
||||||
/// <param name="baseRadialDeltaV">The base radial velocity that will be added to entities within range towards the center of the gravitational pulse.</param>
|
/// <param name="baseRadialDeltaV">The base radial velocity that will be added to entities within range towards the center of the gravitational pulse.</param>
|
||||||
/// <param name="baseTangentialDeltaV">The base tangential velocity that will be added to entities within countrclockwise around the center of the gravitational pulse.</param>
|
/// <param name="baseTangentialDeltaV">The base tangential velocity that will be added to entities within countrclockwise around the center of the gravitational pulse.</param>
|
||||||
public void GravPulse(EntityCoordinates entityPos, float maxRange, float minRange, float baseRadialDeltaV = 0.0f, float baseTangentialDeltaV = 0.0f)
|
public void GravPulse(EntityCoordinates entityPos, float maxRange, float minRange, float baseRadialDeltaV = 0.0f, float baseTangentialDeltaV = 0.0f, float stunTime = 0f, List<EntityUid>? ignore = null)
|
||||||
=> GravPulse(entityPos.ToMap(EntityManager, _transform), maxRange, minRange, baseRadialDeltaV, baseTangentialDeltaV);
|
=> GravPulse(entityPos.ToMap(EntityManager, _transform), maxRange, minRange, baseRadialDeltaV, baseTangentialDeltaV, stunTime, ignore);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Causes a gravitational pulse, shoving around all entities within some distance of an epicenter.
|
/// Causes a gravitational pulse, shoving around all entities within some distance of an epicenter.
|
||||||
@@ -175,7 +177,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
/// <param name="maxRange">The maximum distance at which entities can be affected by the gravity pulse.</param>
|
/// <param name="maxRange">The maximum distance at which entities can be affected by the gravity pulse.</param>
|
||||||
/// <param name="minRange">The minimum distance at which entities can be affected by the gravity pulse. Exists to prevent div/0 errors.</param>
|
/// <param name="minRange">The minimum distance at which entities can be affected by the gravity pulse. Exists to prevent div/0 errors.</param>
|
||||||
/// <param name="baseMatrixDeltaV">The base velocity added to any entities within affected by the gravity pulse scaled by the displacement of those entities from the epicenter.</param>
|
/// <param name="baseMatrixDeltaV">The base velocity added to any entities within affected by the gravity pulse scaled by the displacement of those entities from the epicenter.</param>
|
||||||
public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange, in Matrix3 baseMatrixDeltaV)
|
public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange, in Matrix3 baseMatrixDeltaV, float stunTime = 0f, List<EntityUid>? ignore = null)
|
||||||
{
|
{
|
||||||
if (mapPos == MapCoordinates.Nullspace)
|
if (mapPos == MapCoordinates.Nullspace)
|
||||||
return; // No gravpulses in nullspace please.
|
return; // No gravpulses in nullspace please.
|
||||||
@@ -187,6 +189,9 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
|
|
||||||
foreach(var entity in _lookup.GetEntitiesInRange(mapPos.MapId, epicenter, maxRange, flags: LookupFlags.Dynamic | LookupFlags.Sundries))
|
foreach(var entity in _lookup.GetEntitiesInRange(mapPos.MapId, epicenter, maxRange, flags: LookupFlags.Dynamic | LookupFlags.Sundries))
|
||||||
{
|
{
|
||||||
|
if (ignore?.Contains(entity) is true)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!bodyQuery.TryGetComponent(entity, out var physics)
|
if (!bodyQuery.TryGetComponent(entity, out var physics)
|
||||||
|| physics.BodyType == BodyType.Static)
|
|| physics.BodyType == BodyType.Static)
|
||||||
{
|
{
|
||||||
@@ -206,6 +211,8 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
|
|
||||||
var scaling = (1f / distance2) * physics.Mass; // TODO: Variable falloff gradiants.
|
var scaling = (1f / distance2) * physics.Mass; // TODO: Variable falloff gradiants.
|
||||||
_physics.ApplyLinearImpulse(entity, (displacement * baseMatrixDeltaV) * scaling, body: physics);
|
_physics.ApplyLinearImpulse(entity, (displacement * baseMatrixDeltaV) * scaling, body: physics);
|
||||||
|
if (stunTime > 0f)
|
||||||
|
_stun.TryParalyze(entity, TimeSpan.FromSeconds(stunTime), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,12 +224,12 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
/// <param name="minRange">The minimum distance at which entities can be affected by the gravity pulse. Exists to prevent div/0 errors.</param>
|
/// <param name="minRange">The minimum distance at which entities can be affected by the gravity pulse. Exists to prevent div/0 errors.</param>
|
||||||
/// <param name="baseRadialDeltaV">The base amount of velocity that will be added to entities in range towards the epicenter of the pulse.</param>
|
/// <param name="baseRadialDeltaV">The base amount of velocity that will be added to entities in range towards the epicenter of the pulse.</param>
|
||||||
/// <param name="baseTangentialDeltaV">The base amount of velocity that will be added to entities in range counterclockwise relative to the epicenter of the pulse.</param>
|
/// <param name="baseTangentialDeltaV">The base amount of velocity that will be added to entities in range counterclockwise relative to the epicenter of the pulse.</param>
|
||||||
public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange = 0.0f, float baseRadialDeltaV = 0.0f, float baseTangentialDeltaV = 0.0f)
|
public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange = 0.0f, float baseRadialDeltaV = 0.0f, float baseTangentialDeltaV = 0.0f, float stunTime = 0f, List<EntityUid>? ignore = null)
|
||||||
=> GravPulse(mapPos, maxRange, minRange, new Matrix3(
|
=> GravPulse(mapPos, maxRange, minRange, new Matrix3(
|
||||||
baseRadialDeltaV, +baseTangentialDeltaV, 0.0f,
|
baseRadialDeltaV, +baseTangentialDeltaV, 0.0f,
|
||||||
-baseTangentialDeltaV, baseRadialDeltaV, 0.0f,
|
-baseTangentialDeltaV, baseRadialDeltaV, 0.0f,
|
||||||
0.0f, 0.0f, 1.0f
|
0.0f, 0.0f, 1.0f
|
||||||
));
|
), stunTime, ignore);
|
||||||
|
|
||||||
#endregion GravPulse
|
#endregion GravPulse
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Server._White.IncorporealSystem;
|
using Content.Server._White.IncorporealSystem;
|
||||||
using Content.Server._White.Wizard.Magic.Amaterasu;
|
using Content.Server._White.Wizard.Magic.Amaterasu;
|
||||||
@@ -12,6 +12,7 @@ using Content.Server.Emp;
|
|||||||
using Content.Server.Lightning;
|
using Content.Server.Lightning;
|
||||||
using Content.Server.Magic;
|
using Content.Server.Magic;
|
||||||
using Content.Server.Singularity.EntitySystems;
|
using Content.Server.Singularity.EntitySystems;
|
||||||
|
using Content.Server.Standing;
|
||||||
using Content.Server.Weapons.Ranged.Systems;
|
using Content.Server.Weapons.Ranged.Systems;
|
||||||
using Content.Shared._White.Wizard;
|
using Content.Shared._White.Wizard;
|
||||||
using Content.Shared._White.Wizard.Magic;
|
using Content.Shared._White.Wizard.Magic;
|
||||||
@@ -62,6 +63,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||||
[Dependency] private readonly EmpSystem _empSystem = default!;
|
[Dependency] private readonly EmpSystem _empSystem = default!;
|
||||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||||
|
[Dependency] private readonly StandingStateSystem _standing = default!;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -89,7 +91,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnInstantRecallSpell(InstantRecallSpellEvent msg)
|
private void OnInstantRecallSpell(InstantRecallSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp<HandsComponent>(msg.Performer, out var handsComponent))
|
if (!TryComp<HandsComponent>(msg.Performer, out var handsComponent))
|
||||||
@@ -110,11 +112,13 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
recallComponent.Item = handsComponent.ActiveHandEntity.Value;
|
recallComponent.Item = handsComponent.ActiveHandEntity.Value;
|
||||||
_popupSystem.PopupEntity($"Сопряжено с {MetaData(handsComponent.ActiveHandEntity.Value).EntityName}", msg.Performer, msg.Performer);
|
_popupSystem.PopupEntity($"Сопряжено с {MetaData(handsComponent.ActiveHandEntity.Value).EntityName}",
|
||||||
|
msg.Performer, msg.Performer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handsComponent.ActiveHandEntity == null && recallComponent.Item != null)
|
if (handsComponent.ActiveHandEntity == null && recallComponent.Item != null &&
|
||||||
|
Exists(recallComponent.Item.Value))
|
||||||
{
|
{
|
||||||
var coordsItem = Transform(recallComponent.Item.Value).Coordinates;
|
var coordsItem = Transform(recallComponent.Item.Value).Coordinates;
|
||||||
var coordsPerformer = Transform(msg.Performer).Coordinates;
|
var coordsPerformer = Transform(msg.Performer).Coordinates;
|
||||||
@@ -139,12 +143,12 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnMimeTouchSpell(MimeTouchSpellEvent msg)
|
private void OnMimeTouchSpell(MimeTouchSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!HasComp<HumanoidAppearanceComponent>(msg.Target))
|
if (!HasComp<HumanoidAppearanceComponent>(msg.Target))
|
||||||
{
|
{
|
||||||
_popupSystem.PopupEntity("Работает только на людях!", msg.Performer, msg.Performer);
|
_popupSystem.PopupEntity("Работает только на людях!", msg.Performer, msg.Performer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +168,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnBananaTouchSpell(BananaTouchSpellEvent msg)
|
private void OnBananaTouchSpell(BananaTouchSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!HasComp<HumanoidAppearanceComponent>(msg.Target))
|
if (!HasComp<HumanoidAppearanceComponent>(msg.Target))
|
||||||
@@ -188,7 +192,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnCluwneCurseSpell(CluwneCurseSpellEvent msg)
|
private void OnCluwneCurseSpell(CluwneCurseSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!HasComp<HumanoidAppearanceComponent>(msg.Target))
|
if (!HasComp<HumanoidAppearanceComponent>(msg.Target))
|
||||||
@@ -197,8 +201,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cluwne = EnsureComp<CluwneComponent>(msg.Target);
|
EnsureComp<CluwneComponent>(msg.Target);
|
||||||
cluwne.KnockChance = 0.2f;
|
|
||||||
|
|
||||||
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
||||||
|
|
||||||
@@ -212,7 +215,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmpSpell(EmpSpellEvent msg)
|
private void OnEmpSpell(EmpSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var coords = _transformSystem.ToMapCoordinates(Transform(msg.Performer).Coordinates);
|
var coords = _transformSystem.ToMapCoordinates(Transform(msg.Performer).Coordinates);
|
||||||
@@ -229,7 +232,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnJauntSpell(EtherealJauntSpellEvent msg)
|
private void OnJauntSpell(EtherealJauntSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_statusEffectsSystem.HasStatusEffect(msg.Performer, "Incorporeal"))
|
if (_statusEffectsSystem.HasStatusEffect(msg.Performer, "Incorporeal"))
|
||||||
@@ -240,7 +243,8 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
Spawn("AdminInstantEffectSmoke10", Transform(msg.Performer).Coordinates);
|
Spawn("AdminInstantEffectSmoke10", Transform(msg.Performer).Coordinates);
|
||||||
|
|
||||||
_statusEffectsSystem.TryAddStatusEffect<IncorporealComponent>(msg.Performer, "Incorporeal", TimeSpan.FromSeconds(10), false);
|
_statusEffectsSystem.TryAddStatusEffect<IncorporealComponent>(msg.Performer, "Incorporeal",
|
||||||
|
TimeSpan.FromSeconds(10), false);
|
||||||
|
|
||||||
msg.Handled = true;
|
msg.Handled = true;
|
||||||
Speak(msg);
|
Speak(msg);
|
||||||
@@ -252,7 +256,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnBlinkSpell(BlinkSpellEvent msg)
|
private void OnBlinkSpell(BlinkSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var transform = Transform(msg.Performer);
|
var transform = Transform(msg.Performer);
|
||||||
@@ -291,8 +295,8 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
_audio.PlayPvs("/Audio/White/Cult/veilin.ogg", coords);
|
_audio.PlayPvs("/Audio/White/Cult/veilin.ogg", coords);
|
||||||
_audio.PlayPvs("/Audio/White/Cult/veilout.ogg", oldCoords);
|
_audio.PlayPvs("/Audio/White/Cult/veilout.ogg", oldCoords);
|
||||||
|
|
||||||
Spawn("AdminInstantEffectSmoke10", oldCoords);
|
Spawn("AdminInstantEffectSmoke3", oldCoords);
|
||||||
Spawn("AdminInstantEffectSmoke10", coords);
|
Spawn("AdminInstantEffectSmoke3", coords);
|
||||||
|
|
||||||
msg.Handled = true;
|
msg.Handled = true;
|
||||||
Speak(msg);
|
Speak(msg);
|
||||||
@@ -304,7 +308,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnForcewallSpell(ForceWallSpellEvent msg)
|
private void OnForcewallSpell(ForceWallSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (msg.ActionUseType)
|
switch (msg.ActionUseType)
|
||||||
@@ -372,7 +376,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnCardsSpell(CardsSpellEvent msg)
|
private void OnCardsSpell(CardsSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var result = true;
|
var result = true;
|
||||||
@@ -413,7 +417,8 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
var ent = Spawn(msg.Prototype, spawnCoords);
|
var ent = Spawn(msg.Prototype, spawnCoords);
|
||||||
|
|
||||||
var direction = msg.Target.ToMapPos(EntityManager, _transformSystem) - spawnCoords.ToMapPos(EntityManager, _transformSystem);
|
var direction = msg.Target.ToMapPos(EntityManager, _transformSystem) -
|
||||||
|
spawnCoords.ToMapPos(EntityManager, _transformSystem);
|
||||||
var randomizedDirection = direction + new Vector2(_random.Next(-2, 2), _random.Next(-2, 2));
|
var randomizedDirection = direction + new Vector2(_random.Next(-2, 2), _random.Next(-2, 2));
|
||||||
|
|
||||||
_throwingSystem.TryThrow(ent, randomizedDirection, 60, msg.Performer);
|
_throwingSystem.TryThrow(ent, randomizedDirection, 60, msg.Performer);
|
||||||
@@ -425,14 +430,15 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
var xform = Transform(msg.Performer);
|
var xform = Transform(msg.Performer);
|
||||||
|
|
||||||
var count = 10 * msg.ChargeLevel;
|
var count = 10 + 10 * msg.ChargeLevel;
|
||||||
var angleStep = 360f / count;
|
var angleStep = 360f / count;
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var angle = i * angleStep;
|
var angle = i * angleStep;
|
||||||
|
|
||||||
var direction = new Vector2(MathF.Cos(MathHelper.DegreesToRadians(angle)), MathF.Sin(MathHelper.DegreesToRadians(angle)));
|
var direction = new Vector2(MathF.Cos(MathHelper.DegreesToRadians(angle)),
|
||||||
|
MathF.Sin(MathHelper.DegreesToRadians(angle)));
|
||||||
|
|
||||||
foreach (var pos in _magicSystem.GetSpawnPositions(xform, msg.Pos))
|
foreach (var pos in _magicSystem.GetSpawnPositions(xform, msg.Pos))
|
||||||
{
|
{
|
||||||
@@ -453,7 +459,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
if (!HasComp<ItemComponent>(msg.TargetUid))
|
if (!HasComp<ItemComponent>(msg.TargetUid))
|
||||||
{
|
{
|
||||||
_popupSystem.PopupEntity("Работает только на предметах.", msg.Performer, msg.Performer);
|
_popupSystem.PopupEntity("В карту можно превратить только предметы.", msg.Performer, msg.Performer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +476,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnFireballSpell(FireballSpellEvent msg)
|
private void OnFireballSpell(FireballSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var result = true;
|
var result = true;
|
||||||
@@ -513,7 +519,8 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
userVelocity = physics.LinearVelocity;
|
userVelocity = physics.LinearVelocity;
|
||||||
|
|
||||||
var ent = Spawn(msg.Prototype, spawnCoords);
|
var ent = Spawn(msg.Prototype, spawnCoords);
|
||||||
var direction = msg.Target.ToMapPos(EntityManager, _transformSystem) - spawnCoords.ToMapPos(EntityManager, _transformSystem);
|
var direction = msg.Target.ToMapPos(EntityManager, _transformSystem) -
|
||||||
|
spawnCoords.ToMapPos(EntityManager, _transformSystem);
|
||||||
_gunSystem.ShootProjectile(ent, direction, userVelocity, msg.Performer, msg.Performer);
|
_gunSystem.ShootProjectile(ent, direction, userVelocity, msg.Performer, msg.Performer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -554,9 +561,11 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnForceSpell(ForceSpellEvent msg)
|
private void OnForceSpell(ForceSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var result = true;
|
||||||
|
|
||||||
switch (msg.ActionUseType)
|
switch (msg.ActionUseType)
|
||||||
{
|
{
|
||||||
case ActionUseType.Default:
|
case ActionUseType.Default:
|
||||||
@@ -566,28 +575,41 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
ForceSpellCharge(msg);
|
ForceSpellCharge(msg);
|
||||||
break;
|
break;
|
||||||
case ActionUseType.AltUse:
|
case ActionUseType.AltUse:
|
||||||
ForceSpellAlt(msg);
|
result = ForceSpellAlt(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
return;
|
||||||
|
|
||||||
SetCooldown(msg.Action, msg.ActionUseType);
|
SetCooldown(msg.Action, msg.ActionUseType);
|
||||||
msg.Handled = true;
|
msg.Handled = true;
|
||||||
Speak(msg);
|
Speak(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ForceSpellDefault(ForceSpellEvent msg)
|
private bool ForceSpellAlt(ForceSpellEvent msg)
|
||||||
{
|
{
|
||||||
Spawn("AdminInstantEffectMinusGravityWell", msg.Target);
|
if (!HasComp<TransformComponent>(msg.TargetUid) || !HasComp<PhysicsComponent>(msg.TargetUid))
|
||||||
|
{
|
||||||
|
_popupSystem.PopupEntity("Невозможно это притянуть!", msg.Performer, msg.Performer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_throwingSystem.TryThrow(msg.TargetUid, Transform(msg.Performer).Coordinates, 5f);
|
||||||
|
_standing.TryLieDown(msg.TargetUid);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ForceSpellCharge(ForceSpellEvent msg)
|
private void ForceSpellCharge(ForceSpellEvent msg)
|
||||||
{
|
{
|
||||||
_gravityWell.GravPulse(msg.Performer, 15, 0, -80 * msg.ChargeLevel, -2 * msg.ChargeLevel);
|
_gravityWell.GravPulse(msg.Performer, 15, 0, -80 * msg.ChargeLevel, -2 * msg.ChargeLevel, null, msg.ChargeLevel,
|
||||||
|
new() {msg.Performer});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ForceSpellAlt(ForceSpellEvent msg)
|
private void ForceSpellDefault(ForceSpellEvent msg)
|
||||||
{
|
{
|
||||||
_gravityWell.GravPulse(msg.Target, 10, 0, 200, 10);
|
_gravityWell.GravPulse(msg.Target, 10, 0, 200, 10, 2f, new() {msg.Performer});
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -596,7 +618,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnArcSpell(ArcSpellEvent msg)
|
private void OnArcSpell(ArcSpellEvent msg)
|
||||||
{
|
{
|
||||||
if (msg.Handled || !CheckRequirements(msg.Action, msg.Performer))
|
if (!CanCast(msg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var result = true;
|
var result = true;
|
||||||
@@ -632,7 +654,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
var entityUids = entitiesToHit.ToList();
|
var entityUids = entitiesToHit.ToList();
|
||||||
foreach (var entity in entityUids)
|
foreach (var entity in entityUids)
|
||||||
{
|
{
|
||||||
_lightning.ShootLightning(msg.Performer, entity);
|
_lightning.ShootLightning(msg.Performer, entity, "WizardLightning", true, msg.Performer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entityUids.Count != 0;
|
return entityUids.Count != 0;
|
||||||
@@ -640,7 +662,8 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
private void ArcSpellCharge(ArcSpellEvent msg)
|
private void ArcSpellCharge(ArcSpellEvent msg)
|
||||||
{
|
{
|
||||||
_lightning.ShootRandomLightnings(msg.Performer, 2 * msg.ChargeLevel, msg.ChargeLevel * 2, arcDepth: 2);
|
_lightning.ShootRandomLightnings(msg.Performer, 2f * msg.ChargeLevel, msg.ChargeLevel * 2, "WizardLightning", 1,
|
||||||
|
caster: msg.Performer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ArcSpellAlt(ArcSpellEvent msg)
|
private void ArcSpellAlt(ArcSpellEvent msg)
|
||||||
@@ -660,7 +683,8 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
userVelocity = physics.LinearVelocity;
|
userVelocity = physics.LinearVelocity;
|
||||||
|
|
||||||
var ent = Spawn(msg.Prototype, spawnCoords);
|
var ent = Spawn(msg.Prototype, spawnCoords);
|
||||||
var direction = msg.Target.ToMapPos(EntityManager, _transformSystem) - spawnCoords.ToMapPos(EntityManager, _transformSystem);
|
var direction = msg.Target.ToMapPos(EntityManager, _transformSystem) -
|
||||||
|
spawnCoords.ToMapPos(EntityManager, _transformSystem);
|
||||||
_gunSystem.ShootProjectile(ent, direction, userVelocity, msg.Performer, msg.Performer);
|
_gunSystem.ShootProjectile(ent, direction, userVelocity, msg.Performer, msg.Performer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -669,6 +693,12 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
|
private bool CanCast(BaseActionEvent msg)
|
||||||
|
{
|
||||||
|
return !msg.Handled && CheckRequirements(msg.Action, msg.Performer) &&
|
||||||
|
!_statusEffectsSystem.HasStatusEffect(msg.Performer, "Incorporeal");
|
||||||
|
}
|
||||||
|
|
||||||
private void Speak(BaseActionEvent args)
|
private void Speak(BaseActionEvent args)
|
||||||
{
|
{
|
||||||
if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech))
|
if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech))
|
||||||
@@ -743,7 +773,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
if (!hasReqs)
|
if (!hasReqs)
|
||||||
{
|
{
|
||||||
args.Cancelled = true;
|
args.Cancelled = true;
|
||||||
_popupSystem.PopupEntity("Missing Requirements! You need to wear your robe and hat!", args.Performer, args.Performer);
|
_popupSystem.PopupEntity(Loc.GetString("magic-component-missing-req"), args.Performer, args.Performer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
Resources/Locale/en-US/_white/wizard.ftl
Normal file
1
Resources/Locale/en-US/_white/wizard.ftl
Normal file
@@ -0,0 +1 @@
|
|||||||
|
magic-component-missing-req = Missing Requirements! You need to wear your robe and hat!
|
||||||
@@ -15,3 +15,5 @@ wizard-welcome = Вы - космический волшебник. Федера
|
|||||||
|
|
||||||
wizard-no-more-threat-announcement-shuttle-call = Судя по данным наших датчиков дальнего действия, магическая угроза была устранена. Эвакуационный шаттл скоро прибудет. Время прибытия: {$time} {$units}. Вы можете отозвать его, чтобы продлить смену.
|
wizard-no-more-threat-announcement-shuttle-call = Судя по данным наших датчиков дальнего действия, магическая угроза была устранена. Эвакуационный шаттл скоро прибудет. Время прибытия: {$time} {$units}. Вы можете отозвать его, чтобы продлить смену.
|
||||||
wizard-no-more-threat-announcement = Судя по данным наших датчиков дальнего действия, магическая угроза была устранена. Шаттл уже вызван.
|
wizard-no-more-threat-announcement = Судя по данным наших датчиков дальнего действия, магическая угроза была устранена. Шаттл уже вызван.
|
||||||
|
|
||||||
|
magic-component-missing-req = Недостающие требования! Вам необходимо надеть мантию и шляпу!
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
name: lightning
|
name: lightning
|
||||||
id: BaseLightning
|
id: BaseLightning
|
||||||
abstract: true
|
abstract: true
|
||||||
@@ -60,6 +60,9 @@
|
|||||||
castShadows: false
|
castShadows: false
|
||||||
- type: Lightning
|
- type: Lightning
|
||||||
canArc: false
|
canArc: false
|
||||||
|
- type: Electrified
|
||||||
|
requirePower: false
|
||||||
|
ignoreInsulation: true
|
||||||
shockDamage: 30
|
shockDamage: 30
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -159,3 +162,17 @@
|
|||||||
softness: 1
|
softness: 1
|
||||||
autoRot: true
|
autoRot: true
|
||||||
castShadows: false
|
castShadows: false
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: wizard lightning
|
||||||
|
id: WizardLightning
|
||||||
|
parent: BaseLightning
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: Electrified
|
||||||
|
requirePower: false
|
||||||
|
ignoreInsulation: true
|
||||||
|
shockDamage: 40
|
||||||
|
- type: Lightning
|
||||||
|
canArc: true
|
||||||
|
lightningPrototype: WizardLightning
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
description: This spell opens nearby doors.
|
description: This spell opens nearby doors.
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
|
- type: Magic
|
||||||
|
requiresClothes: false
|
||||||
- type: InstantAction
|
- type: InstantAction
|
||||||
useDelay: 10
|
useDelay: 8
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
checkCanInteract: false
|
checkCanInteract: false
|
||||||
icon:
|
icon:
|
||||||
|
|||||||
@@ -38,8 +38,6 @@
|
|||||||
name: Force
|
name: Force
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: Magic
|
|
||||||
requiresClothes: true
|
|
||||||
- type: WorldTargetAction
|
- type: WorldTargetAction
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
useDelay: 60
|
useDelay: 60
|
||||||
@@ -63,8 +61,8 @@
|
|||||||
speech: "EL DRITCH!"
|
speech: "EL DRITCH!"
|
||||||
- type: VariableUseDelay
|
- type: VariableUseDelay
|
||||||
useDelay: 6
|
useDelay: 6
|
||||||
altUseDelay: 12
|
altUseDelay: 2
|
||||||
chargeUseDelay: 40
|
chargeUseDelay: 20
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ActionFireballSpell
|
id: ActionFireballSpell
|
||||||
@@ -93,8 +91,8 @@
|
|||||||
posData: !type:TargetCasterPos
|
posData: !type:TargetCasterPos
|
||||||
speech: action-speech-spell-fireball
|
speech: action-speech-spell-fireball
|
||||||
- type: VariableUseDelay
|
- type: VariableUseDelay
|
||||||
useDelay: 6
|
useDelay: 5
|
||||||
altUseDelay: 12
|
altUseDelay: 10
|
||||||
chargeUseDelay: 40
|
chargeUseDelay: 40
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -102,8 +100,6 @@
|
|||||||
name: Cards
|
name: Cards
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: Magic
|
|
||||||
requiresClothes: true
|
|
||||||
- type: WorldTargetAction
|
- type: WorldTargetAction
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
useDelay: 60
|
useDelay: 60
|
||||||
@@ -128,7 +124,7 @@
|
|||||||
posData: !type:TargetCasterPos
|
posData: !type:TargetCasterPos
|
||||||
speech: "SHIZO NERO!"
|
speech: "SHIZO NERO!"
|
||||||
- type: VariableUseDelay
|
- type: VariableUseDelay
|
||||||
useDelay: 6
|
useDelay: 4
|
||||||
altUseDelay: 1
|
altUseDelay: 1
|
||||||
chargeUseDelay: 40
|
chargeUseDelay: 40
|
||||||
|
|
||||||
@@ -220,12 +216,10 @@
|
|||||||
name: Cluwne Curse
|
name: Cluwne Curse
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: Magic
|
|
||||||
requiresClothes: true
|
|
||||||
- type: EntityTargetAction
|
- type: EntityTargetAction
|
||||||
canTargetSelf: false
|
canTargetSelf: false
|
||||||
range: 2
|
range: 3
|
||||||
useDelay: 400
|
useDelay: 60
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
icon:
|
icon:
|
||||||
sprite: Objects/Magic/magicactions.rsi
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
@@ -238,12 +232,10 @@
|
|||||||
name: Banana Touch
|
name: Banana Touch
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: Magic
|
|
||||||
requiresClothes: true
|
|
||||||
- type: EntityTargetAction
|
- type: EntityTargetAction
|
||||||
canTargetSelf: false
|
canTargetSelf: false
|
||||||
range: 2
|
range: 3
|
||||||
useDelay: 200
|
useDelay: 30
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
icon:
|
icon:
|
||||||
sprite: Objects/Magic/magicactions.rsi
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
@@ -256,12 +248,10 @@
|
|||||||
name: Mime Touch
|
name: Mime Touch
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: Magic
|
|
||||||
requiresClothes: true
|
|
||||||
- type: EntityTargetAction
|
- type: EntityTargetAction
|
||||||
canTargetSelf: false
|
canTargetSelf: false
|
||||||
range: 2
|
range: 3
|
||||||
useDelay: 200
|
useDelay: 30
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
icon:
|
icon:
|
||||||
sprite: Objects/Magic/magicactions.rsi
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
@@ -275,8 +265,6 @@
|
|||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: InstantRecall
|
- type: InstantRecall
|
||||||
- type: Magic
|
|
||||||
requiresClothes: true
|
|
||||||
- type: InstantAction
|
- type: InstantAction
|
||||||
useDelay: 10
|
useDelay: 10
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: BaseScroll
|
id: BaseScroll
|
||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
name: "Magic Scroll"
|
name: "Magic Scroll"
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
layers:
|
layers:
|
||||||
- state: scroll
|
- state: scroll
|
||||||
- type: Scroll
|
- type: Scroll
|
||||||
|
learnTime: 1
|
||||||
useSound:
|
useSound:
|
||||||
path: /Audio/White/Items/scroll/use.ogg
|
path: /Audio/White/Items/scroll/use.ogg
|
||||||
afterUseSound:
|
afterUseSound:
|
||||||
|
|||||||
Reference in New Issue
Block a user