using ColdMint.scripts.debug;
using ColdMint.scripts.projectile;
using ColdMint.scripts.projectile.decorator;
using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.weapon;
///
/// Projectile weapons
/// 抛射体武器
///
///
///These weapons can fire projectiles to attack the enemy.For example: guns and scepters.Generate a bullet to attack the enemy.
///这类武器可发射抛射体,攻击敌人。例如:枪支和法杖。生成一个子弹攻击敌人。
///
public partial class ProjectileWeapon : WeaponTemplate
{
///
/// The formation position of the projectile
/// 抛射体的生成位置
///
private Marker2D? _marker2D;
///
/// Scattering radians
/// 散射弧度
///
[Export] protected float OffsetAngle;
///
/// Offset angle mode
/// 偏移角度模式
///
[Export] protected int OffsetAngleMode = Config.OffsetAngleMode.Random;
///
/// Whether the last offset angle is positive
/// 上次的偏移角度是否为正向的
///
private bool _positiveOffsetAngle = true;
///
/// The number of projectiles fired at once
/// 一次可以发射多少个子弹
///
[Export] protected float NumberOfProjectiles = 1;
[Export] protected PackedScene[] ProjectileScenes { get; set; } = [];
///
/// Whether to launch in the order of the projectile list
/// 是否按照抛射体列表的循序发射
///
[Export]
protected bool Sequentially { get; set; }
private int _projectileIndex;
public override void _Ready()
{
base._Ready();
_marker2D = GetNode("Marker2D");
}
///
/// GetNextProjectileScene
/// 获取下一个抛射体
///
///
private PackedScene GetNextProjectileScene()
{
if (Sequentially)
{
_projectileIndex = (_projectileIndex + 1) % ProjectileScenes.Length;
return ProjectileScenes[_projectileIndex];
}
else
{
return ProjectileScenes[RandomUtils.Instance.Next(ProjectileScenes.Length)];
}
}
///
/// GetRandomAngle
/// 获取随机的偏移弧度
///
///
private float GetRandomAngle()
{
if (OffsetAngle == 0)
{
//If the offset angle is 0, then return 0
//弧度为0,不用偏移。
return 0;
}
if (OffsetAngleMode == Config.OffsetAngleMode.Cross)
{
float result;
if (_positiveOffsetAngle)
{
result = -OffsetAngle / 2;
}
else
{
result = OffsetAngle / 2;
}
_positiveOffsetAngle = !_positiveOffsetAngle;
return result;
}
if (OffsetAngleMode == Config.OffsetAngleMode.AlwaysSame)
{
return OffsetAngle;
}
var min = -OffsetAngle / 2;
return min + RandomUtils.Instance.NextSingle() * OffsetAngle;
}
protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
{
if (owner == null)
{
LogCat.LogError("owner_is_null");
return;
}
if (_marker2D == null)
{
LogCat.LogError("marker2d_is_null");
return;
}
if (GameSceneDepend.ProjectileContainer == null)
{
LogCat.LogError("projectile_container_is_null");
return;
}
//Empty list check
//空列表检查
if (ProjectileScenes is [])
{
LogCat.LogError("projectiles_is_empty");
return;
}
//Get the first projectile
//获取第一个抛射体
var projectileScene = GetNextProjectileScene();
for (int i = 0; i < NumberOfProjectiles; i++)
{
var projectile = NodeUtils.InstantiatePackedScene(projectileScene);
if (projectile == null) return;
if (Config.IsDebug())
{
var nodeSpawnOnKillCharacterDecorator = new NodeSpawnOnKillCharacterDecorator
{
DefaultParentNode = this,
PackedScenePath = "res://prefab/entitys/BlackenedAboriginalWarrior.tscn"
};
projectile.AddProjectileDecorator(nodeSpawnOnKillCharacterDecorator);
}
NodeUtils.CallDeferredAddChild(GameSceneDepend.ProjectileContainer, projectile);
projectile.Owner = owner;
projectile.TargetNode = GameSceneDepend.TemporaryTargetNode;
projectile.Velocity =
(_marker2D.GlobalPosition.DirectionTo(enemyGlobalPosition) * projectile.Speed)
.Rotated(GetRandomAngle());
projectile.Position = _marker2D.GlobalPosition;
}
}
}