SupaLidlGame/Characters/Player.cs

201 lines
4.8 KiB
C#
Raw Normal View History

2022-11-10 20:29:53 -08:00
using Godot;
2023-06-10 22:15:28 -07:00
using GodotUtilities;
2022-11-25 11:59:55 -08:00
using SupaLidlGame.Utils;
2023-06-10 22:15:28 -07:00
using SupaLidlGame.BoundingBoxes;
2023-07-24 00:56:01 -07:00
using SupaLidlGame.Extensions;
2022-11-10 20:29:53 -08:00
2023-06-03 18:21:46 -07:00
namespace SupaLidlGame.Characters;
2023-06-10 22:15:28 -07:00
[Scene]
public sealed partial class Player : Character
2022-11-10 20:29:53 -08:00
{
2023-06-03 18:21:46 -07:00
private string _spriteAnim;
2022-11-19 21:21:12 -08:00
private Vector2 _desiredTarget;
public Vector2 DesiredTarget
{
get => _desiredTarget;
set
{
if (value.IsZeroApprox())
{
return;
}
_desiredTarget = value;
}
}
2023-09-06 22:53:39 -07:00
private TargetTracer _targetTracer;
2023-09-06 22:53:39 -07:00
2023-06-03 18:21:46 -07:00
[Export]
public PlayerCamera Camera { get; set; }
2022-11-25 11:59:55 -08:00
2023-06-10 22:15:28 -07:00
[Export]
public Marker2D DirectionMarker { get; private set; }
2023-07-21 02:54:13 -07:00
[Export]
public AnimationTree AnimationTree { get; private set; }
2023-06-10 22:15:28 -07:00
2023-09-09 22:33:57 -07:00
[Export]
public PlayerStats Stats { get; private set; }
2023-07-21 02:54:13 -07:00
public InteractionRay InteractionRay { get; private set; }
2022-11-19 21:21:12 -08:00
2023-06-03 18:21:46 -07:00
public override void _Ready()
{
2023-06-10 22:15:28 -07:00
InteractionRay = GetNode<InteractionRay>("Direction2D/InteractionRay");
2023-07-21 02:54:13 -07:00
2023-09-07 11:53:51 -07:00
_targetTracer = GetNode<TargetTracer>("%TargetTracer");
2023-09-09 22:33:57 -07:00
Stats = GetNode<PlayerStats>("Stats");
2023-07-21 02:54:13 -07:00
base._Ready();
Inventory.UsedItem += (Items.Item item) =>
{
if (item is Items.Weapons.Sword)
{
AttackAnimation.Play("sword");
}
};
2023-08-13 16:49:18 -07:00
HealthChanged += (args) =>
{
var signal = Events.EventBus.SignalName.PlayerHealthChanged;
this.GetEventBus().EmitSignal(signal, args);
};
2023-06-13 02:55:30 -07:00
}
2023-08-16 21:02:37 -07:00
public override void _Process(double delta)
{
base._Process(delta);
2023-09-07 11:53:51 -07:00
2023-09-10 09:37:12 -07:00
float angle = DesiredTarget.Angle();
2023-09-10 17:29:57 -07:00
if (Inventory.IsUsingItem)
{
_targetTracer.Intensity = 1;
}
else
{
// must turn > pi / 4 radians per second to increase intensity
float deltaTheta = Mathf.Abs(_targetTracer.Rotation - angle);
_targetTracer.Intensity = Mathf.Min(_targetTracer.Intensity +
deltaTheta, 1);
_targetTracer.Intensity = Mathf.Max(_targetTracer.Intensity -
Mathf.Pi / 4 * (float)delta, 0);
}
2023-09-10 09:37:12 -07:00
_targetTracer.Rotation = angle;
2023-08-16 21:02:37 -07:00
}
2023-06-13 02:55:30 -07:00
public override void _Input(InputEvent @event)
{
if (StateMachine != null)
{
StateMachine.Input(@event);
}
}
2023-08-31 19:03:16 -07:00
/// <summary>
/// Respawns the player with full health and plays spawn animation
/// </summary>
2023-06-13 02:55:30 -07:00
public void Spawn()
{
Health = 100;
2023-08-07 02:38:51 -07:00
HurtAnimation.Play("spawn");
2023-06-03 18:21:46 -07:00
}
2022-11-25 09:11:46 -08:00
2023-06-03 18:21:46 -07:00
public override void ModifyVelocity()
{
base.ModifyVelocity();
}
public override void Stun(float time)
{
base.Stun(time);
Camera.Shake(2, 0.8f);
// TODO: implement visual effects for stun
}
2023-08-07 02:38:51 -07:00
protected override void OnReceivedDamage(
float damage,
Character inflictor,
float knockback,
2023-09-03 17:42:32 -07:00
Items.Weapon weapon = null,
2023-07-21 02:54:13 -07:00
Vector2 knockbackDir = default)
{
if (damage >= 10 && IsAlive)
{
Camera.Shake(2, 0.5f);
}
2023-07-21 02:54:13 -07:00
GetNode<GpuParticles2D>("Effects/HurtParticles")
.SetDirection(knockbackDir);
2023-09-03 17:42:32 -07:00
base.OnReceivedDamage(damage,
inflictor,
knockback,
weapon,
knockbackDir);
}
2023-06-03 18:21:46 -07:00
public override void Die()
{
HurtAnimation.Play("death");
2022-11-13 15:42:04 -08:00
}
2023-06-10 22:15:28 -07:00
protected override void DrawTarget()
{
base.DrawTarget();
2023-09-06 22:53:39 -07:00
DirectionMarker.GlobalRotation = DesiredTarget.Angle();
2023-06-10 22:15:28 -07:00
}
2023-07-24 00:56:01 -07:00
public override void Footstep()
{
GetNode<AudioStreamPlayer2D>("Effects/Footstep")
.OnWorld()
.WithPitchDeviation(0.125f)
.Play();
}
2023-09-06 23:07:51 -07:00
2023-09-10 12:30:26 -07:00
public override void UseCurrentItemAlt()
{
// must have at least 1 level to use
if (Stats.Level.Value >= 1)
{
if (Inventory.SelectedItem is Items.Weapon weapon)
{
if (!weapon.IsUsingAlt)
{
Stats.Level.Value--;
}
}
base.UseCurrentItemAlt();
}
}
2023-09-06 23:07:51 -07:00
public Vector2 GetDesiredInputFromInput()
{
Vector2 mousePos = GetGlobalMousePosition();
Vector2 dirToMouse = GlobalPosition.DirectionTo(mousePos);
Vector2 joystick = Godot.Input.GetVector("look_left", "look_right",
"look_up", "look_down");
var inputMethod = Utils.World.Instance.GlobalState
.Settings.InputMethod;
switch (inputMethod)
{
case State.Global.InputMethod.Joystick:
if (joystick.IsZeroApprox())
{
return Direction;
}
return joystick;
default:
return dirToMouse;
}
}
2022-11-10 20:29:53 -08:00
}