- using System;
- using System.Collections.Generic;
- using Godot;
-
- /// <summary>
- /// 角色身上的武器袋, 存储角色携带的武器
- /// </summary>
- public class Holster
- {
- /// <summary>
- /// 插槽类
- /// </summary>
- public class WeaponSlot
- {
- /// <summary>
- /// 是否启用
- /// </summary>
- public bool Enable = false;
- /// <summary>
- /// 当前插槽存放的武器类型
- /// </summary>
- public WeaponWeightType Type = WeaponWeightType.MainWeapon;
- /// <summary>
- /// 插槽存放的武器
- /// </summary>
- public Weapon Weapon;
- }
-
- /// <summary>
- /// 归属者
- /// </summary>
- public Role Master { get; }
-
- //public Weapon HandheldWeapon { get; private set; }
-
- /// <summary>
- /// 当前使用的武器对象
- /// </summary>
- public Weapon ActiveWeapon { get; private set; }
-
- /// <summary>
- /// 当前使用的武器的索引
- /// </summary>
- public int ActiveIndex { get; private set; } = 0;
-
- /// <summary>
- /// 武器插槽
- /// </summary>
- public WeaponSlot[] SlotList { get; } = new WeaponSlot[4];
-
- public Holster(Role master)
- {
- Master = master;
-
- //创建武器的插槽, 默认前两个都是启用的
- WeaponSlot slot1 = new WeaponSlot();
- slot1.Enable = true;
- SlotList[0] = slot1;
-
- WeaponSlot slot2 = new WeaponSlot();
- slot2.Enable = true;
- slot2.Type = WeaponWeightType.DeputyWeapon;
- SlotList[1] = slot2;
-
- WeaponSlot slot3 = new WeaponSlot();
- SlotList[2] = slot3;
-
- WeaponSlot slot4 = new WeaponSlot();
- slot4.Type = WeaponWeightType.DeputyWeapon;
- SlotList[3] = slot4;
- }
-
- /// <summary>
- /// 返回当前武器袋是否还有空位
- /// </summary>
- public bool HasVacancy()
- {
- for (int i = 0; i < SlotList.Length; i++)
- {
- var item = SlotList[i];
- if (item.Enable && item.Weapon == null)
- {
- return true;
- }
- }
-
- return false;
- }
-
- /// <summary>
- /// 根据索引获取武器
- /// </summary>
- public Weapon GetWeapon(int index)
- {
- if (index < 0 || index >= SlotList.Length)
- {
- return null;
- }
- return SlotList[index].Weapon;
- }
-
- /// <summary>
- /// 根据武器id查找武器袋中该武器所在的位置, 如果没有, 则返回 -1
- /// </summary>
- /// <param name="id">武器id</param>
- public int FindWeapon(string id)
- {
- for (int i = 0; i < SlotList.Length; i++)
- {
- var item = SlotList[i];
- if (item.Weapon != null && item.Weapon.TypeId == id)
- {
- return i;
- }
- }
- return -1;
- }
-
- /// <summary>
- /// 通过回调函数查询武器在武器袋中的位置, 如果没有, 则返回 -1
- /// </summary>
- public int FindWeapon(Func<Weapon, int, bool> handler)
- {
- for (int i = 0; i < SlotList.Length; i++)
- {
- var item = SlotList[i];
- if (item.Weapon != null && handler(item.Weapon, i))
- {
- return i;
- }
- }
- return -1;
- }
-
- /// <summary>
- /// 遍历所有武器
- /// </summary>
- public void ForEach(Action<Weapon, int> handler)
- {
- for (int i = 0; i < SlotList.Length; i++)
- {
- var item = SlotList[i];
- if (item.Weapon != null)
- {
- handler(item.Weapon, i);
- }
- }
- }
-
- /// <summary>
- /// 从武器袋中移除所有武器, 并返回
- /// </summary>
- public Weapon[] GetAndClearWeapon()
- {
- List<Weapon> weapons = new List<Weapon>();
- for (int i = 0; i < SlotList.Length; i++)
- {
- var slot = SlotList[i];
- var weapon = slot.Weapon;
- if (weapon != null)
- {
- weapon.GetParent().RemoveChild(weapon);
- weapon.RemoveAt();
- weapons.Add(weapon);
- slot.Weapon = null;
- }
- }
-
- return weapons.ToArray();
- }
-
- /// <summary>
- /// 返回是否能放入武器
- /// </summary>
- /// <param name="weapon">武器对象</param>
- public bool CanPickupWeapon(Weapon weapon)
- {
- for (int i = 0; i < SlotList.Length; i++)
- {
- var item = SlotList[i];
- if (item.Enable && weapon.Attribute.WeightType == item.Type && item.Weapon == null)
- {
- return true;
- }
- }
- return false;
- }
-
- /// <summary>
- /// 拾起武器, 存入武器袋中, 返回存放在武器袋的位置, 如果容不下这把武器, 则会返回 -1
- /// </summary>
- /// <param name="weapon">武器对象</param>
- /// <param name="exchange">是否立即切换到该武器, 默认 true </param>
- public int PickupWeapon(Weapon weapon, bool exchange = true)
- {
- //已经被拾起了
- if (weapon.Master != null)
- {
- return -1;
- }
- for (int i = 0; i < SlotList.Length; i++)
- {
- var item = SlotList[i];
- if (item.Enable && weapon.Attribute.WeightType == item.Type && item.Weapon == null)
- {
- weapon.Pickup();
- item.Weapon = weapon;
- weapon.PickUpWeapon(Master);
- if (exchange)
- {
- ExchangeByIndex(i);
- }
-
- return i;
- }
- }
- return -1;
- }
-
- /// <summary>
- /// 移除指定位置的武器, 并返回这个武器对象, 如果移除正在使用的这把武器, 则会自动切换到上一把武器
- /// </summary>
- /// <param name="index">所在武器袋的位置索引</param>
- public Weapon RemoveWeapon(int index)
- {
- if (index < 0 || index >= SlotList.Length)
- {
- return null;
- }
- var slot = SlotList[index];
- if (slot.Weapon == null)
- {
- return null;
- }
- var weapon = slot.Weapon;
- weapon.GetParent().RemoveChild(weapon);
- slot.Weapon = null;
-
- //如果是当前手持的武器, 就需要调用切换武器操作
- if (index == ActiveIndex)
- {
- //没有其他武器了
- if (ExchangePrev() == index)
- {
- ActiveIndex = 0;
- ActiveWeapon = null;
- }
- }
- weapon.RemoveAt();
- return weapon;
- }
-
- /// <summary>
- /// 切换到上一个武器
- /// </summary>
- public int ExchangePrev()
- {
- var index = ActiveIndex - 1;
- do
- {
- if (index < 0)
- {
- index = SlotList.Length - 1;
- }
- if (ExchangeByIndex(index))
- {
- return index;
- }
- } while (index-- != ActiveIndex);
- return -1;
- }
-
- /// <summary>
- /// 切换到下一个武器,
- /// </summary>
- public int ExchangeNext()
- {
- var index = ActiveIndex + 1;
- do
- {
- if (index >= SlotList.Length)
- {
- index = 0;
- }
- if (ExchangeByIndex(index))
- {
- return index;
- }
- }
- while (index++ != ActiveIndex);
- return -1;
- }
-
- /// <summary>
- /// 切换到指定索引的武器
- /// </summary>
- public bool ExchangeByIndex(int index)
- {
- if (index == ActiveIndex && ActiveWeapon != null) return true;
- if (index < 0 || index > SlotList.Length) return false;
- var slot = SlotList[index];
- if (slot == null || slot.Weapon == null) return false;
-
- //将上一把武器放到背后
- if (ActiveWeapon != null)
- {
- var tempParent = ActiveWeapon.GetParentOrNull<Node2D>();
- if (tempParent != null)
- {
- tempParent.RemoveChild(ActiveWeapon);
- Master.BackMountPoint.AddChild(ActiveWeapon);
- if (ActiveIndex == 0)
- {
- ActiveWeapon.Position = new Vector2(0, 5);
- ActiveWeapon.RotationDegrees = 50;
- ActiveWeapon.Scale = new Vector2(-1, 1);
- }
- else if (ActiveIndex == 1)
- {
- ActiveWeapon.Position = new Vector2(0, 0);
- ActiveWeapon.RotationDegrees = 120;
- ActiveWeapon.Scale = new Vector2(1, -1);
- }
- else if (ActiveIndex == 2)
- {
- ActiveWeapon.Position = new Vector2(0, 5);
- ActiveWeapon.RotationDegrees = 310;
- ActiveWeapon.Scale = new Vector2(1, 1);
- }
- else if (ActiveIndex == 3)
- {
- ActiveWeapon.Position = new Vector2(0, 0);
- ActiveWeapon.RotationDegrees = 60;
- ActiveWeapon.Scale = new Vector2(1, 1);
- }
- ActiveWeapon.Conceal();
- }
- }
-
- //更改父节点
- var parent = slot.Weapon.GetParentOrNull<Node>();
- if (parent == null)
- {
- Master.MountPoint.AddChild(slot.Weapon);
- }
- else if (parent != Master.MountPoint)
- {
- parent.RemoveChild(slot.Weapon);
- Master.MountPoint.AddChild(slot.Weapon);
- }
-
- slot.Weapon.Position = Vector2.Zero;
- slot.Weapon.Scale = Vector2.One;
- slot.Weapon.RotationDegrees = 0;
- ActiveWeapon = slot.Weapon;
- ActiveIndex = index;
- ActiveWeapon.Active();
- return true;
- }
- }