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