mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 11:15:33 +00:00
99 lines
No EOL
3.5 KiB
C#
99 lines
No EOL
3.5 KiB
C#
using Cirno.Scripts.Components;
|
|
using Cirno.Scripts.Controllers;
|
|
using Cirno.Scripts.Weapons;
|
|
using Godot;
|
|
|
|
namespace Cirno.Scripts.Actors;
|
|
|
|
public partial class BulletSpawner3D : Node3D
|
|
{
|
|
public void SpawnBullet(BulletInfo bulletInfo, Vector3 position)
|
|
{
|
|
// Check if this is a laser
|
|
if (bulletInfo.IsLaser && bulletInfo.LaserConfig != null)
|
|
{
|
|
SpawnLaser(bulletInfo, position);
|
|
return;
|
|
}
|
|
|
|
int count = bulletInfo.BulletCount;
|
|
|
|
// Choose base direction (defaults to +X)
|
|
Vector2 baseDirection = bulletInfo.Direction == Vector2.Zero
|
|
? Vector2.Right
|
|
: bulletInfo.Direction.Normalized();
|
|
|
|
float baseAngle = Mathf.Atan2(baseDirection.Y, baseDirection.X); // angle in radians
|
|
float offsetRadians = Mathf.DegToRad(bulletInfo.RotationOffset);
|
|
|
|
// Calculate per-bullet spread angle step
|
|
float spreadRadians = Mathf.DegToRad(bulletInfo.Spread);
|
|
|
|
// 👇 Configure this depending on desired pattern
|
|
bool isFullCircle = Mathf.Abs(bulletInfo.Spread - 360f) < 0.01f;
|
|
float angleStep = isFullCircle
|
|
? spreadRadians / count // Full circle: divide evenly across bullets
|
|
: count > 1
|
|
? spreadRadians / (count - 1) // Fan spread: divide across gaps
|
|
: 0f;
|
|
|
|
// Determine starting angle for bullet pattern
|
|
float startAngle = isFullCircle
|
|
? baseAngle + offsetRadians // Full circle starts at baseAngle + offset
|
|
: baseAngle + offsetRadians - (spreadRadians / 2.0f); // Fan starts centered
|
|
|
|
// Spawn bullets
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
Bullet3D bullet = PoolingManager.Instance.SpawnBullet<Bullet3D>(bulletInfo.OriginalBulletResource);
|
|
bullet.GlobalPosition = position;
|
|
|
|
// Optionally apply modifiers (null-safe)
|
|
if (bulletInfo.Modifier is not null)
|
|
{
|
|
bulletInfo = bulletInfo.Modifier.ModifyBullet(bulletInfo, i, count);
|
|
}
|
|
|
|
bullet.Initialize(bulletInfo);
|
|
|
|
// Compute final angle for this bullet
|
|
float angle = startAngle + angleStep * i;
|
|
|
|
// Optional: Tiny jitter to avoid precision collapse
|
|
// angle += i * 0.0001f;
|
|
|
|
Vector2 bulletDirection = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)).Normalized();
|
|
bullet.SetDirection(bulletDirection);
|
|
|
|
// Optional: Debug offset to visualize all bullets
|
|
// bullet.GlobalPosition += new Vector3(i * 0.1f, 0, 0);
|
|
|
|
//GD.Print($"Bullet {i}: Angle={Mathf.RadToDeg(angle)}, Direction={bulletDirection}");
|
|
}
|
|
}
|
|
|
|
private void SpawnLaser(BulletInfo bulletInfo, Vector3 position)
|
|
{
|
|
// Lasers don't use bullet count/spread the same way
|
|
// Each laser is typically a single beam
|
|
LaserBullet3D laser = PoolingManager.Instance.SpawnBullet<LaserBullet3D>(bulletInfo.OriginalBulletResource);
|
|
laser.GlobalPosition = position;
|
|
|
|
// Apply modifiers if present
|
|
if (bulletInfo.Modifier is not null)
|
|
{
|
|
bulletInfo = bulletInfo.Modifier.ModifyBullet(bulletInfo, 0, 1);
|
|
}
|
|
|
|
laser.Initialize(bulletInfo);
|
|
|
|
// Set the laser direction
|
|
Vector2 baseDirection = bulletInfo.Direction == Vector2.Zero
|
|
? Vector2.Right
|
|
: bulletInfo.Direction.Normalized();
|
|
|
|
laser.SetDirection(baseDirection);
|
|
}
|
|
|
|
|
|
} |