cirnogodot/Scripts/AttackPatterns/SpiralPattern.cs

211 lines
No EOL
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Cirno.Scripts.Actors;
using Cirno.Scripts.Components;
using Cirno.Scripts.Resources;
using Godot;
using Godot.Collections;
using Array = System.Array;
namespace Cirno.Scripts.AttackPatterns;
[GlobalClass]
public partial class SpiralPattern : AttackPattern
{
[Export] public BulletResource BulletResource { get; set; }
//Export] public PackedScene BulletScene;
//[Export] private float _bulletLifeTime = 20f; // Switch to res
//[Export] private bool _destroyOnCollision = false; // Switch to res
//[Export] private float bulletSpeed = 5f; // Switch to res
[Export] public int bulletCount = 16;
[Export] public float rotationSpeed = 0f;
[Export] public float _rotationOffset = 0f;
[Export] public float duration = 5f;
[Export] public float spread = 360f;
[Export] public float burstInterval = 0.5f;
[ExportCategory("Burst")] [Export] public int ShotsPerBurst { get; private set; } = 100;
[Export] public float BurstRate { get; private set; } = 0f;
//[Export] private BulletOwner owner = BulletOwner.Enemy; // Switch to res
//[Export] private DamageType _damageType = DamageType.Neutral; // Switch to res
//[Export] private float _bulletDamage = 1f; // Switch to res
// [ExportGroup("Modifiers")] [Export] private BulletCreationModifier _modifier;
// [ExportGroup("Modifiers")] [Export] private Array<TimeModifier> _timeModifiers;
[ExportCategory("Other")] [Export] public bool _targetPlayer = false;
protected virtual BulletInfo MakeBullet(Vector2 position, Vector2 direction, float angleOffset)
{
var bl = BulletResource.MakeBullet(position, bulletCount, angleOffset);
bl.Direction = direction;
return bl;
// return new BulletInfo()
// {
// Position = position,
// Direction = direction,
// LifeTime = _bulletLifeTime,
// DestroyOnCollision = _destroyOnCollision,
// Speed = bulletSpeed,
// Owner = owner,
// DamageType = _damageType,
// Damage = _bulletDamage,
// BulletCount = bulletCount,
// Spread = spread,
// BulletScene = BulletScene,
// RotationOffset = angleOffset,
// Modifier = _modifier,
// TimeModifiers = _timeModifiers.ToList()// _timeModifiers.Select(x => x.MakeClone()).ToList()
// // TimeModifiers = _timeModifiers?.Where(mod => mod != null).ToList() ?? new List<TimeModifier>()
// };
}
public override IPatternMachine MakeMachine(Node2D parent)
{
return new SpiralPatternMachine(this, parent);
}
public class SpiralPatternMachine(SpiralPattern pattern, Node2D parent) : IPatternMachine
{
public Node2D Parent => parent;
private double timer;
private double burstTimer;
//private double _burstRateTimer;
private BulletSpawner spawner;
private ShootStatus _state = ShootStatus.Idle;
private int _burstBullets;
public void Start()
{
timer = 0;
_burstBullets = pattern.ShotsPerBurst;
burstTimer = pattern.burstInterval; // start immediately
//_burstRateTimer = pattern.burstInterval;
spawner = parent.GetNode<BulletSpawner>("BulletSpawner");
_state = ShootStatus.Shooting;
}
private void WaitingBurstUpdate(double delta)
{
timer += delta;
burstTimer += delta;
if (burstTimer >= pattern.burstInterval)
{
_state = ShootStatus.Shooting;
}
}
private void WaitingReloadUpdate(double delta)
{
timer += delta;
burstTimer += delta;
if (burstTimer >= pattern.BurstRate)
{
_burstBullets = pattern.ShotsPerBurst;
_state = ShootStatus.Shooting;
}
}
private void ShootingUpdate(double delta)
{
timer += delta;
burstTimer = 0;
Shoot();
_burstBullets--;
if (_burstBullets <= 0)
{
_state = ShootStatus.WaitingReload;
}
else
{
_state = ShootStatus.WaitingBurst;
}
}
public void UpdatePattern(double delta)
{
switch (_state)
{
case ShootStatus.Idle:
case ShootStatus.Done:
return;
case ShootStatus.Shooting:
ShootingUpdate(delta);
break;
case ShootStatus.WaitingBurst:
WaitingBurstUpdate(delta);
break;
case ShootStatus.WaitingReload:
WaitingReloadUpdate(delta);
break;
}
if (timer >= pattern.duration)
{
_state = ShootStatus.Done;
}
// timer += delta;
// burstTimer += delta;
// //_burstRateTimer += delta;
//
// if (timer > pattern.duration)
// {
// return;
// }
//
// if (burstTimer < pattern.burstInterval) return;
//
// Shoot();
//
//
//
// burstTimer = 0;
}
private void Shoot()
{
float angleOffset = pattern._rotationOffset + (float)(pattern.rotationSpeed * timer);
Vector2 direction = pattern.BulletResource.Direction;
if (pattern._targetPlayer && GameManager.Instance.PlayerPosition.HasValue)
{
direction = (GameManager.Instance.PlayerPosition.Value - Parent.GlobalPosition).Normalized();
}
var bullet = pattern.BulletResource.MakeBullet(Parent.GlobalPosition, pattern.bulletCount,
pattern.spread, angleOffset);
bullet.Direction = direction;
//spawner.SpawnBullet(MakeBullet(Boss.GlobalPosition, direction, angleOffset));
spawner.SpawnBullet(bullet);
}
public bool IsComplete()
{
//return timer >= pattern.duration;
return _state is ShootStatus.Done;
}
private enum ShootStatus
{
Idle,
Shooting,
WaitingBurst,
WaitingReload,
Done
}
}
}