diff --git a/Content.Server/_CP14/MagicSpell/CP14AreaEntityEffectComponent.cs b/Content.Server/_CP14/MagicSpell/CP14AreaEntityEffectComponent.cs new file mode 100644 index 0000000000..0e5959d85d --- /dev/null +++ b/Content.Server/_CP14/MagicSpell/CP14AreaEntityEffectComponent.cs @@ -0,0 +1,27 @@ +using Content.Shared._CP14.MagicSpell.Spells; +using Content.Shared.Whitelist; +using Robust.Shared.Prototypes; + +namespace Content.Server._CP14.MagicSpell; + +/// +/// +/// +[RegisterComponent] +public sealed partial class CP14AreaEntityEffectComponent : Component +{ + [DataField(required: true)] + public float Range = 1f; + + /// + /// How many entities can be subject to EntityEffect? Leave 0 to remove the restriction. + /// + [DataField] + public int MaxTargets = 0; + + [DataField(required: true, serverOnly: true)] + public List Effects = new(); + + [DataField] + public EntityWhitelist? Whitelist; +} diff --git a/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs b/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs index 6bbda67805..c8a451b35f 100644 --- a/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs +++ b/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs @@ -4,6 +4,9 @@ using Content.Shared._CP14.MagicEnergy.Components; using Content.Shared._CP14.MagicSpell; using Content.Shared._CP14.MagicSpell.Components; using Content.Shared._CP14.MagicSpell.Events; +using Content.Shared._CP14.MagicSpell.Spells; +using Content.Shared.EntityEffects; +using Content.Shared.Whitelist; using Robust.Server.GameObjects; namespace Content.Server._CP14.MagicSpell; @@ -13,11 +16,14 @@ public sealed partial class CP14MagicSystem : CP14SharedMagicSystem [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly TransformSystem _transform = default!; [Dependency] private readonly CP14MagicEnergySystem _magicEnergy = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnAoEMapInit); SubscribeLocalEvent(OnSpellSpoken); SubscribeLocalEvent(OnSpawnMagicVisualEffect); @@ -26,6 +32,28 @@ public sealed partial class CP14MagicSystem : CP14SharedMagicSystem SubscribeLocalEvent(OnManaConsume); } + private void OnAoEMapInit(Entity ent, ref MapInitEvent args) + { + var entitiesAround = _lookup.GetEntitiesInRange(ent, ent.Comp.Range, LookupFlags.Uncontained); + + var count = 0; + foreach (var entity in entitiesAround) + { + if (ent.Comp.Whitelist is not null && !_whitelist.IsValid(ent.Comp.Whitelist, entity)) + continue; + + foreach (var effect in ent.Comp.Effects) + { + effect.Effect(EntityManager, new CP14SpellEffectBaseArgs(ent, null, entity, Transform(entity).Coordinates)); + } + + count++; + + if (ent.Comp.MaxTargets > 0 && count >= ent.Comp.MaxTargets) + break; + } + } + private void OnSpellSpoken(Entity ent, ref CP14VerbalAspectSpeechEvent args) { if (args.Performer is not null && args.Speech is not null) diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.DelayedActions.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.DelayedActions.cs index 5d2339fe8b..3ca6d055a3 100644 --- a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.DelayedActions.cs +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.DelayedActions.cs @@ -56,7 +56,7 @@ public abstract partial class CP14SharedMagicSystem _action.CP14StartCustomDelay(action, TimeSpan.FromSeconds(cooldown.Value)); } - private void UseDelayedAction(ICP14DelayedMagicEffect delayedEffect, Entity action, DoAfterEvent doAfter, EntityUid performer) + private void UseDelayedAction(ICP14DelayedMagicEffect delayedEffect, Entity action, DoAfterEvent doAfter, EntityUid performer, EntityUid? target = null, EntityCoordinates? worldTarget = null) { if (!CanCastSpell(action, performer)) return; @@ -71,7 +71,7 @@ public abstract partial class CP14SharedMagicSystem RaiseLocalEvent(action, ref evStart); var spellArgs = - new CP14SpellEffectBaseArgs(performer, action.Comp.SpellStorage, performer, Transform(performer).Coordinates); + new CP14SpellEffectBaseArgs(performer, action.Comp.SpellStorage, target, worldTarget); CastTelegraphy(action, spellArgs); } @@ -93,7 +93,7 @@ public abstract partial class CP14SharedMagicSystem return; var doAfter = new CP14DelayedInstantActionDoAfterEvent(args.Cooldown); - UseDelayedAction(delayedEffect, (args.Action, magicEffect), doAfter, args.Performer); + UseDelayedAction(delayedEffect, (args.Action, magicEffect), doAfter, args.Performer, args.Performer); args.Handled = true; } @@ -116,7 +116,7 @@ public abstract partial class CP14SharedMagicSystem EntityManager.GetNetCoordinates(args.Coords), EntityManager.GetNetEntity(args.Entity), args.Cooldown); - UseDelayedAction(delayedEffect, (args.Action, magicEffect), doAfter, args.Performer); + UseDelayedAction(delayedEffect, (args.Action, magicEffect), doAfter, args.Performer, args.Entity, args.Coords); args.Handled = true; } @@ -136,7 +136,7 @@ public abstract partial class CP14SharedMagicSystem return; var doAfter = new CP14DelayedEntityTargetActionDoAfterEvent(EntityManager.GetNetEntity(args.Target), args.Cooldown); - UseDelayedAction(delayedEffect, (args.Action, magicEffect), doAfter, args.Performer); + UseDelayedAction(delayedEffect, (args.Action, magicEffect), doAfter, args.Performer, args.Target); args.Handled = true; } diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T1_fire_rune.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T1_fire_rune.yml new file mode 100644 index 0000000000..57c69314f6 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T1_fire_rune.yml @@ -0,0 +1,94 @@ +- type: entity + id: CP14ActionSpellFireRune + name: Fire rune + description: You create an area where a scalding stream of fire occurs with little delay. + components: + - type: Sprite + sprite: _CP14/Effects/Magic/spells_icons.rsi + state: earth_wall + - type: CP14MagicEffectCastSlowdown + speedMultiplier: 0.5 + - type: CP14MagicEffectManaCost + manaCost: 15 + - type: CP14MagicEffect + magicType: Fire + telegraphyEffects: + - !type:CP14SpellSpawnEntityOnTarget + spawns: + - CP14TelegraphyFireRune + effects: + - !type:CP14SpellSpawnEntityOnTarget + spawns: + - CP14AreaEntityEffectFireRune + - type: CP14MagicEffectCastingVisual + proto: CP14RuneEarthWall + - type: EntityWorldTargetAction + range: 10 + itemIconStyle: BigAction + sound: !type:SoundPathSpecifier + path: /Audio/Magic/rumble.ogg + icon: + sprite: _CP14/Effects/Magic/spells_icons.rsi + state: earth_wall + event: !type:CP14DelayedEntityWorldTargetActionEvent + cooldown: 10 + +- type: entity + id: CP14TelegraphyFireRune + parent: CP14BaseMagicImpact + components: + - type: PointLight + color: "#eea911" + - type: TimedDespawn + lifetime: 0.8 + - type: Sprite + noRot: true + drawdepth: BelowFloor + sprite: _CP14/Effects/Magic/area_impact.rsi + layers: + - state: area_impact_in + color: "#eea911" + scale: 2, 2 + shader: unshaded + +- type: entity + id: CP14AreaEntityEffectFireRune + parent: CP14BaseMagicImpact + components: + - type: PointLight + color: "#eea911" + - type: Sprite + noRot: true + drawdepth: BelowFloor + sprite: _CP14/Effects/Magic/area_impact.rsi + layers: + - state: area_impact_out + color: "#eea911" + scale: 2, 2 + shader: unshaded + - type: TimedDespawn + lifetime: 0.8 + - type: CP14AreaEntityEffect + range: 1 + whitelist: + components: + - Damageable + effects: + - !type:CP14SpellSpawnEntityOnTarget + spawns: + - CP14ImpactEffectTieflingRevenge + - !type:CP14SpellApplyEntityEffect + effects: + - !type:HealthChange + damage: + types: + Heat: 10 + +- type: entity + parent: CP14BaseSpellScrollFire + id: CP14SpellScrollFireRune + name: fire rune spell scroll + components: + - type: CP14SpellStorage + spells: + - CP14ActionSpellFireRune \ No newline at end of file diff --git a/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/area_impact_in.png b/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/area_impact_in.png new file mode 100644 index 0000000000..3773311ddd Binary files /dev/null and b/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/area_impact_in.png differ diff --git a/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/area_impact_out.png b/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/area_impact_out.png new file mode 100644 index 0000000000..f707361eaf Binary files /dev/null and b/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/area_impact_out.png differ diff --git a/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/meta.json b/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/meta.json new file mode 100644 index 0000000000..948de02946 --- /dev/null +++ b/Resources/Textures/_CP14/Effects/Magic/area_impact.rsi/meta.json @@ -0,0 +1,37 @@ +{ + "version": 1, + "size": { + "x": 64, + "y": 64 + }, + "license": "CLA", + "copyright": "Created by TheShuEd", + "states": [ + { + "name": "area_impact_in", + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 1.1 + ] + ] + }, + { + "name": "area_impact_out", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 1.1 + ] + ] + } + ] +}