Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / item / package / Holster.cs
  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 IsEmpty()
  75. {
  76. for (int i = 0; i < SlotList.Length; i++)
  77. {
  78. if (SlotList[i].Weapon != null)
  79. {
  80. return false;
  81. }
  82. }
  83.  
  84. return true;
  85. }
  86. /// <summary>
  87. /// 返回当前武器袋是否还有空位
  88. /// </summary>
  89. public bool HasVacancy()
  90. {
  91. for (int i = 0; i < SlotList.Length; i++)
  92. {
  93. var item = SlotList[i];
  94. if (item.Enable && item.Weapon == null)
  95. {
  96. return true;
  97. }
  98. }
  99.  
  100. return false;
  101. }
  102.  
  103. /// <summary>
  104. /// 根据索引获取武器
  105. /// </summary>
  106. public Weapon GetWeapon(int index)
  107. {
  108. if (index < 0 || index >= SlotList.Length)
  109. {
  110. return null;
  111. }
  112. return SlotList[index].Weapon;
  113. }
  114.  
  115. /// <summary>
  116. /// 根据武器id查找武器袋中该武器所在的位置, 如果没有, 则返回 -1
  117. /// </summary>
  118. /// <param name="id">武器id</param>
  119. public int FindWeapon(string id)
  120. {
  121. for (int i = 0; i < SlotList.Length; i++)
  122. {
  123. var item = SlotList[i];
  124. if (item.Weapon != null && item.Weapon.TypeId == id)
  125. {
  126. return i;
  127. }
  128. }
  129. return -1;
  130. }
  131.  
  132. /// <summary>
  133. /// 通过回调函数查询武器在武器袋中的位置, 如果没有, 则返回 -1
  134. /// </summary>
  135. public int FindWeapon(Func<Weapon, int, bool> handler)
  136. {
  137. for (int i = 0; i < SlotList.Length; i++)
  138. {
  139. var item = SlotList[i];
  140. if (item.Weapon != null && handler(item.Weapon, i))
  141. {
  142. return i;
  143. }
  144. }
  145. return -1;
  146. }
  147.  
  148. /// <summary>
  149. /// 遍历所有武器
  150. /// </summary>
  151. public void ForEach(Action<Weapon, int> handler)
  152. {
  153. for (int i = 0; i < SlotList.Length; i++)
  154. {
  155. var item = SlotList[i];
  156. if (item.Weapon != null)
  157. {
  158. handler(item.Weapon, i);
  159. }
  160. }
  161. }
  162.  
  163. /// <summary>
  164. /// 从武器袋中移除所有武器, 并返回
  165. /// </summary>
  166. public Weapon[] GetAndClearWeapon()
  167. {
  168. List<Weapon> weapons = new List<Weapon>();
  169. for (int i = 0; i < SlotList.Length; i++)
  170. {
  171. var slot = SlotList[i];
  172. var weapon = slot.Weapon;
  173. if (weapon != null)
  174. {
  175. weapon.GetParent().RemoveChild(weapon);
  176. weapon.RemoveAt();
  177. weapons.Add(weapon);
  178. slot.Weapon = null;
  179. }
  180. }
  181.  
  182. return weapons.ToArray();
  183. }
  184.  
  185. /// <summary>
  186. /// 返回是否能放入武器
  187. /// </summary>
  188. /// <param name="weapon">武器对象</param>
  189. public bool CanPickupWeapon(Weapon weapon)
  190. {
  191. for (int i = 0; i < SlotList.Length; i++)
  192. {
  193. var item = SlotList[i];
  194. if (item.Enable && weapon.Attribute.WeightType == item.Type && item.Weapon == null)
  195. {
  196. return true;
  197. }
  198. }
  199. return false;
  200. }
  201.  
  202. /// <summary>
  203. /// 拾起武器, 存入武器袋中, 返回存放在武器袋的位置, 如果容不下这把武器, 则会返回 -1
  204. /// </summary>
  205. /// <param name="weapon">武器对象</param>
  206. /// <param name="exchange">是否立即切换到该武器, 默认 true </param>
  207. public int PickupWeapon(Weapon weapon, bool exchange = true)
  208. {
  209. //已经被拾起了
  210. if (weapon.Master != null)
  211. {
  212. return -1;
  213. }
  214. for (int i = 0; i < SlotList.Length; i++)
  215. {
  216. var item = SlotList[i];
  217. if (item.Enable && weapon.Attribute.WeightType == item.Type && item.Weapon == null)
  218. {
  219. weapon.Pickup();
  220. item.Weapon = weapon;
  221. weapon.PickUpWeapon(Master);
  222. if (exchange)
  223. {
  224. ExchangeByIndex(i);
  225. }
  226.  
  227. return i;
  228. }
  229. }
  230. return -1;
  231. }
  232.  
  233. /// <summary>
  234. /// 移除指定位置的武器, 并返回这个武器对象, 如果移除正在使用的这把武器, 则会自动切换到上一把武器
  235. /// </summary>
  236. /// <param name="index">所在武器袋的位置索引</param>
  237. public Weapon RemoveWeapon(int index)
  238. {
  239. if (index < 0 || index >= SlotList.Length)
  240. {
  241. return null;
  242. }
  243. var slot = SlotList[index];
  244. if (slot.Weapon == null)
  245. {
  246. return null;
  247. }
  248. var weapon = slot.Weapon;
  249. weapon.GetParent().RemoveChild(weapon);
  250. slot.Weapon = null;
  251.  
  252. //如果是当前手持的武器, 就需要调用切换武器操作
  253. if (index == ActiveIndex)
  254. {
  255. //没有其他武器了
  256. if (ExchangePrev() == index)
  257. {
  258. ActiveIndex = 0;
  259. ActiveWeapon = null;
  260. }
  261. }
  262. weapon.RemoveAt();
  263. return weapon;
  264. }
  265.  
  266. /// <summary>
  267. /// 切换到上一个武器
  268. /// </summary>
  269. public int ExchangePrev()
  270. {
  271. var index = ActiveIndex - 1;
  272. do
  273. {
  274. if (index < 0)
  275. {
  276. index = SlotList.Length - 1;
  277. }
  278. if (ExchangeByIndex(index))
  279. {
  280. return index;
  281. }
  282. } while (index-- != ActiveIndex);
  283. return -1;
  284. }
  285.  
  286. /// <summary>
  287. /// 切换到下一个武器,
  288. /// </summary>
  289. public int ExchangeNext()
  290. {
  291. var index = ActiveIndex + 1;
  292. do
  293. {
  294. if (index >= SlotList.Length)
  295. {
  296. index = 0;
  297. }
  298. if (ExchangeByIndex(index))
  299. {
  300. return index;
  301. }
  302. }
  303. while (index++ != ActiveIndex);
  304. return -1;
  305. }
  306.  
  307. /// <summary>
  308. /// 切换到指定索引的武器
  309. /// </summary>
  310. public bool ExchangeByIndex(int index)
  311. {
  312. if (index == ActiveIndex && ActiveWeapon != null) return true;
  313. if (index < 0 || index > SlotList.Length) return false;
  314. var slot = SlotList[index];
  315. if (slot == null || slot.Weapon == null) return false;
  316.  
  317. //将上一把武器放到背后
  318. if (ActiveWeapon != null)
  319. {
  320. var tempParent = ActiveWeapon.GetParentOrNull<Node2D>();
  321. if (tempParent != null)
  322. {
  323. tempParent.RemoveChild(ActiveWeapon);
  324. Master.BackMountPoint.AddChild(ActiveWeapon);
  325. if (ActiveIndex == 0)
  326. {
  327. ActiveWeapon.Position = new Vector2(0, 5);
  328. ActiveWeapon.RotationDegrees = 50;
  329. ActiveWeapon.Scale = new Vector2(-1, 1);
  330. }
  331. else if (ActiveIndex == 1)
  332. {
  333. ActiveWeapon.Position = new Vector2(0, 0);
  334. ActiveWeapon.RotationDegrees = 120;
  335. ActiveWeapon.Scale = new Vector2(1, -1);
  336. }
  337. else if (ActiveIndex == 2)
  338. {
  339. ActiveWeapon.Position = new Vector2(0, 5);
  340. ActiveWeapon.RotationDegrees = 310;
  341. ActiveWeapon.Scale = new Vector2(1, 1);
  342. }
  343. else if (ActiveIndex == 3)
  344. {
  345. ActiveWeapon.Position = new Vector2(0, 0);
  346. ActiveWeapon.RotationDegrees = 60;
  347. ActiveWeapon.Scale = new Vector2(1, 1);
  348. }
  349. ActiveWeapon.Conceal();
  350. }
  351. }
  352.  
  353. //更改父节点
  354. var parent = slot.Weapon.GetParentOrNull<Node>();
  355. if (parent == null)
  356. {
  357. Master.MountPoint.AddChild(slot.Weapon);
  358. }
  359. else if (parent != Master.MountPoint)
  360. {
  361. parent.RemoveChild(slot.Weapon);
  362. Master.MountPoint.AddChild(slot.Weapon);
  363. }
  364.  
  365. slot.Weapon.Position = Vector2.Zero;
  366. slot.Weapon.Scale = Vector2.One;
  367. slot.Weapon.RotationDegrees = 0;
  368. ActiveWeapon = slot.Weapon;
  369. ActiveIndex = index;
  370. ActiveWeapon.Active();
  371. return true;
  372. }
  373. }