From ebac4a2eec17cb059026e85eb8564ae5b9c8cc0a Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:04:49 +0300 Subject: [PATCH] Spellcasting upgrade (#543) * move to gurps magic types * spell traits, categorize spells * Update TraitSystem.cs * magic spells item provider * Update twoHandedStaffs.yml * Update CP14MagicManacostModifySystem.cs * Update CP14SpellStorageSystem.cs * some funny shit * fix problems 1 * FIX * more funny broken shit * predict slowdown, fixes funny * EntityTarget action * fixes * Update T1_sphere_of_light.yml * fix demiplan loot centering * predict movement! --- .../_CP14/MagicSpell/CP14ClientMagicSystem.cs | 7 + .../DungeonJob/DungeonJob.OreDunGen.cs | 10 +- .../_CP14/MagicSpell/CP14MagicSystem.cs | 43 +-- Content.Shared/Actions/SharedActionsSystem.cs | 12 + .../CP14MagicManacostModifySystem.cs | 2 +- .../CP14SharedMagicSystem.Actions.cs | 198 ++++++++++++ .../CP14SharedMagicSystem.Aspects.cs | 68 ++++ .../CP14SharedMagicSystem.Slowdown.cs | 39 +++ .../_CP14/MagicSpell/CP14SharedMagicSystem.cs | 298 +++++------------- .../CP14MagicCasterSlowdownComponent.cs | 2 +- .../Events/CP14CastMagicEffectEvent.cs | 98 +++--- .../Events/CP14DelayedActionEvents.cs | 87 ++++- .../Events/CP14IDelayedMagicEffect.cs | 9 +- .../Actions/Spells/Earth/T1_earth_wall.yml | 5 +- .../Actions/Spells/Fire/T0_flame_creation.yml | 3 +- .../Actions/Spells/Fire/T1_fireball.yml | 6 +- .../Actions/Spells/Gate/T2_shadow_step.yml | 5 +- .../Actions/Spells/Healing/T1_cure_wounds.yml | 10 +- .../Spells/LightDarkness/T1_flash_light.yml | 4 +- .../LightDarkness/T1_sphere_of_light.yml | 4 +- .../Actions/Spells/Meta/T0_mana_gift.yml | 8 +- .../Spells/Movement/T1_shadow_grab.yml | 13 +- .../Actions/Spells/Water/T1_ice_dagger.yml | 4 +- .../Actions/Spells/Water/T1_ice_shards.yml | 6 +- .../_CP14/Entities/Clothing/Rings/ring.yml | 20 -- .../_CP14/Entities/Mobs/NPC/monster.yml | 1 - .../Objects/Weapons/Magic/twoHandedStaffs.yml | 4 +- .../Demiplane/Locations/t1_grass_geode.yml | 17 + .../Procedural/Demiplane/Modifiers/test.yml | 127 ++++---- .../Procedural/Demiplane/required_layers.yml | 22 +- 30 files changed, 681 insertions(+), 451 deletions(-) create mode 100644 Content.Client/_CP14/MagicSpell/CP14ClientMagicSystem.cs create mode 100644 Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Actions.cs create mode 100644 Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Aspects.cs create mode 100644 Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Slowdown.cs diff --git a/Content.Client/_CP14/MagicSpell/CP14ClientMagicSystem.cs b/Content.Client/_CP14/MagicSpell/CP14ClientMagicSystem.cs new file mode 100644 index 0000000000..77f15ea0b0 --- /dev/null +++ b/Content.Client/_CP14/MagicSpell/CP14ClientMagicSystem.cs @@ -0,0 +1,7 @@ +using Content.Shared._CP14.MagicSpell; + +namespace Content.Client._CP14.MagicSpell; + +public sealed partial class CP14ClientMagicSystem : CP14SharedMagicSystem +{ +} diff --git a/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs b/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs index 0f08766c6d..2613c863e2 100644 --- a/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs +++ b/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs @@ -34,10 +34,6 @@ public sealed partial class DungeonJob { if (!gen.TileMask.Contains(((ContentTileDefinition) _tileDefManager[tileRef.Value.Tile.TypeId]).ID)) continue; - - //If entity mask null - we ignore the tiles that have anything on them. - if (gen.EntityMask is null && !_anchorable.TileFree(_grid, tile, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask)) - continue; } //Entity mask filtering @@ -62,6 +58,12 @@ public sealed partial class DungeonJob if (!found) continue; } + else + { + //If entity mask null - we ignore the tiles that have anything on them. + if (!_anchorable.TileFree(_grid, tile, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask)) + continue; + } // Add it to valid nodes. availableTiles.Add(tile); diff --git a/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs b/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs index 40629cb62a..8ae8a9f216 100644 --- a/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs +++ b/Content.Server/_CP14/MagicSpell/CP14MagicSystem.cs @@ -2,7 +2,6 @@ using Content.Server.Chat.Systems; using Content.Shared._CP14.MagicSpell; using Content.Shared._CP14.MagicSpell.Components; using Content.Shared._CP14.MagicSpell.Events; -using Content.Shared.Movement.Systems; using Robust.Server.GameObjects; namespace Content.Server._CP14.MagicSpell; @@ -11,49 +10,15 @@ public sealed partial class CP14MagicSystem : CP14SharedMagicSystem { [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly TransformSystem _transform = default!; - [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; public override void Initialize() { + base.Initialize(); + SubscribeLocalEvent(OnSpellSpoken); SubscribeLocalEvent(OnSpawnMagicVisualEffect); SubscribeLocalEvent(OnDespawnMagicVisualEffect); - - SubscribeLocalEvent(OnSlowdownCaster); - SubscribeLocalEvent(OnUnslowdownCaster); - SubscribeLocalEvent(OnCasterRefreshMovespeed); - } - - private void OnSlowdownCaster(Entity ent, ref CP14StartCastMagicEffectEvent args) - { - if (!TryComp(args.Caster, out var caster)) - return; - - caster.SpeedModifiers.Add(ent.Comp.SpeedMultiplier); - _movement.RefreshMovementSpeedModifiers(args.Caster); - } - - private void OnUnslowdownCaster(Entity ent, ref CP14EndCastMagicEffectEvent args) - { - if (!TryComp(args.Caster, out var caster)) - return; - - if (caster.SpeedModifiers.Contains(ent.Comp.SpeedMultiplier)) - caster.SpeedModifiers.Remove(ent.Comp.SpeedMultiplier); - - _movement.RefreshMovementSpeedModifiers(args.Caster); - } - - private void OnCasterRefreshMovespeed(Entity ent, ref RefreshMovementSpeedModifiersEvent args) - { - var result = 1f; - foreach (var modifier in ent.Comp.SpeedModifiers) - { - result += modifier; - } - - args.ModifySpeed(result); } private void OnSpellSpoken(Entity ent, ref CP14VerbalAspectSpeechEvent args) @@ -64,8 +29,8 @@ public sealed partial class CP14MagicSystem : CP14SharedMagicSystem private void OnSpawnMagicVisualEffect(Entity ent, ref CP14StartCastMagicEffectEvent args) { - var vfx = SpawnAttachedTo(ent.Comp.Proto, Transform(args.Caster).Coordinates); - _transform.SetParent(vfx, args.Caster); + var vfx = SpawnAttachedTo(ent.Comp.Proto, Transform(args.Performer).Coordinates); + _transform.SetParent(vfx, args.Performer); ent.Comp.SpawnedEntity = vfx; } diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index 76b8a1b081..8945547b37 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -247,6 +247,18 @@ public abstract class SharedActionsSystem : EntitySystem Dirty(actionId.Value, action); } + public void CP14StartCustomDelay(EntityUid? actionId, TimeSpan delay) + { + if (actionId == null) + return; + + if (!TryGetActionData(actionId, out var action)) + return; + + action.Cooldown = (GameTiming.CurTime, GameTiming.CurTime + delay); + Dirty(actionId.Value, action); + } + public void SetUseDelay(EntityUid? actionId, TimeSpan? delay) { if (!TryGetActionData(actionId, out var action) || action.UseDelay == delay) diff --git a/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifySystem.cs b/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifySystem.cs index b0398d586b..bae9d9d8e0 100644 --- a/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifySystem.cs +++ b/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifySystem.cs @@ -72,7 +72,7 @@ public sealed partial class CP14MagicManacostModifySystem : EntitySystem private void OnCalculateManacost(Entity ent, ref CP14CalculateManacostEvent args) { - args.Multiplier += (float)ent.Comp.GlobalModifier; + args.Multiplier *= (float)ent.Comp.GlobalModifier; if (args.MagicType is not null && ent.Comp.Modifiers.TryGetValue(args.MagicType.Value, out var modifier)) { diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Actions.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Actions.cs new file mode 100644 index 0000000000..cb2407f0a1 --- /dev/null +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Actions.cs @@ -0,0 +1,198 @@ +using Content.Shared._CP14.MagicSpell.Components; +using Content.Shared._CP14.MagicSpell.Events; +using Content.Shared._CP14.MagicSpell.Spells; +using Robust.Shared.Map; + +namespace Content.Shared._CP14.MagicSpell; + +public abstract partial class CP14SharedMagicSystem +{ + private void InitializeActions() + { + SubscribeLocalEvent(OnInstantAction); + SubscribeLocalEvent(OnEntityWorldTargetAction); + SubscribeLocalEvent(OnEntityTargetAction); + + SubscribeLocalEvent(OnDelayedInstantActionDoAfter); + SubscribeLocalEvent(OnDelayedEntityWorldTargetDoAfter); + SubscribeLocalEvent(OnDelayedEntityTargetDoAfter); + } + + /// + /// Instant action used from hotkey event + /// + private void OnInstantAction(CP14DelayedInstantActionEvent args) + { + if (args.Handled) + return; + + if (args is not ICP14DelayedMagicEffect delayedEffect) + return; + + if (!CanCastSpell(args.Action, args.Performer)) + return; + + if (!TryComp(args.Action, out var magicEffect)) + return; + + if (args.CastDelay > 0) + { + var doAfter = new CP14DelayedInstantActionDoAfterEvent(args.Cooldown); + if (!TryCastSpellDelayed(delayedEffect, doAfter, args.Action, args.Performer)) + return; + } + + var evStart = new CP14StartCastMagicEffectEvent( args.Performer); + RaiseLocalEvent(args.Action, ref evStart); + + var spellArgs = + new CP14SpellEffectBaseArgs(args.Performer, args.Performer, Transform(args.Performer).Coordinates); + + CastTelegraphy((args.Action, magicEffect), spellArgs); + + if (args.CastDelay == 0) + CastSpell((args.Action, magicEffect), spellArgs, args.Cooldown); + + args.Handled = true; + } + + /// + /// Target action used from hotkey event + /// + private void OnEntityWorldTargetAction(CP14DelayedEntityWorldTargetActionEvent args) + { + if (args.Handled) + return; + + if (args is not ICP14DelayedMagicEffect delayedEffect) + return; + + if (!CanCastSpell(args.Action, args.Performer)) + return; + + if (!TryComp(args.Action, out var magicEffect)) + return; + + if (args.CastDelay > 0) + { + var doAfter = new CP14DelayedEntityWorldTargetActionDoAfterEvent( + EntityManager.GetNetCoordinates(args.Coords), + EntityManager.GetNetEntity(args.Entity), + args.Cooldown); + + if (!TryCastSpellDelayed(delayedEffect, doAfter, args.Action, args.Performer)) + return; + } + + var evStart = new CP14StartCastMagicEffectEvent( args.Performer); + RaiseLocalEvent(args.Action, ref evStart); + + var spellArgs = + new CP14SpellEffectBaseArgs(args.Performer, args.Entity, args.Coords); + + CastTelegraphy((args.Action, magicEffect), spellArgs); + + if (args.CastDelay <= 0) + CastSpell((args.Action, magicEffect), spellArgs, args.Cooldown); + + args.Handled = true; + } + + /// + /// Target action used from hotkey event + /// + private void OnEntityTargetAction(CP14DelayedEntityTargetActionEvent args) + { + if (args.Handled) + return; + + if (args is not ICP14DelayedMagicEffect delayedEffect) + return; + + if (!CanCastSpell(args.Action, args.Performer)) + return; + + if (!TryComp(args.Action, out var magicEffect)) + return; + + if (args.CastDelay > 0) + { + var doAfter = new CP14DelayedEntityTargetActionDoAfterEvent( + EntityManager.GetNetEntity(args.Target), + args.Cooldown); + + if (!TryCastSpellDelayed(delayedEffect, doAfter, args.Action, args.Performer)) + return; + } + + var evStart = new CP14StartCastMagicEffectEvent( args.Performer); + RaiseLocalEvent(args.Action, ref evStart); + + var spellArgs = + new CP14SpellEffectBaseArgs(args.Performer, args.Target, Transform(args.Target).Coordinates); + + CastTelegraphy((args.Action, magicEffect), spellArgs); + + //TODO: Bug! If CastDelay = 0, cooldown dont want apply to spell aftercast + if (args.CastDelay <= 0) + CastSpell((args.Action, magicEffect), spellArgs, args.Cooldown); + + args.Handled = true; + } + + /// + /// Action doAfter finished or interrupted + /// + private void OnDelayedInstantActionDoAfter(Entity ent, ref CP14DelayedInstantActionDoAfterEvent args) + { + var endEv = new CP14EndCastMagicEffectEvent(args.User); + RaiseLocalEvent(ent, ref endEv); + + if (args.Cancelled || args.Handled) + return; + + CastSpell(ent, new CP14SpellEffectBaseArgs(args.User, args.User, Transform(args.User).Coordinates), args.Cooldown ?? 0); + + args.Handled = true; + } + + /// + /// Action doAfter finished or interrupted + /// + private void OnDelayedEntityWorldTargetDoAfter(Entity ent, + ref CP14DelayedEntityWorldTargetActionDoAfterEvent args) + { + var endEv = new CP14EndCastMagicEffectEvent(args.User); + RaiseLocalEvent(ent, ref endEv); + + if (args.Cancelled || args.Handled) + return; + + var targetPos = EntityManager.GetCoordinates(args.TargetPosition); + EntityManager.TryGetEntity(args.TargetEntity, out var targetEnt); + + CastSpell(ent, new CP14SpellEffectBaseArgs(args.User, targetEnt, targetPos), args.Cooldown ?? 0); + + args.Handled = true; + } + + /// + /// Action doAfter finished or interrupted + /// + private void OnDelayedEntityTargetDoAfter(Entity ent, ref CP14DelayedEntityTargetActionDoAfterEvent args) + { + var endEv = new CP14EndCastMagicEffectEvent(args.User); + RaiseLocalEvent(ent, ref endEv); + + if (args.Cancelled || args.Handled) + return; + + EntityManager.TryGetEntity(args.TargetEntity, out var targetEnt); + EntityCoordinates? targetPos = null; + if (targetEnt is not null) { targetPos = Transform(targetEnt.Value).Coordinates; } + + CastSpell(ent, new CP14SpellEffectBaseArgs(args.User, targetEnt, targetPos), args.Cooldown ?? 0); + + args.Handled = true; + } +} diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Aspects.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Aspects.cs new file mode 100644 index 0000000000..c1cd5cb9b4 --- /dev/null +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Aspects.cs @@ -0,0 +1,68 @@ +using Content.Shared._CP14.MagicSpell.Components; +using Content.Shared._CP14.MagicSpell.Events; +using Content.Shared.Hands.Components; +using Content.Shared.Speech.Muting; + +namespace Content.Shared._CP14.MagicSpell; + +public abstract partial class CP14SharedMagicSystem +{ + private void InitializeAspects() + { + SubscribeLocalEvent(OnSomaticAspectBeforeCast); + + SubscribeLocalEvent(OnVerbalAspectBeforeCast); + SubscribeLocalEvent(OnVerbalAspectStartCast); + SubscribeLocalEvent(OnVerbalAspectAfterCast); + } + + private void OnSomaticAspectBeforeCast(Entity ent, ref CP14CastMagicEffectAttemptEvent args) + { + if (TryComp(args.Performer, out var hands) || hands is not null) + { + var freeHand = 0; + foreach (var hand in hands.Hands) + { + if (hand.Value.IsEmpty) + freeHand++; + } + if (freeHand >= ent.Comp.FreeHandRequired) + return; + } + args.PushReason(Loc.GetString("cp14-magic-spell-need-somatic-component")); + args.Cancel(); + } + + private void OnVerbalAspectBeforeCast(Entity ent, ref CP14CastMagicEffectAttemptEvent args) + { + if (HasComp(args.Performer)) + { + args.PushReason(Loc.GetString("cp14-magic-spell-need-verbal-component")); + args.Cancel(); + } + } + + private void OnVerbalAspectStartCast(Entity ent, ref CP14StartCastMagicEffectEvent args) + { + var ev = new CP14VerbalAspectSpeechEvent + { + Performer = args.Performer, + Speech = ent.Comp.StartSpeech, + }; + RaiseLocalEvent(ent, ref ev); + } + + private void OnVerbalAspectAfterCast(Entity ent, ref CP14AfterCastMagicEffectEvent args) + { + if (_net.IsClient) + return; + + var ev = new CP14VerbalAspectSpeechEvent + { + Performer = args.Performer, + Speech = ent.Comp.EndSpeech, + }; + RaiseLocalEvent(ent, ref ev); + } + +} diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Slowdown.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Slowdown.cs new file mode 100644 index 0000000000..3570ab66c1 --- /dev/null +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Slowdown.cs @@ -0,0 +1,39 @@ +using Content.Shared._CP14.MagicSpell.Components; +using Content.Shared._CP14.MagicSpell.Events; +using Content.Shared.Movement.Systems; + +namespace Content.Shared._CP14.MagicSpell; + +public abstract partial class CP14SharedMagicSystem +{ + private void InitializeSlowdown() + { + SubscribeLocalEvent(OnSlowdownCaster); + SubscribeLocalEvent(OnUnslowdownCaster); + SubscribeLocalEvent(OnCasterRefreshMovespeed); + } + + private void OnSlowdownCaster(Entity ent, ref CP14StartCastMagicEffectEvent args) + { + if (!TryComp(args.Performer, out var caster)) + return; + + caster.SpeedModifier = ent.Comp.SpeedMultiplier; + _movement.RefreshMovementSpeedModifiers(args.Performer); + } + + private void OnUnslowdownCaster(Entity ent, ref CP14EndCastMagicEffectEvent args) + { + if (!TryComp(args.Performer, out var caster)) + return; + + caster.SpeedModifier = 1f; + + _movement.RefreshMovementSpeedModifiers(args.Performer); + } + + private void OnCasterRefreshMovespeed(Entity ent, ref RefreshMovementSpeedModifiersEvent args) + { + args.ModifySpeed(ent.Comp.SpeedModifier); + } +} diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs index 35d3ddeb56..92df201a6a 100644 --- a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs @@ -5,11 +5,11 @@ using Content.Shared._CP14.MagicSpell.Components; using Content.Shared._CP14.MagicSpell.Events; using Content.Shared._CP14.MagicSpell.Spells; using Content.Shared._CP14.MagicSpellStorage; +using Content.Shared.Actions; using Content.Shared.DoAfter; using Content.Shared.FixedPoint; -using Content.Shared.Hands.Components; +using Content.Shared.Movement.Systems; using Content.Shared.Popups; -using Content.Shared.Speech.Muting; using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -19,7 +19,7 @@ namespace Content.Shared._CP14.MagicSpell; /// /// This system handles the basic mechanics of spell use, such as doAfter, event invocation, and energy spending. /// -public partial class CP14SharedMagicSystem : EntitySystem +public abstract partial class CP14SharedMagicSystem : EntitySystem { [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly INetManager _net = default!; @@ -28,28 +28,25 @@ public partial class CP14SharedMagicSystem : EntitySystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly MetaDataSystem _meta = default!; + [Dependency] private readonly SharedActionsSystem _action = default!; + [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; public override void Initialize() { base.Initialize(); + InitializeActions(); + InitializeAspects(); + InitializeSlowdown(); SubscribeLocalEvent(OnMagicEffectInit); - SubscribeLocalEvent(OnBeforeCastMagicEffect); - - SubscribeLocalEvent(OnInstantAction); - SubscribeLocalEvent(OnEntityWorldTargetAction); - - SubscribeLocalEvent(OnDelayedInstantActionDoAfter); - SubscribeLocalEvent(OnDelayedEntityWorldTargetDoAfter); - - SubscribeLocalEvent(OnSomaticAspectBeforeCast); - - SubscribeLocalEvent(OnVerbalAspectBeforeCast); - SubscribeLocalEvent(OnVerbalAspectAfterCast); + SubscribeLocalEvent(OnBeforeCastMagicEffect); SubscribeLocalEvent(OnAfterCastMagicEffect); } + /// + /// Auto generation description for spell action + /// private void OnMagicEffectInit(Entity ent, ref MapInitEvent args) { var meta = MetaData(ent); @@ -76,219 +73,96 @@ public partial class CP14SharedMagicSystem : EntitySystem _meta.SetEntityDescription(ent, sb.ToString()); } - private void OnBeforeCastMagicEffect(Entity ent, ref CP14BeforeCastMagicEffectEvent args) + /// + /// Checking to see if the spell can be used at all + /// + private bool CanCastSpell(EntityUid spell, EntityUid performer) { - if (!TryComp(args.Caster, out var magicContainer)) - { - args.Cancel(); - return; - } - - var manaCost = CalculateManacost(ent, args.Caster); - - if (!_magicEnergy.HasEnergy(args.Caster, manaCost, magicContainer, ent.Comp.Safe)) - { - args.PushReason(Loc.GetString("cp14-magic-spell-not-enough-mana")); - args.Cancel(); - } - else if(!_magicEnergy.HasEnergy(args.Caster, manaCost, magicContainer, true) && _net.IsServer) - { - _popup.PopupEntity(Loc.GetString("cp14-magic-spell-not-enough-mana-cast-warning-"+_random.Next(5)), args.Caster, args.Caster, PopupType.SmallCaution); - } - } - - private void OnInstantAction(CP14DelayedInstantActionEvent args) - { - if (args.Handled) - return; - - args.Handled = true; - - if (args is not ICP14DelayedMagicEffect delayedEffect) - return; - - if (!TryCastSpell(args.Action, args.Performer)) - return; - - var doAfterEventArgs = new DoAfterArgs(EntityManager, args.Performer, delayedEffect.Delay, new CP14DelayedInstantActionDoAfterEvent(), args.Action) - { - BreakOnMove = delayedEffect.BreakOnMove, - BreakOnDamage = delayedEffect.BreakOnDamage, - Hidden = delayedEffect.Hidden, - BlockDuplicate = true, - DistanceThreshold = 100f, - }; - - _doAfter.TryStartDoAfter(doAfterEventArgs); - - //Telegraphy effects - if (_net.IsServer && TryComp(args.Action, out var magicEffect)) - { - foreach (var effect in magicEffect.TelegraphyEffects) - { - effect.Effect(EntityManager, new CP14SpellEffectBaseArgs(args.Performer, args.Performer, Transform(args.Performer).Coordinates)); - } - } - } - - private void OnEntityWorldTargetAction(CP14DelayedEntityWorldTargetActionEvent args) - { - if (args.Handled) - return; - - args.Handled = true; - - if (args is not ICP14DelayedMagicEffect delayedEffect) - return; - - if (!TryCastSpell(args.Action, args.Performer)) - return; - - var doAfter = new CP14DelayedEntityWorldTargetActionDoAfterEvent( - EntityManager.GetNetCoordinates(args.Coords), - EntityManager.GetNetEntity(args.Entity)); - - var doAfterEventArgs = new DoAfterArgs(EntityManager, args.Performer, delayedEffect.Delay, doAfter, args.Action) - { - BreakOnMove = delayedEffect.BreakOnMove, - BreakOnDamage = delayedEffect.BreakOnDamage, - Hidden = delayedEffect.Hidden, - BlockDuplicate = true, - DistanceThreshold = 100f - }; - - _doAfter.TryStartDoAfter(doAfterEventArgs); - - //Telegraphy effects - if (_net.IsServer && TryComp(args.Action, out var magicEffect)) - { - foreach (var effect in magicEffect.TelegraphyEffects) - { - effect.Effect(EntityManager, new CP14SpellEffectBaseArgs(args.Performer, args.Entity, args.Coords)); - } - } - } - - private void OnDelayedEntityWorldTargetDoAfter(Entity ent, - ref CP14DelayedEntityWorldTargetActionDoAfterEvent args) - { - var endEv = new CP14EndCastMagicEffectEvent(args.User); - RaiseLocalEvent(ent, ref endEv); - - if (args.Cancelled || !_net.IsServer) - return; - - var targetPos = EntityManager.GetCoordinates(args.TargetPosition); - EntityUid? targetEnt; - EntityManager.TryGetEntity(args.TargetEntity, out targetEnt); - - var effectArgs = new CP14SpellEffectBaseArgs(args.User, targetEnt, targetPos); - - foreach (var effect in ent.Comp.Effects) - { - effect.Effect(EntityManager, effectArgs); - } - - var ev = new CP14AfterCastMagicEffectEvent(args.User); - RaiseLocalEvent(ent, ref ev); - } - - private void OnDelayedInstantActionDoAfter(Entity ent, ref CP14DelayedInstantActionDoAfterEvent args) - { - var endEv = new CP14EndCastMagicEffectEvent(args.User); - RaiseLocalEvent(ent, ref endEv); - - 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(args.User); - RaiseLocalEvent(ent, ref ev); - } - - private void OnSomaticAspectBeforeCast(Entity ent, ref CP14BeforeCastMagicEffectEvent args) - { - if (TryComp(args.Caster, out var hands) || hands is not null) - { - var freeHand = 0; - foreach (var hand in hands.Hands) - { - if (hand.Value.IsEmpty) - freeHand++; - } - if (freeHand >= ent.Comp.FreeHandRequired) - return; - } - args.PushReason(Loc.GetString("cp14-magic-spell-need-somatic-component")); - args.Cancel(); - } - - private void OnVerbalAspectBeforeCast(Entity ent, ref CP14BeforeCastMagicEffectEvent args) - { - if (HasComp(args.Caster)) - { - args.PushReason(Loc.GetString("cp14-magic-spell-need-verbal-component")); - args.Cancel(); - } - else - { - if (!args.Cancelled) - { - var ev = new CP14VerbalAspectSpeechEvent - { - Performer = args.Caster, - Speech = ent.Comp.StartSpeech, - }; - RaiseLocalEvent(ent, ref ev); - } - } - } - - private void OnVerbalAspectAfterCast(Entity ent, ref CP14AfterCastMagicEffectEvent args) - { - if (_net.IsClient) - return; - - var ev = new CP14VerbalAspectSpeechEvent - { - Performer = args.Caster, - Speech = ent.Comp.EndSpeech, - }; - RaiseLocalEvent(ent, ref ev); - } - - private bool TryCastSpell(EntityUid spell, EntityUid performer) - { - var ev = new CP14BeforeCastMagicEffectEvent(performer); + var ev = new CP14CastMagicEffectAttemptEvent(performer); RaiseLocalEvent(spell, ref ev); if (ev.Reason != string.Empty && _net.IsServer) { _popup.PopupEntity(ev.Reason, performer, performer); } - - if (!ev.Cancelled) - { - var evStart = new CP14StartCastMagicEffectEvent(performer); - RaiseLocalEvent(spell, ref evStart); - } return !ev.Cancelled; } + /// + /// Before using a spell, a mana check is made for the amount of mana to show warnings. + /// + private void OnBeforeCastMagicEffect(Entity ent, ref CP14CastMagicEffectAttemptEvent args) + { + if (!TryComp(args.Performer, out var magicContainer)) + { + args.Cancel(); + return; + } + + var manaCost = CalculateManacost(ent, args.Performer); + + if (!_magicEnergy.HasEnergy(args.Performer, manaCost, magicContainer, ent.Comp.Safe)) + { + args.PushReason(Loc.GetString("cp14-magic-spell-not-enough-mana")); + args.Cancel(); + } + else if(!_magicEnergy.HasEnergy(args.Performer, manaCost, magicContainer, true) && _net.IsServer) //фу какой некрасивый | хардкод + { // \/ + _popup.PopupEntity(Loc.GetString("cp14-magic-spell-not-enough-mana-cast-warning-"+_random.Next(5)), args.Performer, args.Performer, PopupType.SmallCaution); + } + } + + private void CastTelegraphy(Entity ent, CP14SpellEffectBaseArgs args) + { + if (!_net.IsServer) + return; + + foreach (var effect in ent.Comp.TelegraphyEffects) + { + effect.Effect(EntityManager, args); + } + } + + private bool TryCastSpellDelayed(ICP14DelayedMagicEffect delayedEffect, DoAfterEvent doAfter, EntityUid action, EntityUid performer) + { + var doAfterEventArgs = new DoAfterArgs(EntityManager, performer, delayedEffect.CastDelay, doAfter, action) + { + BreakOnMove = delayedEffect.BreakOnMove, + BreakOnDamage = delayedEffect.BreakOnDamage, + Hidden = delayedEffect.Hidden, + DistanceThreshold = 100f, + CancelDuplicate = true, + BlockDuplicate = true, + }; + + return _doAfter.TryStartDoAfter(doAfterEventArgs); + } + + private void CastSpell(Entity ent, CP14SpellEffectBaseArgs args, float cooldown) + { + _action.CP14StartCustomDelay(ent, TimeSpan.FromSeconds(cooldown)); + + if (_net.IsServer) + { + foreach (var effect in ent.Comp.Effects) + { + effect.Effect(EntityManager, args); + } + } + + var ev = new CP14AfterCastMagicEffectEvent(args.User); + RaiseLocalEvent(ent, ref ev); + } + private void OnAfterCastMagicEffect(Entity ent, ref CP14AfterCastMagicEffectEvent args) { if (_net.IsClient) return; - if (!HasComp(args.Caster)) + if (!HasComp(args.Performer)) return; - - var manaCost = CalculateManacost(ent, args.Caster.Value); - _magicEnergy.TryConsumeEnergy(args.Caster.Value, manaCost, safe: ent.Comp.Safe); + var manaCost = CalculateManacost(ent, args.Performer.Value); + _magicEnergy.TryConsumeEnergy(args.Performer.Value, manaCost, safe: ent.Comp.Safe); } private FixedPoint2 CalculateManacost(Entity ent, EntityUid caster) diff --git a/Content.Shared/_CP14/MagicSpell/Components/CP14MagicCasterSlowdownComponent.cs b/Content.Shared/_CP14/MagicSpell/Components/CP14MagicCasterSlowdownComponent.cs index 75679cdf7b..b5e69bce57 100644 --- a/Content.Shared/_CP14/MagicSpell/Components/CP14MagicCasterSlowdownComponent.cs +++ b/Content.Shared/_CP14/MagicSpell/Components/CP14MagicCasterSlowdownComponent.cs @@ -7,5 +7,5 @@ namespace Content.Shared._CP14.MagicSpell.Components; public sealed partial class CP14MagicCasterSlowdownComponent : Component { [DataField] - public List SpeedModifiers = new(); + public float SpeedModifier = 1f; } diff --git a/Content.Shared/_CP14/MagicSpell/Events/CP14CastMagicEffectEvent.cs b/Content.Shared/_CP14/MagicSpell/Events/CP14CastMagicEffectEvent.cs index b0180fc9f7..7afaa8412d 100644 --- a/Content.Shared/_CP14/MagicSpell/Events/CP14CastMagicEffectEvent.cs +++ b/Content.Shared/_CP14/MagicSpell/Events/CP14CastMagicEffectEvent.cs @@ -5,19 +5,22 @@ using Robust.Shared.Prototypes; namespace Content.Shared._CP14.MagicSpell.Events; +/// +/// Called first to verify that all conditions are met and the spell can be performed. +/// [ByRefEvent] -public sealed class CP14BeforeCastMagicEffectEvent : CancellableEntityEventArgs +public sealed class CP14CastMagicEffectAttemptEvent : CancellableEntityEventArgs { /// /// The Performer of the event, to check if they meet the requirements. /// - public EntityUid Caster { get; init; } + public EntityUid Performer { get; init; } public string Reason = string.Empty; - public CP14BeforeCastMagicEffectEvent(EntityUid caster) + public CP14CastMagicEffectAttemptEvent(EntityUid performer) { - Caster = caster; + Performer = performer; } public void PushReason(string reason) @@ -26,56 +29,21 @@ public sealed class CP14BeforeCastMagicEffectEvent : CancellableEntityEventArgs } } -[ByRefEvent] -public sealed class CP14AfterCastMagicEffectEvent : EntityEventArgs -{ - public EntityUid? Caster { get; init; } - - public CP14AfterCastMagicEffectEvent(EntityUid caster) - { - Caster = caster; - } -} /// -/// is invoked if all conditions are met and the spell has begun to be cast +/// An event that checks all sorts of conditions, and calculates the total cost of casting a spell. Called before the spell is cast. /// -[ByRefEvent] -public sealed class CP14StartCastMagicEffectEvent : EntityEventArgs -{ - public EntityUid Caster { get; init; } - - public CP14StartCastMagicEffectEvent(EntityUid caster) - { - Caster = caster; - } -} - -/// -/// is invoked on the spell itself when the spell process has been completed or interrupted -/// -[ByRefEvent] -public sealed class CP14EndCastMagicEffectEvent : EntityEventArgs -{ - public EntityUid Caster { get; init; } - - public CP14EndCastMagicEffectEvent(EntityUid caster) - { - Caster = caster; - } -} - +/// TODO: This call is duplicated at the beginning of the cast for checks, and at the end of the cast for mana subtraction. public sealed class CP14CalculateManacostEvent : EntityEventArgs, IInventoryRelayEvent { public FixedPoint2 Manacost = 0f; - public float Multiplier = 1f; - public EntityUid Caster; + public EntityUid Performer; public ProtoId? MagicType; - public CP14CalculateManacostEvent(EntityUid caster, FixedPoint2 initialManacost, ProtoId? magicType) + public CP14CalculateManacostEvent(EntityUid performer, FixedPoint2 initialManacost, ProtoId? magicType) { - Caster = caster; + Performer = performer; Manacost = initialManacost; MagicType = magicType; } @@ -87,3 +55,45 @@ public sealed class CP14CalculateManacostEvent : EntityEventArgs, IInventoryRela public SlotFlags TargetSlots { get; } = SlotFlags.All; } + +/// +/// is invoked if all conditions are met and the spell has begun to be cast (doAfter start moment) +/// +[ByRefEvent] +public sealed class CP14StartCastMagicEffectEvent : EntityEventArgs +{ + public EntityUid Performer { get; init; } + + public CP14StartCastMagicEffectEvent(EntityUid performer) + { + Performer = performer; + } +} + +/// +/// is invoked on the spell itself when the spell process has been completed or interrupted (doAfter end moment) +/// +[ByRefEvent] +public sealed class CP14EndCastMagicEffectEvent : EntityEventArgs +{ + public EntityUid Performer { get; init; } + + public CP14EndCastMagicEffectEvent(EntityUid performer) + { + Performer = performer; + } +} + +/// +/// is invoked only if the spell has been successfully cast +/// +[ByRefEvent] +public sealed class CP14AfterCastMagicEffectEvent : EntityEventArgs +{ + public EntityUid? Performer { get; init; } + + public CP14AfterCastMagicEffectEvent(EntityUid? performer) + { + Performer = performer; + } +} diff --git a/Content.Shared/_CP14/MagicSpell/Events/CP14DelayedActionEvents.cs b/Content.Shared/_CP14/MagicSpell/Events/CP14DelayedActionEvents.cs index d96d7d7d1e..e76f94737e 100644 --- a/Content.Shared/_CP14/MagicSpell/Events/CP14DelayedActionEvents.cs +++ b/Content.Shared/_CP14/MagicSpell/Events/CP14DelayedActionEvents.cs @@ -9,7 +9,54 @@ public sealed partial class CP14DelayedEntityWorldTargetActionEvent : EntityWorl ICP14DelayedMagicEffect { [DataField] - public float Delay { get; private set; } = 1f; + public float Cooldown { get; private set; } = 1f; + + [DataField] + public float CastDelay { get; private set; } = 1f; + + [DataField] + public bool BreakOnMove { get; private set; } = true; + + [DataField] + public bool BreakOnDamage { get; private set; } = true; + + [DataField] + public bool Hidden { get; private set; } = false; + + [DataField] + public float EntityDistance { get; private set; } = 100f; +} + +//Entity Target +public sealed partial class CP14DelayedEntityTargetActionEvent : EntityTargetActionEvent, + ICP14DelayedMagicEffect +{ + [DataField] + public float Cooldown { get; private set; } = 1f; + + [DataField] + public float CastDelay { get; private set; } = 1f; + + [DataField] + public bool BreakOnMove { get; private set; } = true; + + [DataField] + public bool BreakOnDamage { get; private set; } = true; + + [DataField] + public bool Hidden { get; private set; } = false; + + [DataField] + public float EntityDistance { get; private set; } = 100f; +} + +public sealed partial class CP14DelayedInstantActionEvent : InstantActionEvent, ICP14DelayedMagicEffect +{ + [DataField] + public float Cooldown { get; private set; } = 3f; + + [DataField] + public float CastDelay { get; private set; } = 1f; [DataField] public bool BreakOnMove { get; private set; } = true; @@ -31,36 +78,46 @@ public sealed partial class CP14DelayedEntityWorldTargetActionDoAfterEvent : DoA public NetCoordinates? TargetPosition; [DataField] public NetEntity? TargetEntity; + [DataField] + public float? Cooldown; - public CP14DelayedEntityWorldTargetActionDoAfterEvent(NetCoordinates? targetPos, NetEntity? targetEntity) + public CP14DelayedEntityWorldTargetActionDoAfterEvent(NetCoordinates? targetPos, NetEntity? targetEntity, float cooldown) { TargetPosition = targetPos; TargetEntity = targetEntity; + Cooldown = cooldown; } public override DoAfterEvent Clone() => this; } -//Instant -public sealed partial class CP14DelayedInstantActionEvent : InstantActionEvent, ICP14DelayedMagicEffect +[Serializable, NetSerializable] +public sealed partial class CP14DelayedEntityTargetActionDoAfterEvent : DoAfterEvent { [DataField] - public float Delay { get; private set; } = 1f; - + public NetEntity? TargetEntity; [DataField] - public bool BreakOnMove { get; private set; } = true; + public float? Cooldown; - [DataField] - public bool BreakOnDamage { get; private set; } = true; + public CP14DelayedEntityTargetActionDoAfterEvent(NetEntity? targetEntity, float cooldown) + { + TargetEntity = targetEntity; + Cooldown = cooldown; + } - [DataField] - public bool Hidden { get; private set; } = false; - - [DataField] - public float EntityDistance { get; private set; } = 100f; + public override DoAfterEvent Clone() => this; } [Serializable, NetSerializable] -public sealed partial class CP14DelayedInstantActionDoAfterEvent : SimpleDoAfterEvent +public sealed partial class CP14DelayedInstantActionDoAfterEvent : DoAfterEvent { + [DataField] + public float? Cooldown; + + public CP14DelayedInstantActionDoAfterEvent(float cooldown) + { + Cooldown = cooldown; + } + + public override DoAfterEvent Clone() => this; } diff --git a/Content.Shared/_CP14/MagicSpell/Events/CP14IDelayedMagicEffect.cs b/Content.Shared/_CP14/MagicSpell/Events/CP14IDelayedMagicEffect.cs index bd829c84b2..983c00dd36 100644 --- a/Content.Shared/_CP14/MagicSpell/Events/CP14IDelayedMagicEffect.cs +++ b/Content.Shared/_CP14/MagicSpell/Events/CP14IDelayedMagicEffect.cs @@ -1,11 +1,10 @@ namespace Content.Shared._CP14.MagicSpell.Events; -public interface ICP14DelayedMagicEffect // The speak n spell interface +public interface ICP14DelayedMagicEffect { - /// - /// Localized string spoken by the caster when casting this spell. - /// - public float Delay { get; } + public float Cooldown { get; } + + public float CastDelay { get; } public bool BreakOnMove { get; } diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml index 4d4f9d542a..b8596d202a 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml @@ -4,7 +4,7 @@ description: Raises a solid wall of earth from the bowels. components: - type: CP14MagicEffectCastSlowdown - speedMultiplier: -0.9 + speedMultiplier: 0.3 - type: CP14MagicEffect magicType: Earth manaCost: 15 @@ -22,7 +22,6 @@ - type: CP14MagicEffectCastingVisual proto: CP14RuneEarthWall - type: EntityWorldTargetAction - useDelay: 10 range: 10 itemIconStyle: BigAction sound: !type:SoundPathSpecifier @@ -31,7 +30,7 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: earth_wall event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 1 + cooldown: 10 - type: entity id: CP14RuneEarthWall diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T0_flame_creation.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T0_flame_creation.yml index 838899ff5e..3ff9b468ee 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T0_flame_creation.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T0_flame_creation.yml @@ -20,7 +20,6 @@ - type: CP14MagicEffectCastingVisual proto: CP14RuneFlameCreation - type: InstantAction - useDelay: 10 itemIconStyle: BigAction sound: !type:SoundPathSpecifier path: /Audio/Magic/rumble.ogg @@ -28,7 +27,7 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: flame_creation event: !type:CP14DelayedInstantActionEvent - delay: 1 + cooldown: 10 breakOnMove: false - type: entity diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T1_fireball.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T1_fireball.yml index 2b1aa00def..fdbdf9eaf5 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T1_fireball.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Fire/T1_fireball.yml @@ -4,7 +4,7 @@ description: An effective method of destruction - an explosive fireball components: - type: CP14MagicEffectCastSlowdown - speedMultiplier: -0.7 + speedMultiplier: 0.3 - type: CP14MagicEffect magicType: Fire manaCost: 20 @@ -21,7 +21,6 @@ - type: CP14MagicEffectCastingVisual proto: CP14RuneFireball - type: EntityWorldTargetAction - useDelay: 20 checkCanAccess: false raiseOnUser: true range: 60 @@ -32,7 +31,8 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: fireball event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 3 + cooldown: 15 + castDelay: 5 breakOnMove: false entityDistance: 1000 diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Gate/T2_shadow_step.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Gate/T2_shadow_step.yml index 86d7205702..bfbdce9ecf 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Gate/T2_shadow_step.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Gate/T2_shadow_step.yml @@ -4,7 +4,7 @@ description: A step through the gash of reality that allows you to cover a small of distance quickly components: - type: CP14MagicEffectCastSlowdown - speedMultiplier: -0.4 + speedMultiplier: 0.8 - type: CP14MagicEffect magicType: Gate manaCost: 20 @@ -18,7 +18,6 @@ proto: CP14ImpactEffectShadowStep - type: CP14MagicEffectSomaticAspect - type: EntityWorldTargetAction - useDelay: 10 range: 7 checkCanAccess: false itemIconStyle: BigAction @@ -28,7 +27,7 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: shadow_step event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 1 + cooldown: 10 hidden: true breakOnMove: false diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/T1_cure_wounds.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/T1_cure_wounds.yml index cdd78018c4..723c4ddc1e 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/T1_cure_wounds.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/T1_cure_wounds.yml @@ -4,7 +4,7 @@ description: You touch the creature, healing its body from physical damage components: - type: CP14MagicEffectCastSlowdown - speedMultiplier: -0.5 + speedMultiplier: 0.5 - type: CP14MagicEffect magicType: Healing manaCost: 20 @@ -39,11 +39,10 @@ endSpeech: "vulnera tua" - type: CP14MagicEffectCastingVisual proto: CP14RuneCureWounds - - type: EntityWorldTargetAction + - type: EntityTargetAction whitelist: components: - MobState - useDelay: 10 range: 7 itemIconStyle: BigAction interactOnMiss: false @@ -52,8 +51,9 @@ icon: sprite: _CP14/Effects/Magic/spells_icons.rsi state: cure_wounds - event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 3 + event: !type:CP14DelayedEntityTargetActionEvent + cooldown: 10 + castDelay: 3 breakOnMove: false - type: entity diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_flash_light.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_flash_light.yml index d270860fa9..6ec62f539d 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_flash_light.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_flash_light.yml @@ -20,7 +20,6 @@ - type: CP14MagicEffectCastingVisual proto: CP14RuneFlashLight - type: EntityWorldTargetAction - useDelay: 5 range: 10 itemIconStyle: BigAction sound: !type:SoundPathSpecifier @@ -29,7 +28,8 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: flash_light event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 0.5 + cooldown: 5 + castDelay: 0.5 - type: entity id: CP14RuneFlashLight diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_sphere_of_light.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_sphere_of_light.yml index 33eaa042ae..09817423e7 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_sphere_of_light.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/LightDarkness/T1_sphere_of_light.yml @@ -20,7 +20,6 @@ - type: CP14MagicEffectCastingVisual proto: CP14RuneSphereOfLight - type: InstantAction - useDelay: 15 itemIconStyle: BigAction sound: !type:SoundPathSpecifier path: /Audio/Magic/rumble.ogg @@ -28,7 +27,8 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: sphere_of_light event: !type:CP14DelayedInstantActionEvent - delay: 0.5 + cooldown: 15 + castDelay: 0.5 breakOnMove: false - type: entity diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Meta/T0_mana_gift.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Meta/T0_mana_gift.yml index f8f6686b54..9d884957be 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Meta/T0_mana_gift.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Meta/T0_mana_gift.yml @@ -26,12 +26,11 @@ - type: CP14MagicEffectSomaticAspect - type: CP14MagicEffectCastingVisual proto: CP14RuneManaGift - - type: EntityWorldTargetAction + - type: EntityTargetAction whitelist: components: - CP14MagicEnergyContainer - CP14MagicEnergyCrystalSlot - useDelay: 5 itemIconStyle: BigAction interactOnMiss: false sound: !type:SoundPathSpecifier @@ -39,8 +38,9 @@ icon: sprite: _CP14/Effects/Magic/spells_icons.rsi state: mana_gift - event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 2 + event: !type:CP14DelayedEntityTargetActionEvent + cooldown: 5 + castDelay: 2 - type: entity id: CP14RuneManaGift diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Movement/T1_shadow_grab.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Movement/T1_shadow_grab.yml index 85db4b8e7e..960497ffe7 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Movement/T1_shadow_grab.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Movement/T1_shadow_grab.yml @@ -20,21 +20,24 @@ spawns: - CP14ImpactEffectShadowStep - type: CP14MagicEffectSomaticAspect - - type: EntityWorldTargetAction + - type: EntityTargetAction + whitelist: + components: + - Item canTargetSelf: false checkCanAccess: false range: 10 - useDelay: 10 itemIconStyle: BigAction sound: !type:SoundPathSpecifier path: /Audio/Magic/rumble.ogg icon: sprite: _CP14/Effects/Magic/spells_icons.rsi state: shadow_grab - event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 2 - hidden: true + event: !type:CP14DelayedEntityTargetActionEvent + cooldown: 5 + castDelay: 0.5 entityDistance: 1000 + breakOnMove: false - type: entity id: CP14ImpactEffectShadowGrab diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_dagger.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_dagger.yml index 35a41104a1..50bc0a39f2 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_dagger.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_dagger.yml @@ -17,7 +17,6 @@ - type: CP14MagicEffectCastingVisual proto: CP14RuneIceDagger - type: InstantAction - useDelay: 15 itemIconStyle: BigAction sound: !type:SoundPathSpecifier path: /Audio/Magic/rumble.ogg @@ -25,7 +24,8 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: ice_dagger event: !type:CP14DelayedInstantActionEvent - delay: 0.5 + cooldown: 10 + castDelay: 0.5 breakOnMove: false - type: entity diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_shards.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_shards.yml index 8e55ebeab9..23753c4538 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_shards.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Water/T1_ice_shards.yml @@ -4,7 +4,7 @@ description: Fast ice needles, for rapid shooting of targets. components: - type: CP14MagicEffectCastSlowdown - speedMultiplier: -0.25 + speedMultiplier: 0.75 - type: CP14MagicEffect magicType: Water manaCost: 5 @@ -17,7 +17,6 @@ - type: CP14MagicEffectCastingVisual proto: CP14RuneIceShards - type: EntityWorldTargetAction - useDelay: 0.5 repeat: true checkCanAccess: false raiseOnUser: true @@ -29,7 +28,8 @@ sprite: _CP14/Effects/Magic/spells_icons.rsi state: ice_shards event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 0.5 + cooldown: 0.5 + castDelay: 0.5 breakOnMove: false entityDistance: 1000 diff --git a/Resources/Prototypes/_CP14/Entities/Clothing/Rings/ring.yml b/Resources/Prototypes/_CP14/Entities/Clothing/Rings/ring.yml index 68cc2ba281..dc4617f961 100644 --- a/Resources/Prototypes/_CP14/Entities/Clothing/Rings/ring.yml +++ b/Resources/Prototypes/_CP14/Entities/Clothing/Rings/ring.yml @@ -23,8 +23,6 @@ layers: - state: brass_ring - state: saphhire_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -41,8 +39,6 @@ layers: - state: brass_ring - state: saphhire_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -59,8 +55,6 @@ layers: - state: brass_ring - state: saphhire_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -77,8 +71,6 @@ layers: - state: brass_ring - state: ruby_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -95,8 +87,6 @@ layers: - state: brass_ring - state: ruby_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -113,8 +103,6 @@ layers: - state: brass_ring - state: amethyst_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -131,8 +119,6 @@ layers: - state: brass_ring - state: amethyst_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -149,8 +135,6 @@ layers: - state: brass_ring - state: berill_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -167,8 +151,6 @@ layers: - state: brass_ring - state: citrine_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: @@ -185,8 +167,6 @@ layers: - state: brass_ring - state: citrine_stone_small - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem - type: CP14SpellStorageAccessWearing - type: CP14SpellStorage spells: diff --git a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/monster.yml b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/monster.yml index 8b8adfdcec..335fb8f6c6 100644 --- a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/monster.yml +++ b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/monster.yml @@ -127,7 +127,6 @@ sprite: _CP14/Effects/Magic/spells_icons_monster.rsi state: subterranean_leap event: !type:CP14DelayedEntityWorldTargetActionEvent - delay: 1 hidden: true breakOnMove: false raiseOnUser: true diff --git a/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Magic/twoHandedStaffs.yml b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Magic/twoHandedStaffs.yml index 5d51ff666f..f57597af5a 100644 --- a/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Magic/twoHandedStaffs.yml +++ b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Magic/twoHandedStaffs.yml @@ -38,8 +38,8 @@ collection: MetalThud cPAnimationLength: 0.3 cPAnimationOffset: -1.3 - - type: CP14SpellStorageRequireAttune - - type: CP14MagicAttuningItem + #- type: CP14SpellStorageRequireAttune + #- type: CP14MagicAttuningItem - type: CP14SpellStorageAccessHolding - type: CP14SpellStorage spells: diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml index a17ea8871c..be43562228 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml @@ -12,6 +12,23 @@ - type: MapLight ambientLightColor: "#020a1c" +- type: dungeonConfig + id: CP14EdTestLayers + layers: + - !type:PrototypeDunGen + proto: CP14DemiplaneGrassGeode + #- !type:EntityTableDunGen + # minCount: 20 + # maxCount: 20 + # table: !type:GroupSelector + # children: + # - id: CP14DemiplanePassway + - !type:OreDunGen + entity: CP14DemiplanePassway + count: 20 + minGroupSize: 1 + maxGroupSize: 1 + - type: dungeonConfig id: CP14DemiplaneGrassGeode layers: diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml index 092d102e00..3a7943284c 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml @@ -246,23 +246,22 @@ difficulty: 0.4 generationWeight: 0.25 layers: - - !type:MobsDunGen - minCount: 25 - maxCount: 50 - groups: - - id: LandMineExplosive - amount: 1 + - !type:OreDunGen + entity: LandMineExplosive + count: 20 + minGroupSize: 1 + maxGroupSize: 2 - type: cp14DemiplaneModifier id: CommonLoot reward: 0.25 generationWeight: 2 layers: - - !type:EntityTableDunGen - minCount: 15 - maxCount: 30 - table: !type:NestedSelector - tableId: CP14TableExpeditionLootCommon + - !type:OreDunGen + entity: CP14SpawnerExpeditionLootCommon + count: 10 + minGroupSize: 1 + maxGroupSize: 3 - type: cp14DemiplaneModifier id: EnemyXeno @@ -270,25 +269,26 @@ requiredTags: - CP14DemiplaneUnderground layers: - - !type:MobsDunGen - minCount: 2 - maxCount: 3 - groups: - - id: CP14MobXenoDrone - amount: 1 - - id: CP14MobXeno - amount: 1 + - !type:OreDunGen + entity: CP14MobXenoDrone + count: 3 + minGroupSize: 1 + maxGroupSize: 2 + - !type:OreDunGen + entity: CP14MobXeno + count: 3 + minGroupSize: 1 + maxGroupSize: 2 - type: cp14DemiplaneModifier id: EnemyZombie difficulty: 0.4 layers: - - !type:MobsDunGen - minCount: 3 - maxCount: 6 - groups: - - id: CP14SpawnMobUndeadZombie - amount: 1 + - !type:OreDunGen + entity: CP14SpawnMobUndeadZombie + count: 3 + minGroupSize: 1 + maxGroupSize: 3 - type: cp14DemiplaneModifier id: EnemyDyno @@ -297,12 +297,11 @@ - CP14DemiplaneOpenSky - CP14DemiplaneGrass layers: - - !type:MobsDunGen - minCount: 3 - maxCount: 6 - groups: - - id: CP14SpawnMobDinoYumkaraptor - amount: 1 + - !type:OreDunGen + entity: CP14SpawnMobDinoYumkaraptor + count: 6 + minGroupSize: 1 + maxGroupSize: 1 - type: cp14DemiplaneModifier id: SmallHydra @@ -310,37 +309,37 @@ requiredTags: - CP14DemiplaneGrass layers: - - !type:MobsDunGen - minCount: 3 - maxCount: 6 - groups: - - id: CP14MobDinoSmallHydra - amount: 2 + - !type:OreDunGen + entity: CP14MobDinoSmallHydra + count: 4 + minGroupSize: 2 + maxGroupSize: 3 - type: cp14DemiplaneModifier id: EnemyMole difficulty: 0.5 requiredTags: - CP14DemiplaneUnderground + - CP14DemiplaneCave layers: - - !type:MobsDunGen - minCount: 3 - maxCount: 6 - groups: - - id: CP14MobMonsterMole - amount: 1 + - !type:OreDunGen + tileMask: + - CP14FloorBase + entity: CP14MobMonsterMole + count: 5 + minGroupSize: 1 + maxGroupSize: 2 - type: cp14DemiplaneModifier id: EnemyMagmawind difficulty: 0.3 generationWeight: 0.4 layers: - - !type:MobsDunGen - minCount: 3 - maxCount: 5 - groups: - - id: CP14MobWatcherMagmawing - amount: 1 + - !type:OreDunGen + entity: CP14MobWatcherMagmawing + count: 5 + minGroupSize: 2 + maxGroupSize: 3 - type: cp14DemiplaneModifier id: Rabbits @@ -349,12 +348,15 @@ requiredTags: - CP14DemiplaneGrass layers: - - !type:MobsDunGen - minCount: 1 - maxCount: 2 - groups: - - id: CP14MobRabbit - amount: 3 + - !type:OreDunGen + tileMask: + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall + entity: CP14MobRabbit + count: 3 + minGroupSize: 2 + maxGroupSize: 3 - type: cp14DemiplaneModifier id: Boar @@ -364,12 +366,15 @@ requiredTags: - CP14DemiplaneGrass layers: - - !type:MobsDunGen - minCount: 1 - maxCount: 3 - groups: - - id: CP14MobBoar - amount: 2 + - !type:OreDunGen + tileMask: + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall + entity: CP14MobBoar + count: 3 + minGroupSize: 2 + maxGroupSize: 3 - type: cp14DemiplaneModifier id: Chasm diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml index 0f39196c65..865f0bb861 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml @@ -1,15 +1,13 @@ - type: dungeonConfig id: DemiplaneConnections layers: - - !type:EntityTableDunGen - minCount: 1 - maxCount: 1 - table: !type:GroupSelector - children: - - id: CP14DemiplanEnterRoomMarker - - !type:EntityTableDunGen - minCount: 2 - maxCount: 2 - table: !type:GroupSelector - children: - - id: CP14DemiplanePassway \ No newline at end of file + - !type:OreDunGen + entity: CP14DemiplanEnterRoomMarker + count: 1 + minGroupSize: 1 + maxGroupSize: 1 + - !type:OreDunGen + entity: CP14DemiplanePassway + count: 2 + minGroupSize: 1 + maxGroupSize: 1 \ No newline at end of file