Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / weapon / Weapon.cs
using Godot;
using System;
using System.Collections.Generic;
using Config;

/// <summary>
/// 武器的基类
/// </summary>
public abstract partial class Weapon : ActivityObject, IPackageItem<Role>
{
    /// <summary>
    /// 武器使用的属性数据, 该属性会根据是否是玩家使用武器, 如果是Ai使用武器, 则会返回 AiUseAttribute 的属性对象
    /// </summary>
    public ExcelConfig.WeaponBase Attribute => _weaponAttribute;

    /// <summary>
    /// Ai使用该武器的属性
    /// </summary>
    public ExcelConfig.WeaponBase AiUseAttribute => _aiWeaponAttribute;

    /// <summary>
    /// 玩家使用该武器的属性
    /// </summary>
    public ExcelConfig.WeaponBase PlayerUseAttribute => _playerWeaponAttribute;
    
    private ExcelConfig.WeaponBase _weaponAttribute;
    private ExcelConfig.WeaponBase _playerWeaponAttribute;
    private ExcelConfig.WeaponBase _aiWeaponAttribute;

    public Role Master { get; set; }

    public int PackageIndex { get; set; } = -1;

    /// <summary>
    /// 当前弹夹弹药剩余量
    /// </summary>
    public int CurrAmmo { get; private set; }

    /// <summary>
    /// 剩余弹药量(备用弹药)
    /// </summary>
    public int ResidueAmmo { get; private set; }
    
    /// <summary>
    /// 总弹药量(备用弹药 + 当前弹夹弹药)
    /// </summary>
    public int TotalAmmon => CurrAmmo + ResidueAmmo;

    /// <summary>
    /// 武器管的开火点
    /// </summary>
    [Export, ExportFillNode]
    public Marker2D FirePoint { get; set; }

    /// <summary>
    /// 弹壳抛出的点
    /// </summary>
    [Export, ExportFillNode]
    public Marker2D ShellPoint { get; set; }
    
    /// <summary>
    /// 武器的当前散射半径
    /// </summary>
    public float CurrScatteringRange { get; private set; } = 0;

    /// <summary>
    /// 是否在换弹中
    /// </summary>
    /// <value></value>
    public bool Reloading { get; private set; } = false;

    /// <summary>
    /// 换弹进度 (从 0 到 1)
    /// </summary>
    public float ReloadProgress
    {
        get
        {
            if (!Reloading)
            {
                return 1;
            }

            if (Attribute.AloneReload)
            {
                //总时间
                var total = Attribute.AloneReloadBeginIntervalTime + (Attribute.ReloadTime * Attribute.AmmoCapacity) + Attribute.AloneReloadFinishIntervalTime;
                //当前时间
                float current;
                if (_aloneReloadState == 1)
                {
                    current = (Attribute.AloneReloadBeginIntervalTime - _reloadTimer) + Attribute.ReloadTime * CurrAmmo;
                }
                else if (_aloneReloadState == 2)
                {
                    current = Attribute.AloneReloadBeginIntervalTime + (Attribute.ReloadTime * (CurrAmmo + (1 - _reloadTimer / Attribute.ReloadTime)));
                }
                else
                {
                    current = Attribute.AloneReloadBeginIntervalTime + (Attribute.ReloadTime * CurrAmmo) + (Attribute.AloneReloadFinishIntervalTime - _reloadTimer);
                }

                return current / total;
            }

            return 1 - _reloadTimer / Attribute.ReloadTime;
        }
    }

    /// <summary>
    /// 返回是否在蓄力中,
    /// 注意, 属性仅在 Attribute.LooseShoot == false 时有正确的返回值, 否则返回 false
    /// </summary>
    public bool IsCharging => _looseShootFlag;

    /// <summary>
    /// 返回武器是否在武器背包中
    /// </summary>
    public bool IsInHolster => Master != null;

    /// <summary>
    /// 返回是否真正使用该武器
    /// </summary>
    public bool IsActive => Master != null && Master.WeaponPack.ActiveItem == this;
    
    /// <summary>
    /// 动画播放器
    /// </summary>
    [Export, ExportFillNode]
    public AnimationPlayer AnimationPlayer { get; set; }

    /// <summary>
    /// 是否自动播放 SpriteFrames 的动画
    /// </summary>
    public bool IsAutoPlaySpriteFrames { get; set; } = true;

    /// <summary>
    /// 在没有所属 Master 的时候是否可以触发扳机
    /// </summary>
    public bool NoMasterCanTrigger { get; set; } = true;
    
    /// <summary>
    /// 上一次触发改武器开火的角色, 可能为 null
    /// </summary>
    public Role TriggerRole { get; private set; }
    
    /// <summary>
    /// 武器当前射速
    /// </summary>
    public float CurrentFiringSpeed { get; private set; }
    
    //--------------------------------------------------------------------------------------------

    //触发板机是是否计算弹药消耗
    private bool _triggerCalcAmmon = true;
    
    //用于记录是否有角色操作过这把武器
    private bool _triggerRoleFlag = false;
    
    //是否按下
    private bool _triggerFlag = false;

    //扳机计时器
    private float _triggerTimer = 0;

    //开火前延时时间
    private float _delayedTime = 0;

    //开火间隙时间
    private float _fireInterval = 0;

    //开火武器口角度
    private float _fireAngle = 0;

    //攻击冷却计时
    private float _attackTimer = 0;

    //攻击状态
    private bool _attackFlag = false;
    
    //多久没开火了
    private float _noAttackTime = 0;

    //按下的时间
    private float _downTimer = 0;

    //松开的时间
    private float _upTimer = 0;

    //连发次数
    private int _continuousCount = 0;

    //连发状态记录
    private bool _continuousShootFlag = false;

    //松开扳机是否开火
    private bool _looseShootFlag = false;

    //蓄力攻击时长
    private float _chargeTime = 0;

    //是否需要重置武器数据
    private bool _dirtyFlag = false;

    //当前后坐力导致的偏移长度
    private float _currBacklashLength = 0;

    //握把位置
    private Vector2 _gripPoint;

    //持握时 Sprite 偏移
    private Vector2 _gripOffset;

    //碰撞器位置
    private Vector2 _collPoint1;
    private Vector2 _collPoint2;

    //换弹计时器
    private float _reloadTimer = 0;
    
    //单独换弹设置下的换弹状态, 0: 未换弹, 1: 装第一颗子弹之前, 2: 单独装弹中, 3: 单独装弹完成
    private byte _aloneReloadState = 3;

    //单独换弹状态下是否强制结束换弹过程
    private bool _aloneReloadStop = false;
    
    //本次换弹已用时间
    private float _reloadUseTime = 0;

    //是否播放过换弹完成音效
    private bool _playReloadFinishSoundFlag = false;

    //上膛状态,-1: 等待执行自动上膛 , 0: 未上膛, 1: 上膛中, 2: 已经完成上膛
    private sbyte _beLoadedState = 2;

    //上膛计时器
    private float _beLoadedStateTimer = -1;

    //换弹投抛弹壳记录
    private bool _reloadShellFlag = false;

    //抖动强度
    private float _shakeStrength = 0;
    
    //抖动间隔
    private float _shakeInterval = 1 / 60f;
    
    //抖动计时器
    private float _shakeTimer = 0;

    //换弹完成后播放的动画
    private string _reloadNextAnimation;
    
    // ----------------------------------------------
    private uint _tempLayer;

    private static bool _init = false;
    private static Dictionary<string, ExcelConfig.WeaponBase> _weaponAttributeMap =
        new Dictionary<string, ExcelConfig.WeaponBase>();

    /// <summary>
    /// 初始化武器属性数据
    /// </summary>
    public static void InitWeaponAttribute()
    {
        if (_init)
        {
            return;
        }

        _init = true;
        foreach (var weaponAttr in ExcelConfig.WeaponBase_List)
        {
            if (weaponAttr.Activity != null)
            {
                if (!_weaponAttributeMap.TryAdd(weaponAttr.Activity.Id, weaponAttr))
                {
                    Debug.LogError("发现重复注册的武器属性: " + weaponAttr.Id);
                }
            }
        }
    }
    
    /// <summary>
    /// 根据 ActivityBase.Id 获取对应武器的属性数据
    /// </summary>
    public static ExcelConfig.WeaponBase GetWeaponAttribute(string itemId)
    {
        if (itemId == null)
        {
            return null;
        }
        if (_weaponAttributeMap.TryGetValue(itemId, out var attr))
        {
            return attr;
        }

        throw new Exception($"武器'{itemId}'没有在 WeaponBase 表中配置属性数据!");
    }
    
    public override void OnInit()
    {
        InitWeapon(GetWeaponAttribute(ActivityBase.Id).Clone());
        AnimatedSprite.AnimationFinished += OnAnimatedSpriteFinished;
        AnimationPlayer.AnimationFinished += OnAnimationPlayerFinished;
        _gripPoint = AnimatedSprite.Position;
        _gripOffset = AnimatedSprite.Offset;
        _collPoint1 = Collision.Position;
        _collPoint2 = _collPoint1 - AnimatedSprite.Offset - AnimatedSprite.Position;
        AnimatedSprite.Position = Vector2.Zero;
        AnimatedSprite.Offset = Vector2.Zero;
        Collision.Position = _collPoint2;
    }

    /// <summary>
    /// 初始化武器属性
    /// </summary>
    private void InitWeapon(ExcelConfig.WeaponBase attribute)
    {
        _playerWeaponAttribute = attribute;
        SetCurrentWeaponAttribute(attribute);
        if (ExcelConfig.WeaponBase_Map.TryGetValue(attribute.Id + "_ai", out var aiAttr))
        {
            _aiWeaponAttribute = aiAttr;
        }
        else
        {
            Debug.LogError("警告: 未找到 AI 武器属性: " + attribute.Id);
            _aiWeaponAttribute = attribute;
        }

        if (Attribute.AmmoCapacity > Attribute.MaxAmmoCapacity)
        {
            Attribute.AmmoCapacity = Attribute.MaxAmmoCapacity;
            Debug.LogError("弹夹的容量不能超过弹药上限, 武器id: " + ActivityBase.Id);
        }
        //弹药量
        CurrAmmo = Attribute.AmmoCapacity;
        //剩余弹药量
        ResidueAmmo = Mathf.Min(Attribute.StandbyAmmoCapacity + CurrAmmo, Attribute.MaxAmmoCapacity) - CurrAmmo;
    }

    /// <summary>
    /// 单次开火时调用的函数
    /// </summary>
    protected abstract void OnFire();

    /// <summary>
    /// 发射子弹时调用的函数, 每发射一枚子弹调用一次,
    /// 如果做霰弹武器效果, 一次开火发射5枚子弹, 则该函数调用5次
    /// </summary>
    /// <param name="fireRotation">开火时枪口旋转角度, 弧度制</param>
    protected abstract void OnShoot(float fireRotation);

    /// <summary>
    /// 上膛开始时调用
    /// </summary>
    protected virtual void OnBeginBeLoaded()
    {
    }
    
    /// <summary>
    /// 上膛结束时调用
    /// </summary>
    protected virtual void OnBeLoadedFinish()
    {
    }
    
    /// <summary>
    /// 当按下扳机时调用
    /// </summary>
    protected virtual void OnDownTrigger()
    {
    }

    /// <summary>
    /// 当松开扳机时调用
    /// </summary>
    protected virtual void OnUpTrigger()
    {
    }

    /// <summary>
    /// 开始蓄力时调用, 
    /// 注意, 该函数仅在 Attribute.LooseShoot == false 时才能被调用
    /// </summary>
    protected virtual void OnBeginCharge()
    {
    }

    /// <summary>
    /// 结束蓄力时调用
    /// 注意, 该函数仅在 Attribute.LooseShoot == false 时才能被调用
    /// </summary>
    protected virtual void OnEndCharge()
    {
    }
    
    /// <summary>
    /// 蓄力完成时调用
    /// </summary>
    protected virtual void OnChargeFinish()
    {
    }
    
    /// <summary>
    /// 蓄力时每帧调用
    /// 注意, 该函数仅在 Attribute.LooseShoot == false 时才能被调用
    /// </summary>
    /// <param name="delta"></param>
    /// <param name="charge">蓄力时长</param>
    protected virtual void OnChargeProcess(float delta, float charge)
    {
    }

    /// <summary>
    /// 当换弹时调用, 如果设置单独装弹, 则每装一次弹调用一次该函数
    /// </summary>
    protected virtual void OnReload()
    {
    }

    /// <summary>
    /// 当开始换弹时调用
    /// </summary>
    protected virtual void OnBeginReload()
    {
    }
    
    /// <summary>
    /// 当换弹完成时调用
    /// </summary>
    protected virtual void OnReloadFinish()
    {
    }

    /// <summary>
    /// 单独装弹完成时调用
    /// </summary>
    protected virtual void OnAloneReloadStateFinish()
    {
    }
    
    /// <summary>
    /// 当武器被拾起时调用
    /// </summary>
    /// <param name="master">拾起该武器的角色</param>
    protected virtual void OnPickUp(Role master)
    {
    }

    /// <summary>
    /// 当武器从武器背包中移除时调用
    /// </summary>
    /// <param name="master">移除该武器的角色</param>
    protected virtual void OnRemove(Role master)
    {
    }

    /// <summary>
    /// 当武器被激活时调用, 也就是使用当武器时调用
    /// </summary>
    protected virtual void OnActive()
    {
    }

    /// <summary>
    /// 当武器被收起时调用
    /// </summary>
    protected virtual void OnConceal()
    {
    }

    /// <summary>
    /// 射击时调用, 返回消耗弹药数量, 默认为1, 如果返回为 0, 则不消耗弹药
    /// </summary>
    protected virtual int UseAmmoCount()
    {
        return 1;
    }

    public override void EnterTree()
    {
        //收集落在地上的武器
        if (IsInGround())
        {
            World.Weapon_UnclaimedList.Add(this);
        }
    }

    public override void ExitTree()
    {
        World.Weapon_UnclaimedList.Remove(this);
    }

    protected override void Process(float delta)
    {
        //抖动 AnimatedSprite
        if (_shakeStrength != 0)
        {
            _shakeTimer += delta;
            if (_shakeTimer >= _shakeInterval)
            {
                _shakeTimer = 0;
                AnimatedSprite.Offset = new Vector2(
                    Utils.Random.RandomRangeFloat(-_shakeStrength, _shakeStrength),
                    Utils.Random.RandomRangeFloat(-_shakeStrength, _shakeStrength)
                );
            }
        }
        else
        {
            _shakeTimer = 0;
        }
        
        //未开火时间
        _noAttackTime += delta;
        
        //这把武器被扔在地上, 或者当前武器没有被使用
        //if (Master == null || Master.WeaponPack.ActiveItem != this)
        if ((Master != null && Master.WeaponPack.ActiveItem != this) || !_triggerRoleFlag) //在背上, 或者被扔出去了
        {
            //_triggerTimer
            _triggerTimer = _triggerTimer > 0 ? _triggerTimer - delta : 0;
            //攻击冷却计时
            _attackTimer = _attackTimer > 0 ? _attackTimer - delta : 0;
            //武器的当前散射半径
            ScatteringRangeBackHandler(delta);
            //武器当前射速
            FiringSpeedBackHandler(delta);
            //松开扳机
            if (_triggerFlag || _downTimer > 0)
            {
                UpTrigger();
                _downTimer = 0;
            }
            
            _triggerFlag = false;

            //重置数据
            if (_dirtyFlag)
            {
                _dirtyFlag = false;
                //_aloneReloadState = 0;
                StopReload();
                _attackFlag = false;
                _continuousCount = 0;
                _delayedTime = 0;
                _upTimer = 0;
                _looseShootFlag = false;
                _chargeTime = 0;
                _beLoadedStateTimer = -1;
            }
        }
        else //正在使用中
        {
            _dirtyFlag = true;
            
            //上膛
            if (_beLoadedState == 1)
            {
                _beLoadedStateTimer -= delta;
                //上膛完成
                if (_beLoadedStateTimer <= 0)
                {
                    _beLoadedStateTimer = -1;
                    _beLoadedState = 2;
                    OnBeLoadedFinish();
                }
            }
            
            //换弹
            if (Reloading)
            {
                //换弹用时
                _reloadUseTime += delta;
                _reloadTimer -= delta;

                if (Attribute.AloneReload) //单独装弹模式
                {
                    switch (_aloneReloadState)
                    {
                        case 0:
                            Debug.LogError("AloneReload状态错误!");
                            break;
                        case 1: //装第一颗子弹之前
                        {
                            if (_reloadTimer <= 0)
                            {
                                //开始装第一颗子弹
                                _aloneReloadState = 2;
                                ReloadHandler();
                            }
                            _aloneReloadStop = false;
                        }
                            break;
                        case 2: //单独装弹中
                        {
                            if (_reloadTimer <= 0)
                            {
                                ReloadSuccess();
                                if (_aloneReloadStop || ResidueAmmo == 0 || CurrAmmo == Attribute.AmmoCapacity) //单独装弹完成
                                {
                                    AloneReloadStateFinish();
                                    if (Attribute.AloneReloadFinishIntervalTime <= 0)
                                    {
                                        //换弹完成
                                        StopReload();
                                        ReloadFinishHandler();
                                    }
                                    else
                                    {
                                        _reloadTimer = Attribute.AloneReloadFinishIntervalTime;
                                        _aloneReloadState = 3;
                                    }
                                }
                            }
                        }
                            break;
                        case 3: //单独装弹完成
                        {
                            //播放换弹完成音效
                            if (!_playReloadFinishSoundFlag && Attribute.ReloadFinishSound != null && _reloadTimer <= Attribute.ReloadFinishSoundAdvanceTime)
                            {
                                _playReloadFinishSoundFlag = true;
                                // Debug.Log("播放换弹完成音效.");
                                PlayReloadFinishSound();
                            }
                            
                            if (_reloadTimer <= 0)
                            {
                                //换弹完成
                                StopReload();
                                ReloadFinishHandler();
                            }
                            _aloneReloadStop = false;
                        }
                            break;
                    }
                }
                else //普通换弹模式
                {
                    //播放换弹完成音效
                    if (!_playReloadFinishSoundFlag && Attribute.ReloadFinishSound != null && _reloadTimer <= Attribute.ReloadFinishSoundAdvanceTime)
                    {
                        _playReloadFinishSoundFlag = true;
                        // Debug.Log("播放换弹完成音效.");
                        PlayReloadFinishSound();
                    }

                    if (_reloadTimer <= 0)
                    {
                        ReloadSuccess();
                    }
                }
            }

            //攻击的计时器
            if (_attackTimer > 0)
            {
                _attackTimer -= delta;
                if (_attackTimer < 0)
                {
                    _delayedTime += _attackTimer;
                    _attackTimer = 0;
                    //枪口默认角度
                    if (Master != null)
                    {
                        RotationDegrees = -Attribute.DefaultAngle;
                    }

                    //自动上膛
                    if (_beLoadedState == -1)
                    {
                        BeLoaded();
                    }
                    
                    //子弹换弹
                    if (CurrAmmo <= 0 && Attribute.AutoReload)
                    {
                        Reload();
                    }
                }
            }
            else if (_delayedTime > 0) //攻击延时
            {
                _delayedTime -= delta;
                if (_attackTimer < 0)
                {
                    _delayedTime = 0;
                }
            }
            
            //扳机判定
            if (_triggerFlag)
            {
                if (_looseShootFlag) //蓄力时长
                {
                    var pv = _chargeTime;
                    _chargeTime += delta;
                    OnChargeProcess(delta, _chargeTime);
                    //蓄力完成
                    if (pv < Attribute.MinChargeTime && _chargeTime >= Attribute.MinChargeTime)
                    {
                        OnChargeFinish();
                    }
                }

                _downTimer += delta;
                if (_upTimer > 0) //第一帧按下扳机
                {
                    DownTrigger();
                    _upTimer = 0;
                }
            }
            else
            {
                _upTimer += delta;
                if (_downTimer > 0) //第一帧松开扳机
                {
                    UpTrigger();
                    _downTimer = 0;
                }
            }

            //连发判断
            if (!_looseShootFlag && _continuousCount > 0 && _delayedTime <= 0 && _attackTimer <= 0)
            {
                //连发开火
                TriggerFire();
                //连发最后一发打完了
                if (Attribute.ManualBeLoaded && _continuousCount <= 0)
                {
                    //执行上膛逻辑
                    RunBeLoaded();
                }
            }

            //散射值消退
            if (_noAttackTime >= Attribute.ScatteringRangeBackDelayTime)
            {
                ScatteringRangeBackHandler(delta);
            }

            if (_triggerFlag) //射速增加
            {
                FiringSpeedAddHandler(delta);
            }
            else if (_noAttackTime >= Attribute.FiringSpeedBackTime) //射速消退
            {
                FiringSpeedBackHandler(delta);
            }

            _triggerTimer = _triggerTimer > 0 ? _triggerTimer - delta : 0;
            _triggerFlag = false;
            _attackFlag = false;
            
            //武器身回归
            //Position = Position.MoveToward(Vector2.Zero, Attribute.BacklashRegressionSpeed * delta).Rotated(Rotation);
            _currBacklashLength = Mathf.MoveToward(_currBacklashLength, 0, Attribute.BacklashRegressionSpeed * delta);
            if (Master != null)
            {
                Position = new Vector2(_currBacklashLength, 0).Rotated(Rotation);
                if (_attackTimer > 0)
                {
                    RotationDegrees = Mathf.Lerp(
                        _fireAngle, -Attribute.DefaultAngle,
                        Mathf.Clamp((_fireInterval - _attackTimer) * Attribute.UpliftAngleRestore / _fireInterval, 0, 1)
                    );
                }
            }
        }
    }

    /// <summary>
    /// 设置抖动强度
    /// </summary>
    public void SetShake(float strength)
    {
        _shakeStrength = strength;
    }
    
    /// <summary>
    /// 设置抖动间隔
    /// </summary>
    public void SetShakeInterval(float interval)
    {
        _shakeInterval = interval;
    }

    /// <summary>
    /// 返回武器是否在地上
    /// </summary>
    /// <returns></returns>
    public bool IsInGround()
    {
        return Master == null && GetParent() == World.Current.NormalLayer;
    }

    /// <summary>
    /// 清除触发角色开火标记数据
    /// </summary>
    public void ClearTriggerRole()
    {
        _triggerRoleFlag = false;
        if (Master == null)
        {
            if (Reloading)
            {
                _reloadNextAnimation = AnimatorNames.Floodlight;
            }
            else
            {
                AnimationPlayer.Play(AnimatorNames.Floodlight);
            }
        }
    }

    /// <summary>
    /// 扳机函数, 调用即视为按下扳机
    /// </summary>
    /// <param name="triggerRole">按下扳机的角色, 如果传 null, 则视为走火</param>
    /// <param name="calcAmmo">是否计算弹药消耗</param>
    public void Trigger(Role triggerRole, bool calcAmmo = true)
    {
        //不能触发扳机
        if (!NoMasterCanTrigger && Master == null) return;

        //这一帧已经按过了, 不需要再按下
        if (_triggerFlag) return;

        //更新武器属性信息
        _triggerFlag = true;
        if (!_triggerRoleFlag && AnimationPlayer.CurrentAnimation == AnimatorNames.Floodlight)
        {
            AnimationPlayer.Play(AnimatorNames.Reset);
        }
        _triggerRoleFlag = true;
        _triggerCalcAmmon = calcAmmo;
        if (triggerRole != null)
        {
            TriggerRole = triggerRole;
            SetCurrentWeaponAttribute(triggerRole.IsAi ? _aiWeaponAttribute : _playerWeaponAttribute);
        }
        else if (Master != null)
        {
            TriggerRole = Master;
            SetCurrentWeaponAttribute(Master.IsAi ? _aiWeaponAttribute : _playerWeaponAttribute);
        }

        //是否第一帧按下
        var justDown = _downTimer == 0;
        if (_beLoadedState == 0 || _beLoadedState == -1) //需要执行上膛操作
        {
            if (justDown && !Reloading && triggerRole != null)
            {
                if (CurrAmmo <= 0)
                {
                    //子弹不够, 触发换弹
                    Reload();
                }
                else if (_attackTimer <= 0)
                {
                    //触发上膛操作
                    BeLoaded();
                }
            }
        }
        else if (_beLoadedState == 1) //上膛中
        {

        }
        else //上膛完成
        {
            //是否能发射
            var flag = false;
            if (_continuousCount <= 0) //不能处于连发状态下
            {
                if (Attribute.ContinuousShoot) //自动射击
                {
                    if (_triggerTimer > 0)
                    {
                        if (_continuousShootFlag)
                        {
                            flag = true;
                        }
                    }
                    else
                    {
                        flag = true;
                        if (_delayedTime <= 0 && _attackTimer <= 0)
                        {
                            _continuousShootFlag = true;
                        }
                    }
                }
                else //半自动
                {
                    if (justDown && _triggerTimer <= 0 && _attackTimer <= 0)
                    {
                        flag = true;
                    }
                }
            }

            if (flag)
            {
                var fireFlag = true; //是否能开火
                if (Reloading) //换弹中
                {
                    fireFlag = false;
                    if (CurrAmmo > 0 && Attribute.AloneReload && Attribute.AloneReloadCanShoot)
                    {
                        //检查是否允许停止换弹
                        if (_aloneReloadState == 2 || _aloneReloadState == 1)
                        {
                            //强制结束
                            _aloneReloadStop = true;
                        }
                    }
                }
                else if (CurrAmmo <= 0) //子弹不够
                {
                    fireFlag = false;
                    if (justDown && triggerRole != null)
                    {
                        //第一帧按下, 触发换弹
                        Reload();
                    }
                }

                if (fireFlag)
                {
                    if (justDown)
                    {
                        //开火前延时
                        if (!Attribute.LooseShoot)
                        {
                            _delayedTime = Attribute.DelayedTime;
                        }

                        //扳机按下间隔
                        _triggerTimer = Attribute.TriggerInterval;
                        //连发数量
                        if (!Attribute.ContinuousShoot)
                        {
                            _continuousCount = Utils.Random.RandomConfigRange(Attribute.ContinuousCountRange);
                        }
                    }

                    if (_delayedTime <= 0 && _attackTimer <= 0)
                    {
                        if (Attribute.LooseShoot) //松发开火
                        {
                            _looseShootFlag = true;
                            OnBeginCharge();
                        }
                        else
                        {
                            //开火
                            TriggerFire();

                            //非连射模式
                            if (!Attribute.ContinuousShoot && Attribute.ManualBeLoaded && _continuousCount <= 0)
                            {
                                //执行上膛逻辑
                                RunBeLoaded();
                            }
                        }
                    }
                }
            }
            else //不能开火
            {
                if (CurrAmmo <= 0 && justDown && triggerRole != null) //子弹不够
                {
                    //第一帧按下, 触发换弹
                    Reload();
                }
            }
        }
    }

    /// <summary>
    /// 返回是否按下扳机
    /// </summary>
    public bool IsPressTrigger()
    {
        return _triggerFlag;
    }
    
    /// <summary>
    /// 获取本次扳机按下的时长, 单位: 秒
    /// </summary>
    public float GetTriggerDownTime()
    {
        return _downTimer;
    }

    /// <summary>
    /// 获取扳机蓄力时长, 计算按下扳机后从可以开火到当前一共经过了多长时间, 可用于计算蓄力攻击
    /// 注意, 该函数仅在 Attribute.LooseShoot == false 时有正确的返回值, 否则返回 0
    /// </summary>
    public float GetTriggerChargeTime()
    {
        return _chargeTime;
    }
    
    /// <summary>
    /// 获取蓄力是否结束
    /// 注意, 该函数仅在 Attribute.LooseShoot == false 时有正确的返回值, 否则返回 false
    /// </summary>
    public bool IsChargeFinish()
    {
        return _chargeTime >= Attribute.MinChargeTime;
    }
    
    /// <summary>
    /// 获取延时射击倒计时, 单位: 秒
    /// </summary>
    public float GetDelayedAttackTime()
    {
        return _delayedTime;
    }

    /// <summary>
    /// 获取当前需要连发弹药的数量, 配置了 ContinuousCountRange 时生效
    /// </summary>
    public int GetContinuousCount()
    {
        return _continuousCount;
    }

    /// <summary>
    /// 获取攻击冷却计时时间, 小于等于 0 表示冷却完成
    /// </summary>
    public float GetAttackTimer()
    {
        return _attackTimer;
    }

    /// <summary>
    /// 返回是否是攻击间隙时间
    /// </summary>
    public bool IsAttackIntervalTime()
    {
        return _attackTimer > 0 || _triggerTimer > 0;
    }

    /// <summary>
    /// 是否可以按下扳机并发射了
    /// </summary>
    public bool TriggerIsReady()
    {
        return GetBeLoadedStateState() >= 2 && !IsAttackIntervalTime();
    }

    /// <summary>
    /// 获取上膛状态,-1: 等待执行自动上膛 , 0: 未上膛, 1: 上膛中, 2: 已经完成上膛
    /// </summary>
    public sbyte GetBeLoadedStateState()
    {
        return _beLoadedState;
    }
    
    /// <summary>
    /// 刚按下扳机
    /// </summary>
    private void DownTrigger()
    {
        OnDownTrigger();
    }

    /// <summary>
    /// 刚松开扳机
    /// </summary>
    private void UpTrigger()
    {
        _continuousShootFlag = false;
        if (_delayedTime > 0)
        {
            _continuousCount = 0;
        }

        //松发开火执行
        if (_looseShootFlag)
        {
            _looseShootFlag = false;
            if (_chargeTime >= Attribute.MinChargeTime) //判断蓄力是否够了
            {
                TriggerFire();
                //非连射模式
                if (!Attribute.ContinuousShoot && Attribute.ManualBeLoaded && _continuousCount <= 0)
                {
                    //执行上膛逻辑
                    RunBeLoaded();
                }
            }
            else //不能攻击
            {
                _continuousCount = 0;
            }
            _chargeTime = 0;
            OnEndCharge();
        }

        OnUpTrigger();
    }

    /// <summary>
    /// 触发开火
    /// </summary>
    private void TriggerFire()
    {
        _attackFlag = true;
        _noAttackTime = 0;
        _reloadShellFlag = false;

        //减子弹数量
        if (_triggerCalcAmmon)
        {
            if (_playerWeaponAttribute != _weaponAttribute) //Ai使用该武器, 有一定概率不消耗弹药
            {
                var count = UseAmmoCount();
                CurrAmmo -= count;
                if (Utils.Random.RandomRangeFloat(0, 1) >= _weaponAttribute.AiAttackAttr.AmmoConsumptionProbability) //不消耗弹药
                {
                    ResidueAmmo += count;
                }
            }
            else
            {
                CurrAmmo -= UseAmmoCount();
            }
        }
        else //不消耗弹药
        {
            var count = UseAmmoCount();
            CurrAmmo -= count;
            ResidueAmmo += count;
        }

        if (CurrAmmo == 0)
        {
            _continuousCount = 0;
        }
        else
        {
            _continuousCount = _continuousCount > 0 ? _continuousCount - 1 : 0;
        }

        //开火间隙, 这里的60指的是60秒
        _fireInterval = 60 / CurrentFiringSpeed;
        //攻击冷却
        _attackTimer += _fireInterval;

        //播放开火动画
        if (IsAutoPlaySpriteFrames)
        {
            if (!PlayAnimationPlayer(AnimatorNames.Fire))
            {
                PlaySpriteAnimation(AnimatorNames.Fire);
            }
        }

        //播放射击音效
        PlayShootSound();
        
        //抛弹
        if (!Attribute.ReloadThrowShell && (Attribute.ContinuousShoot || !Attribute.ManualBeLoaded))
        {
            ThrowShellHandler(1f);
        }
        
        //触发开火函数
        OnFire();


        //武器口角度
        var angle = new Vector2(GameConfig.ScatteringDistance, CurrScatteringRange).Angle();

        //先算武器口方向
        var tempRotation = Utils.Random.RandomRangeFloat(-angle, angle);
        var tempAngle = Mathf.RadToDeg(tempRotation);

        //开火时枪口角度
        var fireRotation = tempRotation;
        
        //开火发射的子弹数量
        var bulletCount = Utils.Random.RandomConfigRange(Attribute.FireBulletCountRange);
        if (Master != null)
        {
            bulletCount = Master.RoleState.CalcBulletCount(bulletCount);
            fireRotation += Master.MountPoint.RealRotation;
        }
        else
        {
            fireRotation += GlobalRotation;
        }

        //创建子弹
        for (var i = 0; i < bulletCount; i++)
        {
            //发射子弹
            OnShoot(fireRotation);
        }

        //开火添加散射值
        ScatteringRangeAddHandler();
        
        //武器的旋转角度
        tempAngle -= Attribute.UpliftAngle;
        _fireAngle = tempAngle;
        
        if (Master != null) //被拾起
        {
            //武器身位置
            var max = Mathf.Abs(Mathf.Max(Utils.GetConfigRangeStart(Attribute.BacklashRange), Utils.GetConfigRangeEnd(Attribute.BacklashRange)));
            _currBacklashLength = Mathf.Clamp(
                _currBacklashLength - Utils.Random.RandomConfigRange(Attribute.BacklashRange),
                -max, max
            );
            Position = new Vector2(_currBacklashLength, 0).Rotated(Rotation);
            RotationDegrees = tempAngle;
        }
        else //在地上
        {
            var v = Utils.Random.RandomConfigRange(Attribute.BacklashRange) * 15;
            var externalForce = MoveController.AddForce(new Vector2(-v, 0).Rotated(Rotation));
            externalForce.RotationSpeed = -Mathf.DegToRad(50);
            externalForce.RotationResistance = Mathf.DegToRad(80);
        }

        if (IsInGround())
        {
            //在地上弹药打光
            if (IsTotalAmmoEmpty())
            {
                //停止动画
                AnimationPlayer.Stop();
                //清除泛白效果
                SetBlendSchedule(0);
            }
        }
    }

    // /// <summary>
    // /// 触发武器的近战攻击
    // /// </summary>
    // public virtual void TriggerMeleeAttack(Role trigger)
    // {
    //     
    // }

    /// <summary>
    /// 根据触扳机的角色对象判断该角色使用的武器数据
    /// </summary>
    public ExcelConfig.WeaponBase GetUseAttribute(Role triggerRole)
    {
        if (triggerRole == null || !triggerRole.IsAi)
        {
            return PlayerUseAttribute;
        }

        return AiUseAttribute;
    }
    
    /// <summary>
    /// 返回弹药是否到达上限
    /// </summary>
    public bool IsAmmoFull()
    {
        return CurrAmmo + ResidueAmmo >= Attribute.MaxAmmoCapacity;
    }

    /// <summary>
    /// 返回弹夹是否打空
    /// </summary>
    public bool IsAmmoEmpty()
    {
        return CurrAmmo == 0;
    }
    
    /// <summary>
    /// 返回是否弹药耗尽
    /// </summary>
    public bool IsTotalAmmoEmpty()
    {
        return CurrAmmo + ResidueAmmo == 0;
    }

    /// <summary>
    /// 强制修改当前弹夹弹药量
    /// </summary>
    public void SetCurrAmmo(int count)
    {
        CurrAmmo = Mathf.Clamp(count, 0, Attribute.AmmoCapacity);
    }

    /// <summary>
    /// 强制修改备用弹药量
    /// </summary>
    public void SetResidueAmmo(int count)
    {
        ResidueAmmo = Mathf.Clamp(count, 0, Attribute.MaxAmmoCapacity - CurrAmmo);
    }
    
    /// <summary>
    /// 强制修改弹药量, 优先改动备用弹药
    /// </summary>
    public void SetTotalAmmo(int total)
    {
        if (total < 0)
        {
            return;
        }
        var totalAmmo = CurrAmmo + ResidueAmmo;
        if (totalAmmo == total)
        {
            return;
        }
        
        if (total > totalAmmo) //弹药增加
        {
            ResidueAmmo = Mathf.Min(total - CurrAmmo, Attribute.MaxAmmoCapacity - CurrAmmo);
        }
        else //弹药减少
        {
            if (CurrAmmo < total)
            {
                ResidueAmmo = total - CurrAmmo;
            }
            else
            {
                CurrAmmo = total;
                ResidueAmmo = 0;
            }
        }
    }

    /// <summary>
    /// 拾起的弹药数量, 如果到达容量上限, 则返回拾取完毕后剩余的弹药数量
    /// </summary>
    /// <param name="count">弹药数量</param>
    private int PickUpAmmo(int count)
    {
        var num = ResidueAmmo;
        ResidueAmmo = Mathf.Min(ResidueAmmo + count, Attribute.MaxAmmoCapacity - CurrAmmo);
        return count - ResidueAmmo + num;
    }

    /// <summary>
    /// 触发换弹
    /// </summary>
    public void Reload()
    {
        if (!Reloading && CurrAmmo < Attribute.AmmoCapacity && ResidueAmmo > 0 && _beLoadedState != 1)
        {
            Reloading = true;
            _playReloadFinishSoundFlag = false;

            //播放开始换弹音效
            PlayBeginReloadSound();
            
            // Debug.Log("开始换弹.");
            //抛弹
            if (!Attribute.ReloadThrowShell && !Attribute.ContinuousShoot &&
                (_beLoadedState == 0 || _beLoadedState == -1) && Attribute.BeLoadedTime > 0)
            {
                ThrowShellHandler(0.6f);
            }
            
            //第一次换弹
            OnBeginReload();

            if (Attribute.AloneReload)
            {
                //单独换弹, 特殊处理
                AloneReloadHandler();
            }
            else
            {
                //普通换弹处理
                ReloadHandler();
            }
            
            //上膛标记完成
            _beLoadedState = 2;
        }
    }

    /// <summary>
    /// 强制停止换弹, 或者结束换弹状态
    /// </summary>
    public void StopReload()
    {
        _aloneReloadState = 0;
        if (_beLoadedState == -1)
        {
            _beLoadedState = 0;
        }
        else if (_beLoadedState == 1)
        {
            _beLoadedState = 2;
        }

        Reloading = false;
        _reloadTimer = 0;
        _reloadUseTime = 0;
    }

    /// <summary>
    /// 触发上膛
    /// </summary>
    public void BeLoaded()
    {
        if (_beLoadedState > 0)
        {
            return;
        }
        //上膛抛弹
        if (!Attribute.ReloadThrowShell && !Attribute.ContinuousShoot && Attribute.BeLoadedTime > 0)
        {
            ThrowShellHandler(0.6f);
        }

        //开始上膛
        OnBeginBeLoaded();

        //上膛时间为0, 直接结束上膛
        if (Attribute.BeLoadedTime <= 0)
        {
            //直接上膛完成
            _beLoadedState = 2;
            OnBeLoadedFinish();
            return;
        }
        
        //上膛中
        _beLoadedState = 1;
        _beLoadedStateTimer = Attribute.BeLoadedTime;
        
        //播放上膛动画
        if (IsAutoPlaySpriteFrames)
        {
            if (Attribute.BeLoadedSoundDelayTime <= 0)
            {
                if (!PlayAnimationPlayer(AnimatorNames.BeLoaded))
                {
                    PlaySpriteAnimation(AnimatorNames.BeLoaded);
                }
            }
            else
            {
                this.CallDelay(Attribute.BeLoadedSoundDelayTime, () =>
                {
                    if (!PlayAnimationPlayer(AnimatorNames.BeLoaded))
                    {
                        PlaySpriteAnimation(AnimatorNames.BeLoaded);
                    }
                });
            }
        }

        //播放上膛音效
        PlayBeLoadedSound();
    }
    
    //播放换弹开始音效
    private void PlayBeginReloadSound()
    {
        if (Attribute.BeginReloadSound != null)
        {
            if (Attribute.BeginReloadSoundDelayTime <= 0)
            {
                SoundManager.PlaySoundByConfig(Attribute.BeginReloadSound, GlobalPosition, TriggerRole);
            }
            else
            {
                SoundManager.PlaySoundByConfigDelay(Attribute.BeginReloadSound, GlobalPosition, Attribute.BeginReloadSoundDelayTime, TriggerRole);
            }
        }
    }
    
    //播放换弹音效
    private void PlayReloadSound()
    {
        if (Attribute.ReloadSound != null)
        {
            if (Attribute.ReloadSoundDelayTime <= 0)
            {
                SoundManager.PlaySoundByConfig(Attribute.ReloadSound, GlobalPosition, TriggerRole);
            }
            else
            {
                SoundManager.PlaySoundByConfigDelay(Attribute.ReloadSound, GlobalPosition, Attribute.ReloadSoundDelayTime, TriggerRole);
            }
        }
    }
    
    //播放换弹完成音效
    private void PlayReloadFinishSound()
    {
        if (Attribute.ReloadFinishSound != null)
        {
            SoundManager.PlaySoundByConfig(Attribute.ReloadFinishSound, GlobalPosition, TriggerRole);
        }
    }

    //播放射击音效
    private void PlayShootSound()
    {
        if (Attribute.ShootSound != null)
        {
            SoundManager.PlaySoundByConfig(Attribute.ShootSound, GlobalPosition, TriggerRole);
        }
    }

    //播放上膛音效
    private void PlayBeLoadedSound()
    {
        if (Attribute.BeLoadedSound != null)
        {
            if (Attribute.BeLoadedSoundDelayTime <= 0)
            {
                SoundManager.PlaySoundByConfig(Attribute.BeLoadedSound, GlobalPosition, TriggerRole);
            }
            else
            {
                SoundManager.PlaySoundByConfigDelay(Attribute.BeLoadedSound, GlobalPosition, Attribute.BeLoadedSoundDelayTime, TriggerRole);
            }
        }
    }

    //执行上膛逻辑
    private void RunBeLoaded()
    {
        if (Attribute.AutoManualBeLoaded)
        {
            if (_attackTimer <= 0)
            {
                //执行自动上膛
                BeLoaded();
            }
            else if (CurrAmmo > 0)
            {
                //等待执行自动上膛
                _beLoadedState = -1;
            }
            else
            {
                //没子弹了, 需要手动上膛
                _beLoadedState = 0;
            }
        }
        else
        {
            //手动上膛
            _beLoadedState = 0;
        }
    }

    //单独换弹处理
    private void AloneReloadHandler()
    {
        if (Attribute.AloneReloadBeginIntervalTime <= 0)
        {
            //开始装第一颗子弹
            _aloneReloadState = 2;
            ReloadHandler();
        }
        else
        {
            _aloneReloadState = 1;
            _reloadTimer = Attribute.AloneReloadBeginIntervalTime;
        }
    }

    //换弹处理逻辑
    private void ReloadHandler()
    {
        _reloadTimer = Attribute.ReloadTime;
        
        //播放换弹动画
        if (IsAutoPlaySpriteFrames)
        {
            if (!PlayAnimationPlayer(AnimatorNames.Reloading))
            {
                PlaySpriteAnimation(AnimatorNames.Reloading);
            }
        }
            
        //播放换弹音效
        PlayReloadSound();
        
        //抛出弹壳
        if (Attribute.ReloadThrowShell && !_reloadShellFlag)
        {
            ThrowShellHandler(0.6f);
        }
        
        OnReload();
        // Debug.Log("装弹.");
    }
    
    //换弹完成处理逻辑
    private void ReloadFinishHandler()
    {
        // Debug.Log("装弹完成.");
        if (_reloadNextAnimation != null)
        {
            AnimationPlayer.Play(_reloadNextAnimation);
            _reloadNextAnimation = null;
        }
        OnReloadFinish();
    }

    //单独装弹完成
    private void AloneReloadStateFinish()
    {
        // Debug.Log("单独装弹完成.");
        OnAloneReloadStateFinish();
    }

    //抛弹逻辑
    private void ThrowShellHandler(float speedScale)
    {
        var attribute = Attribute;
        if (attribute.Shell == null)
        {
            return;
        }
        //创建一个弹壳
        if (attribute.ThrowShellDelayTime > 0)
        {
            this.CallDelay(attribute.ThrowShellDelayTime, () =>
            {
                _reloadShellFlag = true;
                for (var i = 0; i < attribute.ThrowShellCount; i++)
                {
                    FireManager.ThrowShell(this, attribute.Shell, speedScale);
                }
            });
        }
        else if (attribute.ThrowShellDelayTime == 0)
        {
            _reloadShellFlag = true;
            for (var i = 0; i < attribute.ThrowShellCount; i++)
            {
                FireManager.ThrowShell(this, attribute.Shell, speedScale);
            }
        }
    }

    //散射值消退处理
    private void ScatteringRangeBackHandler(float delta)
    {
        var startScatteringRange = Attribute.StartScatteringRange;
        var finalScatteringRange = Attribute.FinalScatteringRange;
        if (Master != null)
        {
            startScatteringRange = Master.RoleState.CalcStartScattering(startScatteringRange);
            finalScatteringRange = Master.RoleState.CalcFinalScattering(finalScatteringRange);
        }
        if (startScatteringRange <= finalScatteringRange)
        {
            CurrScatteringRange = Mathf.Max(CurrScatteringRange - Attribute.ScatteringRangeBackSpeed * delta,
                startScatteringRange);
        }
        else
        {
            CurrScatteringRange = Mathf.Min(CurrScatteringRange + Attribute.ScatteringRangeBackSpeed * delta,
                startScatteringRange);
        }
    }

    //散射值添加处理
    private void ScatteringRangeAddHandler()
    {
        var startScatteringRange = Attribute.StartScatteringRange;
        var finalScatteringRange = Attribute.FinalScatteringRange;
        if (Master != null)
        {
            startScatteringRange = Master.RoleState.CalcStartScattering(startScatteringRange);
            finalScatteringRange = Master.RoleState.CalcFinalScattering(finalScatteringRange);
        }
        if (startScatteringRange <= finalScatteringRange)
        {
            CurrScatteringRange = Mathf.Min(CurrScatteringRange + Attribute.ScatteringRangeAddValue,
                finalScatteringRange);
        }
        else
        {
            CurrScatteringRange = Mathf.Min(CurrScatteringRange - Attribute.ScatteringRangeAddValue,
                finalScatteringRange);
        }
    }

    //射速增加处理
    private void FiringSpeedAddHandler(float delta)
    {
        if (Attribute.ContinuousShoot)
        {
            CurrentFiringSpeed = Mathf.MoveToward(CurrentFiringSpeed, Attribute.FinalFiringSpeed,
                Attribute.FiringSpeedAddSpeed * delta);
        }
        else
        {
            CurrentFiringSpeed = Attribute.StartFiringSpeed;
        }
    }
    
    //射速衰减处理
    private void FiringSpeedBackHandler(float delta)
    {
        if (Attribute.ContinuousShoot)
        {
            CurrentFiringSpeed = Mathf.MoveToward(CurrentFiringSpeed, Attribute.StartFiringSpeed, 
                Attribute.FiringSpeedBackSpeed * delta);
        }
        else
        {
            CurrentFiringSpeed = Attribute.StartFiringSpeed;
        }
    }

    /// <summary>
    /// 换弹计时器时间到, 执行换弹操作
    /// </summary>
    private void ReloadSuccess()
    {
        if (Attribute.AloneReload) //单独装填
        {
            if (ResidueAmmo >= Attribute.AloneReloadCount) //剩余子弹充足
            {
                if (CurrAmmo + Attribute.AloneReloadCount <= Attribute.AmmoCapacity)
                {
                    ResidueAmmo -= Attribute.AloneReloadCount;
                    CurrAmmo += Attribute.AloneReloadCount;
                }
                else //子弹满了
                {
                    var num = Attribute.AmmoCapacity - CurrAmmo;
                    CurrAmmo = Attribute.AmmoCapacity;
                    ResidueAmmo -= num;
                }
            }
            else if (ResidueAmmo != 0) //剩余子弹不足
            {
                if (ResidueAmmo + CurrAmmo <= Attribute.AmmoCapacity)
                {
                    CurrAmmo += ResidueAmmo;
                    ResidueAmmo = 0;
                }
                else //子弹满了
                {
                    var num = Attribute.AmmoCapacity - CurrAmmo;
                    CurrAmmo = Attribute.AmmoCapacity;
                    ResidueAmmo -= num;
                }
            }

            if (!_aloneReloadStop && ResidueAmmo != 0 && CurrAmmo != Attribute.AmmoCapacity) //继续装弹
            {
                ReloadHandler();
            }
        }
        else //换弹结束
        {
            if (CurrAmmo + ResidueAmmo >= Attribute.AmmoCapacity)
            {
                ResidueAmmo -= Attribute.AmmoCapacity - CurrAmmo;
                CurrAmmo = Attribute.AmmoCapacity;
            }
            else
            {
                CurrAmmo += ResidueAmmo;
                ResidueAmmo = 0;
            }

            StopReload();
            ReloadFinishHandler();
        }
    }

    /// <summary>
    /// 播放 AnimationPlayer 动画, 如果这个动画不存在, 则什么也不会发生
    /// </summary>
    public bool PlayAnimationPlayer(string name)
    {
        if (AnimationPlayer != null && AnimationPlayer.HasAnimation(name))
        {
            AnimationPlayer.Play(name);
            return true;
        }

        return false;
    }

    //帧动画播放结束
    private void OnAnimatedSpriteFinished()
    {
        // Debug.Log("帧动画播放结束...");
        AnimatedSprite.Play(AnimatorNames.Default);
    }

    //动画播放器播放结束
    private void OnAnimationPlayerFinished(StringName name)
    {
        if (Master != null && !IsActive)
        {
            Master.OnPutBackMount(this, PackageIndex);
        }
    }

    public override CheckInteractiveResult CheckInteractive(ActivityObject master)
    {
        var result = new CheckInteractiveResult(this);

        if (master is Role roleMaster) //碰到角色
        {
            if (Master == null)
            {
                if (roleMaster.WeaponPack.Capacity == 0)
                {
                    //容量为0
                    return result;
                }
                var masterWeapon = roleMaster.WeaponPack.ActiveItem;
                //查找是否有同类型武器
                var index = roleMaster.WeaponPack.FindIndex(ActivityBase.Id);
                if (index != -1) //如果有这个武器
                {
                    if (CurrAmmo + ResidueAmmo != 0) //子弹不为空
                    {
                        var targetWeapon = roleMaster.WeaponPack.GetItem(index);
                        if (!targetWeapon.IsAmmoFull()) //背包里面的武器子弹未满
                        {
                            //可以互动拾起弹药
                            result.CanInteractive = true;
                            result.Type = CheckInteractiveResult.InteractiveType.Bullet;
                            return result;
                        }
                    }
                }
                else //没有武器
                {
                    if (roleMaster.WeaponPack.HasVacancy()) //有空位, 能拾起武器
                    {
                        //可以互动, 拾起武器
                        result.CanInteractive = true;
                        result.Type = CheckInteractiveResult.InteractiveType.PickUp;
                        return result;
                    }
                    else if (masterWeapon != null) //替换武器  // && masterWeapon.Attribute.WeightType == Attribute.WeightType)
                    {
                        //可以互动, 切换武器
                        result.CanInteractive = true;
                        result.Type = CheckInteractiveResult.InteractiveType.Replace;
                        return result;
                    }
                }
            }
        }

        return result;
    }

    public override void Interactive(ActivityObject master)
    {
        if (master is Role roleMaster) //与role互动
        {
            if (roleMaster.WeaponPack.Capacity == 0)
            {
                //容量为0
                return;
            }
            var holster = roleMaster.WeaponPack;
            //查找是否有同类型武器
            var index = holster.FindIndex(ActivityBase.Id);
            if (index != -1) //如果有这个武器
            {
                if (CurrAmmo + ResidueAmmo == 0) //没有子弹了
                {
                    return;
                }

                var weapon = holster.GetItem(index);
                //子弹上限
                var maxCount = Attribute.MaxAmmoCapacity;
                //是否捡到子弹
                var flag = false;
                if (ResidueAmmo > 0 && weapon.CurrAmmo + weapon.ResidueAmmo < maxCount)
                {
                    var count = weapon.PickUpAmmo(ResidueAmmo);
                    if (count != ResidueAmmo)
                    {
                        ResidueAmmo = count;
                        flag = true;
                    }
                }

                if (CurrAmmo > 0 && weapon.CurrAmmo + weapon.ResidueAmmo < maxCount)
                {
                    var count = weapon.PickUpAmmo(CurrAmmo);
                    if (count != CurrAmmo)
                    {
                        CurrAmmo = count;
                        flag = true;
                    }
                }

                //播放互动效果
                if (flag)
                {
                    Throw(GlobalPosition, 0, Utils.Random.RandomRangeInt(20, 50), Vector2.Zero, Utils.Random.RandomRangeInt(-180, 180));
                    //没有子弹了, 停止播放泛白效果
                    if (IsTotalAmmoEmpty())
                    {
                        //停止动画
                        AnimationPlayer.Stop();
                        //清除泛白效果
                        SetBlendSchedule(0);
                    }
                }
            }
            else //没有武器
            {
                if (!holster.HasVacancy()) //没有空位置, 扔掉当前武器
                {
                    //替换武器
                    roleMaster.ThrowWeapon();
                }
                roleMaster.PickUpWeapon(this);
            }
        }
    }

    /// <summary>
    /// 获取当前武器真实的旋转角度(弧度制), 由于武器旋转时加入了旋转吸附, 所以需要通过该函数来来知道当前武器的真实旋转角度
    /// </summary>
    public float GetRealGlobalRotation()
    {
        return Mathf.DegToRad(Master.MountPoint.RealRotationDegrees) + Rotation;
    }

    /// <summary>
    /// 触发扔掉武器时抛出的效果, 并不会管武器是否在武器背包中
    /// </summary>
    /// <param name="master">触发扔掉该武器的的角色</param>
    public void ThrowWeapon(Role master)
    {
        ThrowWeapon(master, master.GlobalPosition);
    }

    /// <summary>
    /// 触发扔掉武器时抛出的效果, 并不会管武器是否在武器背包中
    /// </summary>
    /// <param name="master">触发扔掉该武器的的角色</param>
    /// <param name="startPosition">投抛起始位置</param>
    public void ThrowWeapon(Role master, Vector2 startPosition)
    {
        //阴影偏移
        ShadowOffset = new Vector2(0, 2);

        if (master.Face == FaceDirection.Left)
        {
            Scale *= new Vector2(1, -1);
        }

        var rotation = master.MountPoint.GlobalRotation;
        GlobalRotation = rotation;

        if (master.Face == FaceDirection.Right)
        {
            startPosition += _gripPoint.Rotated(rotation);
        }
        else
        {
            startPosition += new Vector2(_gripPoint.X, -_gripPoint.Y).Rotated(rotation);
        }

        var startHeight = -master.MountPoint.Position.Y;
        var velocity = new Vector2(20, 0).Rotated(rotation);
        var yf = Utils.Random.RandomRangeInt(50, 70);
        Throw(startPosition, startHeight, yf, velocity, 0);
        
        //继承role的移动速度
        InheritVelocity(master);
    }

    protected override void OnThrowStart()
    {
        //禁用碰撞
        //Collision.Disabled = true;
        //AnimationPlayer.Play(AnimatorNames.Floodlight);
    }

    protected override void OnThrowOver()
    {
        //启用碰撞
        //Collision.Disabled = false;
        //还有弹药, 播放泛白效果
        if (!IsTotalAmmoEmpty())
        {
            AnimationPlayer.Play(AnimatorNames.Floodlight);
        }
    }

    /// <summary>
    /// 触发启用武器, 这个函数由 Holster 对象调用
    /// </summary>
    private void Active()
    {
        //调整阴影
        //ShadowOffset = new Vector2(0, Master.GlobalPosition.Y - GlobalPosition.Y);
        //ShadowOffset = new Vector2(0, -Master.MountPoint.Position.Y + 2);
        ShadowOffset = new Vector2(0, -Master.MountPoint.Position.Y);
        //枪口默认抬起角度
        RotationDegrees = -Attribute.DefaultAngle;
        ShowShadowSprite();
        OnActive();
    }

    /// <summary>
    /// 触发收起武器, 这个函数由 Holster 对象调用
    /// </summary>
    private void Conceal()
    {
        //停止换弹动画
        if (AnimationPlayer.CurrentAnimation == AnimatorNames.Reloading && AnimationPlayer.IsPlaying())
        {
            AnimationPlayer.Play(AnimatorNames.Reset);
        }
        
        HideShadowSprite();
        OnConceal();
    }
    
    public void OnRemoveItem()
    {
        //要重置部分重要属性属性
        if (Master.IsAi)
        {
            _triggerTimer = 0;
        }
        GetParent().RemoveChild(this);
        _triggerRoleFlag = false;
        SetCurrentWeaponAttribute(_playerWeaponAttribute);
        CollisionLayer = _tempLayer;

        //精灵位置, 旋转中心点
        AnimatedSprite.Position = Vector2.Zero;
        AnimatedSprite.Offset = Vector2.Zero;
        Collision.Position = _collPoint2;
        //清除 Ai 拾起标记
        RemoveSign(SignNames.AiFindWeaponSign);
        //停止换弹
        if (Reloading)
        {
            StopReload();
        }
        //停止换弹动画
        if (AnimationPlayer.CurrentAnimation == AnimatorNames.Reloading && AnimationPlayer.IsPlaying())
        {
            AnimationPlayer.Play(AnimatorNames.Reset);
        }
        OnRemove(Master);
    }

    public void OnPickUpItem()
    {
        Pickup();
        _triggerRoleFlag = true;
        SetCurrentWeaponAttribute(Master.IsAi ? _aiWeaponAttribute : _playerWeaponAttribute);
        //停止动画
        AnimationPlayer.Stop();
        //清除泛白效果
        SetBlendSchedule(0);
        ZIndex = 0;
        //禁用碰撞
        //Collision.Disabled = true;
        AnimatedSprite.Position = _gripPoint;
        AnimatedSprite.Offset = _gripOffset;
        Collision.Position = _collPoint1;
        //修改层级
        _tempLayer = CollisionLayer;
        CollisionLayer = PhysicsLayer.OnHand;
        //清除 Ai 拾起标记
        RemoveSign(SignNames.AiFindWeaponSign);
        OnPickUp(Master);
    }

    public void OnActiveItem()
    {
        //更改父节点
        var parent = GetParentOrNull<Node>();
        if (parent == null)
        {
            Master.MountPoint.AddChild(this);
        }
        else if (parent != Master.MountPoint)
        {
            parent.RemoveChild(this);
            Master.MountPoint.AddChild(this);
        }

        Position = Vector2.Zero;
        Scale = Vector2.One;
        RotationDegrees = 0;
        Visible = true;
        Active();
    }

    public void OnConcealItem()
    {
        var tempParent = GetParentOrNull<Node2D>();
        if (tempParent != null)
        {
            tempParent.RemoveChild(this);
            Master.BackMountPoint.AddChild(this);
            Master.OnPutBackMount(this, PackageIndex);
            Conceal();
        }
    }

    public void OnOverflowItem()
    {
        Master.ThrowWeapon(PackageIndex);
    }

    /// <summary>
    /// 获取相对于武器本地坐标的开火位置
    /// </summary>
    public Vector2 GetLocalFirePosition()
    {
        return AnimatedSprite.Position + FirePoint.Position;
    }
    
    /// <summary>
    /// 获取相对于武器本地坐标的抛壳位置
    /// </summary>
    public Vector2 GetLocalShellPosition()
    {
        return AnimatedSprite.Position + ShellPoint.Position;
    }

    /// <summary>
    /// 获取握把位置, 相当于武器的原点坐标
    /// </summary>
    public Vector2 GetGripPosition()
    {
        return _gripPoint + _gripOffset;
    }

    //设置当前使用的武器属性
    private void SetCurrentWeaponAttribute(ExcelConfig.WeaponBase attr)
    {
        if (attr != _weaponAttribute)
        {
            _weaponAttribute = attr;
            //重置开火速率
            CurrentFiringSpeed = _weaponAttribute.StartFiringSpeed;
        }
    }

    //-------------------------------- Ai相关 -----------------------------
    
    /// <summary>
    /// Ai调用, 触发扣动扳机, 并返回攻击状态
    /// </summary>
    public AiAttackEnum AiTriggerAttackState(AiAttackEnum prevState)
    {
        var chargeFinish = false;
        if (prevState == AiAttackEnum.AttackCharge) //蓄力中
        {
            var enemy = (Enemy)Master;
            if (!IsChargeFinish())
            {
                enemy.Attack();
                return prevState;
            }

            chargeFinish = true;
            enemy.LockingTime = 0;
        }
        
        AiAttackEnum flag;
        if (IsTotalAmmoEmpty()) //当前武器弹药打空
        {
            //切换到有子弹的武器
            var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty());
            if (index != -1)
            {
                flag = AiAttackEnum.ExchangeWeapon;
                Master.WeaponPack.ExchangeByIndex(index);
            }
            else //所有子弹打光
            {
                flag = AiAttackEnum.NoAmmo;
            }
        }
        else if (Reloading) //换弹中
        {
            flag = AiAttackEnum.TriggerReload;
        }
        else if (IsAmmoEmpty()) //弹夹已经打空
        {
            flag = AiAttackEnum.Reloading;
            Reload();
        }
        else if (_beLoadedState == 0 || _beLoadedState == -1) //需要上膛
        {
            flag = AiAttackEnum.AttackInterval;
            if (_attackTimer <= 0)
            {
                BeLoaded();
            }
        }
        else if (_beLoadedState == 1) //上膛中
        {
            flag = AiAttackEnum.AttackInterval;
        }
        else if (_continuousCount >= 1 && (!chargeFinish || _continuousCount >= 2)) //连发中
        {
            flag = AiAttackEnum.Attack;
        }
        else if (IsAttackIntervalTime()) //开火间隙
        {
            flag = AiAttackEnum.AttackInterval;
        }
        else
        {
            var enemy = (Enemy)Master;
            if (enemy.LockTargetTime >= Attribute.AiAttackAttr.LockingTime) //正常射击
            {
                if (GetDelayedAttackTime() > 0)
                {
                    flag = AiAttackEnum.Attack;
                    enemy.Attack();
                    if (_attackFlag) //成功触发攻击
                    {
                        enemy.LockingTime = 0;
                    }
                }
                else
                {
                    if (Attribute.ContinuousShoot) //连发
                    {
                        flag = AiAttackEnum.Attack;
                        enemy.Attack();
                        if (_attackFlag) //成功触发攻击
                        {
                            enemy.LockingTime = 0;
                        }
                    }
                    else //单发
                    {
                        if (Attribute.LooseShoot && Attribute.MinChargeTime > 0) //松发并蓄力攻击
                        {
                            flag = AiAttackEnum.AttackCharge;
                            enemy.Attack();
                        }
                        else
                        {
                            flag = AiAttackEnum.Attack;
                            enemy.Attack();
                            if (_attackFlag && _attackTimer > 0) //成功触发攻击
                            {
                                enemy.LockingTime = 0;
                            }
                        }
                    }
                }
            }
            else //锁定时间没到
            {
                flag = AiAttackEnum.LockingTime;
            }
        }

        return flag;
    }

    // /// <summary>
    // /// 获取 Ai 对于该武器的评分, 评分越高, 代表 Ai 会越优先选择该武器, 如果为 -1, 则表示 Ai 不会使用该武器
    // /// </summary>
    // public float GetAiScore()
    // {
    //     return 1;
    // }
}