SAMP Gitlab CI Test
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

416 lines
14 KiB

  1. //
  2. // Admin spawner using previews. For SA-MP 0.3x and above.
  3. // - Kye 2012
  4. //
  5. #include <a_samp>
  6. #include "../include/gl_common.inc"
  7. #define TOTAL_ITEMS 20000
  8. #define SELECTION_ITEMS 21
  9. #define ITEMS_PER_LINE 7
  10. #define HEADER_TEXT "Objects"
  11. #define NEXT_TEXT "Next"
  12. #define PREV_TEXT "Prev"
  13. #define DIALOG_BASE_X 75.0
  14. #define DIALOG_BASE_Y 130.0
  15. #define DIALOG_WIDTH 550.0
  16. #define DIALOG_HEIGHT 180.0
  17. #define SPRITE_DIM_X 60.0
  18. #define SPRITE_DIM_Y 70.0
  19. new gTotalItems = TOTAL_ITEMS;
  20. new PlayerText:gBackgroundTextDrawId[MAX_PLAYERS];
  21. new PlayerText:gNextButtonTextDrawId[MAX_PLAYERS];
  22. new PlayerText:gPrevButtonTextDrawId[MAX_PLAYERS];
  23. new PlayerText:gSelectionItems[MAX_PLAYERS][SELECTION_ITEMS];
  24. new PlayerText:gCurrentPageTextDrawId[MAX_PLAYERS];
  25. new PlayerText:gHeaderTextDrawId[MAX_PLAYERS];
  26. new gSelectionItemsTag[MAX_PLAYERS][SELECTION_ITEMS];
  27. new gItemAt[MAX_PLAYERS];
  28. //------------------------------------------------
  29. public OnFilterScriptInit()
  30. {
  31. print("\n--Admin Vehicle Spawner Loaded\n");
  32. return 1;
  33. }
  34. //------------------------------------------------
  35. GetNumberOfPages()
  36. {
  37. if((gTotalItems >= SELECTION_ITEMS) && (gTotalItems % SELECTION_ITEMS) == 0)
  38. {
  39. return (gTotalItems / SELECTION_ITEMS);
  40. }
  41. else return (gTotalItems / SELECTION_ITEMS) + 1;
  42. }
  43. //------------------------------------------------
  44. PlayerText:CreateCurrentPageTextDraw(playerid, Float:Xpos, Float:Ypos)
  45. {
  46. new PlayerText:txtInit;
  47. txtInit = CreatePlayerTextDraw(playerid, Xpos, Ypos, "0/0");
  48. PlayerTextDrawUseBox(playerid, txtInit, 0);
  49. PlayerTextDrawLetterSize(playerid, txtInit, 0.4, 1.1);
  50. PlayerTextDrawFont(playerid, txtInit, 1);
  51. PlayerTextDrawSetShadow(playerid, txtInit, 0);
  52. PlayerTextDrawSetOutline(playerid, txtInit, 1);
  53. PlayerTextDrawColor(playerid, txtInit, 0xACCBF1FF);
  54. PlayerTextDrawShow(playerid, txtInit);
  55. return txtInit;
  56. }
  57. //------------------------------------------------
  58. // Creates a button textdraw and returns the textdraw ID.
  59. PlayerText:CreatePlayerDialogButton(playerid, Float:Xpos, Float:Ypos, Float:Width, Float:Height, button_text[])
  60. {
  61. new PlayerText:txtInit;
  62. txtInit = CreatePlayerTextDraw(playerid, Xpos, Ypos, button_text);
  63. PlayerTextDrawUseBox(playerid, txtInit, 1);
  64. PlayerTextDrawBoxColor(playerid, txtInit, 0x000000FF);
  65. PlayerTextDrawBackgroundColor(playerid, txtInit, 0x000000FF);
  66. PlayerTextDrawLetterSize(playerid, txtInit, 0.4, 1.1);
  67. PlayerTextDrawFont(playerid, txtInit, 1);
  68. PlayerTextDrawSetShadow(playerid, txtInit, 0); // no shadow
  69. PlayerTextDrawSetOutline(playerid, txtInit, 0);
  70. PlayerTextDrawColor(playerid, txtInit, 0x4A5A6BFF);
  71. PlayerTextDrawSetSelectable(playerid, txtInit, 1);
  72. PlayerTextDrawAlignment(playerid, txtInit, 2);
  73. PlayerTextDrawTextSize(playerid, txtInit, Height, Width); // The width and height are reversed for centering.. something the game does <g>
  74. PlayerTextDrawShow(playerid, txtInit);
  75. return txtInit;
  76. }
  77. //------------------------------------------------
  78. PlayerText:CreatePlayerHeaderTextDraw(playerid, Float:Xpos, Float:Ypos, header_text[])
  79. {
  80. new PlayerText:txtInit;
  81. txtInit = CreatePlayerTextDraw(playerid, Xpos, Ypos, header_text);
  82. PlayerTextDrawUseBox(playerid, txtInit, 0);
  83. PlayerTextDrawLetterSize(playerid, txtInit, 1.25, 3.0);
  84. PlayerTextDrawFont(playerid, txtInit, 0);
  85. PlayerTextDrawSetShadow(playerid, txtInit, 0);
  86. PlayerTextDrawSetOutline(playerid, txtInit, 1);
  87. PlayerTextDrawColor(playerid, txtInit, 0xACCBF1FF);
  88. PlayerTextDrawShow(playerid, txtInit);
  89. return txtInit;
  90. }
  91. //------------------------------------------------
  92. PlayerText:CreatePlayerBackgroundTextDraw(playerid, Float:Xpos, Float:Ypos, Float:Width, Float:Height)
  93. {
  94. new PlayerText:txtBackground = CreatePlayerTextDraw(playerid, Xpos, Ypos,
  95. " ~n~"); // enough space for everyone
  96. PlayerTextDrawUseBox(playerid, txtBackground, 1);
  97. PlayerTextDrawBoxColor(playerid, txtBackground, 0x4A5A6BBB);
  98. PlayerTextDrawLetterSize(playerid, txtBackground, 5.0, 5.0);
  99. PlayerTextDrawFont(playerid, txtBackground, 0);
  100. PlayerTextDrawSetShadow(playerid, txtBackground, 0);
  101. PlayerTextDrawSetOutline(playerid, txtBackground, 0);
  102. PlayerTextDrawColor(playerid, txtBackground,0xFFFFFFFF);
  103. PlayerTextDrawTextSize(playerid, txtBackground, Width, Height);
  104. PlayerTextDrawBackgroundColor(playerid, txtBackground, 0x4A5A6BBB);
  105. PlayerTextDrawShow(playerid, txtBackground);
  106. return txtBackground;
  107. }
  108. //------------------------------------------------
  109. // Creates a model preview sprite
  110. PlayerText:CreateModelPreviewTextDraw(playerid, modelindex, Float:Xpos, Float:Ypos, Float:width, Float:height)
  111. {
  112. new PlayerText:txtPlayerSprite = CreatePlayerTextDraw(playerid, Xpos, Ypos, ""); // it has to be set with SetText later
  113. PlayerTextDrawFont(playerid, txtPlayerSprite, TEXT_DRAW_FONT_MODEL_PREVIEW);
  114. PlayerTextDrawColor(playerid, txtPlayerSprite, 0xFFFFFFFF);
  115. PlayerTextDrawBackgroundColor(playerid, txtPlayerSprite, 0x88888899);
  116. PlayerTextDrawTextSize(playerid, txtPlayerSprite, width, height); // Text size is the Width:Height
  117. PlayerTextDrawSetPreviewModel(playerid, txtPlayerSprite, modelindex);
  118. if(modelindex > 319) {
  119. PlayerTextDrawSetPreviewRot(playerid,txtPlayerSprite, -15.0, 0.0, 0.0);
  120. }
  121. PlayerTextDrawSetSelectable(playerid, txtPlayerSprite, 1);
  122. PlayerTextDrawShow(playerid,txtPlayerSprite);
  123. return txtPlayerSprite;
  124. }
  125. //------------------------------------------------
  126. DestroyPlayerModelPreviews(playerid)
  127. {
  128. new x=0;
  129. while(x != SELECTION_ITEMS) {
  130. if(gSelectionItems[playerid][x] != PlayerText:INVALID_TEXT_DRAW) {
  131. PlayerTextDrawDestroy(playerid, gSelectionItems[playerid][x]);
  132. gSelectionItems[playerid][x] = PlayerText:INVALID_TEXT_DRAW;
  133. }
  134. x++;
  135. }
  136. }
  137. //------------------------------------------------
  138. ShowPlayerModelPreviews(playerid)
  139. {
  140. new x=0;
  141. new Float:BaseX = DIALOG_BASE_X;
  142. new Float:BaseY = DIALOG_BASE_Y - (SPRITE_DIM_Y * 0.33); // down a bit
  143. new linetracker = 0;
  144. new itemat = GetPVarInt(playerid, "ospawner_page") * SELECTION_ITEMS;
  145. // Destroy any previous ones created
  146. DestroyPlayerModelPreviews(playerid);
  147. while(x != SELECTION_ITEMS && itemat < gTotalItems) {
  148. if(linetracker == 0) {
  149. BaseX = DIALOG_BASE_X + 25.0; // in a bit from the box
  150. BaseY += SPRITE_DIM_Y + 1.0; // move on the Y for the next line
  151. }
  152. gSelectionItems[playerid][x] = CreateModelPreviewTextDraw(playerid, itemat, BaseX, BaseY, SPRITE_DIM_X, SPRITE_DIM_Y);
  153. gSelectionItemsTag[playerid][x] = itemat;
  154. BaseX += SPRITE_DIM_X + 1.0; // move on the X for the next sprite
  155. linetracker++;
  156. if(linetracker == ITEMS_PER_LINE) linetracker = 0;
  157. itemat++;
  158. x++;
  159. }
  160. }
  161. //------------------------------------------------
  162. UpdatePageTextDraw(playerid)
  163. {
  164. new PageText[64+1];
  165. format(PageText, 64, "%d/%d", GetPVarInt(playerid,"ospawner_page") + 1, GetNumberOfPages());
  166. PlayerTextDrawSetString(playerid, gCurrentPageTextDrawId[playerid], PageText);
  167. }
  168. //------------------------------------------------
  169. CreateSelectionMenu(playerid)
  170. {
  171. gBackgroundTextDrawId[playerid] = CreatePlayerBackgroundTextDraw(playerid, DIALOG_BASE_X, DIALOG_BASE_Y + 20.0, DIALOG_WIDTH, DIALOG_HEIGHT);
  172. gHeaderTextDrawId[playerid] = CreatePlayerHeaderTextDraw(playerid, DIALOG_BASE_X, DIALOG_BASE_Y, HEADER_TEXT);
  173. gCurrentPageTextDrawId[playerid] = CreateCurrentPageTextDraw(playerid, DIALOG_WIDTH - 50.0, DIALOG_BASE_Y + 15.0);
  174. gNextButtonTextDrawId[playerid] = CreatePlayerDialogButton(playerid, DIALOG_WIDTH - 30.0, DIALOG_BASE_Y+DIALOG_HEIGHT+100.0, 50.0, 16.0, NEXT_TEXT);
  175. gPrevButtonTextDrawId[playerid] = CreatePlayerDialogButton(playerid, DIALOG_WIDTH - 90.0, DIALOG_BASE_Y+DIALOG_HEIGHT+100.0, 50.0, 16.0, PREV_TEXT);
  176. ShowPlayerModelPreviews(playerid);
  177. UpdatePageTextDraw(playerid);
  178. }
  179. //------------------------------------------------
  180. DestroySelectionMenu(playerid)
  181. {
  182. DestroyPlayerModelPreviews(playerid);
  183. PlayerTextDrawDestroy(playerid, gHeaderTextDrawId[playerid]);
  184. PlayerTextDrawDestroy(playerid, gBackgroundTextDrawId[playerid]);
  185. PlayerTextDrawDestroy(playerid, gCurrentPageTextDrawId[playerid]);
  186. PlayerTextDrawDestroy(playerid, gNextButtonTextDrawId[playerid]);
  187. PlayerTextDrawDestroy(playerid, gPrevButtonTextDrawId[playerid]);
  188. gHeaderTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  189. gBackgroundTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  190. gCurrentPageTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  191. gNextButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  192. gPrevButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  193. }
  194. //------------------------------------------------
  195. SpawnVehicle_InfrontOfPlayer(playerid, vehiclemodel, color1, color2)
  196. {
  197. new Float:x,Float:y,Float:z;
  198. new Float:facing;
  199. new Float:distance;
  200. GetPlayerPos(playerid, x, y, z);
  201. GetPlayerFacingAngle(playerid, facing);
  202. new Float:size_x,Float:size_y,Float:size_z;
  203. GetVehicleModelInfo(vehiclemodel, VEHICLE_MODEL_INFO_SIZE, size_x, size_y, size_z);
  204. distance = size_x + 0.5;
  205. x += (distance * floatsin(-facing, degrees));
  206. y += (distance * floatcos(-facing, degrees));
  207. facing += 90.0;
  208. if(facing > 360.0) facing -= 360.0;
  209. return CreateVehicle(vehiclemodel, x, y, z + (size_z * 0.25), facing, color1, color2, -1);
  210. }
  211. //------------------------------------------------
  212. SpawnObject_InfrontOfPlayer(playerid, model)
  213. {
  214. new Float:x,Float:y,Float:z;
  215. new Float:facing;
  216. new Float:distance;
  217. GetPlayerPos(playerid, x, y, z);
  218. GetPlayerFacingAngle(playerid, facing);
  219. distance = 5.0;
  220. x += (distance * floatsin(-facing, degrees));
  221. y += (distance * floatcos(-facing, degrees));
  222. facing += 90.0;
  223. if(facing > 360.0) facing -= 360.0;
  224. return CreateObject(model, x, y, z, 0.0, 0.0, 0.0, 300.0);
  225. }
  226. //------------------------------------------------
  227. HandlePlayerItemSelection(playerid, selecteditem)
  228. {
  229. if(gSelectionItemsTag[playerid][selecteditem] >= 0 && gSelectionItemsTag[playerid][selecteditem] < 319) {
  230. SetPlayerSkin(playerid, gSelectionItemsTag[playerid][selecteditem]);
  231. return;
  232. }
  233. if(gSelectionItemsTag[playerid][selecteditem] >= 400 && gSelectionItemsTag[playerid][selecteditem] < 612) {
  234. // In this case we're spawning a vehicle for them
  235. SpawnVehicle_InfrontOfPlayer(playerid, gSelectionItemsTag[playerid][selecteditem], -1, -1);
  236. return;
  237. }
  238. if(gSelectionItemsTag[playerid][selecteditem] > 615) {
  239. new objectid = SpawnObject_InfrontOfPlayer(playerid, gSelectionItemsTag[playerid][selecteditem]);
  240. EditObject(playerid, objectid);
  241. return;
  242. }
  243. }
  244. //------------------------------------------------
  245. public OnPlayerConnect(playerid)
  246. {
  247. // Init all of the textdraw related globals
  248. gHeaderTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  249. gBackgroundTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  250. gCurrentPageTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  251. gNextButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  252. gPrevButtonTextDrawId[playerid] = PlayerText:INVALID_TEXT_DRAW;
  253. new x=0;
  254. while(x != SELECTION_ITEMS) {
  255. gSelectionItems[playerid][x] = PlayerText:INVALID_TEXT_DRAW;
  256. x++;
  257. }
  258. gItemAt[playerid] = 0;
  259. return 1; // Allow other scripts to keep processing OnPlayerConnect
  260. }
  261. //-------------------------------------------
  262. // Even though only Player* textdraws are used in this script,
  263. // OnPlayerClickTextDraw is still required to handle ESC
  264. public OnPlayerClickTextDraw(playerid, Text:clickedid)
  265. {
  266. if(GetPVarInt(playerid, "ospawner_active") == 0) return 0;
  267. // Handle: They cancelled (with ESC)
  268. if(clickedid == Text:INVALID_TEXT_DRAW) {
  269. DestroySelectionMenu(playerid);
  270. SetPVarInt(playerid, "ospawner_active", 0);
  271. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  272. return 1;
  273. }
  274. return 0;
  275. }
  276. //------------------------------------------------
  277. public OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid)
  278. {
  279. if(GetPVarInt(playerid, "ospawner_active") == 0) return 0;
  280. new curpage = GetPVarInt(playerid, "ospawner_page");
  281. // Handle: next button
  282. if(playertextid == gNextButtonTextDrawId[playerid]) {
  283. if(curpage < (GetNumberOfPages() - 1)) {
  284. SetPVarInt(playerid, "ospawner_page", curpage + 1);
  285. ShowPlayerModelPreviews(playerid);
  286. UpdatePageTextDraw(playerid);
  287. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  288. } else {
  289. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  290. }
  291. return 1;
  292. }
  293. // Handle: previous button
  294. if(playertextid == gPrevButtonTextDrawId[playerid]) {
  295. if(curpage > 0) {
  296. SetPVarInt(playerid, "ospawner_page", curpage - 1);
  297. ShowPlayerModelPreviews(playerid);
  298. UpdatePageTextDraw(playerid);
  299. PlayerPlaySound(playerid, 1084, 0.0, 0.0, 0.0);
  300. } else {
  301. PlayerPlaySound(playerid, 1085, 0.0, 0.0, 0.0);
  302. }
  303. return 1;
  304. }
  305. // Search in the array of textdraws used for the items
  306. new x=0;
  307. while(x != SELECTION_ITEMS) {
  308. if(playertextid == gSelectionItems[playerid][x]) {
  309. DestroySelectionMenu(playerid);
  310. CancelSelectTextDraw(playerid);
  311. HandlePlayerItemSelection(playerid, x);
  312. PlayerPlaySound(playerid, 1083, 0.0, 0.0, 0.0);
  313. SetPVarInt(playerid, "ospawner_active", 0);
  314. return 1;
  315. }
  316. x++;
  317. }
  318. return 0;
  319. }
  320. //------------------------------------------------
  321. public OnPlayerCommandText(playerid, cmdtext[])
  322. {
  323. new cmd[256+1];
  324. new idx;
  325. if(!IsPlayerAdmin(playerid)) return 0;
  326. cmd = strtok(cmdtext, idx);
  327. if(strcmp("/ospawner", cmd, true) == 0)
  328. {
  329. // If there was a previously created selection menu, destroy it
  330. DestroySelectionMenu(playerid);
  331. SetPVarInt(playerid, "ospawner_active", 1);
  332. SetPVarInt(playerid, "ospawner_page", 1);
  333. CreateSelectionMenu(playerid);
  334. SelectTextDraw(playerid, 0xACCBF1FF);
  335. return 1;
  336. }
  337. return 0;
  338. }
  339. //------------------------------------------------