Traveller/scripts/weapon/WeaponTemplate.cs

114 lines
3.5 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;
2024-07-28 09:53:54 +00:00
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 long _recoilStrength;
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;
}
var result = DoFire(owner, enemyGlobalPosition);
if (result)
{
if (owner is CharacterTemplate characterTemplate)
2024-04-28 13:55:19 +00:00
{
if (_recoilStrength != 0)
{
characterTemplate.AddForce(enemyGlobalPosition.DirectionTo(characterTemplate.GlobalPosition) * _recoilStrength * Config.CellSize);
}
}
_audioStreamPlayer2D?.Play();
}
_lastFiringTime = nowTime;
2024-04-28 13:55:19 +00:00
}
/// <summary>
/// <para>Execute fire</para>
/// <para>执行开火</para>
/// </summary>
/// <returns>
///<para>Return Is the fire successful?</para>
///<para>返回是否成功开火?</para>
/// </returns>
protected abstract bool DoFire(Node2D? owner, Vector2 enemyGlobalPosition);
2024-04-28 13:55:19 +00:00
}