126 lines
3.4 KiB
C#
126 lines
3.4 KiB
C#
using Godot;
|
|
|
|
namespace SupaLidlGame.State.Character;
|
|
|
|
public partial class PlayerMaxLevelState : PlayerState
|
|
{
|
|
[Export]
|
|
public float CastDistance { get; set; }
|
|
|
|
[Export]
|
|
public double CastTime { get; set; }
|
|
|
|
[Export]
|
|
public int LevelCost { get; set; }
|
|
|
|
private double _castTimeLeft = 0;
|
|
|
|
private static PackedScene _lightningScene;
|
|
|
|
private GpuParticles2D _particles;
|
|
|
|
static PlayerMaxLevelState()
|
|
{
|
|
_lightningScene = GD.Load<PackedScene>("res://Entities/Lightning.tscn");
|
|
}
|
|
|
|
public override void _Ready()
|
|
{
|
|
base._Ready();
|
|
_particles = GetNode<GpuParticles2D>("%Effects/CastParticles");
|
|
}
|
|
|
|
public override IState<CharacterState> Enter(IState<CharacterState> prevState)
|
|
{
|
|
_player.AttackAnimation.Play("cast");
|
|
_player.Inventory.Visible = false;
|
|
_player.Stats.Level.Value -= LevelCost;
|
|
_castTimeLeft = CastTime;
|
|
return base.Enter(prevState);
|
|
}
|
|
|
|
public override void Exit(IState<CharacterState> nextState)
|
|
{
|
|
_player.Inventory.Visible = true;
|
|
base.Exit(nextState);
|
|
}
|
|
|
|
public override CharacterState Process(double delta)
|
|
{
|
|
// return to idle when finished
|
|
if ((_castTimeLeft -= delta) <= 0)
|
|
{
|
|
return IdleState;
|
|
}
|
|
|
|
return base.Process(delta);
|
|
}
|
|
|
|
public override CharacterState Input(InputEvent @event)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public void Cast()
|
|
{
|
|
Scenes.Map map = Utils.World.Instance.CurrentMap;
|
|
bool hasSpawned = false;
|
|
foreach (var node in map.Entities.GetChildren())
|
|
{
|
|
if (node is Characters.Character ch)
|
|
{
|
|
if (ch.Faction == Character.Faction)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!ch.IsAlive)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// check if distance good and spawn lightning
|
|
var dist = Character.GlobalPosition
|
|
.DistanceTo(ch.GlobalPosition);
|
|
if (dist <= CastDistance)
|
|
{
|
|
// delay up to 150 milliseconds
|
|
double delay = GD.Randf() * 0.150;
|
|
GetTree().CreateTimer(delay).Timeout += () =>
|
|
{
|
|
SpawnLightning(ch);
|
|
};
|
|
hasSpawned = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasSpawned)
|
|
{
|
|
_player.Camera.Shake(2.0f, 0.5f);
|
|
// delay to time out
|
|
// this is a workaround where particles of amount 1 won't render
|
|
GetTree().CreateTimer(0.1f).Timeout += () =>
|
|
{
|
|
_particles.Emitting = false;
|
|
};
|
|
_particles.Emitting = true;
|
|
//_particles.SetDeferred("emitting", false);
|
|
}
|
|
}
|
|
|
|
private void SpawnLightning(Characters.Character target)
|
|
{
|
|
if (target is null || !IsInstanceValid(target) || !target.IsAlive)
|
|
{
|
|
return;
|
|
}
|
|
var map = Utils.World.Instance.CurrentMap;
|
|
var instance = map.SpawnEntity<Entities.Lightning>(_lightningScene);
|
|
instance.Hitbox.Faction = Character.Faction;
|
|
instance.Hitbox.Inflictor = Character;
|
|
instance.Weapon = null;
|
|
instance.GlobalPosition = target.GlobalPosition;
|
|
}
|
|
}
|