y_loader.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. /*----------------------------------------------------------------------------*-
  2. ==============================
  3. Y Server Includes - MTA Loader
  4. ==============================
  5. Description:
  6. Loads MTA XML format map files for use with the object and race systems.
  7. Legal:
  8. Copyright (C) 2007 Alex "Y_Less" Cole
  9. This program is free software; you can redistribute it and/or
  10. modify it under the terms of the GNU General Public License
  11. as published by the Free Software Foundation; either version 2
  12. of the License, or (at your option) any later version.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  20. MA 02110-1301, USA.
  21. Changelog:
  22. 12/10/07:
  23. Added Loader_AddHandler.
  24. Added Loader_GetRace.
  25. 24/08/07:
  26. First version.
  27. Functions:
  28. Public:
  29. Loader_Spawn - Processes a loaded spawn point.
  30. Loader_Check - Processes a loaded checkpoint.
  31. Loader_Obj - Processes a loaded object.
  32. Core:
  33. Loader_Loader - Initialises data.
  34. Stock:
  35. Loader_Parse - Loads a file.
  36. Loader_AddHandler - Adds a custom handle for the race file.
  37. Loader_GetRace - Returns the current race handle.
  38. Static:
  39. -
  40. Inline:
  41. -
  42. API:
  43. -
  44. Callbacks:
  45. -
  46. Definitions:
  47. -
  48. Enums:
  49. -
  50. Macros:
  51. -
  52. Tags:-e_RACE_FLAGS - Race data flag.
  53. Variables:
  54. Global:
  55. -
  56. Static:
  57. YSI_g_sXMLRules - Handle to the XML parse rule set.
  58. YSI_g_sCurRace - Handle to the current race being built.
  59. Commands:
  60. -
  61. Compile options:
  62. -
  63. Operators:
  64. -
  65. -*----------------------------------------------------------------------------*/
  66. static stock
  67. XML:YSI_g_sXMLRules = NO_XML_FILE,
  68. #if defined _YSI_VISUAL_OBJECTS
  69. YSI_g_sRaceObjects[ceildiv(MAX_DYN_OBJECTS, 4)] = {-1, ...},
  70. #endif
  71. YSI_g_sCurRace,
  72. YSI_g_sCurWorld;
  73. forward Loader_Spawn();
  74. forward Loader_Check();
  75. forward Loader_Obj();
  76. /*----------------------------------------------------------------------------*-
  77. Function:
  78. Loader_Loader
  79. Params:
  80. -
  81. Return:
  82. -
  83. Notes:
  84. Defines the parsing rules for reading MTA XML maps.
  85. -*----------------------------------------------------------------------------*/
  86. Loader_Loader()
  87. {
  88. if (YSI_g_sXMLRules == NO_XML_FILE)
  89. {
  90. YSI_g_sXMLRules = XML_New();
  91. if (YSI_g_sXMLRules != NO_XML_FILE)
  92. {
  93. XML_AddHandler(YSI_g_sXMLRules, "object", "Loader_Obj");
  94. XML_AddHandler(YSI_g_sXMLRules, "checkpoint", "Loader_Check");
  95. XML_AddHandler(YSI_g_sXMLRules, "spawnpoint", "Loader_Spawn");
  96. }
  97. }
  98. return 1;
  99. }
  100. /*----------------------------------------------------------------------------*-
  101. Function:
  102. Loader_Parse
  103. Params:
  104. filename[] - File to parse as an XML race file.
  105. laps - Number of laps to race for.
  106. entry - Cost of entry.
  107. countdown - Time to count down from for start.
  108. bool:arial - Use arial checkpoints instead.
  109. bool:fixedPrize - Set prize amounts manually.
  110. exitTime - Time allowed out a vehicle before fail.
  111. interior - The interior of the race.
  112. world - The world of the race.
  113. bool:restart - Don't destroy the race on completion.
  114. Return:
  115. Created race.
  116. Notes:
  117. Tries to create a new race to save to then parses the file.
  118. -*----------------------------------------------------------------------------*/
  119. stock Loader_Parse(filename[], laps = 0, entry = 0, countdown = 3, bool:arial = false, bool:fixedPrize = true, exitTime = 0, interior = 0, world = 0, bool:restart = false)
  120. {
  121. if (!fexist(filename)) return NO_RACE;
  122. new
  123. race = Race_Create(laps, entry, countdown, arial, fixedPrize, exitTime, interior, world, restart);
  124. if (race != NO_RACE)
  125. {
  126. YSI_g_sCurRace = race;
  127. YSI_g_sCurWorld = world;
  128. XML_Parse(YSI_g_sXMLRules, filename);
  129. }
  130. YSI_g_sCurWorld = 0;
  131. YSI_g_sCurRace = NO_RACE;
  132. return race;
  133. }
  134. /*----------------------------------------------------------------------------*-
  135. Function:
  136. Loader_ParseObjects
  137. Params:
  138. filename[] - File to parse.
  139. world - World for the objects to appear in or -1 for all.
  140. Return:
  141. -
  142. Notes:
  143. Parses a map file, loading only the objects.
  144. -*----------------------------------------------------------------------------*/
  145. stock Loader_ParseObjects(filename[], world = -1)
  146. {
  147. YSI_g_sCurWorld = world;
  148. return XML_Parse(YSI_g_sXMLRules, filename);
  149. }
  150. /*----------------------------------------------------------------------------*-
  151. Function:
  152. Loader_Unload
  153. Params:
  154. race - Race to remove objects for.
  155. Return:
  156. -
  157. Notes:
  158. Destroys all the objects created for a race loaded with the loader.
  159. -*----------------------------------------------------------------------------*/
  160. stock Loader_Unload(race)
  161. {
  162. #if defined _YSI_VISUAL_OBJECTS
  163. new
  164. race1 = race << 8,
  165. race2 = race << 16,
  166. race3 = race << 24;
  167. for (new i = 0; i < sizeof (YSI_g_sRaceObjects); i++)
  168. {
  169. if (YSI_g_sRaceObjects[i] & 0xFF000000 == race3)
  170. {
  171. YSI_g_sRaceObjects[i] |= 0xFF000000;
  172. DestroyDynamicObject((i * 4) + 3);
  173. }
  174. if (YSI_g_sRaceObjects[i] & 0x00FF0000 == race2)
  175. {
  176. YSI_g_sRaceObjects[i] |= 0x00FF0000;
  177. DestroyDynamicObject((i * 4) + 2);
  178. }
  179. if (YSI_g_sRaceObjects[i] & 0x0000FF00 == race1)
  180. {
  181. YSI_g_sRaceObjects[i] |= 0x0000FF00;
  182. DestroyDynamicObject((i * 4) + 1);
  183. }
  184. if (YSI_g_sRaceObjects[i] & 0x000000FF == race)
  185. {
  186. YSI_g_sRaceObjects[i] |= 0x000000FF;
  187. DestroyDynamicObject((i * 4));
  188. }
  189. }
  190. #else
  191. #pragma unused race
  192. #endif
  193. }
  194. /*----------------------------------------------------------------------------*-
  195. Function:
  196. Loader_Convert
  197. Params:
  198. Float:radians - Radian angle to convert to degrees.
  199. Return:
  200. Float
  201. Notes:
  202. Based on mtarad2deg made by Trix and fixed by Mike. Converts radians to
  203. degrees and rationalises.
  204. -*----------------------------------------------------------------------------*/
  205. stock Float:Loader_Convert(Float:radians)
  206. {
  207. if (radians == 0.0)
  208. {
  209. return 0.0;
  210. }
  211. new Float:retval = (360.0 + (radians / 0.0174532925));
  212. while (retval >= 360.0) retval -= 360.0;
  213. while (retval < 0.0) retval += 360.0;
  214. return retval;
  215. }
  216. /*----------------------------------------------------------------------------*-
  217. Function:
  218. Loader_Obj
  219. Params:
  220. -
  221. Return:
  222. CreateDynamicObject
  223. Notes:
  224. Called when an end object tag is reached to create an object.
  225. -*----------------------------------------------------------------------------*/
  226. public Loader_Obj()
  227. {
  228. #if defined _YSI_VISUAL_OBJECTS
  229. static
  230. name[MAX_XML_ENTRY_NAME],
  231. val[MAX_XML_ENTRY_TEXT];
  232. new
  233. Float:x,
  234. Float:y,
  235. Float:z,
  236. Float:rx,
  237. Float:ry,
  238. Float:rz,
  239. model;
  240. while (XML_GetKeyValue(name, val))
  241. {
  242. if (!strcmp(name, "position", true))
  243. {
  244. new
  245. pos;
  246. x = floatstr(val);
  247. pos = chrfind(' ', val, pos);
  248. y = floatstr(val[++pos]);
  249. pos = chrfind(' ', val, pos);
  250. z = floatstr(val[++pos]);
  251. }
  252. else if (!strcmp(name, "rotation", true))
  253. {
  254. new
  255. pos;
  256. rz = floatstr(val);
  257. pos = chrfind(' ', val, pos);
  258. ry = floatstr(val[++pos]);
  259. pos = chrfind(' ', val, pos);
  260. rx = floatstr(val[++pos]);
  261. }
  262. else if (!strcmp(name, "model", true))
  263. {
  264. model = strval(val);
  265. }
  266. }
  267. new
  268. obj = CreateDynamicObject(model, x, y, z, Loader_Convert(rx), Loader_Convert(ry), Loader_Convert(rz));
  269. if (YSI_g_sCurWorld != -1)
  270. {
  271. Object_RemoveFromAllWorlds(obj);
  272. Object_AddToWorld(obj, YSI_g_sCurWorld);
  273. }
  274. #if defined _YSI_VISUAL_RACE
  275. new
  276. shift = (8 * (obj & 3)),
  277. mul = obj >>> 2;
  278. if (YSI_g_sCurRace != NO_RACE)
  279. {
  280. YSI_g_sRaceObjects[mul] = (YSI_g_sRaceObjects[mul] & ~(0xFF << shift)) | YSI_g_sCurRace << shift;
  281. }
  282. #endif
  283. return obj;
  284. #else
  285. return -1;
  286. #endif
  287. }
  288. /*----------------------------------------------------------------------------*-
  289. Function:
  290. Loader_Check
  291. Params:
  292. -
  293. Return:
  294. Race_AddCheckpoint
  295. Notes:
  296. Called when an end checkpoint tag is reached to add a checkpoint to a race.
  297. -*----------------------------------------------------------------------------*/
  298. public Loader_Check()
  299. {
  300. #if defined _YSI_VISUAL_RACE
  301. if (YSI_g_sCurRace == NO_RACE) return -1;
  302. static
  303. name[MAX_XML_ENTRY_NAME],
  304. val[MAX_XML_ENTRY_TEXT];
  305. new
  306. Float:x,
  307. Float:y,
  308. Float:z;
  309. while (XML_GetKeyValue(name, val))
  310. {
  311. if (!strcmp(name, "position", true))
  312. {
  313. new
  314. pos;
  315. x = floatstr(val);
  316. pos = chrfind(' ', val, pos);
  317. y = floatstr(val[++pos]);
  318. pos = chrfind(' ', val, pos);
  319. z = floatstr(val[++pos]);
  320. }
  321. }
  322. return Race_AddCheckpoint(YSI_g_sCurRace, x, y, z);
  323. #else
  324. return -1;
  325. #endif
  326. }
  327. /*----------------------------------------------------------------------------*-
  328. Function:
  329. Loader_Spawn
  330. Params:
  331. -
  332. Return:
  333. Race_AddStart
  334. Notes:
  335. Called when an end spawnpoint tag is reached to add a startpoint to a race.
  336. -*----------------------------------------------------------------------------*/
  337. public Loader_Spawn()
  338. {
  339. #if defined _YSI_VISUAL_RACE
  340. if (YSI_g_sCurRace == NO_RACE) return -1;
  341. static
  342. name[MAX_XML_ENTRY_NAME],
  343. val[MAX_XML_ENTRY_TEXT];
  344. new
  345. Float:x,
  346. Float:y,
  347. Float:z,
  348. Float:rz;
  349. while (XML_GetKeyValue(name, val))
  350. {
  351. if (!strcmp(name, "position", true))
  352. {
  353. new
  354. pos;
  355. x = floatstr(val);
  356. pos = chrfind(' ', val, pos);
  357. y = floatstr(val[++pos]);
  358. pos = chrfind(' ', val, pos);
  359. z = floatstr(val[++pos]);
  360. }
  361. else if (!strcmp(name, "rotation", true))
  362. {
  363. rz = floatstr(val);
  364. }
  365. }
  366. return Race_AddStart(YSI_g_sCurRace, x, y, z, rz);
  367. #else
  368. return 1;
  369. #endif
  370. }
  371. /*----------------------------------------------------------------------------*-
  372. Function:
  373. Loader_AddHandler
  374. Params:
  375. trigger[] - Tag to trigger the callback.
  376. function[] - Function to call for the tag.
  377. Return:
  378. -
  379. Notes:
  380. Used to add custom handlers to non-default tags in the race file format.
  381. -*----------------------------------------------------------------------------*/
  382. stock Loader_AddHandler(trigger[], function[])
  383. {
  384. if (YSI_g_sXMLRules != NO_XML_FILE) return XML_AddHandler(YSI_g_sXMLRules, trigger, function);
  385. return 0;
  386. }
  387. /*----------------------------------------------------------------------------*-
  388. Function:
  389. Loader_GetRace
  390. Params:
  391. -
  392. Return:
  393. Current race handle.
  394. Notes:
  395. -
  396. -*----------------------------------------------------------------------------*/
  397. stock Loader_GetRace()
  398. {
  399. return YSI_g_sCurRace;
  400. }