SupaLidlGame/State/Character/PlayerMaxLevelState.cs

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;
}
}