1
0

mSelection.inc 26 KB

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