Guest User

mSelection

a guest
Jan 24th, 2013
459
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. // Model Selection using previews. For SA-MP 0.3x and above.
  3. // - D0erfler 2013
  4. // - Kye 2013
  5. //
  6. // Version 1.1 R2
  7.  
  8. /*Functions to be used
  9.  
  10. LoadModelSelectionMenu(f_name[])
  11. HideModelSelectionMenu(playerid)
  12. ShowModelSelectionMenu(playerid, ListID, header_text[], dialogBGcolor = 0x4A5A6BBB, previewBGcolor = 0x88888899 , tdSelectionColor = 0xFFFF00AA)
  13. ShowModelSelectionMenuEx(playerid, items_array[], item_amount, header_text[], extraid, Float:Xrot = 0.0, Float:Yrot = 0.0, Float:Zrot = 0.0, Float:mZoom = 1.0, dialogBGcolor = 0x4A5A6BBB, previewBGcolor = 0x88888899 , tdSelectionColor = 0xFFFF00AA)
  14.  
  15. */
  16. // Callbacks
  17. forward OnPlayerModelSelection(playerid, response, listid, modelid);
  18. forward OnPlayerModelSelectionEx(playerid, response, extraid, modelid);
  19.  
  20. // settings static lists
  21. #define mS_TOTAL_ITEMS 1000 // Max amount of items from all lists
  22. #define mS_TOTAL_LISTS 20 // Max amount of lists
  23. #define mS_TOTAL_ROT_ZOOM 100 // Max amount of items using extra information like zoom or rotations
  24.  
  25. // settings dynamic per player lists
  26. #define mS_CUSTOM_MAX_ITEMS 20
  27. new gCustomList[MAX_PLAYERS][mS_CUSTOM_MAX_ITEMS];
  28.  
  29. #define mS_INVALID_LISTID mS_TOTAL_LISTS
  30. #define mS_CUSTOM_LISTID (mS_TOTAL_LISTS+1)
  31.  
  32. #define mS_NEXT_TEXT "Next"
  33. #define mS_PREV_TEXT "Prev"
  34. #define mS_CANCEL_TEXT "Cancel"
  35.  
  36. #define mS_SELECTION_ITEMS 21
  37. #define mS_ITEMS_PER_LINE 7
  38. #define mS_DIALOG_BASE_X 75.0
  39. #define mS_DIALOG_BASE_Y 130.0
  40. #define mS_DIALOG_WIDTH 550.0
  41. #define mS_DIALOG_HEIGHT 180.0
  42. #define mS_SPRITE_DIM_X 60.0
  43. #define mS_SPRITE_DIM_Y 70.0
  44.  
  45. new PlayerText:gCurrentPageTextDrawId[MAX_PLAYERS];
  46. new PlayerText:gHeaderTextDrawId[MAX_PLAYERS];
  47. new PlayerText:gBackgroundTextDrawId[MAX_PLAYERS];
  48. new PlayerText:gNextButtonTextDrawId[MAX_PLAYERS];
  49. new PlayerText:gPrevButtonTextDrawId[MAX_PLAYERS];
  50. new PlayerText:gCancelButtonTextDrawId[MAX_PLAYERS];
  51. new PlayerText:gSelectionItems[MAX_PLAYERS][mS_SELECTION_ITEMS];
  52. new gSelectionItemsTag[MAX_PLAYERS][mS_SELECTION_ITEMS];
  53. new gItemAt[MAX_PLAYERS];
  54.  
  55. #define mS_LIST_START 0
  56. #define mS_LIST_END 1
  57. new gLists[mS_TOTAL_LISTS][2]; // list information start/end index
  58.  
  59. #define mS_ITEM_MODEL 0
  60. #define mS_ITEM_ROT_ZOOM_ID 1
  61. new gItemList[mS_TOTAL_ITEMS][2];
  62.  
  63. new Float:gRotZoom[mS_TOTAL_ROT_ZOOM][4]; // Array for saving rotation and zoom info
  64. new gItemAmount = 0; // Amount of items used
  65. new gListAmount = 0; // Amount of lists used
  66. new gRotZoomAmount = 0; // Amount of Rotation/Zoom informations used
  67.  
  68. //------------------------------------------------
  69.  
  70. stock mS_GetNumberOfPages(ListID)
  71. {
  72. new ItemAmount = mS_GetAmountOfListItems(ListID);
  73. if((ItemAmount >= mS_SELECTION_ITEMS) && (ItemAmount % mS_SELECTION_ITEMS) == 0)
  74. {
  75. return (ItemAmount / mS_SELECTION_ITEMS);
  76. }
  77. else return (ItemAmount / mS_SELECTION_ITEMS) + 1;
  78. }
  79.  
  80. //------------------------------------------------
  81.  
  82. stock mS_GetNumberOfPagesEx(playerid)
  83. {
  84. new ItemAmount = mS_GetAmountOfListItemsEx(playerid);
  85. if((ItemAmount >= mS_SELECTION_ITEMS) && (ItemAmount % mS_SELECTION_ITEMS) == 0)
  86. {
  87. return (ItemAmount / mS_SELECTION_ITEMS);
  88. }
  89. else return (ItemAmount / mS_SELECTION_ITEMS) + 1;
  90. }
  91.  
  92. //------------------------------------------------
  93.  
  94. stock mS_GetAmountOfListItems(ListID)
  95. {
  96. return (gLists[ListID][mS_LIST_END] - gLists[ListID][mS_LIST_START])+1;
  97. }
  98.  
  99. //------------------------------------------------
  100.  
  101. stock mS_GetAmountOfListItemsEx(playerid)
  102. {
  103. return GetPVarInt(playerid, "mS_custom_item_amount");
  104. }
  105.  
  106. //------------------------------------------------
  107.  
  108. stock mS_GetPlayerCurrentListID(playerid)
  109. {
  110. if(GetPVarInt(playerid, "mS_list_active") == 1) return GetPVarInt(playerid, "mS_list_id");
  111. else return mS_INVALID_LISTID;
  112. }
  113.  
  114. //------------------------------------------------
  115.  
  116. stock PlayerText:mS_CreateCurrentPageTextDraw(playerid, Float:Xpos, Float:Ypos)
  117. {
  118. new PlayerText:txtInit;
  119. txtInit = CreatePlayerTextDraw(playerid, Xpos, Ypos, "0/0");
  120. PlayerTextDrawUseBox(playerid, txtInit, 0);
  121. PlayerTextDrawLetterSize(playerid, txtInit, 0.4, 1.1);
  122. PlayerTextDrawFont(playerid, txtInit, 1);
  123. PlayerTextDrawSetShadow(playerid, txtInit, 0);
  124. PlayerTextDrawSetOutline(playerid, txtInit, 1);
  125. PlayerTextDrawColor(playerid, txtInit, 0xACCBF1FF);
  126. PlayerTextDrawShow(playerid, txtInit);
  127. return txtInit;
  128. }
  129.  
  130. //------------------------------------------------
  131. // Creates a button textdraw and returns the textdraw ID.
  132.  
  133. stock PlayerText:mS_CreatePlayerDialogButton(playerid, Float:Xpos, Float:Ypos, Float:Width, Float:Height, button_text[])
  134. {
  135. new PlayerText:txtInit;
  136. txtInit = CreatePlayerTextDraw(playerid, Xpos, Ypos, button_text);
  137. PlayerTextDrawUseBox(playerid, txtInit, 1);
  138. PlayerTextDrawBoxColor(playerid, txtInit, 0x000000FF);
  139. PlayerTextDrawBackgroundColor(playerid, txtInit, 0x000000FF);
  140. PlayerTextDrawLetterSize(playerid, txtInit, 0.4, 1.1);
  141. PlayerTextDrawFont(playerid, txtInit, 1);
  142. PlayerTextDrawSetShadow(playerid, txtInit, 0); // no shadow
  143. PlayerTextDrawSetOutline(playerid, txtInit, 0);
  144. PlayerTextDrawColor(playerid, txtInit, 0x4A5A6BFF);
  145. PlayerTextDrawSetSelectable(playerid, txtInit, 1);
  146. PlayerTextDrawAlignment(playerid, txtInit, 2);
  147. PlayerTextDrawTextSize(playerid, txtInit, Height, Width); // The width and height are reversed for centering.. something the game does <g>
  148. PlayerTextDrawShow(playerid, txtInit);
  149. return txtInit;
  150. }
  151.  
  152. //------------------------------------------------
  153.  
  154. stock PlayerText:mS_CreatePlayerHeaderTextDraw(playerid, Float:Xpos, Float:Ypos, header_text[])
  155. {
  156. new PlayerText:txtInit;
  157. txtInit = CreatePlayerTextDraw(playerid, Xpos, Ypos, header_text);
  158. PlayerTextDrawUseBox(playerid, txtInit, 0);
  159. PlayerTextDrawLetterSize(playerid, txtInit, 1.25, 3.0);
  160. PlayerTextDrawFont(playerid, txtInit, 0);
  161. PlayerTextDrawSetShadow(playerid, txtInit, 0);
  162. PlayerTextDrawSetOutline(playerid, txtInit, 1);
  163. PlayerTextDrawColor(playerid, txtInit, 0xACCBF1FF);
  164. PlayerTextDrawShow(playerid, txtInit);
  165. return txtInit;
  166. }
  167.  
  168. //------------------------------------------------
  169.  
  170. stock PlayerText:mS_CreatePlayerBGTextDraw(playerid, Float:Xpos, Float:Ypos, Float:Width, Float:Height, bgcolor)
  171. {
  172. new PlayerText:txtBackground = CreatePlayerTextDraw(playerid, Xpos, Ypos," ~n~"); // enough space for everyone
  173. PlayerTextDrawUseBox(playerid, txtBackground, 1);
  174. PlayerTextDrawBoxColor(playerid, txtBackground, bgcolor);
  175. PlayerTextDrawLetterSize(playerid, txtBackground, 5.0, 5.0);
  176. PlayerTextDrawFont(playerid, txtBackground, 0);
  177. PlayerTextDrawSetShadow(playerid, txtBackground, 0);
  178. PlayerTextDrawSetOutline(playerid, txtBackground, 0);
  179. PlayerTextDrawColor(playerid, txtBackground,0x000000FF);
  180. PlayerTextDrawTextSize(playerid, txtBackground, Width, Height);
  181. PlayerTextDrawBackgroundColor(playerid, txtBackground, bgcolor);
  182. PlayerTextDrawShow(playerid, txtBackground);
  183. return txtBackground;
  184. }
  185.  
  186. //------------------------------------------------
  187. // Creates a model preview sprite
  188.  
  189. stock PlayerText:mS_CreateMPTextDraw(playerid, modelindex, Float:Xpos, Float:Ypos, Float:Xrot, Float:Yrot, Float:Zrot, Float:mZoom, Float:width, Float:height, bgcolor)
  190. {
  191. new PlayerText:txtPlayerSprite = CreatePlayerTextDraw(playerid, Xpos, Ypos, ""); // it has to be set with SetText later
  192. PlayerTextDrawFont(playerid, txtPlayerSprite, TEXT_DRAW_FONT_MODEL_PREVIEW);
  193. PlayerTextDrawColor(playerid, txtPlayerSprite, 0xFFFFFFFF);
  194. PlayerTextDrawBackgroundColor(playerid, txtPlayerSprite, bgcolor);
  195. PlayerTextDrawTextSize(playerid, txtPlayerSprite, width, height); // Text size is the Width:Height
  196. PlayerTextDrawSetPreviewModel(playerid, txtPlayerSprite, modelindex);
  197. PlayerTextDrawSetPreviewRot(playerid,txtPlayerSprite, Xrot, Yrot, Zrot, mZoom);
  198. PlayerTextDrawSetSelectable(playerid, txtPlayerSprite, 1);
  199. PlayerTextDrawShow(playerid,txtPlayerSprite);
  200. return txtPlayerSprite;
  201. }
  202.  
  203. //------------------------------------------------
  204.  
  205. stock mS_DestroyPlayerMPs(playerid)
  206. {
  207. new x=0;
  208. while(x != mS_SELECTION_ITEMS) {
  209. if(gSelectionItems[playerid][x] != PlayerText:INVALID_TEXT_DRAW) {
  210. PlayerTextDrawDestroy(playerid, gSelectionItems[playerid][x]);
  211. gSelectionItems[playerid][x] = PlayerText:INVALID_TEXT_DRAW;
  212. }
  213. x++;
  214. }
  215. }
  216.  
  217. //------------------------------------------------
  218.  
  219. stock mS_ShowPlayerMPs(playerid)
  220. {
  221. new bgcolor = GetPVarInt(playerid, "mS_previewBGcolor");
  222. new x=0;
  223. new Float:BaseX = mS_DIALOG_BASE_X;
  224. new Float:BaseY = mS_DIALOG_BASE_Y - (mS_SPRITE_DIM_Y * 0.33); // down a bit
  225. new linetracker = 0;
  226.  
  227. new mS_listID = mS_GetPlayerCurrentListID(playerid);
  228. if(mS_listID == mS_CUSTOM_LISTID)
  229. {
  230. new itemat = (GetPVarInt(playerid, "mS_list_page") * mS_SELECTION_ITEMS);
  231. new Float:rotzoom[4];
  232. rotzoom[0] = GetPVarFloat(playerid, "mS_custom_Xrot");
  233. rotzoom[1] = GetPVarFloat(playerid, "mS_custom_Yrot");
  234. rotzoom[2] = GetPVarFloat(playerid, "mS_custom_Zrot");
  235. rotzoom[3] = GetPVarFloat(playerid, "mS_custom_Zoom");
  236. new itemamount = mS_GetAmountOfListItemsEx(playerid);
  237. // Destroy any previous ones created
  238. mS_DestroyPlayerMPs(playerid);
  239.  
  240. while(x != mS_SELECTION_ITEMS && itemat < (itemamount)) {
  241. if(linetracker == 0) {
  242. BaseX = mS_DIALOG_BASE_X + 25.0; // in a bit from the box
  243. BaseY += mS_SPRITE_DIM_Y + 1.0; // move on the Y for the next line
  244. }
  245. gSelectionItems[playerid][x] = mS_CreateMPTextDraw(playerid, gCustomList[playerid][itemat], BaseX, BaseY, rotzoom[0], rotzoom[1], rotzoom[2], rotzoom[3], mS_SPRITE_DIM_X, mS_SPRITE_DIM_Y, bgcolor);
  246. gSelectionItemsTag[playerid][x] = gCustomList[playerid][itemat];
  247. BaseX += mS_SPRITE_DIM_X + 1.0; // move on the X for the next sprite
  248. linetracker++;
  249. if(linetracker == mS_ITEMS_PER_LINE) linetracker = 0;
  250. itemat++;
  251. x++;
  252. }
  253. }
  254. else
  255. {
  256. new itemat = (gLists[mS_listID][mS_LIST_START] + (GetPVarInt(playerid, "mS_list_page") * mS_SELECTION_ITEMS));
  257.  
  258. // Destroy any previous ones created
  259. mS_DestroyPlayerMPs(playerid);
  260.  
  261. while(x != mS_SELECTION_ITEMS && itemat < (gLists[mS_listID][mS_LIST_END]+1)) {
  262. if(linetracker == 0) {
  263. BaseX = mS_DIALOG_BASE_X + 25.0; // in a bit from the box
  264. BaseY += mS_SPRITE_DIM_Y + 1.0; // move on the Y for the next line
  265. }
  266. new rzID = gItemList[itemat][mS_ITEM_ROT_ZOOM_ID]; // avoid long line
  267. if(rzID > -1) gSelectionItems[playerid][x] = mS_CreateMPTextDraw(playerid, gItemList[itemat][mS_ITEM_MODEL], BaseX, BaseY, gRotZoom[rzID][0], gRotZoom[rzID][1], gRotZoom[rzID][2], gRotZoom[rzID][3], mS_SPRITE_DIM_X, mS_SPRITE_DIM_Y, bgcolor);
  268. else gSelectionItems[playerid][x] = mS_CreateMPTextDraw(playerid, gItemList[itemat][mS_ITEM_MODEL], BaseX, BaseY, 0.0, 0.0, 0.0, 1.0, mS_SPRITE_DIM_X, mS_SPRITE_DIM_Y, bgcolor);
  269. gSelectionItemsTag[playerid][x] = gItemList[itemat][mS_ITEM_MODEL];
  270. BaseX += mS_SPRITE_DIM_X + 1.0; // move on the X for the next sprite
  271. linetracker++;
  272. if(linetracker == mS_ITEMS_PER_LINE) linetracker = 0;
  273. itemat++;
  274. x++;
  275. }
  276. }
  277. }
  278.  
  279. //------------------------------------------------
  280.  
  281. stock mS_UpdatePageTextDraw(playerid)
  282. {
  283. new PageText[64+1];
  284. new listID = mS_GetPlayerCurrentListID(playerid);
  285. if(listID == mS_CUSTOM_LISTID)
  286. {
  287. format(PageText, 64, "%d/%d", GetPVarInt(playerid,"mS_list_page") + 1, mS_GetNumberOfPagesEx(playerid));
  288. PlayerTextDrawSetString(playerid, gCurrentPageTextDrawId[playerid], PageText);
  289. }
  290. else
  291. {
  292. format(PageText, 64, "%d/%d", GetPVarInt(playerid,"mS_list_page") + 1, mS_GetNumberOfPages(listID));
  293. PlayerTextDrawSetString(playerid, gCurrentPageTextDrawId[playerid], PageText);
  294. }
  295. }
  296.  
  297. //------------------------------------------------
  298.  
  299. stock ShowModelSelectionMenu(playerid, ListID, header_text[], dialogBGcolor = 0x4A5A6BBB, previewBGcolor = 0x88888899 , tdSelectionColor = 0xFFFF00AA)
  300. {
  301. if(!(0 <= ListID < mS_TOTAL_LISTS && gLists[ListID][mS_LIST_START] != gLists[ListID][mS_LIST_END])) return 0;
  302. mS_DestroySelectionMenu(playerid);
  303. SetPVarInt(playerid, "mS_list_page", 0);
  304. SetPVarInt(playerid, "mS_list_id", ListID);
  305. SetPVarInt(playerid, "mS_list_active", 1);
  306. SetPVarInt(playerid, "mS_list_time", GetTickCount());
  307.  
  308. gBackgroundTextDrawId[playerid] = mS_CreatePlayerBGTextDraw(playerid, mS_DIALOG_BASE_X, mS_DIALOG_BASE_Y + 20.0, mS_DIALOG_WIDTH, mS_DIALOG_HEIGHT, dialogBGcolor);
  309. gHeaderTextDrawId[playerid] = mS_CreatePlayerHeaderTextDraw(playerid, mS_DIALOG_BASE_X, mS_DIALOG_BASE_Y, header_text);
  310. gCurrentPageTextDrawId[playerid] = mS_CreateCurrentPageTextDraw(playerid, mS_DIALOG_WIDTH - 30.0, mS_DIALOG_BASE_Y + 15.0);
  311. gNextButtonTextDrawId[playerid] = mS_CreatePlayerDialogButton(playerid, mS_DIALOG_WIDTH - 30.0, mS_DIALOG_BASE_Y+mS_DIALOG_HEIGHT+100.0, 50.0, 16.0, mS_NEXT_TEXT);
  312. gPrevButtonTextDrawId[playerid] = mS_CreatePlayerDialogButton(playerid, mS_DIALOG_WIDTH - 90.0, mS_DIALOG_BASE_Y+mS_DIALOG_HEIGHT+100.0, 50.0, 16.0, mS_PREV_TEXT);
  313. gCancelButtonTextDrawId[playerid] = mS_CreatePlayerDialogButton(playerid, mS_DIALOG_WIDTH - 150.0, mS_DIALOG_BASE_Y+mS_DIALOG_HEIGHT+100.0, 50.0, 16.0, mS_CANCEL_TEXT);
  314.  
  315. SetPVarInt(playerid, "mS_previewBGcolor", previewBGcolor);
  316. mS_ShowPlayerMPs(playerid);
  317. mS_UpdatePageTextDraw(playerid);
  318.  
  319. SelectTextDraw(playerid, tdSelectionColor);
  320. return 1;
  321. }
  322.  
  323. //------------------------------------------------------------
  324.  
  325. stock ShowModelSelectionMenuEx(playerid, items_array[], item_amount, header_text[], extraid, Float:Xrot = 0.0, Float:Yrot = 0.0, Float:Zrot = 0.0, Float:mZoom = 1.0, dialogBGcolor = 0x4A5A6BBB, previewBGcolor = 0x88888899 , tdSelectionColor = 0xFFFF00AA)
  326. {
  327. mS_DestroySelectionMenu(playerid);
  328. if(item_amount > mS_CUSTOM_MAX_ITEMS)
  329. {
  330. item_amount = mS_CUSTOM_MAX_ITEMS;
  331. print("-mSelection- WARNING: Too many items given to \"ShowModelSelectionMenuEx\", increase \"mS_CUSTOM_MAX_ITEMS\" to fix this");
  332. }
  333. if(item_amount > 0)
  334. {
  335. for(new i=0;i<item_amount;i++)
  336. {
  337. gCustomList[playerid][i] = items_array[i];
  338. }
  339. SetPVarInt(playerid, "mS_list_page", 0);
  340. SetPVarInt(playerid, "mS_list_id", mS_CUSTOM_LISTID);
  341. SetPVarInt(playerid, "mS_list_active", 1);
  342. SetPVarInt(playerid, "mS_list_time", GetTickCount());
  343.  
  344. SetPVarInt(playerid, "mS_custom_item_amount", item_amount);
  345. SetPVarFloat(playerid, "mS_custom_Xrot", Xrot);
  346. SetPVarFloat(playerid, "mS_custom_Yrot", Yrot);
  347. SetPVarFloat(playerid, "mS_custom_Zrot", Zrot);
  348. SetPVarFloat(playerid, "mS_custom_Zoom", mZoom);
  349. SetPVarInt(playerid, "mS_custom_extraid", extraid);
  350.  
  351.  
  352. gBackgroundTextDrawId[playerid] = mS_CreatePlayerBGTextDraw(playerid, mS_DIALOG_BASE_X, mS_DIALOG_BASE_Y + 20.0, mS_DIALOG_WIDTH, mS_DIALOG_HEIGHT, dialogBGcolor);
  353. gHeaderTextDrawId[playerid] = mS_CreatePlayerHeaderTextDraw(playerid, mS_DIALOG_BASE_X, mS_DIALOG_BASE_Y, header_text);
  354. gCurrentPageTextDrawId[playerid] = mS_CreateCurrentPageTextDraw(playerid, mS_DIALOG_WIDTH - 30.0, mS_DIALOG_BASE_Y + 15.0);
  355. gNextButtonTextDrawId[playerid] = mS_CreatePlayerDialogButton(playerid, mS_DIALOG_WIDTH - 30.0, mS_DIALOG_BASE_Y+mS_DIALOG_HEIGHT+100.0, 50.0, 16.0, mS_NEXT_TEXT);
  356. gPrevButtonTextDrawId[playerid] = mS_CreatePlayerDialogButton(playerid, mS_DIALOG_WIDTH - 90.0, mS_DIALOG_BASE_Y+mS_DIALOG_HEIGHT+100.0, 50.0, 16.0, mS_PREV_TEXT);
  357. gCancelButtonTextDrawId[playerid] = mS_CreatePlayerDialogButton(playerid, mS_DIALOG_WIDTH - 150.0, mS_DIALOG_BASE_Y+mS_DIALOG_HEIGHT+100.0, 50.0, 16.0, mS_CANCEL_TEXT);
  358.  
  359. SetPVarInt(playerid, "mS_previewBGcolor", previewBGcolor);
  360. mS_ShowPlayerMPs(playerid);
  361. mS_UpdatePageTextDraw(playerid);
  362.  
  363. SelectTextDraw(playerid, tdSelectionColor);
  364. return 1;
  365. }
  366. return 0;
  367. }
  368.  
  369. //------------------------------------------------
  370.  
  371. stock HideModelSelectionMenu(playerid)
  372. {
  373. mS_DestroySelectionMenu(playerid);
  374. SetPVarInt(playerid, "mS_ignore_next_esc", 1);
  375. CancelSelectTextDraw(playerid);
  376. return 1;
  377. }
  378.  
  379. //------------------------------------------------
  380.  
  381. stock mS_DestroySelectionMenu(playerid)
  382. {
  383. if(GetPVarInt(playerid, "mS_list_active") == 1)
  384. {
  385. if(mS_GetPlayerCurrentListID(playerid) == mS_CUSTOM_LISTID)
  386. {
  387. DeletePVar(playerid, "mS_custom_Xrot");
  388. DeletePVar(playerid, "mS_custom_Yrot");
  389. DeletePVar(playerid, "mS_custom_Zrot");
  390. DeletePVar(playerid, "mS_custom_Zoom");
  391. DeletePVar(playerid, "mS_custom_extraid");
  392. DeletePVar(playerid, "mS_custom_item_amount");
  393. }
  394. DeletePVar(playerid, "mS_list_time");
  395. SetPVarInt(playerid, "mS_list_active", 0);
  396. mS_DestroyPlayerMPs(playerid);
  397.  
  398. PlayerTextDrawDestroy(playerid, gHeaderTextDrawId[playerid]);
  399. PlayerTextDrawDestroy(playerid, gBackgroundTextDrawId[playerid]);
  400. PlayerTextDrawDestroy(playerid, gCurrentPageTextDrawId[playerid]);
  401. PlayerTextDrawDestroy(playerid, gNextButtonTextDrawId[playerid]);
  402. PlayerTextDrawDestroy(playerid, gPrevButtonTextDrawId[playerid]);
  403. PlayerTextDrawDestroy(playerid, gCancelButtonTextDrawId[playerid]);
  404.  
  405. gHeaderTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  406. gBackgroundTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  407. gCurrentPageTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  408. gNextButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  409. gPrevButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  410. gCancelButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  411. }
  412. }
  413.  
  414. //------------------------------------------------
  415.  
  416. public OnPlayerConnect(playerid)
  417. {
  418. // Init all of the textdraw related globals
  419. gHeaderTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  420. gBackgroundTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  421. gCurrentPageTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  422. gNextButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  423. gPrevButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  424. gCancelButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  425.  
  426. for(new x=0; x < mS_SELECTION_ITEMS; x++) {
  427. gSelectionItems[playerid][x] = PlayerText:INVALID_TEXT_DRAW;
  428. }
  429.  
  430. gItemAt[playerid] = 0;
  431.  
  432. return CallLocalFunction("MP_OPC", "i", playerid);
  433. }
  434.  
  435. #if defined _ALS_OnPlayerConnect
  436. #undef OnPlayerConnect
  437. #else
  438. #define _ALS_OnPlayerConnect
  439. #endif
  440. #define OnPlayerConnect MP_OPC
  441.  
  442. forward MP_OPC(playerid);
  443.  
  444. //-------------------------------------------
  445. // Even though only Player* textdraws are used in this script,
  446. // OnPlayerClickTextDraw is still required to handle ESC
  447.  
  448. public OnPlayerClickTextDraw(playerid, Text:clickedid)
  449. {
  450. if(GetPVarInt(playerid, "mS_ignore_next_esc") == 1) {
  451. SetPVarInt(playerid, "mS_ignore_next_esc", 0);
  452. return CallLocalFunction("MP_OPCTD", "ii", playerid, _:clickedid);
  453. }
  454. if(GetPVarInt(playerid, "mS_list_active") == 0) return CallLocalFunction("MP_OPCTD", "ii", playerid, _:clickedid);
  455.  
  456. // Handle: They cancelled (with ESC)
  457. if(clickedid == Text:INVALID_TEXT_DRAW) {
  458. new listid = mS_GetPlayerCurrentListID(playerid);
  459. if(listid == mS_CUSTOM_LISTID)
  460. {
  461. new extraid = GetPVarInt(playerid, "mS_custom_extraid");
  462. mS_DestroySelectionMenu(playerid);
  463. CallLocalFunction("OnPlayerModelSelectionEx", "dddd", playerid, 0, extraid, -1);
  464. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  465. }
  466. else
  467. {
  468. mS_DestroySelectionMenu(playerid);
  469. CallLocalFunction("OnPlayerModelSelection", "dddd", playerid, 0, listid, -1);
  470. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  471. }
  472. return 1;
  473. }
  474.  
  475. return CallLocalFunction("MP_OPCTD", "ii", playerid, _:clickedid);
  476. }
  477.  
  478. #if defined _ALS_OnPlayerClickTextDraw
  479. #undef OnPlayerClickTextDraw
  480. #else
  481. #define _ALS_OnPlayerClickTextDraw
  482. #endif
  483. #define OnPlayerClickTextDraw MP_OPCTD
  484.  
  485. forward MP_OPCTD(playerid, Text:clickedid);
  486.  
  487. //------------------------------------------------
  488.  
  489. public OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid)
  490. {
  491. if(GetPVarInt(playerid, "mS_list_active") == 0 || (GetTickCount()-GetPVarInt(playerid, "mS_list_time")) < 200 /* Disable instant selection */) return CallLocalFunction("MP_OPCPTD", "ii", playerid, _:playertextid);
  492.  
  493. new curpage = GetPVarInt(playerid, "mS_list_page");
  494.  
  495. // Handle: cancel button
  496. if(playertextid == gCancelButtonTextDrawId[playerid]) {
  497. new listID = mS_GetPlayerCurrentListID(playerid);
  498. if(listID == mS_CUSTOM_LISTID)
  499. {
  500. new extraid = GetPVarInt(playerid, "mS_custom_extraid");
  501. HideModelSelectionMenu(playerid);
  502. CallLocalFunction("OnPlayerModelSelectionEx", "dddd", playerid, 0, extraid, -1);
  503. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  504. }
  505. else
  506. {
  507. HideModelSelectionMenu(playerid);
  508. CallLocalFunction("OnPlayerModelSelection", "dddd", playerid, 0, listID, -1);
  509. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  510. }
  511. return 1;
  512. }
  513.  
  514. // Handle: next button
  515. if(playertextid == gNextButtonTextDrawId[playerid]) {
  516. new listID = mS_GetPlayerCurrentListID(playerid);
  517. if(listID == mS_CUSTOM_LISTID)
  518. {
  519. if(curpage < (mS_GetNumberOfPagesEx(playerid) - 1)) {
  520. SetPVarInt(playerid, "mS_list_page", curpage + 1);
  521. mS_ShowPlayerMPs(playerid);
  522. mS_UpdatePageTextDraw(playerid);
  523. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  524. } else {
  525. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  526. }
  527. }
  528. else
  529. {
  530. if(curpage < (mS_GetNumberOfPages(listID) - 1)) {
  531. SetPVarInt(playerid, "mS_list_page", curpage + 1);
  532. mS_ShowPlayerMPs(playerid);
  533. mS_UpdatePageTextDraw(playerid);
  534. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  535. } else {
  536. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  537. }
  538. }
  539. return 1;
  540. }
  541.  
  542. // Handle: previous button
  543. if(playertextid == gPrevButtonTextDrawId[playerid]) {
  544. if(curpage > 0) {
  545. SetPVarInt(playerid, "mS_list_page", curpage - 1);
  546. mS_ShowPlayerMPs(playerid);
  547. mS_UpdatePageTextDraw(playerid);
  548. PlayerPlaySound(playerid, 1084, 0.0, 0.0, 0.0);
  549. } else {
  550. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  551. }
  552. return 1;
  553. }
  554.  
  555. // Search in the array of textdraws used for the items
  556. new x=0;
  557. while(x != mS_SELECTION_ITEMS) {
  558. if(playertextid == gSelectionItems[playerid][x]) {
  559. new listID = mS_GetPlayerCurrentListID(playerid);
  560. if(listID == mS_CUSTOM_LISTID)
  561. {
  562. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  563. new item_id = gSelectionItemsTag[playerid][x];
  564. new extraid = GetPVarInt(playerid, "mS_custom_extraid");
  565. HideModelSelectionMenu(playerid);
  566. CallLocalFunction("OnPlayerModelSelectionEx", "dddd", playerid, 1, extraid, item_id);
  567. return 1;
  568. }
  569. else
  570. {
  571. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  572. new item_id = gSelectionItemsTag[playerid][x];
  573. HideModelSelectionMenu(playerid);
  574. CallLocalFunction("OnPlayerModelSelection", "dddd", playerid, 1, listID, item_id);
  575. return 1;
  576. }
  577. }
  578. x++;
  579. }
  580.  
  581. return CallLocalFunction("MP_OPCPTD", "ii", playerid, _:playertextid);
  582. }
  583.  
  584. #if defined _ALS_OnPlayerClickPlayerTD
  585. #undef OnPlayerClickPlayerTextDraw
  586. #else
  587. #define _ALS_OnPlayerClickPlayerTD
  588. #endif
  589. #define OnPlayerClickPlayerTextDraw MP_OPCPTD
  590.  
  591. forward MP_OPCPTD(playerid, PlayerText:playertextid);
  592.  
  593. //------------------------------------------------------------------
  594.  
  595.  
  596. stock LoadModelSelectionMenu(f_name[])
  597. {
  598. new File:f, str[75];
  599. format(str, sizeof(str), "%s", f_name);
  600. f = fopen(str, io_read);
  601. if( !f ) {
  602. printf("-mSelection- WARNING: Failed to load list: \"%s\"", f_name);
  603. return mS_INVALID_LISTID;
  604. }
  605.  
  606. if(gListAmount >= mS_TOTAL_LISTS)
  607. {
  608. printf("-mSelection- WARNING: Reached maximum amount of lists, increase \"mS_TOTAL_LISTS\"", f_name);
  609. return mS_INVALID_LISTID;
  610. }
  611. new tmp_ItemAmount = gItemAmount; // copy value if loading fails
  612.  
  613.  
  614. new line[128], idxx;
  615. while(fread(f,line,sizeof(line),false))
  616. {
  617. if(tmp_ItemAmount >= mS_TOTAL_ITEMS)
  618. {
  619. printf("-mSelection- WARNING: Reached maximum amount of items, increase \"mS_TOTAL_ITEMS\"", f_name);
  620. break;
  621. }
  622. idxx = 0;
  623. if(!line[0]) continue;
  624. new mID = strval( mS_strtok(line,idxx) );
  625. if(0 <= mID < 20000)
  626. {
  627. gItemList[tmp_ItemAmount][mS_ITEM_MODEL] = mID;
  628.  
  629. new tmp_mS_strtok[20];
  630. new Float:mRotation[3], Float:mZoom = 1.0;
  631. new bool:useRotation = false;
  632.  
  633. tmp_mS_strtok = mS_strtok(line,idxx);
  634. if(tmp_mS_strtok[0]) {
  635. useRotation = true;
  636. mRotation[0] = floatstr(tmp_mS_strtok);
  637. }
  638. tmp_mS_strtok = mS_strtok(line,idxx);
  639. if(tmp_mS_strtok[0]) {
  640. useRotation = true;
  641. mRotation[1] = floatstr(tmp_mS_strtok);
  642. }
  643. tmp_mS_strtok = mS_strtok(line,idxx);
  644. if(tmp_mS_strtok[0]) {
  645. useRotation = true;
  646. mRotation[2] = floatstr(tmp_mS_strtok);
  647. }
  648. tmp_mS_strtok = mS_strtok(line,idxx);
  649. if(tmp_mS_strtok[0]) {
  650. useRotation = true;
  651. mZoom = floatstr(tmp_mS_strtok);
  652. }
  653. if(useRotation)
  654. {
  655. new bool:foundRotZoom = false;
  656. for(new i=0; i < gRotZoomAmount; i++)
  657. {
  658. if(gRotZoom[i][0] == mRotation[0] && gRotZoom[i][1] == mRotation[1] && gRotZoom[i][2] == mRotation[2] && gRotZoom[i][3] == mZoom)
  659. {
  660. foundRotZoom = true;
  661. gItemList[tmp_ItemAmount][mS_ITEM_ROT_ZOOM_ID] = i;
  662. break;
  663. }
  664. }
  665. if(gRotZoomAmount < mS_TOTAL_ROT_ZOOM)
  666. {
  667. if(!foundRotZoom)
  668. {
  669. gRotZoom[gRotZoomAmount][0] = mRotation[0];
  670. gRotZoom[gRotZoomAmount][1] = mRotation[1];
  671. gRotZoom[gRotZoomAmount][2] = mRotation[2];
  672. gRotZoom[gRotZoomAmount][3] = mZoom;
  673. gItemList[tmp_ItemAmount][mS_ITEM_ROT_ZOOM_ID] = gRotZoomAmount;
  674. gRotZoomAmount++;
  675. }
  676. }
  677. else print("-mSelection- WARNING: Not able to save rotation/zoom information. Reached maximum rotation/zoom information count. Increase '#define mS_TOTAL_ROT_ZOOM' to fix the issue");
  678. }
  679. else gItemList[tmp_ItemAmount][mS_ITEM_ROT_ZOOM_ID] = -1;
  680. tmp_ItemAmount++;
  681. }
  682. }
  683. if(tmp_ItemAmount > gItemAmount) // any models loaded ?
  684. {
  685. gLists[gListAmount][mS_LIST_START] = gItemAmount;
  686. gItemAmount = tmp_ItemAmount; // copy back
  687. gLists[gListAmount][mS_LIST_END] = (gItemAmount-1);
  688.  
  689. gListAmount++;
  690. return (gListAmount-1);
  691. }
  692. printf("-mSelection- WARNING: No Items found in file: %s", f_name);
  693. return mS_INVALID_LISTID;
  694. }
  695.  
  696.  
  697.  
  698. stock mS_strtok(const string[], &index)
  699. {
  700. new length = strlen(string);
  701. while ((index < length) && (string[index] <= ' '))
  702. {
  703. index++;
  704. }
  705.  
  706. new offset = index;
  707. new result[20];
  708. while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
  709. {
  710. result[index - offset] = string[index];
  711. index++;
  712. }
  713. result[index - offset] = EOS;
  714. return result;
  715. }
RAW Paste Data