using Godot; using System; using System.Diagnostics; using Cirno.Scripts; public partial class Weapon : Node2D { [Export] public PackedScene BulletScene { get; set; } [Export] public Marker2D Muzzle { get; set; } [Export] public double RateOfFire = 0.4f; [Export] public int BulletCapacity = 20; [Export] public double ReloadTime = 1.0f; [Export] public float BulletSpeed = 100f; [Export] public bool AutoReload = true; [Export] public bool InfiniteAmmo = true; [Export] public int BulletsPerShot = 1; [Export] public float BulletsSpreadAngle = 0f; public int Ammo { get; set; } = 0; public int LoadedAmmo { get; private set; } public Vector2 ShootDirection { get; set; } = Vector2.Zero; private Timer _cooldownTimer; private Marker2D _muzzle; private Node2D _bulletsContainer; private GameManager _gameManager; // Called when the node enters the scene tree for the first time. public override void _Ready() { _muzzle = GetNode("./Muzzle"); _cooldownTimer = GetNode("./ShootTimer"); _gameManager = GetNode("/root/GameScene"); } public void Reload() { _cooldownTimer.Start(ReloadTime); if (InfiniteAmmo) { LoadedAmmo = BulletCapacity; } else { // TODO: Calculate subtraction, etc LoadedAmmo = BulletCapacity; } } public void Shoot() { // Waiting on reload or Rate of Fire cooldown? if (!_cooldownTimer.IsStopped()) { return; } // Out of ammo? if (LoadedAmmo <= 0) { if (AutoReload) { Reload(); } return; } // TODO: Shoot at muzzle position, need to provide a way to turn it, on a radius? float halfSpread = BulletsSpreadAngle / 2f; float spreadStep = BulletsPerShot > 1 ? BulletsSpreadAngle / (BulletsPerShot - 1) : 0; for (int i = 0; i < BulletsPerShot; i++) { // Calculate angle offset for this bullet float spreadOffset = -halfSpread + (spreadStep * i); // Rotate the ShootDirection by the spread angle Vector2 spreadDirection = ShootDirection.Rotated(Mathf.DegToRad(spreadOffset)); var bullet = this.CreateChildOf(_gameManager.BulletsContainer, BulletScene, _muzzle.GlobalPosition); if (bullet == null) { GD.PrintErr("Bullet is null, not shooting"); return; }; //bullet.SetDirection(ShootDirection); bullet.SetDirection(spreadDirection); bullet.Speed = BulletSpeed; } LoadedAmmo -= 1; _cooldownTimer.Start(RateOfFire); } }