Compare commits
4 Commits
ed-05-06-2
...
magick
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f6e73831a | ||
|
|
a0a2e8fabf | ||
|
|
765d226a9d | ||
|
|
25c174af41 |
8
Content.Server/_CP14/Magic/CPMagicSpellComponent.cs
Normal file
8
Content.Server/_CP14/Magic/CPMagicSpellComponent.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CPMagicSpellComponent : Component
|
||||
{
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public List<CPMagicEffectPrototype> Effects = new();
|
||||
}
|
||||
22
Content.Server/_CP14/Magic/CPMagicSpellContainerComponent.cs
Normal file
22
Content.Server/_CP14/Magic/CPMagicSpellContainerComponent.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CPMagicSpellContainerComponent : Component
|
||||
{
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public List<ProtoId<CPMagicEffectPrototype>> Effects = new();
|
||||
|
||||
[DataField, ViewVariables]
|
||||
public List<CPMagicEffectPrototype> EffectPrototypes = new ();
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float MaximumCompleteness = 1f;
|
||||
|
||||
[DataField, ViewVariables]
|
||||
public float TotalCompleteness;
|
||||
|
||||
[DataField, ViewVariables]
|
||||
public TimeSpan TotalCastTime;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared._CP14.Magic.Events;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Verbs;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
public sealed partial class CPMagicSpellContainerSystem
|
||||
{
|
||||
private void InitializeCast()
|
||||
{
|
||||
SubscribeLocalEvent<CPMagicSpellContainerComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerb);
|
||||
SubscribeLocalEvent<CPMagicSpellContainerComponent, CPMagicCastDoAfterEvent>(OnCast);
|
||||
}
|
||||
|
||||
private void OnGetVerb(Entity<CPMagicSpellContainerComponent> container, ref GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
var user = args.User;
|
||||
|
||||
args.Verbs.Add(new AlternativeVerb
|
||||
{
|
||||
Text = "Get spell",
|
||||
Disabled = container.Comp.Effects.Count == 0,
|
||||
Priority = 10,
|
||||
Act = () =>
|
||||
{
|
||||
StartCast(container, user);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void OnCast(Entity<CPMagicSpellContainerComponent> container, ref CPMagicCastDoAfterEvent args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled || args.Target is null)
|
||||
return;
|
||||
|
||||
Cast(container, args.Target.Value);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
public void StartCast(Entity<CPMagicSpellContainerComponent> container, EntityUid caster)
|
||||
{
|
||||
if (!CastValidate(container, caster, out _))
|
||||
return;
|
||||
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, caster, container.Comp.TotalCastTime, new CPMagicCastDoAfterEvent(), target: caster, used: container, eventTarget: container)
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
MovementThreshold = 0.5f,
|
||||
CancelDuplicate = false,
|
||||
};
|
||||
|
||||
_doAfter.TryStartDoAfter(doAfterArgs);
|
||||
}
|
||||
|
||||
public void Cast(Entity<CPMagicSpellContainerComponent> container, EntityUid caster)
|
||||
{
|
||||
if (!CastValidate(container, caster, out var hand))
|
||||
return;
|
||||
|
||||
var entity = Spawn(BaseSpellItemEntity, _transform.GetMapCoordinates(container));
|
||||
var spell = EnsureComp<CPMagicSpellComponent>(entity);
|
||||
|
||||
spell.Effects = new List<CPMagicEffectPrototype>(container.Comp.EffectPrototypes);
|
||||
|
||||
_hands.TryPickup(caster, entity, hand);
|
||||
}
|
||||
|
||||
private bool CastValidate(Entity<CPMagicSpellContainerComponent> container, EntityUid caster, [NotNullWhen(true)] out Hand? hand)
|
||||
{
|
||||
hand = default;
|
||||
|
||||
if (container.Comp.TotalCompleteness > container.Comp.MaximumCompleteness)
|
||||
{
|
||||
_popup.PopupEntity("Too much complicated", container);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_hands.TryGetEmptyHand(caster, out hand))
|
||||
{
|
||||
_popup.PopupEntity("The spell can't fit in your hand", container);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Content.Server._CP14.Magic.Events;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
public sealed partial class CPMagicSpellContainerSystem
|
||||
{
|
||||
private void InitializeHash()
|
||||
{
|
||||
SubscribeLocalEvent<CPMagicSpellContainerComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<CPMagicSpellContainerComponent, CPMagicSpellContainerListUpdatedEvent>(OnListUpdated);
|
||||
}
|
||||
|
||||
private void OnStartup(Entity<CPMagicSpellContainerComponent> container, ref ComponentStartup args)
|
||||
{
|
||||
RaiseListUpdated(container);
|
||||
}
|
||||
|
||||
private void OnListUpdated(Entity<CPMagicSpellContainerComponent> container, ref CPMagicSpellContainerListUpdatedEvent args)
|
||||
{
|
||||
container.Comp.EffectPrototypes = new List<CPMagicEffectPrototype>();
|
||||
container.Comp.TotalCompleteness = 0f;
|
||||
container.Comp.TotalCastTime = TimeSpan.Zero;
|
||||
|
||||
foreach (var effectId in container.Comp.Effects)
|
||||
{
|
||||
if (!_prototype.TryIndex(effectId, out var prototype))
|
||||
{
|
||||
_sawmill.Error($"Impossible to find a prototype for {effectId}");
|
||||
return;
|
||||
}
|
||||
|
||||
container.Comp.EffectPrototypes.Add(prototype);
|
||||
container.Comp.TotalCompleteness += prototype.Complexity;
|
||||
container.Comp.TotalCastTime += prototype.CastTime;
|
||||
}
|
||||
}
|
||||
|
||||
private void RaiseListUpdated(Entity<CPMagicSpellContainerComponent> container)
|
||||
{
|
||||
var ev = new CPMagicSpellContainerListUpdatedEvent();
|
||||
RaiseLocalEvent(container, ev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Content.Shared.Interaction;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
public sealed partial class CPMagicSpellContainerSystem
|
||||
{
|
||||
private void InitializeSpell()
|
||||
{
|
||||
SubscribeLocalEvent<CPMagicSpellComponent, AfterInteractEvent>(OnInteract);
|
||||
}
|
||||
|
||||
private void OnInteract(Entity<CPMagicSpellComponent> spell, ref AfterInteractEvent args)
|
||||
{
|
||||
var entity = Spawn(BaseSpellEffectEntity, args.ClickLocation.ToMap(EntityManager, _transform));
|
||||
foreach (var effect in spell.Comp.Effects)
|
||||
{
|
||||
EntityManager.AddComponents(entity, effect.Components);
|
||||
}
|
||||
|
||||
var ev = new CPMagicCastedEvent(args.User, args.Target, args.ClickLocation);
|
||||
RaiseLocalEvent(entity, ev);
|
||||
|
||||
Del(spell);
|
||||
}
|
||||
}
|
||||
33
Content.Server/_CP14/Magic/CPMagicSpellContainerSystem.cs
Normal file
33
Content.Server/_CP14/Magic/CPMagicSpellContainerSystem.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Popups;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
public sealed partial class CPMagicSpellContainerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
[Dependency] private readonly HandsSystem _hands = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
|
||||
public readonly EntProtoId BaseSpellItemEntity = "CPBSpellItemEntity";
|
||||
public readonly EntProtoId BaseSpellEffectEntity = "CPBaseSpellEntity";
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_sawmill = _logManager.GetSawmill("cp14_magic_spell_container");
|
||||
|
||||
InitializeHash();
|
||||
InitializeCast();
|
||||
InitializeSpell();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Content.Shared.Damage;
|
||||
|
||||
namespace Content.Server._CP14.Magic.Effects.Damage;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CPCastEffectDamageComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public DamageSpecifier Damage = default!;
|
||||
|
||||
[DataField]
|
||||
public bool IgnoreResistances;
|
||||
|
||||
[DataField]
|
||||
public bool InterruptsDoAfters = true;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Content.Shared.Damage;
|
||||
|
||||
namespace Content.Server._CP14.Magic.Effects.Damage;
|
||||
|
||||
public sealed class CPCastEffectDamageSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CPCastEffectDamageComponent, CPMagicCastedEvent>(OnCasted);
|
||||
}
|
||||
|
||||
private void OnCasted(Entity<CPCastEffectDamageComponent> effect, ref CPMagicCastedEvent args)
|
||||
{
|
||||
if (args.Target is null)
|
||||
return;
|
||||
|
||||
_damageable.TryChangeDamage(args.Target, effect.Comp.Damage, effect.Comp.IgnoreResistances,
|
||||
effect.Comp.InterruptsDoAfters);
|
||||
}
|
||||
}
|
||||
10
Content.Server/_CP14/Magic/Events/CPMagicCastedEvent.cs
Normal file
10
Content.Server/_CP14/Magic/Events/CPMagicCastedEvent.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
public sealed class CPMagicCastedEvent(EntityUid caster, EntityUid? target, EntityCoordinates coordinates) : EntityEventArgs
|
||||
{
|
||||
public readonly EntityUid Caster = caster;
|
||||
public readonly EntityUid? Target = target;
|
||||
public readonly EntityCoordinates Coordinates = coordinates;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Content.Server._CP14.Magic.Events;
|
||||
|
||||
public sealed class CPMagicSpellContainerListUpdatedEvent : EntityEventArgs
|
||||
{
|
||||
|
||||
}
|
||||
19
Content.Shared/_CP14/Magic/CPMagicEffectPrototype.cs
Normal file
19
Content.Shared/_CP14/Magic/CPMagicEffectPrototype.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Magic;
|
||||
|
||||
[Prototype("CPMagicEffect")]
|
||||
public sealed partial class CPMagicEffectPrototype : IPrototype
|
||||
{
|
||||
[IdDataField]
|
||||
public string ID { get; } = string.Empty;
|
||||
|
||||
[DataField]
|
||||
public ComponentRegistry Components = new();
|
||||
|
||||
[DataField]
|
||||
public float Complexity = 1f;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan CastTime = TimeSpan.Zero;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Magic.Events;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class CPMagicCastDoAfterEvent : SimpleDoAfterEvent;
|
||||
9
Resources/Prototypes/_CP14/Magic/Effects/damage.yml
Normal file
9
Resources/Prototypes/_CP14/Magic/Effects/damage.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
- type: CPMagicEffect
|
||||
id: CPDamageGibber
|
||||
complexity: 100
|
||||
components:
|
||||
- type: CPCastEffectDamage
|
||||
damage:
|
||||
types:
|
||||
Blunt: 20000
|
||||
ignoreResistances: true
|
||||
9
Resources/Prototypes/_CP14/Magic/Effects/light.yml
Normal file
9
Resources/Prototypes/_CP14/Magic/Effects/light.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
- type: CPMagicEffect
|
||||
id: CPPointLight
|
||||
complexity: 0.5
|
||||
castTime: 5
|
||||
components:
|
||||
- type: PointLight
|
||||
radius: 10
|
||||
energy: 10
|
||||
color: "#ffffff"
|
||||
14
Resources/Prototypes/_CP14/Magic/base.yml
Normal file
14
Resources/Prototypes/_CP14/Magic/base.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: CPBSpellItemEntity
|
||||
name: spell
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: Unremoveable
|
||||
- type: TimedDespawn
|
||||
lifetime: 5
|
||||
|
||||
- type: entity
|
||||
id: CPBaseSpellEntity
|
||||
name: magic entity
|
||||
noSpawn: true
|
||||
12
Resources/Prototypes/_CP14/Magic/charms.yml
Normal file
12
Resources/Prototypes/_CP14/Magic/charms.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: CPBaseMagicCharm
|
||||
name: charm
|
||||
description: The simplest storage for your spell
|
||||
components:
|
||||
- type: DoAfter
|
||||
- type: CPMagicSpellContainer
|
||||
maximumCompleteness: 999
|
||||
effects:
|
||||
- CPPointLight
|
||||
- CPDamageGibber
|
||||
Reference in New Issue
Block a user