y_groupsecond.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /*----------------------------------------------------------------------------*-
  2. =======================================
  3. y_groups - Player group abstractions!
  4. =======================================
  5. Description:
  6. Admin levels, gangs, teams etc - they're all "groups" of people, this
  7. provides an abstraction for all of these collections.
  8. Legal:
  9. Version: MPL 1.1
  10. The contents of this file are subject to the Mozilla Public License Version
  11. 1.1 (the "License"); you may not use this file except in compliance with
  12. the License. You may obtain a copy of the License at
  13. http://www.mozilla.org/MPL/
  14. Software distributed under the License is distributed on an "AS IS" basis,
  15. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  16. for the specific language governing rights and limitations under the
  17. License.
  18. The Original Code is the SA:MP script information include.
  19. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  20. Portions created by the Initial Developer are Copyright (C) 2008
  21. the Initial Developer. All Rights Reserved.
  22. Contributors:
  23. ZeeX, koolk
  24. Thanks:
  25. Peter, Cam - Support.
  26. ZeeX - Very productive conversations.
  27. koolk - IsPlayerinAreaEx code.
  28. TheAlpha - Danish translation.
  29. breadfish - German translation.
  30. Fireburn - Dutch translation.
  31. yom - French translation.
  32. 50p - Polish translation.
  33. Zamaroht - Spanish translation.
  34. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
  35. for me to strive to better.
  36. Pixels^ - Running XScripters where the idea was born.
  37. Matite - Pestering me to release it and using it.
  38. Very special thanks to:
  39. Thiadmer - PAWN.
  40. Kye/Kalcor - SA:MP.
  41. SA:MP Team past, present and future - SA:MP.
  42. Version:
  43. 1.0
  44. Changelog:
  45. 29/11/10:
  46. First version
  47. -*----------------------------------------------------------------------------*/
  48. #undef _inc_y_groupsecond
  49. // This is actually the second half of a function!
  50. //_GROUP_INIT(group);
  51. //_GROUP_MAKE_NAME<Group_...Init>(group);
  52. #if YSIM_HAS_MASTER
  53. #if YSIM_IS_CLIENT
  54. #else
  55. #if YSIM_IS_SERVER
  56. _GROUP_OPC_IS_CALLED(playerid);
  57. #else
  58. #if YSIM_IS_STUB
  59. #error y_groupsecond called with YSIM_IS_STUB.
  60. #else
  61. _GROUP_OPC_IS_CALLED(playerid);
  62. #endif
  63. #endif
  64. #endif
  65. #else
  66. _GROUP_OPC_IS_CALLED(playerid);
  67. #endif
  68. // This is also NOT a master controlled function as the group master may be
  69. // different to a system using the group system's master.
  70. #pragma tabsize 4
  71. _GROUP_OPC_OTHER_CALLED(playerid);
  72. }
  73. forward _GROUP_OPC_PUBLIC(playerid);
  74. // This file contains generic code for setting all the stats to do with a single
  75. // element type. Groups can be defined for any element (classes, objects etc)
  76. // and each one will specialise this file to give different functions.
  77. #if !defined _GROUP_MAKE_NAME
  78. #error Please define _GROUP_MAKE_NAME before including y_groups.
  79. #endif
  80. #if !defined _GROUP_MAKE_LIMIT
  81. #error Please define _GROUP_MAKE_LIMIT before including y_groups.
  82. #endif
  83. // Start of the multi-use file.
  84. static stock
  85. BitArray:_GROUP_GLOBAL_NAME<_GROUP_MAKE_LIMIT>,
  86. BitArray:_GROUP_GROUP_NAME[MAX_GROUPS]<_GROUP_MAKE_LIMIT>,
  87. BitArray:_GROUP_DEFAULTS<_:MAX_GROUPS + 1>,
  88. YSI_g_sNextUpdateFunc[32],
  89. YSI_g_sNextInitFunc[32],
  90. bool:YSI_g_sHasOPC = false;
  91. // Initialise permissions for a new player based on the default settings. This
  92. // is one of the few places where direct master system intervention is required
  93. // due to the horrible combination of function naming macros.
  94. // TODO: Uncomment when the better y_hooks library is integrated.
  95. _GROUP_OPC_OTHER_CALLED(playerid)
  96. {
  97. if (YSI_g_sHasOPC) CallLocalFunction(#_GROUP_OPC_PUBLIC, "i", playerid);
  98. }
  99. #if YSIM_CLOUD
  100. _GROUP_OPC_IS_CALLED(playerid)<>
  101. {
  102. #pragma unused playerid
  103. }
  104. _GROUP_OPC_IS_CALLED(playerid)<_YCM:y>
  105. #else
  106. stock _GROUP_OPC_IS_CALLED(playerid)
  107. #endif
  108. {
  109. P:3(#_GROUP_OPC_IS_CALLED " called in %d", _@);
  110. for (new j = 0; j != _GROUP_MAKE_LIMIT; ++j)
  111. {
  112. // Set and unset all the global items.
  113. _GROUP_SET_PLAYER(j, playerid, Bit_Get(_GROUP_GLOBAL_NAME, j));
  114. P:5(#_GROUP_SET_PLAYER ": Set %d %d %d", j, playerid, Bit_Get(_GROUP_GLOBAL_NAME, j));
  115. }
  116. }
  117. #if YSIM_HAS_MASTER
  118. #if YSIM_IS_CLIENT
  119. #define __GF<%0...%1>[%2](%3)<%4> stock _GROUP_MAKE_NAME<%0...%1>(%3)U@(8,YSIM_CALLER,_@),W@(#@#_GROUP_MAKE_NAME<%0...%1>,#%2#x,%4),U@(8,YSIM_CALLER,-1);stock _GROUP_MAKE_NAME<_%0...%1>(%3)
  120. #else
  121. #if YSIM_IS_SERVER
  122. #define __GF<%0...%1>[%2](%3)<%4> forward _GROUP_MAKE_NAME<@%0...%1>(%3);_GROUP_MAKE_NAME<@%0...%1>(%3)_GROUP_MAKE_NAME<%0...%1>(%4);_GROUP_MAKE_NAME<%0...%1>(%3)
  123. #else
  124. #if YSIM_IS_STUB
  125. #error y_groupsecond called with YSIM_IS_STUB.
  126. #else
  127. #define __GF<%0...%1>[%2](%3)<%4> forward _GROUP_MAKE_NAME<@%0...%1>(%3);_GROUP_MAKE_NAME<@%0...%1>(%3)<>{}_GROUP_MAKE_NAME<@%0...%1>(%3)<_YCM:y>_GROUP_MAKE_NAME<%0...%1>(%4);_GROUP_MAKE_NAME<%0...%1>(%3)<>Y@(),W@(#@#_GROUP_MAKE_NAME<%0...%1>,#%2#x,%4),T@();_GROUP_MAKE_NAME<%0...%1>(%3)<_YCM:y>
  128. #endif
  129. #endif
  130. #endif
  131. #else
  132. #define __GF<%0...%1>[%2](%3)<%4> stock _GROUP_MAKE_NAME<%0...%1>(%3)
  133. #endif
  134. _GROUP_CREATE(group,idx);
  135. #if YSIM_HAS_MASTER
  136. #if YSIM_IS_CLIENT
  137. // Note: not the same.
  138. _GROUP_MAKE_NAME<_yG@Init...>(group,idx)
  139. #else
  140. #if YSIM_IS_SERVER
  141. _GROUP_CREATE(group,idx)
  142. #else
  143. #if !YSIM_IS_STUB
  144. _GROUP_CREATE(group,idx)<>
  145. {
  146. P:3(#_GROUP_MAKE_NAME<@yG_Init...> " called in %d", _@);
  147. if (group == -1)
  148. {
  149. YSI_g_sHasOPC = funcidx(#_GROUP_OPC_PUBLIC) != -1;
  150. P:3(#_GROUP_OPC_PUBLIC " does%s exist", YSI_g_sHasOPC ? ("") : ("not"));
  151. new
  152. a = Scripting_GetPublic(idx >>> 16, YSI_g_sNextUpdateFunc, "@yG_Upd"),
  153. b = Scripting_GetPublic(idx & 0xFFFF, YSI_g_sNextInitFunc, "@yG_Init");
  154. if (b)
  155. {
  156. CallLocalFunction(YSI_g_sNextInitFunc, "ii", -1, (a << 16) | b);
  157. }
  158. }
  159. }
  160. _GROUP_CREATE(group,idx)<_YCM:y>
  161. #endif
  162. #endif
  163. #endif
  164. #else
  165. _GROUP_CREATE(group,idx)
  166. #endif
  167. {
  168. P:3(#_GROUP_MAKE_NAME<@yG_Init...> " called in %d", _@);
  169. if (group == -1)
  170. {
  171. Bit_SetAll(_GROUP_GLOBAL_NAME, true, bits<_GROUP_MAKE_LIMIT>);
  172. Bit_Let(_GROUP_DEFAULTS, _:MAX_GROUPS);
  173. // Initialise the next item
  174. YSI_g_sHasOPC = funcidx(#_GROUP_OPC_PUBLIC) != -1;
  175. P:3(#_GROUP_OPC_PUBLIC " does%s exist", YSI_g_sHasOPC ? ("") : (" not"));
  176. new
  177. a = Scripting_GetPublic(idx >>> 16, YSI_g_sNextUpdateFunc, "@yG_Upd"),
  178. b = Scripting_GetPublic(idx & 0xFFFF, YSI_g_sNextInitFunc, "@yG_Init");
  179. if (b)
  180. {
  181. CallLocalFunction(YSI_g_sNextInitFunc, "ii", -1, (a << 16) | b);
  182. }
  183. }
  184. else if (group < _:MAX_GROUPS)
  185. {
  186. // This is called when a new group is created, it sets the default default
  187. // values - i.e. sets everything to true.
  188. Bit_SetAll(_GROUP_GROUP_NAME[Group:group], false, bits<_GROUP_MAKE_LIMIT>);
  189. Bit_Vet(_GROUP_DEFAULTS, group);
  190. if (YSI_g_sNextInitFunc[0])
  191. {
  192. CallLocalFunction(YSI_g_sNextInitFunc, "ii", group, -1);
  193. }
  194. }
  195. }
  196. #if !defined _YSI_GROUPS_FIRST_HALF
  197. forward bool:_GROUP_INITIALISE(x = _GROUP_MAKE_LIMIT);
  198. #endif
  199. stock bool:_GROUP_INITIALISE(x = _GROUP_MAKE_LIMIT) <YSI_has_groups:y>
  200. {
  201. // A new item has been added to the system - update all players according to
  202. // the default settings for a group.
  203. //_GROUP_UPDATE_ALL(_GROUP_LOCAL_NAME);
  204. if (x != _GROUP_MAKE_LIMIT)
  205. {
  206. P:3(#_GROUP_INITIALISE "<YSI_has_groups:y> called in %d", _@);
  207. _GROUP_MAKE_NAME<Group_UpdateAll...>(x, true);
  208. }
  209. return true;
  210. }
  211. // Called to set all players to a new element. Can ignore defaults for
  212. // specialised setups such as classes.
  213. __GF<Group_UpdateAll...>[i](_GROUP_LOCAL_NAME,bool:d)<_GROUP_LOCAL_NAME,d>
  214. {
  215. // Set the permissions from the defaults for each groups.
  216. new
  217. s = Bit_Slot(_GROUP_LOCAL_NAME),
  218. Bit:m = Bit_Mask(_GROUP_LOCAL_NAME),
  219. Bit:v = ~m;
  220. if (d)
  221. {
  222. for (new Group:i; i != MAX_GROUPS; ++i)
  223. {
  224. if (Bit_Get(_GROUP_DEFAULTS, i)) _GROUP_GROUP_NAME[i][s] |= m;
  225. else _GROUP_GROUP_NAME[i][s] &= v;
  226. }
  227. // Set the default settings.
  228. if (Bit_Get(_GROUP_DEFAULTS, MAX_GROUPS)) _GROUP_GLOBAL_NAME[s] |= m;
  229. else _GROUP_GLOBAL_NAME[s] &= v;
  230. // Now update all the existing players.
  231. foreach (Player, i) _GROUP_MAKE_NAME<Group_UpdatePlayer...>(_GROUP_LOCAL_NAME, i);
  232. }
  233. else
  234. {
  235. P:3(#_GROUP_MAKE_NAME<Group_UpdateAll...> " called as 0");
  236. for (new Group:i; i != MAX_GROUPS; ++i) _GROUP_GROUP_NAME[i][s] &= v;
  237. _GROUP_GLOBAL_NAME[s] &= v;
  238. }
  239. }
  240. static stock _GROUP_MAKE_NAME<Group_UpdatePlayer...>(_GROUP_LOCAL_NAME,playerid)
  241. {
  242. if (Bit_Get(_GROUP_GLOBAL_NAME, _GROUP_LOCAL_NAME))
  243. {
  244. _GROUP_SET_PLAYER(_GROUP_LOCAL_NAME, playerid, true);
  245. return;
  246. }
  247. new
  248. ps = Bit_Slot(playerid),
  249. Bit:pm = Bit_Mask(playerid),
  250. es = Bit_Slot(_GROUP_LOCAL_NAME),
  251. Bit:em = Bit_Mask(_GROUP_LOCAL_NAME);
  252. for (new Group:i; i != MAX_GROUPS; ++i)
  253. {
  254. if (_Group_IsActive(i) && YSI_gGroupPlayers[i][ps] & pm && _GROUP_GROUP_NAME[i][es] & em)
  255. //if (Group_IsActive(i) && Group_HasPlayer(i, playerid) && Bit_Get(_GROUP_GROUP_NAME[i], _GROUP_LOCAL_NAME))
  256. {
  257. _GROUP_SET_PLAYER(_GROUP_LOCAL_NAME, playerid, true);
  258. return;
  259. }
  260. }
  261. _GROUP_SET_PLAYER(_GROUP_LOCAL_NAME, playerid, false);
  262. }
  263. _GROUP_UPDATE_PLAYER(playerid, group, set);
  264. #if YSIM_HAS_MASTER
  265. #if YSIM_IS_CLIENT
  266. // Note: not the same.
  267. _GROUP_MAKE_NAME<_yG@Upd...>(playerid, group, set)
  268. #else
  269. #if YSIM_IS_SERVER
  270. _GROUP_UPDATE_PLAYER(playerid, group, set)
  271. #else
  272. #if !YSIM_IS_STUB
  273. _GROUP_UPDATE_PLAYER(playerid, group, set)<>
  274. {
  275. if (YSI_g_sNextUpdateFunc[0])
  276. {
  277. CallLocalFunction(YSI_g_sNextUpdateFunc, "iii", playerid, group, set);
  278. }
  279. }
  280. _GROUP_UPDATE_PLAYER(playerid, group, set)<_YCM:y>
  281. #endif
  282. #endif
  283. #endif
  284. #else
  285. _GROUP_UPDATE_PLAYER(playerid, group, set)
  286. #endif
  287. {
  288. if (set)
  289. {
  290. // Joined a group - add everything they will need.
  291. for (new j = 0; j != _GROUP_MAKE_LIMIT; ++j)
  292. {
  293. if (Bit_Get(_GROUP_GROUP_NAME[group], j))
  294. {
  295. _GROUP_SET_PLAYER(j, playerid, true);
  296. }
  297. }
  298. }
  299. else
  300. {
  301. // Left a group - full update.
  302. for (new j = 0; j != _GROUP_MAKE_LIMIT; ++j)
  303. {
  304. _GROUP_MAKE_NAME<Group_UpdatePlayer...>(j, playerid);
  305. }
  306. }
  307. }
  308. __GF<Group_Set...Default>[ii](Group:g,bool:s)<g,s>
  309. {
  310. GROUP_FIX(g);
  311. if (g == GROUP_GLOBAL & ~GROUP_MASK)
  312. {
  313. _GROUP_MAKE_NAME<Group_SetGlobal...Default>(s);
  314. }
  315. else if (_Group_IsValid(g))
  316. {
  317. Bit_SetAll(_GROUP_GROUP_NAME[g], s, bits<_GROUP_MAKE_LIMIT>);
  318. if (s)
  319. {
  320. Bit_Let(_GROUP_DEFAULTS, _:g);
  321. foreach (Player, i)
  322. {
  323. if (_Group_HasPlayer(g, i))
  324. {
  325. for (new j = 0; j != _GROUP_MAKE_LIMIT; ++j)
  326. {
  327. _GROUP_SET_PLAYER(j, i, true);
  328. }
  329. }
  330. }
  331. }
  332. else
  333. {
  334. Bit_Vet(_GROUP_DEFAULTS, _:g);
  335. foreach (Player, i)
  336. {
  337. if (_Group_HasPlayer(g, i))
  338. {
  339. for (new j = 0; j != _GROUP_MAKE_LIMIT; ++j)
  340. {
  341. _GROUP_MAKE_NAME<Group_UpdatePlayer...>(j, i);
  342. }
  343. }
  344. }
  345. }
  346. }
  347. }
  348. __GF<Group_SetGlobal...Default>[i](bool:s)<s>
  349. {
  350. Bit_SetAll(_GROUP_GLOBAL_NAME, s, bits<_GROUP_MAKE_LIMIT>);
  351. if (s)
  352. {
  353. Bit_Let(_GROUP_DEFAULTS, _:MAX_GROUPS);
  354. foreach (Player, i)
  355. {
  356. for (new j = 0; j != _GROUP_MAKE_LIMIT; ++j)
  357. {
  358. _GROUP_SET_PLAYER(j, i, true);
  359. }
  360. }
  361. }
  362. else
  363. {
  364. Bit_Vet(_GROUP_DEFAULTS, _:MAX_GROUPS);
  365. foreach (Player, i)
  366. {
  367. for (new j = 0; j != _GROUP_MAKE_LIMIT; ++j)
  368. {
  369. _GROUP_MAKE_NAME<Group_UpdatePlayer...>(j, i);
  370. }
  371. }
  372. }
  373. }
  374. __GF<Group_SetGlobal...>[ii](_GROUP_LOCAL_NAME,bool:s)<_GROUP_LOCAL_NAME,s>
  375. {
  376. // Set wether the global group can use this item.
  377. //Bit_Set(_GROUP_GLOBAL_NAME, _GROUP_LOCAL_NAME, set, bits<_GROUP_MAKE_LIMIT>);
  378. if (s)
  379. {
  380. Bit_Let(_GROUP_GLOBAL_NAME, _GROUP_LOCAL_NAME);
  381. foreach (Player, i)
  382. {
  383. _GROUP_SET_PLAYER(_GROUP_LOCAL_NAME, i, true);
  384. }
  385. }
  386. else
  387. {
  388. Bit_Vet(_GROUP_GLOBAL_NAME, _GROUP_LOCAL_NAME);
  389. foreach (Player, i)
  390. {
  391. _GROUP_MAKE_NAME<Group_UpdatePlayer...>(_GROUP_LOCAL_NAME, i);
  392. }
  393. }
  394. }
  395. __GF<Group_Set...>[iii](Group:g,_GROUP_LOCAL_NAME,bool:s)<g,_GROUP_LOCAL_NAME,s>
  396. {
  397. // Set wether a group can use this item.
  398. if (0 <= _GROUP_LOCAL_NAME < _GROUP_MAKE_LIMIT)
  399. {
  400. GROUP_FIX(g);
  401. if (g == GROUP_GLOBAL & ~GROUP_MASK)
  402. {
  403. //_GROUP_GLOBAL_FUNC(_GROUP_LOCAL_NAME, set);
  404. _GROUP_MAKE_NAME<Group_SetGlobal...>(_GROUP_LOCAL_NAME, s);
  405. }
  406. else if (_Group_IsValid(g))
  407. {
  408. //Bit_Set(_GROUP_GROUP_NAME[group], _GROUP_LOCAL_NAME, set, bits<_GROUP_MAKE_LIMIT>);
  409. if (s)
  410. {
  411. Bit_Let(_GROUP_GROUP_NAME[g], _GROUP_LOCAL_NAME);
  412. foreach (Player, i)
  413. {
  414. if (_Group_HasPlayer(g, i))
  415. {
  416. _GROUP_SET_PLAYER(_GROUP_LOCAL_NAME, i, true);
  417. }
  418. }
  419. }
  420. else
  421. {
  422. Bit_Vet(_GROUP_GROUP_NAME[g], _GROUP_LOCAL_NAME);
  423. foreach (Player, i)
  424. {
  425. if (_Group_HasPlayer(g, i))
  426. {
  427. //_GROUP_UPDATE(_GROUP_LOCAL_NAME, i);
  428. _GROUP_MAKE_NAME<Group_UpdatePlayer...>(_GROUP_LOCAL_NAME, i);
  429. }
  430. }
  431. }
  432. }
  433. }
  434. }
  435. #undef __GF