diff --git a/Content.Client/_CP14/Dash/CP14ClientDashSystem.cs b/Content.Client/_CP14/Dash/CP14ClientDashSystem.cs new file mode 100644 index 0000000000..46f7c0f36e --- /dev/null +++ b/Content.Client/_CP14/Dash/CP14ClientDashSystem.cs @@ -0,0 +1,17 @@ +using Content.Shared._CP14.Dash; + +namespace Content.Client._CP14.Dash; + +public sealed partial class CP14DClientDashSystem : EntitySystem +{ + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var dash)) + { + SpawnAtPosition(dash.DashEffect, Transform(uid).Coordinates); + } + } +} diff --git a/Content.Shared/_CP14/Dash/CP14DashComponent.cs b/Content.Shared/_CP14/Dash/CP14DashComponent.cs new file mode 100644 index 0000000000..f86b3352ac --- /dev/null +++ b/Content.Shared/_CP14/Dash/CP14DashComponent.cs @@ -0,0 +1,21 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared._CP14.Dash; + +/// +/// This component marks entities that are currently in the dash +/// +[RegisterComponent, NetworkedComponent, Access(typeof(CP14DashSystem))] +public sealed partial class CP14DashComponent : Component +{ + [DataField] + public EntProtoId DashEffect = "CP14DustEffect"; + + [DataField] + public SoundSpecifier DashSound = new SoundPathSpecifier("/Audio/_CP14/Effects/dash.ogg") + { + Params = AudioParams.Default.WithVariation(0.05f) + }; +} diff --git a/Content.Shared/_CP14/Dash/CP14DashSystem.cs b/Content.Shared/_CP14/Dash/CP14DashSystem.cs new file mode 100644 index 0000000000..beac1b20ec --- /dev/null +++ b/Content.Shared/_CP14/Dash/CP14DashSystem.cs @@ -0,0 +1,55 @@ +using Content.Shared.ActionBlocker; +using Content.Shared.Movement.Events; +using Content.Shared.Throwing; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Map; + +namespace Content.Shared._CP14.Dash; + +public sealed partial class CP14DashSystem : EntitySystem +{ + [Dependency] private readonly ActionBlockerSystem _blocker = default!; + [Dependency] private readonly ThrowingSystem _throwing = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMoveAttempt); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnLand); + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + _blocker.UpdateCanMove(ent); + } + + private void OnInit(Entity ent, ref ComponentInit args) + { + _blocker.UpdateCanMove(ent); + } + + private void OnLand(Entity ent, ref LandEvent args) + { + RemCompDeferred(ent); + } + + private void OnMoveAttempt(Entity ent, ref UpdateCanMoveEvent args) + { + if (ent.Comp.LifeStage > ComponentLifeStage.Running) + return; + + //Cant move while dashing + args.Cancel(); + } + + public void PerformDash(EntityUid ent, EntityCoordinates targetPosition, float speed = 10f) + { + EnsureComp(ent, out var dash); + _audio.PlayPredicted(dash.DashSound, ent, ent); + _throwing.TryThrow(ent, targetPosition, speed, null, 0f, 10, true, false, false, false, false); + } +} diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs index 98f786ae94..c2b23ae87f 100644 --- a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs @@ -64,7 +64,7 @@ public abstract partial class CP14SharedMagicSystem return; } - if (!_magicEnergy.HasEnergy(args.Performer, requiredMana, playerMana, true) && _net.IsServer) + if (!_magicEnergy.HasEnergy(args.Performer, requiredMana, playerMana, true)) _popup.PopupEntity(Loc.GetString($"cp14-magic-spell-not-enough-mana-cast-warning-{_random.Next(5)}"), args.Performer, args.Performer, @@ -199,9 +199,6 @@ public abstract partial class CP14SharedMagicSystem private void OnVerbalAspectAfterCast(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { - if (_net.IsClient) - return; - var ev = new CP14SpellSpeechEvent { Performer = args.Performer, @@ -225,9 +222,6 @@ public abstract partial class CP14SharedMagicSystem private void OnEmoteEndCast(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { - if (_net.IsClient) - return; - var ev = new CP14SpellSpeechEvent { Performer = args.Performer, diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs index 66a64d2b64..cdffe4cb6b 100644 --- a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs @@ -5,14 +5,12 @@ 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._CP14.MagicSpellStorage; using Content.Shared.Actions; using Content.Shared.Damage.Systems; using Content.Shared.DoAfter; using Content.Shared.FixedPoint; using Content.Shared.Movement.Systems; using Content.Shared.Popups; -using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -25,7 +23,6 @@ namespace Content.Shared._CP14.MagicSpell; public abstract partial class CP14SharedMagicSystem : EntitySystem { [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; - [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly SharedCP14MagicEnergySystem _magicEnergy = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -165,9 +162,6 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem private void CastTelegraphy(Entity ent, CP14SpellEffectBaseArgs args) { - if (_net.IsClient) - return; - foreach (var effect in ent.Comp.TelegraphyEffects) { effect.Effect(EntityManager, args); @@ -179,9 +173,6 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem var ev = new CP14MagicEffectConsumeResourceEvent(args.User); RaiseLocalEvent(ent, ref ev); - if (_net.IsClient) - return; - foreach (var effect in ent.Comp.Effects) { effect.Effect(EntityManager, args); diff --git a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellDash.cs b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellDash.cs new file mode 100644 index 0000000000..f971472fed --- /dev/null +++ b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellDash.cs @@ -0,0 +1,20 @@ +using Content.Shared._CP14.Dash; + +namespace Content.Shared._CP14.MagicSpell.Spells; + +public sealed partial class CP14SpellDash : CP14SpellEffect +{ + [DataField] + public float DashSpeed = 10f; + public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args) + { + if (args.User is null) + return; + if (args.Position is null) + return; + + var dashSys = entManager.System(); + + dashSys.PerformDash(args.User.Value, args.Position.Value, DashSpeed); + } +} diff --git a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellProjectile.cs b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellProjectile.cs index 1e77e3991c..2dd78f0fab 100644 --- a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellProjectile.cs +++ b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellProjectile.cs @@ -64,7 +64,7 @@ public sealed partial class CP14SpellProjectile : CP14SpellEffect (float) (random.NextDouble() * 2 - 1) * Spread, (float) (random.NextDouble() * 2 - 1) * Spread)); - var ent = entManager.SpawnAtPosition(Prototype, spawnCoords); + var ent = entManager.PredictedSpawnAtPosition(Prototype, spawnCoords); var direction = offsetedTargetPoint.ToMapPos(entManager, transform) - spawnCoords.ToMapPos(entManager, transform); diff --git a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntitiesOnTargetInRadius.cs b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntitiesOnTargetInRadius.cs index 61a40b16d7..687127d134 100644 --- a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntitiesOnTargetInRadius.cs +++ b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntitiesOnTargetInRadius.cs @@ -28,7 +28,7 @@ public sealed partial class CP14SpellSpawnEntitiesOnTargetInRadius : CP14SpellEf var direction = (DirectionFlag) (1 << i); var coords = targetPoint.Value.Offset(direction.AsDir().ToVec()); - entManager.SpawnAtPosition(Spawn, coords); + entManager.PredictedSpawnAtPosition(Spawn, coords); } } } diff --git a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnTarget.cs b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnTarget.cs index 9020e0e294..ae84a3454b 100644 --- a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnTarget.cs +++ b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnTarget.cs @@ -21,7 +21,7 @@ public sealed partial class CP14SpellSpawnEntityOnTarget : CP14SpellEffect foreach (var spawn in Spawns) { - entManager.SpawnAtPosition(spawn, targetPoint.Value); + entManager.PredictedSpawnAtPosition(spawn, targetPoint.Value); } } } diff --git a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnUser.cs b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnUser.cs index 43b3cc34e5..dd260bc62c 100644 --- a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnUser.cs +++ b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnEntityOnUser.cs @@ -15,7 +15,7 @@ public sealed partial class CP14SpellSpawnEntityOnUser : CP14SpellEffect foreach (var spawn in Spawns) { - entManager.SpawnAtPosition(spawn, transformComponent.Coordinates); + entManager.PredictedSpawnAtPosition(spawn, transformComponent.Coordinates); } } } diff --git a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnInHandEntity.cs b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnInHandEntity.cs index 26f748a30b..343945aee3 100644 --- a/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnInHandEntity.cs +++ b/Content.Shared/_CP14/MagicSpell/Spells/CP14SpellSpawnInHandEntity.cs @@ -23,7 +23,7 @@ public sealed partial class CP14SpellSpawnInHandEntity : CP14SpellEffect foreach (var spawn in Spawns) { - var item = entManager.SpawnAtPosition(spawn, transformComponent.Coordinates); + var item = entManager.PredictedSpawnAtPosition(spawn, transformComponent.Coordinates); if (!handSystem.TryPickupAnyHand(args.Target.Value, item) && DeleteIfCantPickup) entManager.QueueDeleteEntity(item); } diff --git a/Resources/Audio/_CP14/Effects/attributions.yml b/Resources/Audio/_CP14/Effects/attributions.yml index 3c17d8a357..cea41ea34f 100644 --- a/Resources/Audio/_CP14/Effects/attributions.yml +++ b/Resources/Audio/_CP14/Effects/attributions.yml @@ -101,4 +101,9 @@ - files: ["moon_strike1.ogg", "moon_strike2.ogg", "moon_strike3.ogg", "moon_strike4.ogg"] license: "CC-BY-4.0" copyright: 'Created by EminYILDIRIM on Freesound.org' - source: "https://freesound.org/people/EminYILDIRIM/sounds/668244/" \ No newline at end of file + source: "https://freesound.org/people/EminYILDIRIM/sounds/668244/" + +- files: ["dash.ogg"] + license: "CC-BY-4.0" + copyright: 'Created by qubodup on Freesound.org' + source: "https://freesound.org/people/qubodup/sounds/714258/" \ No newline at end of file diff --git a/Resources/Audio/_CP14/Effects/dash.ogg b/Resources/Audio/_CP14/Effects/dash.ogg new file mode 100644 index 0000000000..b2d6c913c2 Binary files /dev/null and b/Resources/Audio/_CP14/Effects/dash.ogg differ diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Physical/dash.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Physical/dash.yml new file mode 100644 index 0000000000..29f8cd566e --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Physical/dash.yml @@ -0,0 +1,22 @@ +- type: entity + id: CP14ActionSpellDash + parent: CP14ActionSpellBase + name: Dash + description: You make a quick dash to the chosen position to quickly close the distance or dodge danger. + components: + - type: CP14MagicEffectStaminaCost + stamina: 40 + - type: CP14MagicEffect + effects: + - !type:CP14SpellDash + dashSpeed: 20 + - type: Action + icon: + sprite: _CP14/Actions/Spells/physical.rsi + state: dash + - type: TargetAction + checkCanAccess: false + range: 3.5 + - type: WorldTargetAction + event: !type:CP14WorldTargetActionEvent + cooldown: 5 \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Skill/Basic/atlethic.yml b/Resources/Prototypes/_CP14/Skill/Basic/atlethic.yml index 9a534617ae..a1317a1259 100644 --- a/Resources/Prototypes/_CP14/Skill/Basic/atlethic.yml +++ b/Resources/Prototypes/_CP14/Skill/Basic/atlethic.yml @@ -20,6 +20,17 @@ - !type:AddAction action: CP14ActionSpellSprint +- type: cp14Skill + id: CP14ActionSpellDash + skillUiPosition: 0, 4 + tree: Atlethic + icon: + sprite: _CP14/Actions/Spells/physical.rsi + state: dash + effects: + - !type:AddAction + action: CP14ActionSpellDash + - type: cp14Skill id: CP14ActionSpellSprintGoblin skillUiPosition: 2, 2 diff --git a/Resources/Textures/_CP14/Actions/Spells/physical.rsi/dash.png b/Resources/Textures/_CP14/Actions/Spells/physical.rsi/dash.png new file mode 100644 index 0000000000..759abad7a2 Binary files /dev/null and b/Resources/Textures/_CP14/Actions/Spells/physical.rsi/dash.png differ diff --git a/Resources/Textures/_CP14/Actions/Spells/physical.rsi/meta.json b/Resources/Textures/_CP14/Actions/Spells/physical.rsi/meta.json index 968e8fd278..f29daf5ecb 100644 --- a/Resources/Textures/_CP14/Actions/Spells/physical.rsi/meta.json +++ b/Resources/Textures/_CP14/Actions/Spells/physical.rsi/meta.json @@ -18,6 +18,9 @@ }, { "name": "kick_skull" + }, + { + "name": "dash" } ] } \ No newline at end of file