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