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 long _recoilStrength; /// /// 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; } var result = DoFire(owner, enemyGlobalPosition); if (result) { if (owner is CharacterTemplate characterTemplate) { if (_recoilStrength != 0) { characterTemplate.AddForce(enemyGlobalPosition.DirectionTo(characterTemplate.GlobalPosition) * _recoilStrength * Config.CellSize); } } _audioStreamPlayer2D?.Play(); } _lastFiringTime = nowTime; } /// /// Execute fire /// 执行开火 /// /// ///Return Is the fire successful? ///返回是否成功开火? /// protected abstract bool DoFire(Node2D? owner, Vector2 enemyGlobalPosition); }