cirnogodot/Scripts/PlayerMovement.cs

591 lines
14 KiB
C#
Raw Normal View History

2024-02-26 08:33:37 +01:00
using Godot;
using System;
2024-02-27 17:16:55 +01:00
using System.Diagnostics;
2025-02-11 11:50:45 +01:00
using System.Linq;
2024-06-09 18:19:57 +02:00
using Cirno.Scripts;
2025-02-20 16:12:53 +01:00
using Cirno.Scripts.Components;
using Cirno.Scripts.Components.Actors;
2025-02-11 11:50:45 +01:00
using Cirno.Scripts.Resources;
using Godot.Collections;
2025-02-22 14:45:46 +01:00
using System.Threading.Tasks;
using Cirno.Scripts.Components.FSM;
using Cirno.Scripts.Components.FSM._3DPlayer;
2025-06-08 16:33:38 +02:00
using Cirno.Scripts.Controllers;
using Cirno.Scripts.Utils;
2024-02-26 08:33:37 +01:00
2024-08-18 17:38:32 +02:00
public partial class PlayerMovement : CharacterBody2D, IDestructible
2024-02-26 08:33:37 +01:00
{
[Export]
public int Speed { get; set; } = 400;
2025-02-28 11:17:28 +01:00
2025-01-28 14:05:38 +01:00
[Export]
public int StrafeSpeed { get; set; } = 200;
public int MovementSpeed => _isStrafing ? StrafeSpeed : Speed;
2024-02-26 23:45:20 +01:00
2024-05-01 16:39:14 +02:00
[Export]
public float CrosshairDistance { get; set; } = 10f;
2024-06-09 18:19:57 +02:00
[Export]
public PackedScene SelectorScene { get; set; }
2024-08-24 15:25:30 +02:00
[Export]
2024-08-25 17:06:59 +02:00
public string GameOverScene { get; set; }
2025-02-28 11:17:28 +01:00
2025-02-17 18:42:37 +01:00
[Export]
public Texture2D WingsSprite { get; set; }
2024-08-24 15:25:30 +02:00
2025-01-30 15:45:29 +01:00
private Selector _selector;
2024-06-09 18:19:57 +02:00
2025-01-30 15:45:29 +01:00
//private Interactable _lastInteractable;
2024-02-27 17:16:55 +01:00
[Export]
2024-05-01 11:48:04 +02:00
public Marker2D Muzzle { get; set; }
2024-02-27 17:16:55 +01:00
2024-02-26 08:33:37 +01:00
private AnimatedSprite2D _animatedSprite;
2024-02-26 23:45:20 +01:00
2024-05-01 11:48:04 +02:00
private Vector2 _movementDirection { get; set; }
private Vector2 _facingDirection { get; set; }
2025-02-28 11:17:28 +01:00
2025-01-27 17:30:45 +01:00
private Vector2 _rightStickInput { get; set; }
2024-05-01 11:48:04 +02:00
2024-05-01 16:39:14 +02:00
private Sprite2D _crosshair;
2025-01-28 09:17:35 +01:00
[Export] public float MaxHealth = 32f;
2025-02-11 17:55:50 +01:00
[Export] public float MaxShield = 32f;
2025-02-28 11:17:28 +01:00
[Export] public Shader BlinkShader { get; set; }
2025-02-22 17:08:19 +01:00
[Export] public Sprite2D HitboxSprite { get; set; }
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.Player;
2025-02-22 14:45:46 +01:00
2025-02-20 16:12:53 +01:00
[ExportGroup("Action Names")]
[Export] private string _shootActionName = "shoot";
[Export] private string _useActionName = "Use";
[Export] private string _strafeActionName = "strafe";
[Export] private string _nextWeaponActionName = "next_weapon";
[Export] private string _previousWeaponActionName = "previous_weapon";
2025-02-22 17:08:19 +01:00
[ExportCategory("Particles")]
[Export] private PackedScene _deathParticles;
[Export] private GpuParticles2D _shieldParticles;
2025-02-11 13:47:31 +01:00
2025-02-28 13:50:52 +01:00
private PlayerState _state;
2024-08-18 17:38:32 +02:00
private bool _isDestroyed = false;
2025-01-24 15:24:37 +01:00
private GameManager _gameManager;
2025-02-11 11:50:45 +01:00
private InventoryManager _inventoryManager;
2025-02-20 16:12:53 +01:00
private ActorResourceProvider _healthProvider;
private ActorResourceProvider _shieldProvider;
2025-02-28 11:17:28 +01:00
2025-01-27 17:30:45 +01:00
private bool _isStrafing { get; set; }
2025-02-28 11:17:28 +01:00
2025-02-06 15:57:03 +01:00
private bool _canMove = true;
2025-02-28 11:17:28 +01:00
public Weapon EquippedWeapon => _weaponProvider.EquippedWeapon;
2025-01-28 09:17:35 +01:00
[Signal]
2025-02-20 14:09:42 +01:00
public delegate void HealthChangedEventHandler(float newHealth, float maxHealth);
2025-02-28 11:17:28 +01:00
2025-02-11 17:55:50 +01:00
[Signal]
public delegate void ShieldChangedEventHandler(float newShield, float maxShield);
2025-01-28 09:17:35 +01:00
2025-01-30 08:34:09 +01:00
[Signal]
public delegate void InteractableAreaEnteredEventHandler(Interactable interactable);
[Signal]
public delegate void InteractableAreaExitedEventHandler(Interactable interactable);
2025-02-28 11:17:28 +01:00
2025-02-20 16:12:53 +01:00
[Signal]
public delegate void DeathEventHandler();
2025-01-28 09:17:35 +01:00
public float CurrentHealth
{
2025-02-20 16:12:53 +01:00
get => _healthProvider.CurrentResource;
set => _healthProvider.CurrentResource = value;
2025-01-28 09:17:35 +01:00
}
2025-02-28 11:17:28 +01:00
2025-02-11 17:55:50 +01:00
public float CurrentShield
{
2025-02-20 16:12:53 +01:00
get => _shieldProvider.CurrentResource;
set => _shieldProvider.CurrentResource = value;
}
2025-02-19 23:40:31 +01:00
2025-02-20 16:12:53 +01:00
private Vector2 _lastCheckPointPosition;
2025-02-19 23:40:31 +01:00
2025-02-20 16:12:53 +01:00
public Vector2 LastCheckPointPosition
{
get => _lastCheckPointPosition;
set => _lastCheckPointPosition = value;
2025-02-19 23:40:31 +01:00
}
private PlayerWeaponProvider _weaponProvider;
2024-02-26 08:33:37 +01:00
public override void _Ready()
{
2025-02-20 16:12:53 +01:00
// CurrentHealth = MaxHealth;
// CurrentShield = MaxShield;
2024-08-18 17:38:32 +02:00
2025-02-28 13:50:52 +01:00
_state = PlayerState.Active;
_weaponProvider = GetNode<PlayerWeaponProvider>("WeaponProvider");
2025-02-28 19:59:36 +01:00
_weaponProvider.Init(this);
2024-05-01 12:49:46 +02:00
_animatedSprite = GetNode<AnimatedSprite2D>("./Smoothing2D/AnimatedSprite2D");
2024-05-02 12:50:08 +02:00
_crosshair = GetNode<Sprite2D>("./Smoothing2D/Crosshair");
2025-02-28 11:17:28 +01:00
2025-02-20 16:12:53 +01:00
_healthProvider = GetNode<ActorResourceProvider>("HealthProvider");
_shieldProvider = GetNode<ActorResourceProvider>("ShieldProvider");
_healthProvider.MaxResource = MaxHealth;
_shieldProvider.MaxResource = MaxShield;
_healthProvider.ResourceChanged += (value, maxValue) =>
{
EmitSignal(nameof(HealthChanged), value, maxValue);
};
_shieldProvider.ResourceChanged += (value, maxValue) =>
{
EmitSignal(nameof(ShieldChanged), value, maxValue);
};
_healthProvider.FillResource();
_shieldProvider.FillResource();
2024-05-01 16:39:14 +02:00
2024-05-01 11:48:04 +02:00
_movementDirection = Vector2.Zero;
_facingDirection = Vector2.Zero;
2025-01-27 17:30:45 +01:00
_rightStickInput = Vector2.Zero;
_isStrafing = false;
2024-06-09 18:19:57 +02:00
2025-02-20 21:26:51 +01:00
_gameManager = GameManager.Instance;
//_gameManager = this.GetGameManager();
2025-02-11 11:50:45 +01:00
_inventoryManager = this.GetInventoryManager();
GameStateManager.Instance.GameStateChange += GameManagerOnGameStateChange;
2025-02-28 11:17:28 +01:00
2024-06-09 18:19:57 +02:00
if (SelectorScene != null)
{
2025-01-30 15:45:29 +01:00
_selector = this.CreateSibling<Selector>(SelectorScene, this.GlobalPosition);
2025-02-07 14:58:59 +01:00
_selector.Visible = false;
2024-06-09 18:19:57 +02:00
}
2025-02-28 11:17:28 +01:00
2025-02-28 18:50:42 +01:00
_inventoryManager.ItemUsed += this.UseItem;
2025-02-20 16:12:53 +01:00
_lastCheckPointPosition = GlobalPosition;
2025-02-22 14:45:46 +01:00
_ = UnTeleport();
2024-02-26 08:33:37 +01:00
}
2025-02-28 11:17:28 +01:00
2025-02-06 15:57:03 +01:00
private void GameManagerOnGameStateChange(GameState state)
{
switch (state)
{
case GameState.Menu:
case GameState.Paused:
_canMove = false;
break;
case GameState.Playing:
_canMove = true;
2025-02-28 13:50:52 +01:00
_state = PlayerState.Active;
2025-02-06 15:57:03 +01:00
break;
case GameState.Dialogue:
_canMove = false;
2025-02-28 13:50:52 +01:00
break;
case GameState.Controlling:
_canMove = false;
_state = PlayerState.Controlling;
2025-02-06 15:57:03 +01:00
break;
}
}
2025-02-06 17:57:06 +01:00
/// <summary>
/// Requests disable movement
/// </summary>
/// <param name="disable">true disables false enables</param>
public void RequestMovementDisable(bool disable)
{
if (disable)
{
_canMove = false;
}
else
{
_canMove = true;
}
}
2025-02-28 11:17:28 +01:00
2025-02-11 13:47:31 +01:00
public void AddWeapon(Weapon weapon)
{
2025-05-02 15:49:25 +02:00
_weaponProvider.Equip(weapon, false);
2025-02-11 13:47:31 +01:00
}
public void EquipWeapon(string itemKey)
{
2025-05-02 15:49:25 +02:00
_weaponProvider.Equip(itemKey, true);
}
2025-02-28 11:17:28 +01:00
public void UseItem(LootItem item, int currentAmount)
{
GD.Print($"Used item on player {item.ItemKey}");
switch (item.Item)
{
case ItemTypes.FrogBomb:
_inventoryManager.RemoveItem(item.ItemKey, 1);
// emit projectile
var bulletData = item.WeaponData.MakeBullet(this.GlobalPosition);
2025-06-17 11:57:59 +02:00
var bullet = PoolingManager.Instance.SpawnBullet<Bullet>(bulletData.OriginalBulletResource);
2025-06-08 16:33:38 +02:00
bullet.GlobalPosition = this.GlobalPosition;
//var bullet = this.CreateChildOf<Bullet>(_gameManager.BulletsContainer, item.WeaponData.BulletData.BulletScene, this.GlobalPosition);
2025-06-19 17:55:23 +02:00
bullet.Initialize(bulletData);
2025-02-28 11:17:28 +01:00
//bullet.SetDirection(ShootDirection);
bullet.SetDirection(_facingDirection);
bullet.Speed = item.WeaponData.BulletData.BulletSpeed;
RequestMovementDisable(true);
// set camera
_gameManager.CameraTargetObject(bullet);
// set event destroy
bullet.OnDestroy += () =>
{
_gameManager.CameraTargetPlayer();
RequestMovementDisable(false);
};
// go back
break;
}
//var item = _inventoryManager.getitem
}
// Triggered by event in inventorymanager
2025-02-11 13:47:31 +01:00
public void EquipWeapon(Weapon weapon)
{
2025-05-02 15:49:25 +02:00
_weaponProvider.Equip(weapon, true);
2025-02-11 13:47:31 +01:00
}
2024-06-09 18:19:57 +02:00
private void FindInteractable()
{
2025-02-20 11:04:51 +01:00
var selected = _selector.SelectedInteractable;
2025-02-20 16:12:53 +01:00
if (!Input.IsActionJustPressed(_useActionName) || selected == null) return;
2025-02-20 11:04:51 +01:00
if (!selected.CanActivate()) return;
bool success = selected.Activate();
2025-01-30 17:43:39 +01:00
if (success)
2024-06-09 18:19:57 +02:00
{
2025-01-30 17:43:39 +01:00
// Deselect and scan for next
2025-02-20 11:04:51 +01:00
_selector.RemoveInteractable(selected);
//_selector.SelectedInteractable = null;
//_selector.SelectNext();
2024-06-09 18:19:57 +02:00
}
2024-08-24 15:25:30 +02:00
2024-06-09 18:19:57 +02:00
//var spaceState = GetWorld2D().DirectSpaceState;
2024-08-24 15:25:30 +02:00
2024-06-09 18:19:57 +02:00
//var query = PhysicsRayQueryParameters2D.Create(Vector2.Zero, )
2024-02-26 23:45:20 +01:00
}
2024-02-27 17:16:55 +01:00
private void HandleShoot()
{
2025-02-20 16:12:53 +01:00
if (!Input.IsActionPressed(_shootActionName)) return;
_weaponProvider.Shoot(this._facingDirection);
2024-02-27 17:16:55 +01:00
}
2024-02-26 23:45:20 +01:00
private void SetAnimation()
{
if (Velocity.X == 0 && Velocity.Y == 0)
{
_animatedSprite.SpeedScale = 0;
}
else
{
_animatedSprite.SpeedScale = 1;
}
if (Velocity.X > 0)
{
_animatedSprite.Play("walk_right");
}
else if (Velocity.X < 0)
{
_animatedSprite.Play("walk_left");
}
else if (Velocity.Y > 0)
{
_animatedSprite.Play("walk_down");
}
else if (Velocity.Y < 0)
{
_animatedSprite.Play("walk_up");
}
}
2024-02-26 17:35:40 +01:00
public Vector2 GetInput()
2024-02-26 08:33:37 +01:00
{
2024-02-26 17:35:40 +01:00
return Input.GetVector("left", "right", "up", "down");
2024-02-26 08:33:37 +01:00
}
2025-02-28 11:17:28 +01:00
2025-01-27 17:30:45 +01:00
private Vector2 GetRightStickInput()
{
return new Vector2(
2025-02-28 11:17:28 +01:00
Input.GetAxis("aim_left", "aim_right"),
2025-01-27 17:30:45 +01:00
Input.GetAxis("aim_up", "aim_down")
);
}
2024-02-26 08:33:37 +01:00
2024-05-01 16:39:14 +02:00
private Vector2 CalculateCrosshairPosition()
{
return _facingDirection * CrosshairDistance;// + this.Position;
//var angle = Mathf.Atan2(this.Position.X, this.Position.Y);
//var cPos = new Vector2(this.Position.X + CrosshairDistance * Godot.Mathf.Cos(angle), this.Position.Y + CrosshairDistance * Godot.Mathf.Sin(angle));
}
2025-02-28 11:17:28 +01:00
2025-02-16 16:55:33 +01:00
public override void _Process(double delta)
2024-08-24 15:25:30 +02:00
{
2025-02-20 16:12:53 +01:00
if (_isDestroyed)
{
if (Input.IsActionJustPressed(_shootActionName))
Respawn();
return;
2025-02-28 11:17:28 +01:00
}
;
2025-02-16 16:55:33 +01:00
SetAnimation();
2025-02-06 15:57:03 +01:00
if (!_canMove) return;
2025-02-16 16:55:33 +01:00
2024-05-01 11:48:04 +02:00
_movementDirection = GetInput();
2025-02-16 16:55:33 +01:00
2025-02-20 16:12:53 +01:00
_isStrafing = Input.IsActionPressed(_strafeActionName);
2025-01-28 10:43:35 +01:00
// Toggle visibility of the hitbox sprite based on strafing
if (HitboxSprite != null)
{
HitboxSprite.Visible = _isStrafing;
}
2025-02-28 11:17:28 +01:00
2025-01-27 17:30:45 +01:00
_rightStickInput = GetRightStickInput();
2025-02-28 11:17:28 +01:00
2025-01-27 17:30:45 +01:00
// Update Facing Direction
if (!_isStrafing)
2024-08-24 15:25:30 +02:00
{
2025-01-27 17:30:45 +01:00
if (_rightStickInput.Length() > 0.1f) // If the right stick is moved
{
_facingDirection = _rightStickInput.Normalized();
}
else if (_movementDirection != Vector2.Zero) // Fall back to movement direction
{
_facingDirection = _movementDirection;
}
2024-05-01 11:48:04 +02:00
}
2025-02-16 16:55:33 +01:00
HandleShoot();
FindInteractable();
2025-02-20 16:12:53 +01:00
if (Input.IsActionJustPressed(_nextWeaponActionName))
2025-02-16 16:55:33 +01:00
{
2025-02-28 18:50:42 +01:00
_weaponProvider.NextWeapon();
2025-02-16 16:55:33 +01:00
}
2025-02-20 16:12:53 +01:00
if (Input.IsActionJustPressed(_previousWeaponActionName))
2025-02-16 16:55:33 +01:00
{
2025-02-28 18:50:42 +01:00
_weaponProvider.PreviousWeapon();
2025-02-16 16:55:33 +01:00
}
2025-02-28 11:17:28 +01:00
_crosshair.Position = CalculateCrosshairPosition();
2025-02-16 16:55:33 +01:00
}
2025-02-20 16:12:53 +01:00
public void Respawn()
{
if (!_isDestroyed) return;
_isDestroyed = false;
this.GlobalPosition = LastCheckPointPosition;
_healthProvider.FillResource();
this.Visible = true;
}
2025-02-16 16:55:33 +01:00
public override void _PhysicsProcess(double delta)
{
2025-02-20 16:12:53 +01:00
if (_isDestroyed) return;
2025-02-16 16:55:33 +01:00
if (!_canMove) return;
2025-02-28 11:17:28 +01:00
Velocity = _movementDirection * MovementSpeed;
2024-02-26 17:35:40 +01:00
2024-02-26 08:33:37 +01:00
MoveAndSlide();
2024-06-09 18:19:57 +02:00
}
2025-02-06 15:57:03 +01:00
2024-06-09 18:19:57 +02:00
private void _on_interaction_controller_area_entered(Area2D area)
{
2025-02-06 15:57:03 +01:00
if (!_canMove) return;
2024-06-09 18:19:57 +02:00
// Replace with function body.
2025-01-30 17:43:39 +01:00
if (area.IsInGroup("Interactable") && area is Interactable interactable && interactable.CanActivate())
2024-06-09 18:19:57 +02:00
{
2025-01-29 14:54:01 +01:00
Debug.WriteLine($"Interactable {area.Name} Entered");
2024-06-09 18:19:57 +02:00
2025-01-30 08:34:09 +01:00
EmitSignal(nameof(InteractableAreaEntered), interactable);
2025-01-30 15:45:29 +01:00
if (_selector == null) return;
_selector.AddInteractable(interactable);
//_selector.SelectedInteractable = interactable;
2025-02-28 11:17:28 +01:00
2024-06-09 18:19:57 +02:00
}
2024-02-26 08:33:37 +01:00
}
2024-08-18 17:38:32 +02:00
2025-01-29 14:54:01 +01:00
private void _on_interaction_controller_area_exited(Area2D area)
{
2025-02-06 15:57:03 +01:00
if (!_canMove) return;
2025-02-28 11:17:28 +01:00
if (area.IsInGroup("Interactable") && area is Interactable interactable)
2025-01-30 08:34:09 +01:00
{
Debug.WriteLine($"Interactable {area.Name} Exited");
EmitSignal(nameof(InteractableAreaExited), interactable);
2025-02-28 11:17:28 +01:00
2025-01-30 15:45:29 +01:00
if (_selector == null) return;
_selector.RemoveInteractable(interactable);
2025-01-30 08:34:09 +01:00
}
2025-01-29 14:54:01 +01:00
}
2024-08-18 17:38:32 +02:00
private void Explode()
{
Debug.WriteLine("Ded");
//CreateParticles();
//CreateDebris();
2025-02-20 16:12:53 +01:00
// if (GameOverScene != null)
// {
// GetTree().ChangeSceneToFile(GameOverScene);
// }
// else
// {
// QueueFree();
// }
var particles = this.CreateSibling<AutodeleteParticle>(_deathParticles, this.GlobalPosition);
//particles.Init();
this.Visible = false;
EmitSignal(SignalName.Death);
2024-08-18 17:38:32 +02:00
}
2025-02-11 19:00:01 +01:00
public void Hit(float damage, DamageType type = DamageType.Neutral)
2024-08-18 17:38:32 +02:00
{
2025-02-06 15:57:03 +01:00
if (!_canMove) return;
2024-08-18 17:38:32 +02:00
GD.Print($"Player damaged for {damage}");
if (_isDestroyed) return;
2024-08-24 15:25:30 +02:00
2025-02-28 11:17:28 +01:00
if (CurrentShield > 0 && type is not DamageType.Explosive or DamageType.Acid)
{
2025-02-16 17:59:46 +01:00
// Reduce shield
2025-02-22 17:08:19 +01:00
PlayShieldAnimation();
2025-02-16 17:59:46 +01:00
CurrentShield -= damage;
2025-02-28 11:17:28 +01:00
if (CurrentShield < 0)
{
2025-02-16 17:59:46 +01:00
CurrentHealth -= Math.Abs(CurrentShield);
CurrentShield = 0;
}
}
2025-02-28 11:17:28 +01:00
else
{
if (type is DamageType.Fire)
{
2025-02-16 17:59:46 +01:00
CurrentHealth -= damage * 2;
}
2025-02-28 11:17:28 +01:00
else
{
2025-02-16 17:59:46 +01:00
CurrentHealth -= damage;
}
2025-02-22 17:08:19 +01:00
Blink();
2025-02-22 14:45:46 +01:00
}
2025-01-28 09:17:35 +01:00
if (!(CurrentHealth <= 0)) return;
2024-08-18 17:38:32 +02:00
_isDestroyed = true;
Explode();
}
2025-02-28 11:17:28 +01:00
private void PlayShieldAnimation()
2025-02-22 17:08:19 +01:00
{
if (_shieldParticles is null) return;
_shieldParticles.Emitting = true;
}
2025-02-28 11:17:28 +01:00
public void Blink()
2025-02-22 17:08:19 +01:00
{
if (BlinkShader != null)
{
_ = BlinkAsync();
}
}
private async Task BlinkAsync()
2025-02-22 14:45:46 +01:00
{
((ShaderMaterial)_animatedSprite.Material).Shader = BlinkShader;
Tween tween = GetTree().CreateTween();
tween.TweenMethod(Callable.From((float value) => SetShaderBlinkIntensity(value)), 1f, 0, 0.5);
await ToSignal(tween, "finished");
}
2025-02-28 11:17:28 +01:00
public async Task Teleport()
2025-02-22 14:45:46 +01:00
{
((ShaderMaterial)_animatedSprite.Material).Shader = BlinkShader;
Tween tween = GetTree().CreateTween();
tween.TweenMethod(Callable.From((float value) => SetShaderScanlineDensity(value)), 0f, 50f, 0.5);
tween.Parallel().TweenMethod(Callable.From((float value) => SetShaderTeleportProgress(value)), 0f, 1f, 0.5);
await ToSignal(tween, "finished");
}
2025-02-28 11:17:28 +01:00
public async Task UnTeleport()
2025-02-22 14:45:46 +01:00
{
((ShaderMaterial)_animatedSprite.Material).Shader = BlinkShader;
Tween tween = GetTree().CreateTween();
tween.TweenMethod(Callable.From((float value) => SetShaderTeleportProgress(value)), 1f, 0f, 0.5);
tween.Parallel().TweenMethod(Callable.From((float value) => SetShaderScanlineDensity(value)), 50f, 0f, 0.5);
await ToSignal(tween, "finished");
}
private void SetShaderTeleportProgress(float value)
{
((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("teleport_progress", value);
}
private void SetShaderScanlineDensity(float value)
{
((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("scanline_density", value);
}
private void SetShaderBlinkIntensity(float newValue)
{
((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("blink_intensity", newValue);
}
2025-02-16 17:59:46 +01:00
2024-08-18 17:38:32 +02:00
public bool IsDestroyed()
{
return _isDestroyed;
}
2024-08-24 15:25:30 +02:00
private void _on_damage_hit_box_area_entered(Area2D area)
{
2025-02-06 15:57:03 +01:00
if (!_canMove) return;
2025-02-15 17:51:06 +01:00
if (area is Bullet bullet && bullet.BulletOwner != BulletGroup)
2024-08-24 15:25:30 +02:00
{
2025-06-08 16:33:38 +02:00
if (!bullet.Enabled) return;
2025-02-11 19:00:01 +01:00
this.Hit(bullet.Damage, bullet.DamageType);
2025-02-20 12:17:21 +01:00
bullet.RequestCollisionDestruction();
2024-08-18 17:38:32 +02:00
}
}
2024-02-26 08:33:37 +01:00
}
2025-02-28 13:50:52 +01:00