Magic Items (#370)
* attuning to items start * verbs attuning, forgot oldest attuning * Update CP14SharedMagicAttuningSystem.cs * some fixes * add deattuning * fix popups on owner * file restructurization * MORE FOLDER RENAMING GODD * magic via holding yea! * fix deattuning * vfx bugfixs * wearing magic items * Cure wounds spell * refactor spells * more redo * finish refactor
This commit is contained in:
@@ -10,7 +10,6 @@ public partial class CP14MagicEnergySystem
|
||||
{
|
||||
SubscribeLocalEvent<CP14MagicEnergyDrawComponent, MapInitEvent>(OnDrawMapInit);
|
||||
SubscribeLocalEvent<CP14RandomAuraNodeComponent, MapInitEvent>(OnRandomRangeMapInit);
|
||||
|
||||
}
|
||||
|
||||
private void OnRandomRangeMapInit(Entity<CP14RandomAuraNodeComponent> random, ref MapInitEvent args)
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Shared._CP14.Magic;
|
||||
using Content.Shared._CP14.Magic.Components;
|
||||
using Content.Shared._CP14.Magic.Events;
|
||||
using Content.Shared._CP14.MagicSpell;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
namespace Content.Server._CP14.MagicSpell;
|
||||
|
||||
public sealed partial class CP14MagicSystem : CP14SharedMagicSystem
|
||||
{
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -26,6 +28,7 @@ public sealed partial class CP14MagicSystem : CP14SharedMagicSystem
|
||||
private void OnSpawnMagicVisualEffect(Entity<CP14MagicEffectCastingVisualComponent> ent, ref CP14StartCastMagicEffectEvent args)
|
||||
{
|
||||
var vfx = SpawnAttachedTo(ent.Comp.Proto, Transform(args.Performer).Coordinates);
|
||||
_transform.SetParent(vfx, args.Performer);
|
||||
ent.Comp.SpawnedEntity = vfx;
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
using Content.Shared._CP14.Magic.Components.Spells;
|
||||
using Content.Shared._CP14.Magic.Events;
|
||||
using Content.Shared.EntityEffects;
|
||||
|
||||
namespace Content.Shared._CP14.Magic;
|
||||
|
||||
public partial class CP14SharedMagicSystem
|
||||
{
|
||||
private void InitializeSpells()
|
||||
{
|
||||
// Instants
|
||||
SubscribeLocalEvent<CP14DelayedSpawnEntitiesSpellComponent, CP14DelayedInstantActionDoAfterEvent>(OnCastEntitiesSpawn);
|
||||
SubscribeLocalEvent<CP14DelayedSelfEntityEffectSpellComponent, CP14DelayedInstantActionDoAfterEvent>(OnCastSelfEntityEffects);
|
||||
//Entity Target
|
||||
SubscribeLocalEvent<CP14DelayedApplyEntityEffectsSpellComponent, CP14DelayedEntityTargetActionDoAfterEvent>(OnCastApplyEntityEffects);
|
||||
//World Target
|
||||
SubscribeLocalEvent<CP14DelayedProjectileSpellComponent, CP14DelayedWorldTargetActionDoAfterEvent>(OnCastProjectileSpell);
|
||||
SubscribeLocalEvent<CP14DelayedSpawnOnWorldTargetSpellComponent, CP14DelayedWorldTargetActionDoAfterEvent>(OnCastSpawnOnPoint);
|
||||
}
|
||||
|
||||
//TODO: Fuck,there's a lot of code repetition here that needs to be squeezed together somehow. Event calls, checks, and all this stuff
|
||||
private void OnCastEntitiesSpawn(Entity<CP14DelayedSpawnEntitiesSpellComponent> spell, ref CP14DelayedInstantActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(spell, ref stopEv);
|
||||
|
||||
if (args.Cancelled || args.Handled || !_net.IsServer)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
foreach (var spawn in spell.Comp.Spawns)
|
||||
{
|
||||
SpawnAtPosition(spawn, Transform(args.User).Coordinates);
|
||||
}
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(spell, ref ev);
|
||||
}
|
||||
|
||||
private void OnCastSelfEntityEffects(Entity<CP14DelayedSelfEntityEffectSpellComponent> spell, ref CP14DelayedInstantActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(spell, ref stopEv);
|
||||
|
||||
if (args.Cancelled || args.Handled)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
foreach (var effect in spell.Comp.Effects)
|
||||
{
|
||||
effect.Effect(new EntityEffectBaseArgs(args.User, EntityManager));
|
||||
}
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(spell, ref ev);
|
||||
}
|
||||
|
||||
private void OnCastApplyEntityEffects(Entity<CP14DelayedApplyEntityEffectsSpellComponent> spell, ref CP14DelayedEntityTargetActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(spell, ref stopEv);
|
||||
|
||||
if (args.Cancelled || args.Handled || args.Target == null)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
foreach (var effect in spell.Comp.Effects)
|
||||
{
|
||||
effect.Effect(new EntityEffectBaseArgs(args.Target.Value, EntityManager));
|
||||
}
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(spell, ref ev);
|
||||
}
|
||||
|
||||
private void OnCastProjectileSpell(Entity<CP14DelayedProjectileSpellComponent> spell, ref CP14DelayedWorldTargetActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(spell, ref stopEv);
|
||||
|
||||
if (args.Cancelled || args.Handled || !_net.IsServer)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
var xform = Transform(args.User);
|
||||
var fromCoords = xform.Coordinates;
|
||||
var toCoords = GetCoordinates(args.Target);
|
||||
var userVelocity = _physics.GetMapLinearVelocity(args.User);
|
||||
|
||||
// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
|
||||
var fromMap = fromCoords.ToMap(EntityManager, _transform);
|
||||
var spawnCoords = _mapManager.TryFindGridAt(fromMap, out var gridUid, out _)
|
||||
? fromCoords.WithEntityId(gridUid, EntityManager)
|
||||
: new(_mapManager.GetMapEntityId(fromMap.MapId), fromMap.Position);
|
||||
|
||||
var ent = Spawn(spell.Comp.Prototype, spawnCoords);
|
||||
var direction = toCoords.ToMapPos(EntityManager, _transform) -
|
||||
spawnCoords.ToMapPos(EntityManager, _transform);
|
||||
_gunSystem.ShootProjectile(ent, direction, userVelocity, args.User, args.User);
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(spell, ref ev);
|
||||
}
|
||||
|
||||
private void OnCastSpawnOnPoint(Entity<CP14DelayedSpawnOnWorldTargetSpellComponent> spell, ref CP14DelayedWorldTargetActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(spell, ref stopEv);
|
||||
|
||||
if (args.Cancelled || args.Handled || !_net.IsServer)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
var xform = Transform(args.User);
|
||||
var toCoords = GetCoordinates(args.Target);
|
||||
|
||||
foreach (var spawn in spell.Comp.Spawns)
|
||||
{
|
||||
SpawnAtPosition(spawn, toCoords);
|
||||
}
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(spell, ref ev);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using Content.Shared.EntityEffects;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components.Spells;
|
||||
|
||||
/// <summary>
|
||||
/// Stores a list of effects for delayed actions.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14DelayedApplyEntityEffectsSpellComponent : Component
|
||||
{
|
||||
[DataField(required: true, serverOnly: true)]
|
||||
public List<EntityEffect> Effects = new();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components.Spells;
|
||||
|
||||
/// <summary>
|
||||
/// Stores a list of effects for delayed actions.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14DelayedProjectileSpellComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// What entity should be spawned.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public EntProtoId Prototype;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using Content.Shared.EntityEffects;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components.Spells;
|
||||
|
||||
/// <summary>
|
||||
/// Stores a list of effects for delayed actions.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14DelayedSelfEntityEffectSpellComponent : Component
|
||||
{
|
||||
[DataField(required: true, serverOnly: true)]
|
||||
public List<EntityEffect> Effects = new();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components.Spells;
|
||||
|
||||
/// <summary>
|
||||
/// Stores a list of effects for delayed actions.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14DelayedSpawnEntitiesSpellComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// What entities should be spawned.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public HashSet<EntProtoId> Spawns = new();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components.Spells;
|
||||
|
||||
/// <summary>
|
||||
/// Stores a list of effects for delayed actions.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicSystem))]
|
||||
public sealed partial class CP14DelayedSpawnOnWorldTargetSpellComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// What entities should be spawned.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public HashSet<EntProtoId> Spawns = new();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Content.Shared._CP14.MagicAttuning;
|
||||
|
||||
/// <summary>
|
||||
/// Reflects the fact that this subject can be focused on (Magical attune as a mechanic from DnD.)
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicAttuningSystem))]
|
||||
public sealed partial class CP14MagicAttuningItemComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// how long it takes to focus on that object
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan FocusTime = TimeSpan.FromSeconds(5f);
|
||||
|
||||
public Entity<CP14MagicAttuningMindComponent>? Link = null;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Content.Shared._CP14.MagicAttuning;
|
||||
|
||||
/// <summary>
|
||||
/// A mind that can focus on objects
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SharedMagicAttuningSystem))]
|
||||
public sealed partial class CP14MagicAttuningMindComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public int MaxAttuning = 3;
|
||||
/// <summary>
|
||||
/// The entities that this being is focused on
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntityUid> AttunedTo = new();
|
||||
|
||||
/// <summary>
|
||||
/// cheat: if added to an entity with MindContainer, automatically copied to the mind, removing it from the body. This is to make it easy to add the component to prototype creatures.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool AutoCopyToMind = false;
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.MagicAttuning;
|
||||
|
||||
/// <summary>
|
||||
/// This system controls the customization to magic items by the players.
|
||||
/// </summary>
|
||||
public sealed partial class CP14SharedMagicAttuningSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14MagicAttuningItemComponent, GetVerbsEvent<InteractionVerb>>(OnInteractionVerb);
|
||||
SubscribeLocalEvent<CP14MagicAttuningMindComponent, CP14MagicAttuneDoAfterEvent>(OnAttuneDoAfter);
|
||||
SubscribeLocalEvent<CP14MagicAttuningMindComponent, MindAddedMessage>(OnMindAdded);
|
||||
}
|
||||
|
||||
private void OnMindAdded(Entity<CP14MagicAttuningMindComponent> ent, ref MindAddedMessage args)
|
||||
{
|
||||
if (!ent.Comp.AutoCopyToMind)
|
||||
return;
|
||||
|
||||
if (HasComp<MindComponent>(ent))
|
||||
return;
|
||||
|
||||
if (!_mind.TryGetMind(ent, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
var attuneMind = AddComp<CP14MagicAttuningMindComponent>(mindId);
|
||||
attuneMind.MaxAttuning = ent.Comp.MaxAttuning;
|
||||
}
|
||||
|
||||
public bool IsAttunedTo(EntityUid mind, EntityUid item)
|
||||
{
|
||||
if (!TryComp<CP14MagicAttuningItemComponent>(item, out var attuningItem))
|
||||
return false;
|
||||
|
||||
if (!TryComp<CP14MagicAttuningMindComponent>(mind, out var attuningMind))
|
||||
return false;
|
||||
|
||||
return attuningMind.AttunedTo.Contains(item);
|
||||
}
|
||||
|
||||
private void OnInteractionVerb(Entity<CP14MagicAttuningItemComponent> attuningItem, ref GetVerbsEvent<InteractionVerb> args)
|
||||
{
|
||||
if (!args.CanAccess || !args.CanInteract)
|
||||
return;
|
||||
|
||||
if (!_mind.TryGetMind(args.User, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14MagicAttuningMindComponent>(mindId, out var attumingMind))
|
||||
return;
|
||||
|
||||
var user = args.User;
|
||||
if (attumingMind.AttunedTo.Contains(args.Target))
|
||||
{
|
||||
args.Verbs.Add(new()
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
RemoveAttune((mindId, attumingMind), attuningItem);
|
||||
},
|
||||
Text = Loc.GetString("cp14-magic-deattuning-verb-text"),
|
||||
Message = Loc.GetString("cp14-magic-attuning-verb-message"),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Verbs.Add(new()
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
TryStartAttune(user, attuningItem);
|
||||
},
|
||||
Text = Loc.GetString("cp14-magic-attuning-verb-text"),
|
||||
Message = Loc.GetString("cp14-magic-attuning-verb-message"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryStartAttune(EntityUid user, Entity<CP14MagicAttuningItemComponent> item)
|
||||
{
|
||||
if (!_mind.TryGetMind(user, out var mindId, out var mind))
|
||||
return false;
|
||||
|
||||
if (!TryComp<CP14MagicAttuningMindComponent>(mindId, out var attuningMind))
|
||||
return false;
|
||||
|
||||
if (attuningMind.MaxAttuning <= 0)
|
||||
return false;
|
||||
|
||||
//if there's an overabundance of ties, we report that the oldest one is torn.
|
||||
if (attuningMind.AttunedTo.Count >= attuningMind.MaxAttuning)
|
||||
{
|
||||
var oldestAttune = attuningMind.AttunedTo[0];
|
||||
_popup.PopupEntity(Loc.GetString("cp14-magic-attune-oldest-forgot", ("item", MetaData(oldestAttune).EntityName)), user, user);
|
||||
}
|
||||
|
||||
//we notify the current owner of the item that someone is cutting ties.
|
||||
if (item.Comp.Link is not null &&
|
||||
item.Comp.Link.Value.Owner != mindId &&
|
||||
TryComp<MindComponent>(item.Comp.Link.Value.Owner, out var ownerMind) &&
|
||||
ownerMind.OwnedEntity is not null)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cp14-magic-attune-oldest-forgot", ("item", MetaData(item).EntityName)), ownerMind.OwnedEntity.Value, ownerMind.OwnedEntity.Value);
|
||||
}
|
||||
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager,
|
||||
user,
|
||||
item.Comp.FocusTime,
|
||||
new CP14MagicAttuneDoAfterEvent(),
|
||||
mindId,
|
||||
item)
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
DistanceThreshold = 2f,
|
||||
BlockDuplicate = true,
|
||||
};
|
||||
|
||||
_doAfter.TryStartDoAfter(doAfterArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnAttuneDoAfter(Entity<CP14MagicAttuningMindComponent> ent, ref CP14MagicAttuneDoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Handled || args.Target is null)
|
||||
return;
|
||||
|
||||
if (ent.Comp.AttunedTo.Count >= ent.Comp.MaxAttuning)
|
||||
{
|
||||
var oldestAttune = ent.Comp.AttunedTo[0];
|
||||
RemoveAttune(ent, oldestAttune);
|
||||
}
|
||||
|
||||
AddAttune(ent, args.Target.Value);
|
||||
}
|
||||
|
||||
private void RemoveAttune(Entity<CP14MagicAttuningMindComponent> attuningMind, EntityUid item)
|
||||
{
|
||||
if (!attuningMind.Comp.AttunedTo.Contains(item))
|
||||
return;
|
||||
|
||||
attuningMind.Comp.AttunedTo.Remove(item);
|
||||
|
||||
if (!TryComp<CP14MagicAttuningItemComponent>(item, out var attuningItem))
|
||||
return;
|
||||
|
||||
if (!TryComp<MindComponent>(attuningMind, out var mind))
|
||||
return;
|
||||
|
||||
attuningItem.Link = null;
|
||||
|
||||
var ev = new RemovedAttuneFromMindEvent(attuningMind, mind.OwnedEntity, item);
|
||||
RaiseLocalEvent(attuningMind, ev);
|
||||
RaiseLocalEvent(item, ev);
|
||||
|
||||
if (mind.OwnedEntity is not null)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cp14-magic-attune-oldest-forgot-end", ("item", MetaData(item).EntityName)), mind.OwnedEntity.Value, mind.OwnedEntity.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddAttune(Entity<CP14MagicAttuningMindComponent> attuningMind, EntityUid item)
|
||||
{
|
||||
if (attuningMind.Comp.AttunedTo.Contains(item))
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14MagicAttuningItemComponent>(item, out var attuningItem))
|
||||
return;
|
||||
|
||||
if (!TryComp<MindComponent>(attuningMind, out var mind))
|
||||
return;
|
||||
|
||||
if (attuningItem.Link is not null)
|
||||
RemoveAttune(attuningItem.Link.Value, item);
|
||||
|
||||
attuningMind.Comp.AttunedTo.Add(item);
|
||||
attuningItem.Link = attuningMind;
|
||||
|
||||
|
||||
var ev = new AddedAttuneToMindEvent(attuningMind, mind.OwnedEntity, item);
|
||||
RaiseLocalEvent(attuningMind, ev);
|
||||
RaiseLocalEvent(item, ev);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class CP14MagicAttuneDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// is evoked on both the item and the mind when a new connection between them appears.
|
||||
/// </summary>
|
||||
public sealed class AddedAttuneToMindEvent : EntityEventArgs
|
||||
{
|
||||
public readonly EntityUid Mind;
|
||||
public readonly EntityUid? User;
|
||||
public readonly EntityUid Item;
|
||||
|
||||
public AddedAttuneToMindEvent(EntityUid mind, EntityUid? user, EntityUid item)
|
||||
{
|
||||
Mind = mind;
|
||||
User = user;
|
||||
Item = item;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// is evoked on both the item and the mind when the connection is broken
|
||||
/// </summary>
|
||||
public sealed class RemovedAttuneFromMindEvent : EntityEventArgs
|
||||
{
|
||||
public readonly EntityUid Mind;
|
||||
public readonly EntityUid? User;
|
||||
public readonly EntityUid Item;
|
||||
|
||||
public RemovedAttuneFromMindEvent(EntityUid mind, EntityUid? user, EntityUid item)
|
||||
{
|
||||
Mind = mind;
|
||||
User = user;
|
||||
Item = item;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
using Content.Shared._CP14.Magic.Components;
|
||||
using Content.Shared._CP14.Magic.Events;
|
||||
using Content.Shared._CP14.MagicEnergy;
|
||||
using Content.Shared._CP14.MagicEnergy.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Components;
|
||||
using Content.Shared._CP14.MagicSpell.Events;
|
||||
using Content.Shared._CP14.MagicSpell.Spells;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Speech.Muting;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
@@ -13,8 +13,11 @@ using Robust.Shared.Network;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared._CP14.Magic;
|
||||
namespace Content.Shared._CP14.MagicSpell;
|
||||
|
||||
/// <summary>
|
||||
/// This system handles the basic mechanics of spell use, such as doAfter, event invocation, and energy spending.
|
||||
/// </summary>
|
||||
public partial class CP14SharedMagicSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
@@ -26,7 +29,6 @@ public partial class CP14SharedMagicSystem : EntitySystem
|
||||
[Dependency] private readonly SharedCP14MagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -34,6 +36,10 @@ public partial class CP14SharedMagicSystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectComponent, CP14BeforeCastMagicEffectEvent>(OnBeforeCastMagicEffect);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectComponent, CP14DelayedInstantActionDoAfterEvent>(OnDelayedInstantActionDoAfter);
|
||||
SubscribeLocalEvent<CP14MagicEffectComponent, CP14DelayedEntityTargetActionDoAfterEvent>(OnDelayedEntityTargetDoAfter);
|
||||
SubscribeLocalEvent<CP14MagicEffectComponent, CP14DelayedWorldTargetActionDoAfterEvent>(OnDelayedWorldTargetDoAfter);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectSomaticAspectComponent, CP14BeforeCastMagicEffectEvent>(OnSomaticAspectBeforeCast);
|
||||
|
||||
SubscribeLocalEvent<CP14MagicEffectVerbalAspectComponent, CP14BeforeCastMagicEffectEvent>(OnVerbalAspectBeforeCast);
|
||||
@@ -44,8 +50,57 @@ public partial class CP14SharedMagicSystem : EntitySystem
|
||||
SubscribeLocalEvent<CP14DelayedInstantActionEvent>(OnInstantAction);
|
||||
SubscribeLocalEvent<CP14DelayedEntityTargetActionEvent>(OnEntityTargetAction);
|
||||
SubscribeLocalEvent<CP14DelayedWorldTargetActionEvent>(OnWorldTargetAction);
|
||||
}
|
||||
|
||||
InitializeSpells();
|
||||
private void OnDelayedWorldTargetDoAfter(Entity<CP14MagicEffectComponent> ent, ref CP14DelayedWorldTargetActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(ent, ref stopEv);
|
||||
|
||||
if (args.Cancelled || !_net.IsServer)
|
||||
return;
|
||||
|
||||
foreach (var effect in ent.Comp.Effects)
|
||||
{
|
||||
effect.Effect(EntityManager, new CP14SpellEffectBaseArgs(args.User, null, GetCoordinates(args.Target)));
|
||||
}
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
private void OnDelayedEntityTargetDoAfter(Entity<CP14MagicEffectComponent> ent, ref CP14DelayedEntityTargetActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(ent, ref stopEv);
|
||||
|
||||
if (args.Cancelled || !_net.IsServer)
|
||||
return;
|
||||
|
||||
foreach (var effect in ent.Comp.Effects)
|
||||
{
|
||||
effect.Effect(EntityManager, new CP14SpellEffectBaseArgs(args.User, args.Target, null));
|
||||
}
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
private void OnDelayedInstantActionDoAfter(Entity<CP14MagicEffectComponent> ent, ref CP14DelayedInstantActionDoAfterEvent args)
|
||||
{
|
||||
var stopEv = new CP14StopCastMagicEffectEvent();
|
||||
RaiseLocalEvent(ent, ref stopEv);
|
||||
|
||||
if (args.Cancelled || !_net.IsServer)
|
||||
return;
|
||||
|
||||
foreach (var effect in ent.Comp.Effects)
|
||||
{
|
||||
effect.Effect(EntityManager, new CP14SpellEffectBaseArgs(args.User, args.User, Transform(args.User).Coordinates));
|
||||
}
|
||||
|
||||
var ev = new CP14AfterCastMagicEffectEvent {Performer = args.User};
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
private void OnSomaticAspectBeforeCast(Entity<CP14MagicEffectSomaticAspectComponent> ent, ref CP14BeforeCastMagicEffectEvent args)
|
||||
@@ -85,6 +140,9 @@ public partial class CP14SharedMagicSystem : EntitySystem
|
||||
|
||||
private void OnVerbalAspectAfterCast(Entity<CP14MagicEffectVerbalAspectComponent> ent, ref CP14AfterCastMagicEffectEvent args)
|
||||
{
|
||||
if (_net.IsClient)
|
||||
return;
|
||||
|
||||
var ev = new CP14VerbalAspectSpeechEvent
|
||||
{
|
||||
Performer = args.Performer,
|
||||
@@ -1,6 +1,6 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components;
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a temporary entity that exists while the spell is cast, and disappears at the end. For visual special effects.
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared._CP14.MagicSpell.Spells;
|
||||
using Content.Shared.FixedPoint;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components;
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Restricts the use of this action, by spending mana or user requirements.
|
||||
@@ -13,4 +14,7 @@ public sealed partial class CP14MagicEffectComponent : Component
|
||||
|
||||
[DataField]
|
||||
public bool Safe = false;
|
||||
|
||||
[DataField]
|
||||
public List<CP14SpellEffect> Effects = new();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Shared._CP14.Magic.Components;
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the user to have at least one free hand to use this spell
|
||||
@@ -1,6 +1,4 @@
|
||||
using Content.Shared.FixedPoint;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Components;
|
||||
namespace Content.Shared._CP14.MagicSpell.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the user to be able to speak in order to use this spell. Also forces the user to use certain phrases at the beginning and end of a spell cast
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Shared._CP14.Magic.Events;
|
||||
namespace Content.Shared._CP14.MagicSpell.Events;
|
||||
|
||||
[ByRefEvent]
|
||||
public sealed class CP14BeforeCastMagicEffectEvent : CancellableEntityEventArgs
|
||||
@@ -3,7 +3,7 @@ using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Events;
|
||||
namespace Content.Shared._CP14.MagicSpell.Events;
|
||||
|
||||
//World target
|
||||
public sealed partial class CP14DelayedWorldTargetActionEvent : WorldTargetActionEvent, ICP14DelayedMagicEffect
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Shared._CP14.Magic;
|
||||
namespace Content.Shared._CP14.MagicSpell.Events;
|
||||
|
||||
public interface ICP14DelayedMagicEffect // The speak n spell interface
|
||||
{
|
||||
@@ -0,0 +1,22 @@
|
||||
using Content.Shared.EntityEffects;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellApplyEntityEffect : CP14SpellEffect
|
||||
{
|
||||
[DataField(required: true, serverOnly: true)]
|
||||
public List<EntityEffect> Effects = new();
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
if (args.Target is null)
|
||||
return;
|
||||
|
||||
var targetEntity = args.Target.Value;
|
||||
|
||||
foreach (var effect in Effects)
|
||||
{
|
||||
effect.Effect(new EntityEffectBaseArgs(targetEntity, entManager));
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Content.Shared/_CP14/MagicSpell/Spells/CP14SpellEffect.cs
Normal file
25
Content.Shared/_CP14/MagicSpell/Spells/CP14SpellEffect.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14SpellEffect
|
||||
{
|
||||
public abstract void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args);
|
||||
}
|
||||
|
||||
public record class CP14SpellEffectBaseArgs
|
||||
{
|
||||
public EntityUid? User;
|
||||
public EntityUid? Target;
|
||||
public EntityCoordinates? Position;
|
||||
|
||||
public CP14SpellEffectBaseArgs(EntityUid? user, EntityUid? target, EntityCoordinates? position)
|
||||
{
|
||||
User = user;
|
||||
Target = target;
|
||||
Position = position;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellProjectile : CP14SpellEffect
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public EntProtoId Prototype;
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
EntityCoordinates? targetPoint = null;
|
||||
if (args.Position is not null)
|
||||
targetPoint = args.Position.Value;
|
||||
else if (args.Target is not null && entManager.TryGetComponent<TransformComponent>(args.Target.Value, out var transformComponent))
|
||||
targetPoint = transformComponent.Coordinates;
|
||||
|
||||
if (targetPoint is null)
|
||||
return;
|
||||
|
||||
|
||||
var transform = entManager.System<SharedTransformSystem>();
|
||||
var physics = entManager.System<SharedPhysicsSystem>();
|
||||
var gunSystem = entManager.System<SharedGunSystem>();
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
|
||||
if (!entManager.TryGetComponent<TransformComponent>(args.User, out var xform))
|
||||
return;
|
||||
|
||||
var fromCoords = xform.Coordinates;
|
||||
|
||||
if (fromCoords == targetPoint)
|
||||
return;
|
||||
|
||||
var userVelocity = physics.GetMapLinearVelocity(args.User.Value);
|
||||
|
||||
// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
|
||||
var fromMap = transform.ToMapCoordinates(fromCoords);
|
||||
var spawnCoords = mapManager.TryFindGridAt(fromMap, out var gridUid, out _)
|
||||
? transform.WithEntityId(fromCoords, gridUid)
|
||||
: new(mapManager.GetMapEntityId(fromMap.MapId), fromMap.Position);
|
||||
|
||||
|
||||
var ent = entManager.SpawnAtPosition(Prototype, spawnCoords);
|
||||
var direction = targetPoint.Value.ToMapPos(entManager, transform) -
|
||||
spawnCoords.ToMapPos(entManager, transform);
|
||||
gunSystem.ShootProjectile(ent, direction, userVelocity, args.User.Value, args.User);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
public sealed partial class CP14SpellSpawnEntity : CP14SpellEffect
|
||||
{
|
||||
[DataField]
|
||||
public List<EntProtoId> Spawns = new();
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
EntityCoordinates? targetPoint = null;
|
||||
if (args.Position is not null)
|
||||
targetPoint = args.Position.Value;
|
||||
else if (args.Target is not null && entManager.TryGetComponent<TransformComponent>(args.Target.Value, out var transformComponent))
|
||||
targetPoint = transformComponent.Coordinates;
|
||||
|
||||
if (targetPoint is null)
|
||||
return;
|
||||
|
||||
foreach (var spawn in Spawns)
|
||||
{
|
||||
entManager.SpawnAtPosition(spawn, targetPoint.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Content.Shared._CP14.MagicSpellStorage;
|
||||
|
||||
/// <summary>
|
||||
/// Denotes that this item's spells can be accessed while holding it in your hand
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SpellStorageSystem))]
|
||||
public sealed partial class CP14SpellStorageAccessHoldingComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Content.Shared._CP14.MagicSpellStorage;
|
||||
|
||||
/// <summary>
|
||||
/// Denotes that this item's spells can be accessed while wearing it in your body
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SpellStorageSystem))]
|
||||
public sealed partial class CP14SpellStorageAccessWearingComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpellStorage;
|
||||
|
||||
/// <summary>
|
||||
/// A component that allows you to store spells in items
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SpellStorageSystem))]
|
||||
public sealed partial class CP14SpellStorageComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// list of spell prototypes used for initialization.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntProtoId> Spells = new();
|
||||
|
||||
/// <summary>
|
||||
/// created after the initialization of spell entities.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntityUid> SpellEntities = new();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Content.Shared._CP14.MagicSpellStorage;
|
||||
|
||||
/// <summary>
|
||||
/// The ability to access spellcasting is limited by the attuning requirement
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14SpellStorageSystem))]
|
||||
public sealed partial class CP14SpellStorageRequireAttuneComponent : Component
|
||||
{
|
||||
}
|
||||
109
Content.Shared/_CP14/MagicSpellStorage/CP14SpellStorageSystem.cs
Normal file
109
Content.Shared/_CP14/MagicSpellStorage/CP14SpellStorageSystem.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using Content.Shared._CP14.MagicAttuning;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Mind;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpellStorage;
|
||||
|
||||
/// <summary>
|
||||
/// this part of the system is responsible for storing spells in items, and the methods players use to obtain them.
|
||||
/// </summary>
|
||||
public sealed partial class CP14SpellStorageSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
[Dependency] private readonly CP14SharedMagicAttuningSystem _attuning = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<CP14SpellStorageComponent, MapInitEvent>(OnMagicStorageInit);
|
||||
|
||||
SubscribeLocalEvent<CP14SpellStorageAccessHoldingComponent, GotEquippedHandEvent>(OnEquippedHand);
|
||||
SubscribeLocalEvent<CP14SpellStorageAccessHoldingComponent, AddedAttuneToMindEvent>(OnHandAddedAttune);
|
||||
|
||||
SubscribeLocalEvent<CP14SpellStorageAccessWearingComponent, ClothingGotEquippedEvent>(OnClothingEquipped);
|
||||
SubscribeLocalEvent<CP14SpellStorageAccessWearingComponent, ClothingGotUnequippedEvent>(OnClothingUnequipped);
|
||||
|
||||
SubscribeLocalEvent<CP14SpellStorageRequireAttuneComponent, RemovedAttuneFromMindEvent>(OnRemovedAttune);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When we initialize, we create action entities, and add them to this item.
|
||||
/// </summary>
|
||||
private void OnMagicStorageInit(Entity<CP14SpellStorageComponent> mStorage, ref MapInitEvent args)
|
||||
{
|
||||
foreach (var spell in mStorage.Comp.Spells)
|
||||
{
|
||||
var spellEnt = _actionContainer.AddAction(mStorage, spell);
|
||||
if (spellEnt is null)
|
||||
continue;
|
||||
|
||||
mStorage.Comp.SpellEntities.Add(spellEnt.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEquippedHand(Entity<CP14SpellStorageAccessHoldingComponent> ent, ref GotEquippedHandEvent args)
|
||||
{
|
||||
if (!TryComp<CP14SpellStorageComponent>(ent, out var spellStorage))
|
||||
return;
|
||||
|
||||
TryGrantAccess((ent, spellStorage), args.User);
|
||||
}
|
||||
|
||||
private void OnHandAddedAttune(Entity<CP14SpellStorageAccessHoldingComponent> ent, ref AddedAttuneToMindEvent args)
|
||||
{
|
||||
if (!TryComp<CP14SpellStorageComponent>(ent, out var spellStorage))
|
||||
return;
|
||||
|
||||
if (args.User is null)
|
||||
return;
|
||||
|
||||
if (!_hands.IsHolding(args.User.Value, ent))
|
||||
return;
|
||||
|
||||
TryGrantAccess((ent, spellStorage), args.User.Value);
|
||||
}
|
||||
|
||||
private void OnClothingEquipped(Entity<CP14SpellStorageAccessWearingComponent> ent, ref ClothingGotEquippedEvent args)
|
||||
{
|
||||
if (!TryComp<CP14SpellStorageComponent>(ent, out var spellStorage))
|
||||
return;
|
||||
|
||||
TryGrantAccess((ent, spellStorage), args.Wearer);
|
||||
}
|
||||
|
||||
private void OnClothingUnequipped(Entity<CP14SpellStorageAccessWearingComponent> ent, ref ClothingGotUnequippedEvent args)
|
||||
{
|
||||
_actions.RemoveProvidedActions(args.Wearer, ent);
|
||||
}
|
||||
|
||||
private bool TryGrantAccess(Entity<CP14SpellStorageComponent> storage, EntityUid user)
|
||||
{
|
||||
if (!_mind.TryGetMind(user, out var mindId, out var mind))
|
||||
return false;
|
||||
|
||||
if (mind.OwnedEntity is null)
|
||||
return false;
|
||||
|
||||
if (TryComp<CP14SpellStorageRequireAttuneComponent>(storage, out var reqAttune))
|
||||
{
|
||||
if (!_attuning.IsAttunedTo(mindId, storage))
|
||||
return false;
|
||||
}
|
||||
|
||||
_actions.GrantActions(user, storage.Comp.SpellEntities, storage);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnRemovedAttune(Entity<CP14SpellStorageRequireAttuneComponent> ent, ref RemovedAttuneFromMindEvent args)
|
||||
{
|
||||
if (args.User is null)
|
||||
return;
|
||||
|
||||
_actions.RemoveProvidedActions(args.User.Value, ent);
|
||||
}
|
||||
}
|
||||
7
Resources/Locale/en-US/_CP14/magicEnergy/magic-focus.ftl
Normal file
7
Resources/Locale/en-US/_CP14/magicEnergy/magic-focus.ftl
Normal file
@@ -0,0 +1,7 @@
|
||||
cp14-magic-attuning-verb-text = Attune yourself
|
||||
cp14-magic-attuning-verb-message = Some magic items require a creature to form a bond with them before their magical properties can be used.
|
||||
|
||||
cp14-magic-deattuning-verb-text = Break attune
|
||||
|
||||
cp14-magic-attune-oldest-forgot = Your connection to {$item} is weakening ...
|
||||
cp14-magic-attune-oldest-forgot-end = Your connection to {$item} has broken...
|
||||
7
Resources/Locale/ru-RU/_CP14/magicEnergy/magic-focus.ftl
Normal file
7
Resources/Locale/ru-RU/_CP14/magicEnergy/magic-focus.ftl
Normal file
@@ -0,0 +1,7 @@
|
||||
cp14-magic-attuning-verb-text = Настроиться на магический предмет
|
||||
cp14-magic-attuning-verb-message = Некоторые магические предметы требуют того, чтобы существо образовало с ними связь, прежде чем оно сможет использовать их магические свойства.
|
||||
|
||||
cp14-magic-deattuning-verb-text = Разорвать связь с магическим предметом
|
||||
|
||||
cp14-magic-attune-oldest-forgot = Ваша связь с {$item} слабеет...
|
||||
cp14-magic-attune-oldest-forgot-end = Ваша связь с {$item} оборвалась...
|
||||
@@ -0,0 +1,62 @@
|
||||
- type: entity
|
||||
id: CP14ActionSpellCureWounds
|
||||
name: Cure wounds
|
||||
description: You touch the creature, healing its body from physical damage
|
||||
components:
|
||||
- type: CP14MagicEffect
|
||||
manaCost: 10
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntity
|
||||
spawns:
|
||||
- CP14CureWoundsImpactEffect
|
||||
- !type:CP14SpellApplyEntityEffect
|
||||
effects:
|
||||
- !type:HealthChange
|
||||
damage:
|
||||
types:
|
||||
Slash: -8
|
||||
Blunt: -8
|
||||
Piercing: -8
|
||||
Heat: -8
|
||||
- !type:Jitter
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
startSpeech: "Et curabuntur..."
|
||||
endSpeech: "vulnera tua"
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14CureWoundsRune
|
||||
- type: EntityTargetAction
|
||||
useDelay: 5
|
||||
itemIconStyle: BigAction
|
||||
interactOnMiss: false
|
||||
sound: !type:SoundPathSpecifier
|
||||
path: /Audio/Magic/rumble.ogg
|
||||
icon:
|
||||
sprite: _CP14/Effects/Magic/spells_icons.rsi
|
||||
state: cure_wounds
|
||||
event: !type:CP14DelayedEntityTargetActionEvent
|
||||
delay: 2
|
||||
|
||||
- type: entity
|
||||
id: CP14CureWoundsRune
|
||||
noSpawn: true
|
||||
parent: CP14BaseMagicRune
|
||||
components:
|
||||
- type: PointLight
|
||||
color: "#328643"
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: sun
|
||||
color: "#79b330"
|
||||
shader: unshaded
|
||||
|
||||
- type: entity
|
||||
id: CP14CureWoundsImpactEffect
|
||||
parent: CP14BaseMagicImpact
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: particles_up
|
||||
color: "#79b330"
|
||||
shader: unshaded
|
||||
@@ -1,153 +0,0 @@
|
||||
- type: entity
|
||||
id: CP14ActionSpellHealingWord
|
||||
name: Healing word
|
||||
description: bruh
|
||||
components:
|
||||
- type: CP14MagicEffect
|
||||
manaCost: 10
|
||||
- type: EntityTargetAction
|
||||
useDelay: 1
|
||||
itemIconStyle: BigAction
|
||||
interactOnMiss: true
|
||||
sound: !type:SoundPathSpecifier
|
||||
path: /Audio/Magic/rumble.ogg
|
||||
icon:
|
||||
sprite: Objects/Magic/magicactions.rsi
|
||||
state: gib
|
||||
event: !type:CP14DelayedEntityTargetActionEvent
|
||||
- type: CP14DelayedApplyEntityEffectsSpell
|
||||
effects:
|
||||
- !type:HealthChange
|
||||
damage:
|
||||
types:
|
||||
Slash: -5
|
||||
Blunt: -5
|
||||
Piercing: -5
|
||||
Heat: -10
|
||||
- !type:Jitter
|
||||
|
||||
- type: entity
|
||||
id: CP14ActionSpellFireball
|
||||
name: Fireball
|
||||
description: Fires an explosive fireball towards the clicked location.
|
||||
components:
|
||||
- type: CP14MagicEffect
|
||||
manaCost: 70
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
startSpeech: "O tenebrae, ubi lux non penetrat..."
|
||||
endSpeech: "Quaeso, quemdam inter vos quaero!"
|
||||
- type: CP14MagicEffectSomaticAspect
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14FireballRune
|
||||
- type: WorldTargetAction
|
||||
useDelay: 3
|
||||
itemIconStyle: BigAction
|
||||
checkCanAccess: false
|
||||
raiseOnUser: true
|
||||
range: 60
|
||||
sound: !type:SoundPathSpecifier
|
||||
path: /Audio/Magic/fireball.ogg
|
||||
icon:
|
||||
sprite: Objects/Magic/magicactions.rsi
|
||||
state: fireball
|
||||
event: !type:CP14DelayedWorldTargetActionEvent
|
||||
delay: 3
|
||||
- type: CP14DelayedProjectileSpell
|
||||
prototype: ProjectileFireball
|
||||
|
||||
- type: entity
|
||||
id: CP14ActionSpellSelfHeal
|
||||
name: Self Heal
|
||||
description: Toggles your suit's phase cloak. Beware that if you are hit, all abilities are disabled for 5 seconds, including your cloak!
|
||||
components:
|
||||
- type: InstantAction
|
||||
# have to plan (un)cloaking ahead of time
|
||||
useDelay: 5
|
||||
priority: -9
|
||||
event: !type:CP14DelayedInstantActionEvent
|
||||
- type: CP14DelayedSelfEntityEffectSpell
|
||||
effects:
|
||||
- !type:HealthChange
|
||||
damage:
|
||||
types:
|
||||
Slash: -5
|
||||
Blunt: -5
|
||||
Piercing: -5
|
||||
Heat: -10
|
||||
- !type:Jitter
|
||||
|
||||
- type: entity
|
||||
id: CP14ActionSpelldaggerSpawn
|
||||
name: Gravity well
|
||||
description: Toggles your suit's phase cloak. Beware that if you are hit, all abilities are disabled for 5 seconds, including your cloak!
|
||||
components:
|
||||
- type: CP14MagicEffect
|
||||
manaCost: 20
|
||||
- type: WorldTargetAction
|
||||
useDelay: 1
|
||||
itemIconStyle: BigAction
|
||||
checkCanAccess: false
|
||||
raiseOnUser: true
|
||||
range: 4
|
||||
sound: !type:SoundPathSpecifier
|
||||
path: /Audio/Magic/fireball.ogg
|
||||
icon:
|
||||
sprite: Objects/Magic/magicactions.rsi
|
||||
state: fireball
|
||||
event: !type:CP14DelayedWorldTargetActionEvent
|
||||
- type: CP14DelayedSpawnOnWorldTargetSpell
|
||||
spawns:
|
||||
- AdminInstantEffectGravityWell
|
||||
|
||||
- type: listing
|
||||
id: CP14SpellbookJutter
|
||||
name: jit
|
||||
description: jit
|
||||
productAction: CP14ActionSpellHealingWord
|
||||
cost:
|
||||
WizCoin: 1
|
||||
categories:
|
||||
- SpellbookOffensive
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
|
||||
- type: listing
|
||||
id: CP14SpellbookFireball
|
||||
name: fifire
|
||||
description: fifire
|
||||
productAction: CP14ActionSpellFireball
|
||||
cost:
|
||||
WizCoin: 1
|
||||
categories:
|
||||
- SpellbookOffensive
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: CP14SpellbookFireball3
|
||||
name: selfheal
|
||||
description: selfheal
|
||||
productAction: CP14ActionSpellSelfHeal
|
||||
cost:
|
||||
WizCoin: 1
|
||||
categories:
|
||||
- SpellbookOffensive
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: CP14SpellbookFireball33
|
||||
name: Gravity Well
|
||||
description: well...
|
||||
productAction: CP14ActionSpelldaggerSpawn
|
||||
cost:
|
||||
WizCoin: 1
|
||||
categories:
|
||||
- SpellbookOffensive
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
@@ -5,6 +5,7 @@
|
||||
abstract: true
|
||||
components:
|
||||
- type: Sprite
|
||||
noRot: true
|
||||
drawDepth: FloorTiles
|
||||
sprite: _CP14/Effects/Magic/cast_rune.rsi
|
||||
- type: Tag
|
||||
@@ -16,16 +17,19 @@
|
||||
netsync: false
|
||||
|
||||
- type: entity
|
||||
id: CP14FireballRune
|
||||
parent: CP14BaseMagicRune
|
||||
id: CP14BaseMagicImpact
|
||||
name: magic impact
|
||||
description: manifestation of magical energy in the physical plane
|
||||
abstract: true
|
||||
components:
|
||||
- type: PointLight
|
||||
color: "#d47d26"
|
||||
- type: TimedDespawn
|
||||
lifetime: 1.6
|
||||
- type: AnimationPlayer
|
||||
- type: EffectVisuals
|
||||
- type: Tag
|
||||
tags:
|
||||
- HideContextMenu
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: medium_circle
|
||||
color: "#d47d26"
|
||||
shader: unshaded
|
||||
- state: sun
|
||||
color: "#d47d26"
|
||||
shader: unshaded
|
||||
drawdepth: Effects
|
||||
sprite: _CP14/Effects/Magic/cast_impact.rsi
|
||||
noRot: true
|
||||
@@ -7,4 +7,11 @@
|
||||
sprite: Objects/Specific/Hydroponics/seeds.rsi
|
||||
state: seed
|
||||
- type: CP14Seed
|
||||
plantProto: CP14PlantWheat
|
||||
plantProto: CP14PlantWheat
|
||||
- type: CP14MagicAttuningItem
|
||||
focusTime: 1
|
||||
- type: CP14SpellStorageAccessHolding
|
||||
- type: CP14SpellStorage
|
||||
spells:
|
||||
- CP14ActionSpellCureWounds
|
||||
- type: CP14SpellStorageRequireAttune
|
||||
@@ -211,10 +211,12 @@
|
||||
maxEnergy: 100
|
||||
energy: 100
|
||||
- type: CP14MagicEnergyDraw
|
||||
energy: 5
|
||||
delay: 5
|
||||
energy: 1
|
||||
delay: 6 # 10m to full restore
|
||||
- type: CP14MagicUnsafeDamage
|
||||
- type: CP14MagicUnsafeSleep
|
||||
- type: CP14MagicAttuningMind
|
||||
autoCopyToMind: true
|
||||
|
||||
|
||||
- type: entity
|
||||
|
||||
@@ -5,25 +5,25 @@
|
||||
minPlayers: 0
|
||||
stations:
|
||||
Empty:
|
||||
stationProto: StandardNanotrasenStation
|
||||
stationProto: StandardStationArena
|
||||
components:
|
||||
- type: StationNameSetup
|
||||
mapNameTemplate: "Empty"
|
||||
- type: StationJobs
|
||||
availableJobs:
|
||||
CP14Adventurer: [ -1, -1 ] #CrystallPunk Dev replacement
|
||||
CP14Adventurer: [ -1, -1 ]
|
||||
|
||||
- type: gameMap
|
||||
id: Dev
|
||||
mapName: Dev
|
||||
mapPath: /Maps/_CP14/dev_map.yml #CrystallPunk Dev replacement
|
||||
mapPath: /Maps/_CP14/dev_map.yml
|
||||
minPlayers: 0
|
||||
stations:
|
||||
Dev:
|
||||
stationProto: StandardNanotrasenStation
|
||||
stationProto: StandardStationArena
|
||||
components:
|
||||
- type: StationNameSetup
|
||||
mapNameTemplate: "Dev"
|
||||
- type: StationJobs
|
||||
availableJobs:
|
||||
CP14Adventurer: [ -1, -1 ] #CrystallPunk Dev replacement
|
||||
CP14Adventurer: [ -1, -1 ]
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 48,
|
||||
"y": 48
|
||||
},
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd for CrystallPunk",
|
||||
"states": [
|
||||
{
|
||||
"name": "particles_up",
|
||||
"delays": [
|
||||
[
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2,
|
||||
0.2
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "All rights reserved for the CrystallPunk14 project only",
|
||||
"copyright": "Created by TheShuEd",
|
||||
"states": [
|
||||
{
|
||||
"name": "cure_wounds"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user