Залью спеллы потестить, мне похуй ПР НОМЕР 156
* refactor CheZaHuetaMagicSystem * эщкере * alt-spells system. lmb, rmb, alt-click * fix * ChargeSpellsIndicator + Visual(CheZaHueta) * Custom charge effect for spell * Custom MaxChargeLevel * Finally. Alt spells seems to work!! Need to start do spells and gamerule * fuckkk * fix crash, actually burn scroll.. * some fixes blyat * ArcSpell * очередная CheZaHuetaSystem, ForceSpell * ONI'SOMA! * mraow * prepare this LMAO * Yebanyy rot etogo kazino blyat! - CardsSpell * forcewall * nig * blink * Ethereal Jaunt * игра говно * Блядина * ну на еще спеллов * blyadina * да иди ты нахуй БЛЯДЬ * кто прочитал, тот сдохнет. сделай 5 репостов чтобы выжить.... * icons * та ваще поебать * одежда
This commit is contained in:
@@ -1,17 +1,15 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Server.Magic.Components;
|
||||
using Content.Server.Weapons.Ranged.Systems;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Coordinates.Helpers;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Doors.Systems;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Magic;
|
||||
using Content.Shared.Magic.Events;
|
||||
using Content.Shared.Maps;
|
||||
@@ -21,6 +19,7 @@ using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
@@ -33,31 +32,25 @@ namespace Content.Server.Magic;
|
||||
/// </summary>
|
||||
public sealed class MagicSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ISerializationManager _seriMan = default!;
|
||||
[Dependency] private readonly ISerializationManager _serializationManager = default!;
|
||||
[Dependency] private readonly IComponentFactory _compFact = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly DoorBoltSystem _boltsSystem = default!;
|
||||
[Dependency] private readonly BodySystem _bodySystem = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly SharedDoorSystem _doorSystem = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly GunSystem _gunSystem = default!;
|
||||
[Dependency] private readonly PhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SpellbookComponent, MapInitEvent>(OnInit);
|
||||
SubscribeLocalEvent<SpellbookComponent, UseInHandEvent>(OnUse);
|
||||
SubscribeLocalEvent<SpellbookComponent, SpellbookDoAfterEvent>(OnDoAfter);
|
||||
|
||||
SubscribeLocalEvent<InstantSpawnSpellEvent>(OnInstantSpawn);
|
||||
SubscribeLocalEvent<TeleportSpellEvent>(OnTeleportSpell);
|
||||
SubscribeLocalEvent<KnockSpellEvent>(OnKnockSpell);
|
||||
@@ -67,73 +60,8 @@ public sealed class MagicSystem : EntitySystem
|
||||
SubscribeLocalEvent<ChangeComponentsSpellEvent>(OnChangeComponentsSpell);
|
||||
}
|
||||
|
||||
private void OnDoAfter(EntityUid uid, SpellbookComponent component, DoAfterEvent args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
if (!component.LearnPermanently)
|
||||
{
|
||||
_actionsSystem.GrantActions(args.Args.User, component.Spells, uid);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var (id, charges) in component.SpellActions)
|
||||
{
|
||||
// TOOD store spells entity ids on some sort of innate magic user component or something like that.
|
||||
EntityUid? actionId = null;
|
||||
if (_actionsSystem.AddAction(args.Args.User, ref actionId, id))
|
||||
_actionsSystem.SetCharges(actionId, charges < 0 ? null : charges);
|
||||
}
|
||||
|
||||
component.SpellActions.Clear();
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, SpellbookComponent component, MapInitEvent args)
|
||||
{
|
||||
if (component.LearnPermanently)
|
||||
return;
|
||||
|
||||
foreach (var (id, charges) in component.SpellActions)
|
||||
{
|
||||
var spell = _actionContainer.AddAction(uid, id);
|
||||
if (spell == null)
|
||||
continue;
|
||||
|
||||
_actionsSystem.SetCharges(spell, charges < 0 ? null : charges);
|
||||
component.Spells.Add(spell.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUse(EntityUid uid, SpellbookComponent component, UseInHandEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
AttemptLearn(uid, component, args);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void AttemptLearn(EntityUid uid, SpellbookComponent component, UseInHandEvent args)
|
||||
{
|
||||
var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.LearnTime, new SpellbookDoAfterEvent(), uid, target: uid)
|
||||
{
|
||||
BreakOnTargetMove = true,
|
||||
BreakOnUserMove = true,
|
||||
BreakOnDamage = true,
|
||||
NeedHand = true //What, are you going to read with your eyes only??
|
||||
};
|
||||
|
||||
_doAfter.TryStartDoAfter(doAfterEventArgs);
|
||||
}
|
||||
|
||||
#region Spells
|
||||
|
||||
/// <summary>
|
||||
/// Handles the instant action (i.e. on the caster) attempting to spawn an entity.
|
||||
/// </summary>
|
||||
private void OnInstantSpawn(InstantSpawnSpellEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
@@ -145,11 +73,11 @@ public sealed class MagicSystem : EntitySystem
|
||||
{
|
||||
var ent = Spawn(args.Prototype, position.SnapToGrid(EntityManager, _mapManager));
|
||||
|
||||
if (args.PreventCollideWithCaster)
|
||||
{
|
||||
var comp = EnsureComp<PreventCollideComponent>(ent);
|
||||
comp.Uid = args.Performer;
|
||||
}
|
||||
if (!args.PreventCollideWithCaster)
|
||||
continue;
|
||||
|
||||
var comp = EnsureComp<PreventCollideComponent>(ent);
|
||||
comp.Uid = args.Performer;
|
||||
}
|
||||
|
||||
Speak(args);
|
||||
@@ -166,22 +94,17 @@ public sealed class MagicSystem : EntitySystem
|
||||
|
||||
var xform = Transform(ev.Performer);
|
||||
|
||||
// var userVelocity = _physics.GetMapLinearVelocity(ev.Performer); WD EDIT
|
||||
|
||||
foreach (var pos in GetSpawnPositions(xform, ev.Pos))
|
||||
{
|
||||
// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
|
||||
var mapPos = pos.ToMap(EntityManager);
|
||||
var spawnCoords = _mapManager.TryFindGridAt(mapPos, out var gridUid, out var grid) // WD EDIT
|
||||
var mapPos = _transformSystem.ToMapCoordinates(pos);
|
||||
var spawnCoords = _mapManager.TryFindGridAt(mapPos, out var gridUid, out var grid)
|
||||
? pos.WithEntityId(gridUid, EntityManager)
|
||||
: new(_mapManager.GetMapEntityId(mapPos.MapId), mapPos.Position);
|
||||
: new EntityCoordinates(_mapManager.GetMapEntityId(mapPos.MapId), mapPos.Position);
|
||||
|
||||
// WD EDIT
|
||||
var userVelocity = Vector2.Zero;
|
||||
|
||||
if (grid != null && TryComp(gridUid, out PhysicsComponent? physics))
|
||||
userVelocity = physics.LinearVelocity;
|
||||
// WD EDIT
|
||||
|
||||
var ent = Spawn(ev.Prototype, spawnCoords);
|
||||
var direction = ev.Target.ToMapPos(EntityManager, _transformSystem) -
|
||||
@@ -194,7 +117,9 @@ public sealed class MagicSystem : EntitySystem
|
||||
{
|
||||
if (ev.Handled)
|
||||
return;
|
||||
|
||||
ev.Handled = true;
|
||||
|
||||
Speak(ev);
|
||||
|
||||
foreach (var toRemove in ev.ToRemove)
|
||||
@@ -209,75 +134,12 @@ public sealed class MagicSystem : EntitySystem
|
||||
continue;
|
||||
|
||||
var component = (Component) _compFact.GetComponent(name);
|
||||
component.Owner = ev.Target;
|
||||
var temp = (object) component;
|
||||
_seriMan.CopyTo(data.Component, ref temp);
|
||||
_serializationManager.CopyTo(data.Component, ref temp);
|
||||
EntityManager.AddComponent(ev.Target, (Component) temp!);
|
||||
}
|
||||
}
|
||||
|
||||
private List<EntityCoordinates> GetSpawnPositions(TransformComponent casterXform, MagicSpawnData data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case TargetCasterPos:
|
||||
return new List<EntityCoordinates>(1) {casterXform.Coordinates};
|
||||
case TargetInFront:
|
||||
{
|
||||
// This is shit but you get the idea.
|
||||
var directionPos = casterXform.Coordinates.Offset(casterXform.LocalRotation.ToWorldVec().Normalized());
|
||||
|
||||
if (!_mapManager.TryGetGrid(casterXform.GridUid, out var mapGrid))
|
||||
return new List<EntityCoordinates>();
|
||||
|
||||
if (!directionPos.TryGetTileRef(out var tileReference, EntityManager, _mapManager))
|
||||
return new List<EntityCoordinates>();
|
||||
|
||||
var tileIndex = tileReference.Value.GridIndices;
|
||||
var coords = mapGrid.GridTileToLocal(tileIndex);
|
||||
EntityCoordinates coordsPlus;
|
||||
EntityCoordinates coordsMinus;
|
||||
|
||||
var dir = casterXform.LocalRotation.GetCardinalDir();
|
||||
switch (dir)
|
||||
{
|
||||
case Direction.North:
|
||||
case Direction.South:
|
||||
{
|
||||
coordsPlus = mapGrid.GridTileToLocal(tileIndex + (1, 0));
|
||||
coordsMinus = mapGrid.GridTileToLocal(tileIndex + (-1, 0));
|
||||
return new List<EntityCoordinates>(3)
|
||||
{
|
||||
coords,
|
||||
coordsPlus,
|
||||
coordsMinus,
|
||||
};
|
||||
}
|
||||
case Direction.East:
|
||||
case Direction.West:
|
||||
{
|
||||
coordsPlus = mapGrid.GridTileToLocal(tileIndex + (0, 1));
|
||||
coordsMinus = mapGrid.GridTileToLocal(tileIndex + (0, -1));
|
||||
return new List<EntityCoordinates>(3)
|
||||
{
|
||||
coords,
|
||||
coordsPlus,
|
||||
coordsMinus,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return new List<EntityCoordinates>();
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Teleports the user to the clicked location
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private void OnTeleportSpell(TeleportSpellEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
@@ -285,19 +147,16 @@ public sealed class MagicSystem : EntitySystem
|
||||
|
||||
var transform = Transform(args.Performer);
|
||||
|
||||
if (transform.MapID != args.Target.GetMapId(EntityManager)) return;
|
||||
if (transform.MapID != args.Target.GetMapId(EntityManager))
|
||||
return;
|
||||
|
||||
_transformSystem.SetCoordinates(args.Performer, args.Target);
|
||||
transform.AttachToGridOrMap();
|
||||
_transformSystem.AttachToGridOrMap(args.Performer);
|
||||
_audio.PlayPvs(args.BlinkSound, args.Performer, AudioParams.Default.WithVolume(args.BlinkVolume));
|
||||
Speak(args);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens all doors within range
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private void OnKnockSpell(KnockSpellEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
@@ -306,13 +165,11 @@ public sealed class MagicSystem : EntitySystem
|
||||
args.Handled = true;
|
||||
Speak(args);
|
||||
|
||||
//Get the position of the player
|
||||
var transform = Transform(args.Performer);
|
||||
var coords = transform.Coordinates;
|
||||
|
||||
_audio.PlayPvs(args.KnockSound, args.Performer, AudioParams.Default.WithVolume(args.KnockVolume));
|
||||
|
||||
//Look for doors and don't open them if they're already open.
|
||||
foreach (var entity in _lookup.GetEntitiesInRange(coords, args.Range))
|
||||
{
|
||||
if (TryComp<DoorBoltComponent>(entity, out var bolts))
|
||||
@@ -329,9 +186,10 @@ public sealed class MagicSystem : EntitySystem
|
||||
return;
|
||||
|
||||
ev.Handled = true;
|
||||
|
||||
Speak(ev);
|
||||
|
||||
var direction = Transform(ev.Target).MapPosition.Position - Transform(ev.Performer).MapPosition.Position;
|
||||
var direction = _transformSystem.GetMapCoordinates(ev.Target).Position - _transformSystem.GetMapCoordinates(ev.Performer).Position;
|
||||
var impulseVector = direction * 10000;
|
||||
|
||||
_physics.ApplyLinearImpulse(ev.Target, impulseVector);
|
||||
@@ -339,28 +197,17 @@ public sealed class MagicSystem : EntitySystem
|
||||
if (!TryComp<BodyComponent>(ev.Target, out var body))
|
||||
return;
|
||||
|
||||
var ents = _bodySystem.GibBody(ev.Target, true, body);
|
||||
var entities = _bodySystem.GibBody(ev.Target, true, body);
|
||||
|
||||
if (!ev.DeleteNonBrainParts)
|
||||
return;
|
||||
|
||||
foreach (var part in ents)
|
||||
foreach (var part in entities.Where(part => HasComp<BodyComponent>(part) && !HasComp<BrainComponent>(part)))
|
||||
{
|
||||
// just leaves a brain and clothes
|
||||
if (HasComp<BodyComponent>(part) && !HasComp<BrainComponent>(part))
|
||||
{
|
||||
QueueDel(part);
|
||||
}
|
||||
QueueDel(part);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns entity prototypes from a list within range of click.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It will offset mobs after the first mob based on the OffsetVector2 property supplied.
|
||||
/// </remarks>
|
||||
/// <param name="args"> The Spawn Spell Event args.</param>
|
||||
private void OnWorldSpawn(WorldSpawnSpellEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
@@ -373,24 +220,85 @@ public sealed class MagicSystem : EntitySystem
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loops through a supplied list of entity prototypes and spawns them
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If an offset of 0, 0 is supplied then the entities will all spawn on the same tile.
|
||||
/// Any other offset will spawn entities starting from the source Map Coordinates and will increment the supplied
|
||||
/// offset
|
||||
/// </remarks>
|
||||
/// <param name="entityEntries"> The list of Entities to spawn in</param>
|
||||
/// <param name="entityCoords"> Map Coordinates where the entities will spawn</param>
|
||||
/// <param name="lifetime"> Check to see if the entities should self delete</param>
|
||||
/// <param name="offsetVector2"> A Vector2 offset that the entities will spawn in</param>
|
||||
private void SpawnSpellHelper(List<EntitySpawnEntry> entityEntries, EntityCoordinates entityCoords, float? lifetime, Vector2 offsetVector2)
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
public List<EntityCoordinates> GetSpawnPositions(TransformComponent casterXform, MagicSpawnData data)
|
||||
{
|
||||
var getProtos = EntitySpawnCollection.GetSpawns(entityEntries, _random);
|
||||
return data switch
|
||||
{
|
||||
TargetCasterPos => GetCasterPosition(casterXform),
|
||||
TargetInFront => GetPositionsInFront(casterXform),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
|
||||
public List<EntityCoordinates> GetCasterPosition(TransformComponent casterXform)
|
||||
{
|
||||
return new List<EntityCoordinates>(1) { casterXform.Coordinates };
|
||||
}
|
||||
|
||||
public List<EntityCoordinates> GetPositionsInFront(TransformComponent casterXform)
|
||||
{
|
||||
var directionPos = casterXform.Coordinates.Offset(casterXform.LocalRotation.ToWorldVec().Normalized());
|
||||
|
||||
if (!TryComp<MapGridComponent>(casterXform.GridUid, out var mapGrid) ||
|
||||
!directionPos.TryGetTileRef(out var tileReference, EntityManager, _mapManager))
|
||||
{
|
||||
return new List<EntityCoordinates>();
|
||||
}
|
||||
|
||||
var tileIndex = tileReference.Value.GridIndices;
|
||||
var coords = _mapSystem.GridTileToLocal(casterXform.GridUid.Value, mapGrid, tileIndex);
|
||||
|
||||
var directions = GetCardinalDirections(casterXform.LocalRotation.GetCardinalDir());
|
||||
var spawnPositions = new List<EntityCoordinates>(3);
|
||||
|
||||
foreach (var direction in directions)
|
||||
{
|
||||
var offset = GetOffsetForDirection(direction);
|
||||
var coordinates = _mapSystem.GridTileToLocal(casterXform.GridUid.Value, mapGrid, tileIndex + offset);
|
||||
spawnPositions.Add(coordinates);
|
||||
}
|
||||
|
||||
spawnPositions.Add(coords);
|
||||
return spawnPositions;
|
||||
}
|
||||
|
||||
public IEnumerable<Direction> GetCardinalDirections(Direction dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case Direction.North:
|
||||
case Direction.South:
|
||||
return new[] { Direction.North, Direction.South };
|
||||
case Direction.East:
|
||||
case Direction.West:
|
||||
return new[] { Direction.East, Direction.West };
|
||||
default:
|
||||
return Array.Empty<Direction>();
|
||||
}
|
||||
}
|
||||
|
||||
public (int, int) GetOffsetForDirection(Direction direction)
|
||||
{
|
||||
return direction switch
|
||||
{
|
||||
Direction.North => (1, 0),
|
||||
Direction.South => (-1, 0),
|
||||
Direction.East => (0, 1),
|
||||
Direction.West => (0, -1),
|
||||
_ => (0, 0)
|
||||
};
|
||||
}
|
||||
|
||||
public void SpawnSpellHelper(List<EntitySpawnEntry> entityEntries, EntityCoordinates entityCoords, float? lifetime, Vector2 offsetVector2)
|
||||
{
|
||||
var getPrototypes = EntitySpawnCollection.GetSpawns(entityEntries, _random);
|
||||
|
||||
var offsetCoords = entityCoords;
|
||||
foreach (var proto in getProtos)
|
||||
foreach (var proto in getPrototypes)
|
||||
{
|
||||
// TODO: Share this code with instant because they're both doing similar things for positioning.
|
||||
var entity = Spawn(proto, offsetCoords);
|
||||
@@ -404,8 +312,6 @@ public sealed class MagicSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void Speak(BaseActionEvent args)
|
||||
{
|
||||
if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech))
|
||||
@@ -414,4 +320,6 @@ public sealed class MagicSystem : EntitySystem
|
||||
_chat.TrySendInGameICMessage(args.Performer, Loc.GetString(speak.Speech),
|
||||
InGameICChatType.Speak, false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user