y_masteronce.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /*----------------------------------------------------------------------------*\
  2. ===================
  3. YSI - Master Core
  4. ===================
  5. Description:
  6. There seems to be a bug with a compiler when using #emit in files included
  7. more than once, so this code has been moved to a file only included once.
  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 YSI master include.
  19. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  20. Portions created by the Initial Developer are Copyright (C) 2011
  21. the Initial Developer. All Rights Reserved.
  22. Contributors:
  23. ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
  24. Thanks:
  25. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  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, whose limits continue to amaze me!
  40. Kye/Kalcor - SA:MP.
  41. SA:MP Team past, present and future - SA:MP.
  42. Version:
  43. 0.2
  44. Changelog:
  45. 07/08/10:
  46. Split in to y_masteronce.
  47. Added assembly for publics scanning.
  48. 06/08/10:
  49. Managed the ultimate - got completely transparent inclusion!
  50. 05/08/10:
  51. Completed new master system, now does all syncing and clients.
  52. 06/10/09:
  53. Rewrote using states.
  54. Added remote function macros.
  55. Reduced the number of masters to a single one. It must have them all.
  56. Vastly simplified the master model - ending the master ends everything.
  57. 06/01/08:
  58. Added code to not pass data if no other script exists.
  59. 17/11/07:
  60. Added code for a script to remove itself from the global list.
  61. 11/10/07:
  62. Not first version but added documentation months late.
  63. Functions:
  64. Public:
  65. -
  66. Core:
  67. -
  68. Stock:
  69. -
  70. Static:
  71. -
  72. Inline:
  73. -
  74. API:
  75. -
  76. Hooks:
  77. OnGameModeInit
  78. OnGameModeExit
  79. Callbacks:
  80. -
  81. Definitions:
  82. -
  83. Enums:
  84. -
  85. Macros:
  86. -
  87. Tags:
  88. -
  89. Variables:
  90. Global:
  91. _@ - ID of this script.
  92. Static:
  93. -
  94. Commands:
  95. -
  96. Compile options:
  97. -
  98. Operators:
  99. -
  100. Natives:
  101. -
  102. \*----------------------------------------------------------------------------*/
  103. // These parts should only be defined once ever. This code is not dependent on
  104. // the current MASTER value, it's all generic.
  105. #include "y_version"
  106. #include "..\y_debug"
  107. #include "..\y_hooks"
  108. #include "y_shortfunc"
  109. #include "y_natives"
  110. #define _YSIM_COMPARE -1
  111. #if defined YSI_IS_CLIENT
  112. #if NO_VALUE(YSI_IS_CLIENT)
  113. #undef YSI_IS_CLIENT
  114. #define YSI_IS_CLIENT 100
  115. #endif
  116. #endif
  117. #if defined YSI_IS_SERVER
  118. #if NO_VALUE(YSI_IS_SERVER)
  119. #undef YSI_IS_SERVER
  120. #define YSI_IS_SERVER 100
  121. #endif
  122. #endif
  123. #if defined YSI_IS_STUB
  124. #if NO_VALUE(YSI_IS_STUB)
  125. #undef YSI_IS_STUB
  126. #define YSI_IS_STUB 100
  127. #endif
  128. #endif
  129. // Define all the alternate spellings once.
  130. #define RF@cp RF@pc
  131. #define RF@pvc RF@pcv
  132. #define RF@cpv RF@pcv
  133. #define RF@cvp RF@pcv
  134. #define RF@vpc RF@pcv
  135. #define RF@vcp RF@pcv
  136. #define RF@vp RF@pv
  137. #define RF@cv RF@vc
  138. //#define RF@nv RF@vn
  139. #define RF@cpt RF@pct
  140. #define RF@tcp RF@pct
  141. #define RF@tpc RF@pct
  142. #define RF@ctp RF@pct
  143. #define RF@ptc RF@pct
  144. #define RF@tp RF@pt
  145. #define RF@tc RF@ct
  146. //#define RF@tn RF@nt
  147. #define mhook master_hook
  148. #define OnScriptClose Master_OnScriptClose
  149. forward Master_OnScriptClose(script);
  150. // These are the macros used by y_master for the recursive function definition
  151. // structure, but they are not used unless a cloud-based "foreign" or "global"
  152. // are used.
  153. // "foreign" declaration.
  154. #define @Zs:@Za:@Zd:#%0#%1|||%2string:%3[%4]|||%5,%6) @Zs:@Za:@Zd:#%0s#%1,@Ze:%3|||%5|||%6)
  155. #define @Za:@Zd:#%0#%1|||%3[%4]|||%5,%6) @Zs:@Za:@Zd:#%0a#%1,@Ze:%3|||%5|||%6)
  156. #define @Zd:#%0#%1|||%3|||%5,%6) @Zs:@Za:@Zd:#%0i#%1,@Ze:%3|||%5|||%6)
  157. #define @Ze:%0|||||| @Ze:%0
  158. #define z,@Ze:||||||) )
  159. #define _YM@CM:%0,%1) @Zf:@Zs:@Za:@Zd:##z|||%0|||%1)
  160. #define W@(#%0:%1##,%2);%3Z@(i) W@(#%1,%2);return %0:Z@(%0:i)
  161. #define Z@(%0string:i) S@(i),Q@
  162. // Second "foreign" declaration.
  163. #define @Zu:Y@();W@(#%0##,_YM@CX:,,);return%1(%2);}%3(%4);%5(%6)<%7> Y@();W@(#%0##,#);return%1(%2);}%3(%4);stock %5(%6)<%7>return @Zv:@Zq:%5&H@();
  164. //#define @Zu:Y@();W@(#%0##,_YM@CX:,,);return%1(%2);}%3(%4);%5(%6)<%7> Y@();W@(#%0##,#);return%1(%2);}%3(%4);%5(%6)<%7>return @Zv:@Zq:%5&H@();
  165. //#define @Zc:%0(#%1:%2##,%3);return%4;
  166. // Second "foreign" declaration.
  167. // This has been updated to check for arrays, then check if the array is a
  168. // string, instead of the old method which checked for those separately.
  169. #define @Zn:@Zo:@Zp:#%0#%1|||%3[%4]|||%5,%6);%7}%8&H@(%9||| @Zm:@Zr:#%0#%1|||%3|||%5,%6);%7}%8&H@(%9|||
  170. #define @Zm:@Zr:#%0#%1|||%2string:%3|||%5,%6);%7}%8&H@(%9||| @Zn:@Zo:@Zp:#%0s#%1,%3|||%5|||%6);%7}%8&H@(%9,%3|||
  171. #define @Zr:#%0#%1|||%3|||%5,%6);%7}%8&H@(%9||| @Zn:@Zo:@Zp:#%0a#%1,%3|||%5|||%6);%7}%8&H@(%9,%3|||
  172. #define @Zo:@Zp:#%0#%1|||%3|||%5,%6);%7}%8&H@(%9||| @Zn:@Zo:@Zp:#%0i#%1,%3|||%5|||%6);%7}%8&H@(%9,%3|||
  173. #define @Zp:%0||||||);%1}%2&H@(,%4||| %0);%1}%2&H@(%4
  174. #define _YM@CX:%0,%1);%2}%8;%3(%9)<%4> @Zn:@Zo:@Zp:##|||%0|||%1);%2}%8;stock %3(%9)<%4>return @Zv:@Zq:%3&H@(|||);
  175. #define @Zv:@Zq:%9:%1&H@( %9:@Zw:@Zx:%9&H@(
  176. #define @Zw:@Zx:%0string%2&H@( G@(
  177. #define @Zx:%0&H@( H@(
  178. #define @Zq:%1&H@( H@(
  179. /*#define @Zm:@Zn:@Zo:#%0#%1|||%2string:%3[%4]|||%5,%6);%7}%8H@(%9||| @Zm:@Zn:@Zo:#%0s#%1,@Zp:%3|||%5|||%6);%7}%8H@(%9,%3|||
  180. #define @Zn:@Zo:#%0#%1|||%3[%4]|||%5,%6);%7}%8H@(%9||| @Zm:@Zn:@Zo:#%0a#%1,@Zp:%3|||%5|||%6);%7}%8H@(%9,%3|||
  181. #define @Zo:#%0#%1|||%3|||%5,%6);%7}%8H@(%9||| @Zm:@Zn:@Zo:#%0i#%1,@Zp:%3|||%5|||%6);%7}%8H@(%9,%3|||
  182. #define @Zp:%0||||||);%1}%2H@(,%4||| @Zp:%0);%1}%2H@(%4
  183. #define y,@Zp:||||||);%1}%2H@(,%4||| );%1}%2H@(%4
  184. #define _YM@CX:%0,%1);%2}%8;%3<%4> @Zl:@Zm:@Zn:@Zo:##y|||%0|||%1);%2}%8;%3<%4>return @Zv:@Zq:%3:H@(|||);
  185. #define @Zv:@Zq:%9:%1:H@( %9:@Zw:@Zx:%9:H@(
  186. #define @Zw:@Zx:%0string%2:H@( G@(
  187. #define @Zx:%0:H@( H@(
  188. //#define @Zv:@Zq:@Zu:%0string%9:%1:%2H@( G@(
  189. //#define @Zq:%1H@( H@(
  190. #define @Zq:%1(%2):%3( H@(*/
  191. //#define @Zu:%0H@( H@(
  192. //#define @Zq:@Zm:@Zn:@Zo:##y|||%0|||%1);%2;} woo%0%1%2
  193. // HAHA
  194. //%2}%8;%3:%4return%5H@(|||); %0);%2}%8;%3:%4return%3:H@(|||);
  195. //#define W@(#%0:%1##,%2);%3Z@(i) W@(#%1,%2);return %0:Z@(%0:i)
  196. //#define Z@(%0string:i) S@(i),Q@
  197. //#define string:
  198. //#define foreign%0(%1); %0(%1)<>{new i=Y@();W@(#%0@##,_YM@CM:%1,,);return Z@(i);}%0@(%1);
  199. /*// "shut-up" declaration. Make the compiler not complain about <_YCM:m>.
  200. #define @Zl:@Zm:#%0#%1|||%3[%4]|||%5,%6) @Zs:@Za:@Zd:#%0a#%1,@Ze:%3|||%5|||%6)
  201. #define @Zm:#%0#%1|||%3|||%5,%6) @Zs:@Za:@Zd:#%0i#%1,@Ze:%3|||%5|||%6)
  202. #define @Ze:%0|||||| @Ze:%0
  203. #define z,@Ze:||||||) )
  204. #define _YM@CS:%0,%1; @Zl:@Zm:%1;
  205. //#define W@(#%0:%1##,%2);%3Z@(i) W@(#%1,%2);return %0:Z@(%0:i)
  206. //#define Z@(%0string:i) S@(i),Q@
  207. #define string:*/
  208. // "global" declaration
  209. #define @Zt:@Zb:@Zh:@Zi:%0(%1|||%2:%3|||%5,%6) @Zb:@Zh:@Zi:%0(%1|||%3|||%5,%6)
  210. #define @Zb:@Zh:@Zi:%0(%1|||%3[%4]|||%5,%6) @Zt:@Zb:@Zh:@Zi:%0(%1,%3|||%5|||%6)
  211. #define @Zh:@Zi:%0(%1|||%3|||%5,%6) @Zt:@Zb:@Zh:@Zi:%0(%1,%3|||%5|||%6)
  212. #define @Zi:%0(,%1||||||) %0(%1)
  213. //#define @Zj:X@(%0(_YM@CP:,,)) X@(%0())
  214. #define @Zk:_YM@CP:%0(,,) %0()
  215. #define _YM@CP:%0(%1,%2) @Zt:@Zb:@Zh:@Zi:%0(|||%1|||%2)
  216. //#define X@(%0string:%1) R@(%1)
  217. #define X@(_:@Zk:_YM@CP:%0string:%1(%2)) R@(_:@Zk:_YM@CP:%1(%2))
  218. /*#define @Zt:@Zb:@Zh:%1|||%2:%3|||%5) %1%2:@Zb:@Zh:|||%3|||%5)
  219. #define @Zb:@Zh:%1|||%3[%4]|||%5,%6) @Zt:@Zb:@Zh:%1@Zi:%3,|||%5|||%6)
  220. #define @Zh:%1|||%3|||%5,%6) @Zt:@Zb:@Zh:%1@Zi:%3,|||%5|||%6)
  221. #define @Zi:%0,|||||| %0
  222. #define @Zj:X@(%0(_YM@CP:,,)) X@(%0())
  223. #define @Zk:%0(_YM@CP:,,) %0()
  224. #define _YM@CP:%0,%1) @Zt:@Zb:@Zh:|||%0|||%1)
  225. #define X@(%0string:%1) R@(%1)*/
  226. //#define global%0(%1) public%0@(%1)<>{}public%0@(%1)<_YCM:y>X@(_:%0(_YM@CP:%1,,));%0(%1)<_YCM:y>
  227. #define YSIM_NOT_CLIENT (!YSIM_HAS_MASTER || !_YSIM_IS_CLIENT)
  228. #include "y_shortfunc"
  229. #if defined YSI_NO_MASTER
  230. #endinput
  231. #endif
  232. //#if !defined MAX_MASTERS
  233. #define MAX_MASTERS 26
  234. //#else
  235. // #if MAX_MASTERS > 32
  236. // #undef MAX_MASTERS
  237. // #define MAX_MASTERS 32
  238. // #endif
  239. //#endif
  240. forward Master_Reassert();
  241. static
  242. YSI_g_sMasterCount,
  243. YSI_g_sMasterData[MAX_MASTERS];
  244. /*----------------------------------------------------------------------------*\
  245. Function:
  246. Master_GetNext
  247. Params:
  248. -
  249. Return:
  250. Next master ID to be assigned.
  251. Notes:
  252. -
  253. \*----------------------------------------------------------------------------*/
  254. stock Master_GetNext()
  255. {
  256. P:3("Master_GetNext called");
  257. new
  258. masters = getproperty(8, YSIM_MASTER),
  259. i = 0;
  260. while (i != 32)
  261. {
  262. if (!(masters & (1 << i)))
  263. {
  264. return i;
  265. }
  266. ++i;
  267. }
  268. return -1;
  269. }
  270. /*----------------------------------------------------------------------------*\
  271. Hook:
  272. OnGameModeInit
  273. Notes:
  274. Constructor. Gets the script a master ID. Now ALWAYS gets an ID, even if
  275. the master system is disabled - doing otherwise is just too complicated.
  276. \*----------------------------------------------------------------------------*/
  277. hook OnScriptInit()
  278. {
  279. P:1("Master_OGM");
  280. if (!existproperty(8, YSIM_MASTER))
  281. {
  282. setproperty(8, YSIM_MASTER, 0);
  283. }
  284. // Properties get lost between script changes so we need to force a rebuild.
  285. CallRemoteFunction("Master_Reassert", "");
  286. new
  287. masters = getproperty(8, YSIM_MASTER),
  288. i = 0;
  289. while (i != 32)
  290. {
  291. if (!(masters & (1 << i)))
  292. {
  293. _@ = i;
  294. masters |= 1 << i;
  295. break;
  296. }
  297. ++i;
  298. }
  299. if (i != 32)
  300. {
  301. setproperty(8, YSIM_MASTER, masters);
  302. }
  303. C:1(if (_@ == -1) P:E("MasterID not assigned"););
  304. // Make sure this is called before all other YSI initialisations, at least
  305. // all the ones which use the master system.
  306. CallLocalFunction("YSIM_OnMasterSystemInit", "");
  307. // Just use one name...
  308. return 1;
  309. }
  310. #define OnMasterSystemInit YSIM_OnMasterSystemInit
  311. forward OnMasterSystemInit();
  312. /*----------------------------------------------------------------------------*\
  313. Hook:
  314. OnGameModeExit
  315. Notes:
  316. Destructor.
  317. \*----------------------------------------------------------------------------*/
  318. public OnScriptExit()
  319. {
  320. P:1("MasterOnce_OnScriptExit called");
  321. // Loop through everything this script is master for and call the remote
  322. // function for it. EXCEPT for this script itself!
  323. new
  324. func[4];
  325. //printf("%d", YSI_g_sMasterCount);
  326. for (new i = 0; i != YSI_g_sMasterCount; ++i)
  327. {
  328. // This is slightly slower for ending and starting scripts, but uses far
  329. // less heap space, and these values are rarely used, so may as well
  330. // pack them (which is what has happened here).
  331. func[0] = YSI_g_sMasterData[i] & 0xFF;
  332. func[1] = (YSI_g_sMasterData[i] >> 8) & 0xFF;
  333. func[2] = YSI_g_sMasterData[i] >> 16;
  334. //if (getproperty(9, func) == _@)
  335. //{
  336. // deleteproperty(9, func);
  337. //}
  338. //printf("call %s", func);
  339. CallLocalFunction(func, "");
  340. // The properties currently clear instantly, but that may not always be
  341. // the case.
  342. //printf("after");
  343. }
  344. setproperty(8, YSIM_MASTER, getproperty(8, YSIM_MASTER) & ~(1 << _@));
  345. //printf("s0");
  346. CallLocalFunction("YSIM_OnScriptExit", "");
  347. //printf("s1");
  348. CallRemoteFunction("Master_OnScriptClose", "i", _@);
  349. //printf("s2");
  350. return 1;
  351. }
  352. #undef OnScriptExit
  353. #define OnScriptExit YSIM_OnScriptExit
  354. forward OnScriptExit();
  355. /*----------------------------------------------------------------------------*\
  356. Function:
  357. Master_Reassert
  358. Params:
  359. -
  360. Return:
  361. -
  362. Notes:
  363. Rebuilds the collection of master data whenever a script is restarted.
  364. \*----------------------------------------------------------------------------*/
  365. public Master_Reassert()
  366. {
  367. // Make sure that the caller parameter is always -1 by default.
  368. U@(8, YSIM_CALLER, -1);
  369. if (_@ != -1)
  370. {
  371. // Read this script's master value.
  372. setproperty(8, YSIM_MASTER, getproperty(8, YSIM_MASTER) | (1 << _@));
  373. // Readd this script's owned scripts.
  374. new
  375. func[4];
  376. for (new i = 0; i != YSI_g_sMasterCount; ++i)
  377. {
  378. // This is slightly slower for ending and starting scripts, but uses far
  379. // less heap space, and these values are rarely used, so may as well
  380. // pack them (which is what has happened here).
  381. func[0] = YSI_g_sMasterData[i] & 0xFF;
  382. func[1] = (YSI_g_sMasterData[i] >> 8) & 0xFF;
  383. func[2] = YSI_g_sMasterData[i] >> 16;
  384. setproperty(9, func, _@);
  385. }
  386. }
  387. }
  388. /*----------------------------------------------------------------------------*\
  389. Function:
  390. _Master_Get
  391. Params:
  392. library[] - The name of the library to try become master for.
  393. Return:
  394. -
  395. Notes:
  396. -
  397. \*----------------------------------------------------------------------------*/
  398. stock bool:_Master_Get(library[], bool:force = false)
  399. {
  400. P:3("bool:_Master_Get called: \"%s\", %i", library, _:force);
  401. P:2("_Master_Get called");
  402. if (!force && existproperty(9, library))
  403. {
  404. new
  405. master = getproperty(9, library);
  406. P:4("_Master_Get: Prop exists: %d %d", master, _@);
  407. if (master != -1)
  408. {
  409. if (master == _@)
  410. {
  411. return true;
  412. }
  413. P:4("_Master_Get: Prop set");
  414. return false;
  415. }
  416. }
  417. P:4("_Master_Get: Get master.");
  418. setproperty(9, library, _@);
  419. P:4("_Master_Get: Set master.");
  420. // Add this library to the list. The list is designed to only deal with
  421. // two or three character master names now!
  422. if (YSI_g_sMasterCount < MAX_MASTERS)
  423. {
  424. P:4("_Master_Get: Set master string.");
  425. YSI_g_sMasterData[YSI_g_sMasterCount++] = library[0] | (library[1] << 8) | (library[2] << 16);
  426. P:4("_Master_Get: Set master string.");
  427. }
  428. P:C(else P:E("Too many master scripts"););
  429. return true;
  430. }
  431. //#define RS@pc RS@cp
  432. /*
  433. #define RF:%1[%2](%3)
  434. #define RF@p:%1[%2](%3)<%4>
  435. #define RF@c:%1[%2](%3)
  436. #define RF@v:%1[%2](%3)
  437. #define RF@n:%1[]()
  438. #define RF@pc:%1[%2](%3)<%4>
  439. #define RF@pv:%1[%2](%3)<%4>
  440. #define RF@pcv:%1[%2](%3)<%4>
  441. #define RF@vc:%1[%2](%3)
  442. #define RF@vn:%1[]()
  443. */
  444. // Define all the alternate spellings once.
  445. //#define RC@nv RC@vn
  446. /*
  447. #define RC:%1[%2](%3)
  448. #define RC@v:%1[%2](%3)
  449. #define RC@n:%1[]()
  450. #define RC@vn:%1[]()
  451. */