y_weapons.inc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*enum E_Y_WEAPONS_DATA
  2. {
  3. E_Y_WEAPONS_DATA_NEXT
  4. E_Y_WEAPONS_DATA_LAST
  5. E_Y_WEAPONS_DATA_SLOT
  6. E_Y_WEAPONS_DATA_NEXT
  7. }*/
  8. static stock const
  9. YSI_g_scWeaponSlots[] =
  10. {
  11. 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
  12. 10, 10, 10, 10, 10, 10, 8, 8, 8, 2,
  13. 2, 2, 3, 3, 3, 4, 4, 5, 5, 4,
  14. 6, 6, 7, 7, 7, 7, 8, 12, 9, 9,
  15. 9, 11, 11, 11
  16. };
  17. // Store the ammo, -1 means does not have.
  18. static stock
  19. YSI_g_sWeapons[MAX_PLAYERS][47 - 3],
  20. YSI_g_sSlots[MAX_PLAYERS],
  21. YSI_g_sCurrentSet[MAX_PLAYERS][13],
  22. PlayerArray:YSI_g_sHasConflict<MAX_PLAYERS>,
  23. PlayerArray:YSI_g_sHasExtras<MAX_PLAYERS>;
  24. hook OnPlayerConnect(playerid)
  25. {
  26. // Always have fists.
  27. YSI_g_sSlots = 1;
  28. // Have no other weapons though.
  29. for (new i = 0; i != sizeof (YSI_g_sWeapons[]); ++i)
  30. {
  31. YSI_g_sWeapons[playerid][i] = -1;
  32. }
  33. for (new i = 0; i != sizeof (YSI_g_sCurrentSet[]); ++i)
  34. {
  35. YSI_g_sCurrentSet[playerid][i] = 0;
  36. }
  37. }
  38. static stock Weapon_CountSlots(playerid)
  39. {
  40. new
  41. count = 0,
  42. slots = YSI_g_sSlots[playerid];
  43. for (new j = 1; j != (1 << 13); j <<= 1)
  44. {
  45. if (slots & j)
  46. {
  47. ++count;
  48. }
  49. }
  50. return count;
  51. }
  52. static stock Weapon_DoRemove(playerid, weaponid)
  53. {
  54. new
  55. w[13],
  56. a[13];
  57. // Get existing weapons (minus one).
  58. for (new i = 0; i != 13; ++i)
  59. {
  60. GetPlayerWeaponData(playerid, i, w[i], a[i]);
  61. if (w[i] == weaponid)
  62. {
  63. w[i] = 0;
  64. }
  65. }
  66. // Get the current weapon and reset all.
  67. new
  68. s = GetPlayerWeapon(playerid);
  69. ResetPlayerWeapons(playerid);
  70. // Restore all weapons except the removed one.
  71. for (new i = 0; i != 13; ++i)
  72. {
  73. if (w[i])
  74. {
  75. GivePlayerWeapon(playerid, w[i], a[i]);
  76. }
  77. }
  78. if (s != weaponid)
  79. {
  80. SetPlayerArmedWeapon(playerid, s);
  81. }
  82. return 1;
  83. }
  84. static stock Weapon_CheckExtra(playerid)
  85. {
  86. // Check if we need (or no longer need) extra weapons to detect multiple
  87. // weapons in the same slot while not having enough weapons naturally to do
  88. // it cleanly.
  89. if (PA_Get(YSI_g_sHasExtras, playerid))
  90. {
  91. // Has extras already - do we still need them.
  92. new
  93. count = 0,
  94. slots = YSI_g_sSlots[playerid],
  95. w[13],
  96. a[13];
  97. // Get existing weapons (minus one).
  98. for (new i = 0, j = 1; i != 13; ++i, j <<= 1)
  99. {
  100. if (slots & j)
  101. {
  102. GetPlayerWeaponData(playerid, i, w[i], a[i]);
  103. ++count;
  104. }
  105. }
  106. if (count < 3)
  107. {
  108. }
  109. else
  110. {
  111. // No longer need extras.
  112. if (
  113. }
  114. }
  115. else
  116. {
  117. }
  118. return 1;
  119. }
  120. static stock Weapon_DoGive(playerid, weaponid, id, ammo)
  121. {
  122. ammo = max(ammo, 0);
  123. if (weaponid == WEAPON_SATCHEL)
  124. {
  125. // VERY special case - give them two weapons, neither of which are in
  126. // shared slots. This means that a) we never need to check for slot
  127. // conflicts and b) we don't need to check if we need extra hidden
  128. // weapons to detect changing slots because there will be at least 3
  129. // slots in use (so remove any extra weapons they may have).
  130. if (PA_Get(YSI_g_sHasConflict, playerid))
  131. {
  132. // Has a conflict.
  133. if (PA_Get(YSI_g_sHasExtras, playerid))
  134. {
  135. // Has extra weapons to make up the difference.
  136. PA_Vet(YSI_g_sHasExtras, playerid);
  137. if (YSI_g_sSlots[playerid] & (1 << 10))
  138. {
  139. Weapon_DoRemove(playerid, WEAPON_FLOWER);
  140. }
  141. else
  142. {
  143. Weapon_DoRemove(playerid, WEAPON_FLOWER);
  144. }
  145. }
  146. }
  147. return 1;
  148. }
  149. new
  150. slot = YSI_g_scWeaponSlots[id];
  151. if (YSI_g_sWeapons[playerid][id] == -1)
  152. {
  153. // Don't already have this weapon.
  154. YSI_g_sWeapons[playerid][id] = ammo;
  155. if (YSI_g_sSlots[playerid] & (1 << slot))
  156. {
  157. // Already have a different weapon in this slot.
  158. PA_Let(YSI_g_sHasConflict, playerid);
  159. // Now we need to work out if we need extra fake slots.
  160. if (Weapon_CountSlots(playerid) < 3)
  161. {
  162. // We need at least three slots for this to work to detect when
  163. // the player changes weapon in one direction or the other. One
  164. // of these will always be slot 0, as that can never be empty.
  165. // The other COULD be slot 10 or 12, but never both.
  166. if (YSI_g_sSlots[playerid] & (1 << 10))
  167. {
  168. // Give them the detonator (they will have no satchels).
  169. }
  170. else
  171. {
  172. //
  173. }
  174. }
  175. }
  176. else
  177. {
  178. // Don't already have a weapon in this slot - just give them it.
  179. GivePlayerWeapon(playerid, weaponid, ammo);
  180. YSI_g_sCurrentSet[playerid][slot] = weaponid;
  181. }
  182. }
  183. else
  184. {
  185. YSI_g_sWeapons[playerid][id] += ammo;
  186. if (YSI_g_sCurrentSet[playerid][slot] == weaponid)
  187. {
  188. // They are currently holding the weapon, give them more ammo.
  189. GivePlayerWeapon(playerid, weaponid, ammo);
  190. }
  191. // Now we need to work out if we no longer need extra fake slots.
  192. }
  193. // Make sure we know there is a weapon in this slot.
  194. YSI_g_scWeaponSlots[id] |= (1 << slot);
  195. return 1;
  196. }
  197. stock Weapon_Give(playerid, weaponid, ammo)
  198. {
  199. if (0 <= weaponid <= 18)
  200. {
  201. Weapon_DoGive(playerid, weaponid, weaponid, ammo);
  202. }
  203. else if (22 <= weaponid <= 46)
  204. {
  205. Weapon_DoGive(playerid, weaponid, weaponid - 3, ammo);
  206. }
  207. }