Traveller/scripts/weapon/WeaponTemplate.cs

118 lines
3.8 KiB
C#
Raw Normal View History

2024-04-28 13:55:19 +00:00
using System;
using ColdMint.scripts.character;
using ColdMint.scripts.pickable;
2024-04-28 13:55:19 +00:00
using Godot;
namespace ColdMint.scripts.weapon;
2024-04-28 13:55:19 +00:00
/// <summary>
/// <para>WeaponTemplate</para>
/// <para>武器模板</para>
/// </summary>
public abstract partial class WeaponTemplate : PickAbleTemplate
2024-04-28 13:55:19 +00:00
{
private float _gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle();
2024-07-28 09:53:54 +00:00
/// <summary>
/// <para>Fire audio playback component</para>
/// <para>开火音效播放组件</para>
/// </summary>
private AudioStreamPlayer2D? _audioStreamPlayer2D;
public override void _Ready()
{
base._Ready();
_audioStreamPlayer2D = GetNodeOrNull<AudioStreamPlayer2D>("Marker2D/AudioStreamPlayer2D");
}
public override void Use(Node2D? owner, Vector2 targetGlobalPosition)
{
Fire(owner, targetGlobalPosition);
}
2024-04-28 13:55:19 +00:00
private DateTime? _lastFiringTime;
/// <summary>
/// <para>Firing interval</para>
/// <para>开火间隔</para>
/// </summary>
2024-04-28 13:55:19 +00:00
private TimeSpan _firingInterval;
private long _firingIntervalAsMillisecond = 100;
[Export] protected long FiringIntervalAsMillisecond
{
get => _firingIntervalAsMillisecond;
set
{
_firingIntervalAsMillisecond = value;
_firingInterval = TimeSpan.FromMilliseconds(_firingIntervalAsMillisecond);
}
}
2024-04-28 13:55:19 +00:00
/// <summary>
/// <para>The recoil of the weapon</para>
/// <para>武器的后坐力</para>
/// </summary>
/// <remarks>
///<para>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.</para>
///<para>武器开火要对使用者施加多大的后坐力单位格数力的X方向是自动推断的。</para>
/// </remarks>
[Export] private Vector2 _recoil;
2024-04-28 13:55:19 +00:00
/// <summary>
/// <para>Discharge of the weapon</para>
/// <para>武器开火</para>
/// </summary>
/// <remarks>
///<param name="owner">
///<para>owner</para>
///<para>武器所有者</para>
/// </param>
/// <param name="enemyGlobalPosition">
///<para>enemyGlobalPosition</para>
///<para>敌人所在位置</para>
/// </param>
/// </remarks>
public void Fire(Node2D? owner, Vector2 enemyGlobalPosition)
2024-04-28 13:55:19 +00:00
{
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)
2024-04-28 13:55:19 +00:00
{
return;
}
if (owner is CharacterTemplate characterTemplate)
{
//We check the recoil of the weapon before each firing.
//我们在每次开火之前,检查武器的后坐力。
if (_recoil != Vector2.Zero)
2024-04-28 13:55:19 +00:00
{
var force = new Vector2();
var forceX = Math.Abs(_recoil.X);
if (Math.Abs(RotationDegrees) < 90)
2024-04-28 13:55:19 +00:00
{
//The weapon goes to the right, and we apply a recoil to the left
//武器朝向右边我们向左施加后坐力
forceX = -forceX;
2024-04-28 13:55:19 +00:00
}
force.X = forceX * Config.CellSize;
force.Y = _recoil.Y * Config.CellSize;
characterTemplate.AddForce(force);
}
2024-04-28 13:55:19 +00:00
}
2024-07-28 09:53:54 +00:00
_audioStreamPlayer2D?.Play();
DoFire(owner, enemyGlobalPosition);
_lastFiringTime = nowTime;
2024-04-28 13:55:19 +00:00
}
/// <summary>
/// <para>Execute fire</para>
/// <para>执行开火</para>
/// </summary>
protected abstract void DoFire(Node2D? owner, Vector2 enemyGlobalPosition);
2024-04-28 13:55:19 +00:00
}