cirnogodot/Scripts/Components/BulletSpawner.cs

119 lines
5.3 KiB
C#
Raw Normal View History

2025-02-09 09:37:43 +01:00
using System;
2025-02-09 11:48:30 +01:00
using System.Collections.Generic;
2025-02-09 09:37:43 +01:00
using Cirno.Scripts.Resources;
2025-02-14 10:59:32 +01:00
using Cirno.Scripts.Weapons;
2025-02-05 19:41:49 +01:00
using Godot;
2025-02-09 11:48:30 +01:00
using Godot.Collections;
2025-02-05 19:41:49 +01:00
namespace Cirno.Scripts.Components;
public partial class BulletSpawner : Node2D
{
[Export] public PackedScene BulletScene;
private GameManager _gameManager;
2025-02-27 18:48:13 +01:00
2025-02-05 19:41:49 +01:00
public override void _Ready()
{
2025-02-11 19:00:01 +01:00
_gameManager = this.GetGameManager();
2025-02-05 19:41:49 +01:00
}
2025-02-09 09:37:43 +01:00
public void SpawnBullet(BulletInfo bulletInfo)
{
2025-02-14 10:59:32 +01:00
var bulletScene = bulletInfo.BulletScene ?? BulletScene;
Bullet bullet;
2025-02-27 18:48:13 +01:00
2025-02-09 09:37:43 +01:00
for (int i = 0; i < bulletInfo.BulletCount; i++)
{
2025-02-14 10:59:32 +01:00
if (bulletInfo.IsLaser)
bullet = this.CreateChildOf<LaserBullet>(_gameManager.BulletsContainer, bulletScene, bulletInfo.Position);
else
bullet = this.CreateChildOf<Bullet>(_gameManager.BulletsContainer, bulletScene, bulletInfo.Position);
2025-02-27 18:48:13 +01:00
2025-02-14 10:59:32 +01:00
// var bullet = this.CreateChildOf<Bullet>(_gameManager.BulletsContainer, bulletInfo.BulletScene ?? BulletScene, bulletInfo.Position);
2025-02-27 18:48:13 +01:00
2025-02-13 21:55:14 +01:00
bullet.Initialize(bulletInfo, _gameManager);
2025-02-13 18:25:55 +01:00
2025-02-09 09:37:43 +01:00
float modifiedSpeed = bulletInfo.Modifier?.ModifySpeed(bulletInfo.Speed, i, bulletInfo.BulletCount) ?? bulletInfo.Speed;
bullet.Speed = modifiedSpeed;
Vector2 baseDirection = bulletInfo.Direction == Vector2.Zero ? Vector2.Right : bulletInfo.Direction.Normalized();
float baseAngle = Mathf.Atan2(baseDirection.Y, baseDirection.X);
2025-02-27 18:48:13 +01:00
2025-02-13 18:25:55 +01:00
float offsetRadians = Mathf.DegToRad(bulletInfo.RotationOffset);
2025-02-27 18:48:13 +01:00
float spreadStep = Mathf.DegToRad(bulletInfo.Spread) / Mathf.Max(1, bulletInfo.BulletCount - 1); // Ensure proper spread spacing, also add 1 if 0
2025-02-13 18:25:55 +01:00
float angle = baseAngle + offsetRadians + (spreadStep * i);
// float angle = baseAngle + Mathf.DegToRad(bulletInfo.RotationOffset + (bulletInfo.Spread / bulletInfo.BulletCount) * i);
2025-02-27 18:48:13 +01:00
2025-02-09 09:37:43 +01:00
Vector2 bulletDirection = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
2025-02-27 18:48:13 +01:00
2025-02-09 09:37:43 +01:00
bullet.SetDirection(bulletDirection);
}
}
2025-02-27 18:48:13 +01:00
2025-02-05 19:41:49 +01:00
public void SpawnBullet(Vector2 position, Vector2 direction, float speed, BulletOwner owner, int count = 1, float angleOffset = 0, float spread = 0, PackedScene bulletScene = null, IBulletModifier modifier = null)
{
for (int i = 0; i < count; i++)
{
var bullet = this.CreateChildOf<Bullet>(_gameManager.BulletsContainer, bulletScene ?? BulletScene, position);
2025-02-27 18:48:13 +01:00
2025-02-05 19:41:49 +01:00
//var bullet = BulletScene.Instantiate<Bullet>();
bullet.Position = position;
//bullet.Speed = speed;
2025-02-27 18:48:13 +01:00
2025-02-09 09:37:43 +01:00
float modifiedSpeed = modifier?.ModifySpeed(speed, i, count) ?? speed;
2025-02-05 19:41:49 +01:00
bullet.Speed = modifiedSpeed;
Vector2 baseDirection = direction == Vector2.Zero ? Vector2.Right : direction.Normalized();
float baseAngle = Mathf.Atan2(baseDirection.Y, baseDirection.X);
//float angle = angleOffset + (360 / count) * i;
float angle = baseAngle + Mathf.DegToRad(angleOffset + (spread / count) * i);
Vector2 bulletDirection = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
//Vector2 bulletDirection = new Vector2(Mathf.Cos(Mathf.DegToRad(angle)), Mathf.Sin(Mathf.DegToRad(angle)));
bullet.SetDirection(bulletDirection);
//GetParent().AddChild(bullet);
}
}
2025-02-27 18:48:13 +01:00
2025-02-05 19:41:49 +01:00
public void SpawnTargetedBullet(Vector2 position, Vector2 target, float speed, BulletOwner owner, PackedScene bulletScene = null, int burstCount = 1, float spread = 0, IBulletModifier modifier = null)
{
Vector2 direction = (target - position).Normalized();
SpawnBullet(position, direction, speed, owner, burstCount, spread: spread, bulletScene: bulletScene, modifier: modifier);
}
2025-02-09 09:37:43 +01:00
}
public class BulletInfo
{
public Vector2 Position { get; set; }
public Vector2 Direction { get; set; }
public float Speed { get; set; }
2025-02-09 23:20:49 +01:00
public float LifeTime { get; set; }
2025-02-20 12:17:21 +01:00
public bool DestroyOnCollision { get; set; }
2025-02-09 09:37:43 +01:00
public BulletOwner Owner { get; set; }
2025-02-11 19:00:01 +01:00
public DamageType DamageType { get; set; }
public float Damage { get; set; }
2025-02-09 09:37:43 +01:00
public int BulletCount { get; set; }
public float RotationSpeed { get; set; }
public float RotationOffset { get; set; }
//public double Time { get; set; }
public float Spread { get; set; }
2025-04-09 16:41:22 +02:00
public bool RotateSprite { get; set; } = false;
2025-02-27 18:48:13 +01:00
public bool Controllabe { get; set; } = false;
2025-04-26 11:24:20 +02:00
public bool Freezable { get; set; } = true;
2025-02-09 09:37:43 +01:00
public PackedScene BulletScene { get; set; }
2025-02-12 16:20:55 +01:00
public PackedScene DestructionParticlesScene { get; set; }
2025-02-09 09:37:43 +01:00
public IBulletModifier Modifier { get; set; }
2025-02-14 13:47:20 +01:00
public List<TimeModifier> TimeModifiers { get; set; } = new List<TimeModifier>();
2025-04-01 15:46:25 +02:00
public bool Grazeable { get; set; }
public float GrazeValue { get; set; }
2025-02-14 10:59:32 +01:00
#region Laser
public bool IsLaser { get; set; }
public float SpawnDelay { get; set; } = 0.3f; // Delay before beam appears
public float PreFireTime { get; set; } = 0.5f; // Time before laser becomes lethal
public float LethalTime { get; set; } = 1.5f; // Time laser remains lethal
public Color PreFireColor { get; set; } = new Color(1, 0, 0, 0.5f); // Thin red beam
public Color LethalColor { get; set; } = new Color(1, 0, 0, 1.0f); // Thicker beam
#endregion
}