Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / item / package / Holster.cs
@小李xl 小李xl on 11 Dec 2022 9 KB 敌人寻找可用武器逻辑
  1. using System;
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 角色身上的武器袋, 存储角色携带的武器
  7. /// </summary>
  8. public class Holster
  9. {
  10. /// <summary>
  11. /// 插槽类
  12. /// </summary>
  13. public class WeaponSlot
  14. {
  15. /// <summary>
  16. /// 是否启用
  17. /// </summary>
  18. public bool Enable = false;
  19. /// <summary>
  20. /// 当前插槽存放的武器类型
  21. /// </summary>
  22. public WeaponWeightType Type = WeaponWeightType.MainWeapon;
  23. /// <summary>
  24. /// 插槽存放的武器
  25. /// </summary>
  26. public Weapon Weapon;
  27. }
  28.  
  29. /// <summary>
  30. /// 归属者
  31. /// </summary>
  32. public Role Master { get; }
  33. //public Weapon HandheldWeapon { get; private set; }
  34. /// <summary>
  35. /// 当前使用的武器对象
  36. /// </summary>
  37. public Weapon ActiveWeapon { get; private set; }
  38.  
  39. /// <summary>
  40. /// 当前使用的武器的索引
  41. /// </summary>
  42. public int ActiveIndex { get; private set; } = 0;
  43.  
  44. /// <summary>
  45. /// 武器插槽
  46. /// </summary>
  47. public WeaponSlot[] SlotList { get; } = new WeaponSlot[4];
  48.  
  49. public Holster(Role master)
  50. {
  51. Master = master;
  52.  
  53. //创建武器的插槽, 默认前两个都是启用的
  54. WeaponSlot slot1 = new WeaponSlot();
  55. slot1.Enable = true;
  56. SlotList[0] = slot1;
  57.  
  58. WeaponSlot slot2 = new WeaponSlot();
  59. slot2.Enable = true;
  60. slot2.Type = WeaponWeightType.DeputyWeapon;
  61. SlotList[1] = slot2;
  62.  
  63. WeaponSlot slot3 = new WeaponSlot();
  64. SlotList[2] = slot3;
  65.  
  66. WeaponSlot slot4 = new WeaponSlot();
  67. slot4.Type = WeaponWeightType.DeputyWeapon;
  68. SlotList[3] = slot4;
  69. }
  70.  
  71. /// <summary>
  72. /// 返回当前武器袋是否还有空位
  73. /// </summary>
  74. public bool HasVacancy()
  75. {
  76. for (int i = 0; i < SlotList.Length; i++)
  77. {
  78. var item = SlotList[i];
  79. if (item.Enable && item.Weapon == null)
  80. {
  81. return true;
  82. }
  83. }
  84.  
  85. return false;
  86. }
  87.  
  88. /// <summary>
  89. /// 根据索引获取武器
  90. /// </summary>
  91. public Weapon GetWeapon(int index) {
  92. if (index >= SlotList.Length)
  93. {
  94. return null;
  95. }
  96. return SlotList[index].Weapon;
  97. }
  98.  
  99. /// <summary>
  100. /// 根据武器id查找武器袋中该武器所在的位置, 如果没有, 则返回 -1
  101. /// </summary>
  102. /// <param name="id">武器id</param>
  103. public int FindWeapon(string id)
  104. {
  105. for (int i = 0; i < SlotList.Length; i++)
  106. {
  107. var item = SlotList[i];
  108. if (item.Weapon != null && item.Weapon.TypeId == id)
  109. {
  110. return i;
  111. }
  112. }
  113. return -1;
  114. }
  115.  
  116. /// <summary>
  117. /// 通过回调函数查询武器在武器袋中的位置, 如果没有, 则返回 -1
  118. /// </summary>
  119. public int FindWeapon(Func<Weapon, int, bool> handler)
  120. {
  121. for (int i = 0; i < SlotList.Length; i++)
  122. {
  123. var item = SlotList[i];
  124. if (item.Weapon != null && handler(item.Weapon, i))
  125. {
  126. return i;
  127. }
  128. }
  129. return -1;
  130. }
  131.  
  132. /// <summary>
  133. /// 遍历所有武器
  134. /// </summary>
  135. public void ForEach(Action<Weapon, int> handler)
  136. {
  137. for (int i = 0; i < SlotList.Length; i++)
  138. {
  139. var item = SlotList[i];
  140. if (item.Weapon != null)
  141. {
  142. handler(item.Weapon, i);
  143. }
  144. }
  145. }
  146.  
  147. /// <summary>
  148. /// 从武器袋中移除所有武器, 并返回
  149. /// </summary>
  150. public Weapon[] GetAndClearWeapon()
  151. {
  152. List<Weapon> weapons = new List<Weapon>();
  153. for (int i = 0; i < SlotList.Length; i++)
  154. {
  155. var slot = SlotList[i];
  156. var weapon = slot.Weapon;
  157. if (weapon != null)
  158. {
  159. weapon.GetParent().RemoveChild(weapon);
  160. weapon.Remove();
  161. weapons.Add(weapon);
  162. slot.Weapon = null;
  163. }
  164. }
  165.  
  166. return weapons.ToArray();
  167. }
  168.  
  169. /// <summary>
  170. /// 返回是否能放入武器
  171. /// </summary>
  172. /// <param name="weapon">武器对象</param>
  173. public bool CanPickupWeapon(Weapon weapon)
  174. {
  175. for (int i = 0; i < SlotList.Length; i++)
  176. {
  177. var item = SlotList[i];
  178. if (item.Enable && weapon.Attribute.WeightType == item.Type && item.Weapon == null)
  179. {
  180. return true;
  181. }
  182. }
  183. return false;
  184. }
  185.  
  186. /// <summary>
  187. /// 拾起武器, 存入武器袋中, 返回存放在武器袋的位置, 如果容不下这把武器, 则会返回 -1
  188. /// </summary>
  189. /// <param name="weapon">武器对象</param>
  190. /// <param name="exchange">是否立即切换到该武器, 默认 true </param>
  191. public int PickupWeapon(Weapon weapon, bool exchange = true)
  192. {
  193. //已经被拾起了
  194. if (weapon.Master != null)
  195. {
  196. return -1;
  197. }
  198. for (int i = 0; i < SlotList.Length; i++)
  199. {
  200. var item = SlotList[i];
  201. if (item.Enable && weapon.Attribute.WeightType == item.Type && item.Weapon == null)
  202. {
  203. weapon.Pickup();
  204. item.Weapon = weapon;
  205. weapon.PickUpWeapon(Master);
  206. if (exchange)
  207. {
  208. ExchangeByIndex(i);
  209. }
  210.  
  211. return i;
  212. }
  213. }
  214. return -1;
  215. }
  216.  
  217. /// <summary>
  218. /// 移除指定位置的武器, 并返回这个武器对象, 如果移除正在使用的这把武器, 则会自动切换到上一把武器
  219. /// </summary>
  220. /// <param name="index">所在武器袋的位置索引</param>
  221. public Weapon RemoveWeapon(int index)
  222. {
  223. if (index < 0 || index >= SlotList.Length)
  224. {
  225. return null;
  226. }
  227. var slot = SlotList[index];
  228. if (slot.Weapon == null)
  229. {
  230. return null;
  231. }
  232. var weapon = slot.Weapon;
  233. weapon.GetParent().RemoveChild(weapon);
  234. slot.Weapon = null;
  235.  
  236. //如果是当前手持的武器, 就需要调用切换武器操作
  237. if (index == ActiveIndex)
  238. {
  239. //没有其他武器了
  240. if (ExchangePrev() == index)
  241. {
  242. ActiveIndex = 0;
  243. ActiveWeapon = null;
  244. }
  245. }
  246. weapon.Remove();
  247. return weapon;
  248. }
  249.  
  250. /// <summary>
  251. /// 切换到上一个武器
  252. /// </summary>
  253. public int ExchangePrev()
  254. {
  255. var index = ActiveIndex - 1;
  256. do
  257. {
  258. if (index < 0)
  259. {
  260. index = SlotList.Length - 1;
  261. }
  262. if (ExchangeByIndex(index))
  263. {
  264. return index;
  265. }
  266. } while (index-- != ActiveIndex);
  267. return -1;
  268. }
  269.  
  270. /// <summary>
  271. /// 切换到下一个武器,
  272. /// </summary>
  273. public int ExchangeNext()
  274. {
  275. var index = ActiveIndex + 1;
  276. do
  277. {
  278. if (index >= SlotList.Length)
  279. {
  280. index = 0;
  281. }
  282. if (ExchangeByIndex(index))
  283. {
  284. return index;
  285. }
  286. }
  287. while (index++ != ActiveIndex);
  288. return -1;
  289. }
  290.  
  291. /// <summary>
  292. /// 切换到指定索引的武器
  293. /// </summary>
  294. public bool ExchangeByIndex(int index)
  295. {
  296. if (index == ActiveIndex && ActiveWeapon != null) return true;
  297. if (index < 0 || index > SlotList.Length) return false;
  298. var slot = SlotList[index];
  299. if (slot == null || slot.Weapon == null) return false;
  300.  
  301. //将上一把武器放到背后
  302. if (ActiveWeapon != null)
  303. {
  304. var tempParent = ActiveWeapon.GetParentOrNull<Node2D>();
  305. if (tempParent != null)
  306. {
  307. tempParent.RemoveChild(ActiveWeapon);
  308. Master.BackMountPoint.AddChild(ActiveWeapon);
  309. if (ActiveIndex == 0)
  310. {
  311. ActiveWeapon.Position = new Vector2(0, 5);
  312. ActiveWeapon.RotationDegrees = 50;
  313. ActiveWeapon.Scale = new Vector2(-1, 1);
  314. }
  315. else if (ActiveIndex == 1)
  316. {
  317. ActiveWeapon.Position = new Vector2(0, 0);
  318. ActiveWeapon.RotationDegrees = 120;
  319. ActiveWeapon.Scale = new Vector2(1, -1);
  320. }
  321. else if (ActiveIndex == 2)
  322. {
  323. ActiveWeapon.Position = new Vector2(0, 5);
  324. ActiveWeapon.RotationDegrees = 310;
  325. ActiveWeapon.Scale = new Vector2(1, 1);
  326. }
  327. else if (ActiveIndex == 3)
  328. {
  329. ActiveWeapon.Position = new Vector2(0, 0);
  330. ActiveWeapon.RotationDegrees = 60;
  331. ActiveWeapon.Scale = new Vector2(1, 1);
  332. }
  333. ActiveWeapon.Conceal();
  334. }
  335. }
  336.  
  337. //更改父节点
  338. var parent = slot.Weapon.GetParentOrNull<Node>();
  339. if (parent == null)
  340. {
  341. Master.MountPoint.AddChild(slot.Weapon);
  342. }
  343. else if (parent != Master.MountPoint)
  344. {
  345. parent.RemoveChild(slot.Weapon);
  346. Master.MountPoint.AddChild(slot.Weapon);
  347. }
  348.  
  349. slot.Weapon.Position = Vector2.Zero;
  350. slot.Weapon.Scale = Vector2.One;
  351. slot.Weapon.RotationDegrees = 0;
  352. ActiveWeapon = slot.Weapon;
  353. ActiveIndex = index;
  354. ActiveWeapon.Active();
  355. return true;
  356. }
  357. }