using System; using ColdMint.scripts.character; using ColdMint.scripts.pickable; using Godot; namespace ColdMint.scripts.weapon; /// /// WeaponTemplate /// 武器模板 /// public abstract partial class WeaponTemplate : PickAbleTemplate { private float _gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle(); /// /// Fire audio playback component /// 开火音效播放组件 /// private AudioStreamPlayer2D? _audioStreamPlayer2D; public override void _Ready() { base._Ready(); _audioStreamPlayer2D = GetNodeOrNull("Marker2D/AudioStreamPlayer2D"); } public override void Use(Node2D? owner, Vector2 targetGlobalPosition) { Fire(owner, targetGlobalPosition); } private DateTime? _lastFiringTime; /// /// Firing interval /// 开火间隔 /// private TimeSpan _firingInterval; private long _firingIntervalAsMillisecond = 100; [Export] protected long FiringIntervalAsMillisecond { get => _firingIntervalAsMillisecond; set { _firingIntervalAsMillisecond = value; _firingInterval = TimeSpan.FromMilliseconds(_firingIntervalAsMillisecond); } } /// /// The recoil of the weapon /// 武器的后坐力 /// /// ///When the weapon is fired, how much recoil is applied to the user, in units: the number of cells, and the X direction of the force is automatically inferred. ///武器开火,要对使用者施加多大的后坐力,单位:格数,力的X方向是自动推断的。 /// [Export] private Vector2 _recoil; /// /// Discharge of the weapon /// 武器开火 /// /// /// ///owner ///武器所有者 /// /// ///enemyGlobalPosition ///敌人所在位置 /// /// public void Fire(Node2D? owner, Vector2 enemyGlobalPosition) { var nowTime = DateTime.Now; //If the present time minus the time of the last fire is less than the interval between fires, it means that the fire cannot be fired yet. //如果现在时间减去上次开火时间小于开火间隔,说明还不能开火。 if (_lastFiringTime != null && nowTime - _lastFiringTime < _firingInterval) { return; } if (owner is CharacterTemplate characterTemplate) { //We check the recoil of the weapon before each firing. //我们在每次开火之前,检查武器的后坐力。 if (_recoil != Vector2.Zero) { var force = new Vector2(); var forceX = Math.Abs(_recoil.X); if (Math.Abs(RotationDegrees) < 90) { //The weapon goes to the right, and we apply a recoil to the left //武器朝向右边我们向左施加后坐力 forceX = -forceX; } force.X = forceX * Config.CellSize; force.Y = _recoil.Y * Config.CellSize; characterTemplate.AddForce(force); } } _audioStreamPlayer2D?.Play(); DoFire(owner, enemyGlobalPosition); _lastFiringTime = nowTime; } /// /// Execute fire /// 执行开火 /// protected abstract void DoFire(Node2D? owner, Vector2 enemyGlobalPosition); }