yom_buttons.pwn 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /*##############################################################################
  2. #########################################
  3. # #
  4. # BUTTONS - FILTERSCRIPT BY YOM #
  5. # v1.3 BETA #
  6. # Steal my work and die >:D #
  7. # #
  8. #########################################
  9. - Informations about this file:
  10. ===============================
  11. - You must #include <yom_buttons> in the scripts you want to use buttons
  12. - Copyright:
  13. ============
  14. - Yom's Scripts Factory � �.
  15. - You can use this script and distribute it but,
  16. - You WILL NOT sell it or tell it's your own work.
  17. - Versions changes:
  18. ===================
  19. - 1.0 : Initial release.
  20. - 1.1 : Small tweaks here and there.
  21. - 1.2 : Removed: rX and rY parameters (was useless, for me anyway)
  22. Changed: rZ parameter is now named Angle
  23. Changed: CreateButton now returns the objectid, not the buttonid.
  24. Added: Sets the pos of the player, so he press exactly on the button.
  25. - 1.3 : Changed again: CreateButton returns the buttonid (from 1 to MAX_BUTTONS).
  26. Changed: Player can press the button from any angle
  27. Added: more or less useful functions for use in your scripts
  28. Added: sound
  29. Added: button placer (if debug enabled, type /button)
  30. THIS IS A BETA VERSION, PLEASE DON'T BE A BASTARD, AND REPORT BUGS/PROBLEMS!
  31. ##############################################################################*/
  32. /*################################ CONFIGURATION #############################*/
  33. //max buttons that can be created.
  34. #define MAX_BUTTONS 200
  35. //this is the distance max for detecting buttons. If the player is at this
  36. //distance, or less, of a button, he will press this button.
  37. #define MAX_DISTANCE 1.3
  38. //this is the object modelid used for buttons.
  39. //i'm asking for nice objects, if you know some that can be used as buttons, tell me!
  40. #define OBJECT 2886
  41. //comment this line to disable the sound, or change the number for another sound
  42. //don't forget that you can do whatever you want in OnPlayerPressButton
  43. #define SOUND 1083
  44. //comment this line to disable debug (recommended once you finished using the
  45. //buttons editor, this will make the script more efficient)
  46. //#define DEBUG
  47. /*############################################################################*/
  48. /*----------------------------------------------------------------------------*/
  49. #include <a_samp>
  50. #undef MAX_PLAYERS
  51. #define MAX_PLAYERS (700)
  52. #include <streamer>
  53. #define INVALID_BUTTON_ID -1
  54. enum BUTTON_INFOS
  55. {
  56. bool:Created,
  57. bool:Moving,
  58. bool:Usable[MAX_PLAYERS],
  59. Float:Pos[4],
  60. ObjectID
  61. }
  62. new ButtonInfo[MAX_BUTTONS+1][BUTTON_INFOS];
  63. #if defined DEBUG
  64. enum PLAYER_INFOS
  65. {
  66. Float:MSpeed,
  67. SelectedButton,
  68. TimerID
  69. }
  70. new PlayerInfo[MAX_PLAYERS][PLAYER_INFOS];
  71. new String[128];
  72. #endif
  73. /*----------------------------------------------------------------------------*/
  74. /*----------------------------------------------------------------------------*/
  75. Float:Distance3D(Float:PointA[], Float:PointB[], bool:sqrt = true)
  76. {
  77. new Float:Dist[4];
  78. for (new i = 0; i < 3; i++)
  79. {
  80. Dist[i] = PointA[i] - PointB[i];
  81. Dist[i] *= Dist[i];
  82. }
  83. Dist[3] = Dist[0] + Dist[1] + Dist[2];
  84. return sqrt ? floatsqroot(Dist[3]) : Dist[3];
  85. }
  86. /*----------------------------------------------------------------------------*/
  87. /*----------------------------------------------------------------------------*/
  88. Float:Angle2D(Float:PointA[], Float:PointB[])
  89. {
  90. new bool:A_LS_B[2], Float:Dist[2], Float:Angle;
  91. for (new i = 0; i < 2; i++)
  92. {
  93. A_LS_B[i] = PointA[i] < PointB[i];
  94. Dist[i] = A_LS_B[i] ? PointB[i] - PointA[i] : PointA[i] - PointB[i];
  95. }
  96. Angle = atan2(Dist[1],Dist[0]);
  97. Angle = A_LS_B[0] ? 270.0 + Angle : 90.0 - Angle;
  98. Angle = A_LS_B[1] ? Angle : 180.0 - Angle;
  99. return Angle;
  100. }
  101. /*----------------------------------------------------------------------------*/
  102. /*----------------------------------------------------------------------------*/
  103. GetClosestButton(Float:Point[], &Float:Distance = 0.0)
  104. {
  105. new Closest = INVALID_BUTTON_ID, Float:Distance2 = 100000.0;
  106. for (new buttonid = 1, highest = FS_GetHighestButtonID(); buttonid <= highest; buttonid ++)
  107. {
  108. if (ButtonInfo[buttonid][Created])
  109. {
  110. Distance = Distance3D(Point, ButtonInfo[buttonid][Pos]);
  111. if (Distance < Distance2)
  112. {
  113. Distance2 = Distance;
  114. Closest = buttonid;
  115. }
  116. }
  117. }
  118. Distance = Distance2;
  119. return Closest;
  120. }
  121. /*----------------------------------------------------------------------------*/
  122. /*----------------------------------------------------------------------------*/
  123. forward FS_CreateButton(Float:X, Float:Y, Float:Z, Float:Angle, VW);
  124. public FS_CreateButton(Float:X, Float:Y, Float:Z, Float:Angle, VW)
  125. {
  126. new buttonid;
  127. for(buttonid = 1; buttonid <= MAX_BUTTONS; buttonid ++)
  128. if (!ButtonInfo[buttonid][Created])
  129. break;
  130. ButtonInfo[buttonid][ObjectID] = CreateDynamicObject(OBJECT,X,Y,Z,0.0,0.0,Angle, VW);
  131. ButtonInfo[buttonid][Pos][0] = X;
  132. ButtonInfo[buttonid][Pos][1] = Y;
  133. ButtonInfo[buttonid][Pos][2] = Z;
  134. ButtonInfo[buttonid][Pos][3] = Angle;
  135. ButtonInfo[buttonid][Moving] = false;
  136. ButtonInfo[buttonid][Created] = true;
  137. for (new playerid = 0; playerid < MAX_PLAYERS; playerid ++)
  138. ButtonInfo[buttonid][Usable][playerid] = true;
  139. return buttonid;
  140. }
  141. /*----------------------------------------------------------------------------*/
  142. /*----------------------------------------------------------------------------*/
  143. forward FS_DestroyButton(buttonid);
  144. public FS_DestroyButton(buttonid)
  145. {
  146. if (FS_IsValidButton(buttonid))
  147. {
  148. CallRemoteFunction("OnButtonDestroyed", "i", buttonid);
  149. ButtonInfo[buttonid][Created] = false;
  150. DestroyDynamicObject(ButtonInfo[buttonid][ObjectID]);
  151. }
  152. }
  153. /*----------------------------------------------------------------------------*/
  154. /*----------------------------------------------------------------------------*/
  155. forward FS_SetButtonPos(buttonid, Float:X, Float:Y, Float:Z, Float:Angle);
  156. public FS_SetButtonPos(buttonid, Float:X, Float:Y, Float:Z, Float:Angle)
  157. {
  158. if (FS_IsValidButton(buttonid))
  159. {
  160. new objectid = ButtonInfo[buttonid][ObjectID];
  161. SetDynamicObjectPos(objectid, X, Y, Z);
  162. SetDynamicObjectRot(objectid, 0.0, 0.0, Angle);
  163. ButtonInfo[buttonid][Pos][0] = X;
  164. ButtonInfo[buttonid][Pos][1] = Y;
  165. ButtonInfo[buttonid][Pos][2] = Z;
  166. ButtonInfo[buttonid][Pos][3] = Angle;
  167. }
  168. }
  169. /*----------------------------------------------------------------------------*/
  170. /*----------------------------------------------------------------------------*/
  171. forward FS_MoveButton(buttonid, Float:X, Float:Y, Float:Z, Float:Speed);
  172. public FS_MoveButton(buttonid, Float:X, Float:Y, Float:Z, Float:Speed)
  173. {
  174. if (FS_IsValidButton(buttonid))
  175. {
  176. MoveDynamicObject(ButtonInfo[buttonid][ObjectID], X, Y, Z, Speed);
  177. ButtonInfo[buttonid][Moving] = true;
  178. ButtonInfo[buttonid][Pos][0] = X;
  179. ButtonInfo[buttonid][Pos][1] = Y;
  180. ButtonInfo[buttonid][Pos][2] = Z;
  181. }
  182. }
  183. /*----------------------------------------------------------------------------*/
  184. /*----------------------------------------------------------------------------*/
  185. forward FS_StopButton(buttonid);
  186. public FS_StopButton(buttonid)
  187. {
  188. if (FS_IsValidButton(buttonid))
  189. StopDynamicObject(ButtonInfo[buttonid][ObjectID]);
  190. }
  191. /*----------------------------------------------------------------------------*/
  192. /*----------------------------------------------------------------------------*/
  193. forward bool:FS_IsValidButton(buttonid);
  194. public bool:FS_IsValidButton(buttonid)
  195. {
  196. return (buttonid <= MAX_BUTTONS && ButtonInfo[buttonid][Created]);
  197. }
  198. /*----------------------------------------------------------------------------*/
  199. /*----------------------------------------------------------------------------*/
  200. forward FS_GetHighestButtonID();
  201. public FS_GetHighestButtonID()
  202. {
  203. for (new buttonid = MAX_BUTTONS; buttonid > 0; buttonid --)
  204. if (ButtonInfo[buttonid][Created])
  205. return buttonid;
  206. return INVALID_BUTTON_ID;
  207. }
  208. /*----------------------------------------------------------------------------*/
  209. /*----------------------------------------------------------------------------*/
  210. forward FS_GetButtonObjectID(buttonid);
  211. public FS_GetButtonObjectID(buttonid)
  212. {
  213. return FS_IsValidButton(buttonid) ? ButtonInfo[buttonid][ObjectID] : INVALID_OBJECT_ID;
  214. }
  215. /*----------------------------------------------------------------------------*/
  216. /*----------------------------------------------------------------------------*/
  217. forward FS_GetObjectButtonID(objectid);
  218. public FS_GetObjectButtonID(objectid)
  219. {
  220. for (new buttonid = 1, highest = FS_GetHighestButtonID(); buttonid <= highest; buttonid ++)
  221. if (ButtonInfo[buttonid][Created] && ButtonInfo[buttonid][ObjectID] == objectid)
  222. return buttonid;
  223. return INVALID_BUTTON_ID;
  224. }
  225. /*----------------------------------------------------------------------------*/
  226. /*----------------------------------------------------------------------------*/
  227. forward FS_PrintButtonsInfos();
  228. public FS_PrintButtonsInfos()
  229. {
  230. print
  231. (
  232. "\n \
  233. ���������������������������������������������������������Ŀ\n \
  234. � Buttons Informations �\n \
  235. ���������������������������������������������������������Ĵ\n \
  236. �ButtonID�ObjectID� X � Y � Z � A �\n \
  237. ���������������������������������������������������������Ĵ"
  238. );
  239. for (new buttonid = 1; buttonid <= MAX_BUTTONS; buttonid ++)
  240. {
  241. if (ButtonInfo[buttonid][Created])
  242. {
  243. printf
  244. (
  245. " �%8d�%8d�%6.2f�%6.2f�%6.2f�%6.2f�",
  246. buttonid,
  247. ButtonInfo[buttonid][ObjectID],
  248. ButtonInfo[buttonid][Pos][0],
  249. ButtonInfo[buttonid][Pos][1],
  250. ButtonInfo[buttonid][Pos][2],
  251. ButtonInfo[buttonid][Pos][3]
  252. );
  253. }
  254. }
  255. print(" �����������������������������������������������������������\n");
  256. }
  257. /*----------------------------------------------------------------------------*/
  258. /*----------------------------------------------------------------------------*/
  259. forward Float:FS_GetDistanceToButton(buttonid, Float:X, Float:Y, Float:Z);
  260. public Float:FS_GetDistanceToButton(buttonid, Float:X, Float:Y, Float:Z)
  261. {
  262. if (FS_IsValidButton(buttonid))
  263. {
  264. new Float:Point[3];
  265. Point[0] = X;
  266. Point[1] = Y;
  267. Point[2] = Z;
  268. return Distance3D(Point, ButtonInfo[buttonid][Pos]);
  269. }
  270. return -1.0;
  271. }
  272. /*----------------------------------------------------------------------------*/
  273. /*----------------------------------------------------------------------------*/
  274. forward FS_TeleportPlayerToButton(playerid, buttonid);
  275. public FS_TeleportPlayerToButton(playerid, buttonid)
  276. {
  277. if (FS_IsValidButton(buttonid) && !ButtonInfo[buttonid][Moving])
  278. {
  279. new Float:Angle = ButtonInfo[buttonid][Pos][3];
  280. SetPlayerPos
  281. (
  282. playerid,
  283. ButtonInfo[buttonid][Pos][0] - (0.65 * floatsin(-Angle,degrees)),
  284. ButtonInfo[buttonid][Pos][1] - (0.65 * floatcos(-Angle,degrees)),
  285. ButtonInfo[buttonid][Pos][2] - 0.63
  286. );
  287. SetPlayerFacingAngle(playerid, -Angle);
  288. SetCameraBehindPlayer(playerid);
  289. }
  290. }
  291. /*----------------------------------------------------------------------------*/
  292. /*----------------------------------------------------------------------------*/
  293. forward FS_ToggleButtonEnabledForPlayer(playerid, buttonid, bool:enabled);
  294. public FS_ToggleButtonEnabledForPlayer(playerid, buttonid, bool:enabled)
  295. {
  296. if (FS_IsValidButton(buttonid))
  297. ButtonInfo[buttonid][Usable][playerid] = enabled;
  298. }
  299. /*----------------------------------------------------------------------------*/
  300. /*----------------------------------------------------------------------------*/
  301. forward FS_ToggleButtonEnabled(buttonid, bool:enabled);
  302. public FS_ToggleButtonEnabled(buttonid, bool:enabled)
  303. {
  304. if (FS_IsValidButton(buttonid))
  305. for (new playerid = 0; playerid < MAX_PLAYERS; playerid ++)
  306. ButtonInfo[buttonid][Usable][playerid] = enabled;
  307. }
  308. /*----------------------------------------------------------------------------*/
  309. /*----------------------------------------------------------------------------*/
  310. forward OnPlayerPressButton_Delay(playerid, buttonid);
  311. public OnPlayerPressButton_Delay(playerid, buttonid)
  312. {
  313. #if defined SOUND
  314. PlayerPlaySound(playerid, SOUND, 0.0, 0.0, 0.0);
  315. #endif
  316. CallRemoteFunction("OnPlayerPressButton", "ii", playerid, buttonid);
  317. }
  318. /*----------------------------------------------------------------------------*/
  319. /*----------------------------------------------------------------------------*/
  320. public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
  321. {
  322. if (GetPlayerState(playerid) == PLAYER_STATE_ONFOOT)
  323. {
  324. if (newkeys & 16)
  325. {
  326. new Float:Distance, Float:Angle, Float:PlayerPos[3], buttonid;
  327. GetPlayerPos(playerid, PlayerPos[0], PlayerPos[1], PlayerPos[2]);
  328. buttonid = GetClosestButton(PlayerPos, Distance);
  329. if (buttonid != INVALID_BUTTON_ID && ButtonInfo[buttonid][Usable][playerid] && Distance <= MAX_DISTANCE)
  330. {
  331. Angle = Angle2D(PlayerPos, ButtonInfo[buttonid][Pos]);
  332. SetPlayerFacingAngle(playerid, Angle);
  333. SetPlayerPos
  334. (
  335. playerid,
  336. ButtonInfo[buttonid][Pos][0] - (0.65 * floatsin(-Angle,degrees)),
  337. ButtonInfo[buttonid][Pos][1] - (0.65 * floatcos(-Angle,degrees)),
  338. ButtonInfo[buttonid][Pos][2] - 0.63
  339. );
  340. ApplyAnimation(playerid, "HEIST9", "Use_SwipeCard", 10.0, 0, 0, 0, 0, 0);
  341. SetTimerEx("OnPlayerPressButton_Delay", 500, false, "ii", playerid, buttonid);
  342. }
  343. }
  344. #if defined DEBUG
  345. else if (newkeys & KEY_HANDBRAKE)
  346. {
  347. if (PlayerInfo[playerid][SelectedButton] != INVALID_BUTTON_ID)
  348. {
  349. switch (PlayerInfo[playerid][MSpeed])
  350. {
  351. case 1.0 : { PlayerInfo[playerid][MSpeed] = 2.5; String = "Slow"; }
  352. case 2.5 : { PlayerInfo[playerid][MSpeed] = 5.0; String = "Normal"; }
  353. case 5.0 : { PlayerInfo[playerid][MSpeed] = 15.0; String = "Fast"; }
  354. default : { PlayerInfo[playerid][MSpeed] = 1.0; String = "Very Slow"; }
  355. }
  356. format(String, sizeof(String), "~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~w~Movement speed~n~~r~%s~w~!", String);
  357. GameTextForPlayer(playerid, String, 1500, 3);
  358. }
  359. }
  360. else if (newkeys & KEY_WALK)
  361. {
  362. if (PlayerInfo[playerid][SelectedButton] != INVALID_BUTTON_ID)
  363. OnPlayerCommandText(playerid, "/button deselect");
  364. else
  365. OnPlayerCommandText(playerid, "/button select");
  366. }
  367. #endif
  368. }
  369. }
  370. /*----------------------------------------------------------------------------*/
  371. /*----------------------------------------------------------------------------*/
  372. public OnObjectMoved(objectid)
  373. {
  374. new buttonid = FS_GetObjectButtonID(objectid);
  375. if (buttonid != INVALID_BUTTON_ID)
  376. {
  377. new Float:ObjectPos[3];
  378. GetObjectPos(objectid, ObjectPos[0], ObjectPos[1], ObjectPos[2]);
  379. ButtonInfo[buttonid][Pos][0] = ObjectPos[0];
  380. ButtonInfo[buttonid][Pos][1] = ObjectPos[1];
  381. ButtonInfo[buttonid][Pos][2] = ObjectPos[2];
  382. ButtonInfo[buttonid][Moving] = false;
  383. CallRemoteFunction("OnButtonMoved", "i", buttonid);
  384. }
  385. }
  386. /*----------------------------------------------------------------------------*/
  387. /*----------------------------------------------------------------------------*/
  388. public OnPlayerConnect(playerid)
  389. {
  390. #if defined DEBUG
  391. if (PlayerInfo[playerid][SelectedButton] != INVALID_BUTTON_ID)
  392. {
  393. PlayerInfo[playerid][SelectedButton] = INVALID_BUTTON_ID;
  394. PlayerInfo[playerid][MSpeed] = 5.0;
  395. KillTimer(PlayerInfo[playerid][TimerID]);
  396. }
  397. #endif
  398. ApplyAnimation(playerid, "HEIST9", "Use_SwipeCard", 10.0, 0, 0, 0, 0, 0);
  399. return 1;
  400. }
  401. /*----------------------------------------------------------------------------*/
  402. /*----------------------------------------------------------------------------*/
  403. public OnGameModeInit()
  404. {
  405. #if defined DEBUG
  406. FS_PrintButtonsInfos();
  407. #endif
  408. return true;
  409. }
  410. /*----------------------------------------------------------------------------*/
  411. /*----------------------------------------------------------------------------*/
  412. public OnGameModeExit()
  413. {
  414. #if defined DEBUG
  415. FS_PrintButtonsInfos();
  416. #endif
  417. for (new buttonid = 1; buttonid <= MAX_BUTTONS; buttonid ++)
  418. if (ButtonInfo[buttonid][Created])
  419. FS_DestroyButton(buttonid);
  420. return true;
  421. }
  422. /*----------------------------------------------------------------------------*/
  423. /*----------------------------------------------------------------------------*/
  424. #if defined DEBUG
  425. argpos(const string[], idx = 0, sep = ' ')
  426. {
  427. for(new i = idx, j = strlen(string); i < j; i++)
  428. if (string[i] == sep && string[i+1] != sep)
  429. return i+1;
  430. return -1;
  431. }
  432. public OnPlayerCommandText(playerid, cmdtext[])
  433. {
  434. if (strlen(cmdtext) > 50)
  435. {
  436. SendClientMessage(playerid, 0xFF0000FF, "Invalid command length (exceeding 50 characters)");
  437. return true;
  438. }
  439. if(!strcmp(cmdtext, "/button", .length = 7))
  440. {
  441. if (!IsPlayerAdmin(playerid))
  442. return true;
  443. new arg1 = argpos(cmdtext);
  444. if (!cmdtext[arg1])
  445. {
  446. SendClientMessage(playerid, 0xFF0000FF, "Button Editor's commands:");
  447. SendClientMessage(playerid, 0xFFFFFFFF, "\"/button create\" - Create a button at your position, then type \"/button select\" to move this button.");
  448. SendClientMessage(playerid, 0xFFFFFFFF, "\"/button select <opt:buttonid>\" - If you don't use the optional parameter, it will select the closest button.");
  449. SendClientMessage(playerid, 0xFFFFFFFF, "\"/button save <opt:comment>\" - Save the positions of the selected button, optionally with a short comment.");
  450. SendClientMessage(playerid, 0xFFFFFFFF, "\"/button deselect\" - Deselect the selected button, this stops the editing mode.");
  451. SendClientMessage(playerid, 0xFF0000FF, "Button Editor's keys:");
  452. SendClientMessage(playerid, 0xFFFFFFFF, "Use Directional key to move the selected button forward, backward, to the left and to the right.");
  453. SendClientMessage(playerid, 0xFFFFFFFF, "Use Look Behind + Left or Right to rotate the selected button.");
  454. SendClientMessage(playerid, 0xFFFFFFFF, "Use Secondary Fire to change the movement speed.");
  455. SendClientMessage(playerid, 0xFFFFFFFF, "Use Walk to toggle Deselect/Select closest button.");
  456. return true;
  457. }
  458. else if (!strcmp(cmdtext[arg1], "create", .length = 6))
  459. {
  460. new Float:PlayerPos[4], buttonid;
  461. GetPlayerPos(playerid, PlayerPos[0], PlayerPos[1], PlayerPos[2]);
  462. GetPlayerFacingAngle(playerid, PlayerPos[3]);
  463. buttonid = FS_CreateButton(PlayerPos[0],PlayerPos[1],PlayerPos[2] + 0.63,PlayerPos[3]);
  464. format(String, sizeof(String), "Buttonid %d created! Select it with \"/button select\"", buttonid);
  465. SendClientMessage(playerid, 0x00FF00FF, String);
  466. return true;
  467. }
  468. else if (!strcmp(cmdtext[arg1], "select", .length = 6))
  469. {
  470. new arg2 = argpos(cmdtext, arg1),
  471. buttonid;
  472. if (PlayerInfo[playerid][SelectedButton] != INVALID_BUTTON_ID)
  473. KillTimer(PlayerInfo[playerid][TimerID]);
  474. if (!cmdtext[arg2])
  475. {
  476. new Float:PlayerPos[3];
  477. GetPlayerPos(playerid, PlayerPos[0], PlayerPos[1], PlayerPos[2]);
  478. buttonid = GetClosestButton(PlayerPos);
  479. if (buttonid == INVALID_BUTTON_ID)
  480. SendClientMessage(playerid, 0xFF0000FF, "Can't find a button! You may need to create one!");
  481. else
  482. {
  483. PlayerInfo[playerid][SelectedButton] = buttonid;
  484. PlayerInfo[playerid][TimerID] = SetTimerEx("ButtonEditor_Timer", 50, true, "ii", playerid, PlayerInfo[playerid][SelectedButton]);
  485. TogglePlayerControllable(playerid, false);
  486. format(String, sizeof(String), "Buttonid %d selected! Once you placed it where you want, save it with \"/button save <comment>\"", buttonid);
  487. SendClientMessage(playerid, 0x00FF00FF, String);
  488. }
  489. }
  490. else
  491. {
  492. buttonid = strval(cmdtext[arg2]);
  493. if (FS_IsValidButton(buttonid))
  494. {
  495. PlayerInfo[playerid][SelectedButton] = buttonid;
  496. PlayerInfo[playerid][TimerID] = SetTimerEx("ButtonEditor_Timer", 50, true, "ii", playerid, PlayerInfo[playerid][SelectedButton]);
  497. TogglePlayerControllable(playerid, false);
  498. format(String, sizeof(String), "Buttonid %d selected! Once you placed it where you want, save it with \"/button save\"", buttonid);
  499. SendClientMessage(playerid, 0x00FF00FF, String);
  500. }
  501. else
  502. SendClientMessage(playerid, 0xFF0000FF, "This buttonid is invalid!");
  503. }
  504. return true;
  505. }
  506. else if (!strcmp(cmdtext[arg1], "save", .length = 4))
  507. {
  508. new arg2 = argpos(cmdtext, arg1),
  509. buttonid = PlayerInfo[playerid][SelectedButton];
  510. if (buttonid != INVALID_BUTTON_ID)
  511. {
  512. new File:savedbuttons_file = fopen("savedbuttons.txt", io_append);
  513. if (!cmdtext[arg2])
  514. {
  515. format
  516. (
  517. String,
  518. sizeof(String),
  519. "CreateButton(%.2f, %.2f, %.2f, %.1f);\r\n",
  520. ButtonInfo[buttonid][Pos][0],
  521. ButtonInfo[buttonid][Pos][1],
  522. ButtonInfo[buttonid][Pos][2],
  523. float(floatround(ButtonInfo[buttonid][Pos][3])%360)
  524. );
  525. }
  526. else
  527. {
  528. format
  529. (
  530. String,
  531. sizeof(String),
  532. "CreateButton(%.2f, %.2f, %.2f, %.1f); // %s\r\n",
  533. ButtonInfo[buttonid][Pos][0],
  534. ButtonInfo[buttonid][Pos][1],
  535. ButtonInfo[buttonid][Pos][2],
  536. float(floatround(ButtonInfo[buttonid][Pos][3])%360),
  537. cmdtext[arg2]
  538. );
  539. }
  540. fwrite(savedbuttons_file,String);
  541. fclose(savedbuttons_file);
  542. SendClientMessage(playerid, 0x00FF00FF, "Button's informations saved in \"/scriptfiles/savedbuttons.txt\"!");
  543. }
  544. else
  545. SendClientMessage(playerid, 0xFF0000FF, "Umm..Select a button first?");
  546. return true;
  547. }
  548. else if (!strcmp(cmdtext[arg1], "deselect", .length = 6))
  549. {
  550. if (PlayerInfo[playerid][SelectedButton] != INVALID_BUTTON_ID)
  551. {
  552. format(String, sizeof(String), "Buttonid %d deselected!", PlayerInfo[playerid][SelectedButton]);
  553. SendClientMessage(playerid, 0x00FF00FF, String);
  554. PlayerInfo[playerid][SelectedButton] = INVALID_BUTTON_ID;
  555. TogglePlayerControllable(playerid, true);
  556. KillTimer(PlayerInfo[playerid][TimerID]);
  557. }
  558. else
  559. SendClientMessage(playerid, 0xFF0000FF, "Umm..Select a button first?");
  560. return true;
  561. }
  562. return false;
  563. }
  564. return false;
  565. }
  566. forward ButtonEditor_Timer(playerid, buttonid);
  567. public ButtonEditor_Timer(playerid, buttonid)
  568. {
  569. new PlayerKeys[3],
  570. Float:Move_Sin = PlayerInfo[playerid][MSpeed]/100.0 * floatsin(-ButtonInfo[buttonid][Pos][3], degrees),
  571. Float:Move_Cos = PlayerInfo[playerid][MSpeed]/100.0 * floatcos(-ButtonInfo[buttonid][Pos][3], degrees);
  572. GetPlayerKeys(playerid,PlayerKeys[0],PlayerKeys[1],PlayerKeys[2]);
  573. if (PlayerKeys[0] + PlayerKeys[1] + PlayerKeys[2] != 0 && PlayerKeys[0] != KEY_HANDBRAKE)
  574. {
  575. if (PlayerKeys[0] & 512)
  576. {
  577. if (PlayerKeys[2] == KEY_LEFT)
  578. ButtonInfo[buttonid][Pos][3] += PlayerInfo[playerid][MSpeed]/5.0;
  579. else if (PlayerKeys[2] == KEY_RIGHT)
  580. ButtonInfo[buttonid][Pos][3] -= PlayerInfo[playerid][MSpeed]/5.0;
  581. format
  582. (
  583. String,
  584. sizeof(String),
  585. "~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~w~Rotating buttonid ~r~%d ~n~~w~Angle=~r~%d",
  586. buttonid,
  587. floatround(ButtonInfo[buttonid][Pos][3]) % 360
  588. );
  589. GameTextForPlayer(playerid, String, 1500, 3);
  590. }
  591. else
  592. {
  593. if (PlayerKeys[1] == KEY_UP)
  594. {
  595. ButtonInfo[buttonid][Pos][0] += Move_Sin;
  596. ButtonInfo[buttonid][Pos][1] += Move_Cos;
  597. }
  598. else if (PlayerKeys[1] == KEY_DOWN)
  599. {
  600. ButtonInfo[buttonid][Pos][0] -= Move_Sin;
  601. ButtonInfo[buttonid][Pos][1] -= Move_Cos;
  602. }
  603. if (PlayerKeys[2] == KEY_LEFT)
  604. {
  605. ButtonInfo[buttonid][Pos][0] -= Move_Cos;
  606. ButtonInfo[buttonid][Pos][1] += Move_Sin;
  607. }
  608. else if (PlayerKeys[2] == KEY_RIGHT)
  609. {
  610. ButtonInfo[buttonid][Pos][0] += Move_Cos;
  611. ButtonInfo[buttonid][Pos][1] -= Move_Sin;
  612. }
  613. format
  614. (
  615. String,
  616. sizeof(String),
  617. "~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~w~Moving buttonid ~r~%d ~n~~w~X=~r~%.2f ~w~Y=~r~%.2f",
  618. buttonid,
  619. ButtonInfo[buttonid][Pos][0],
  620. ButtonInfo[buttonid][Pos][1]
  621. );
  622. GameTextForPlayer(playerid, String, 1500, 3);
  623. }
  624. FS_SetButtonPos
  625. (
  626. buttonid,
  627. ButtonInfo[buttonid][Pos][0],
  628. ButtonInfo[buttonid][Pos][1],
  629. ButtonInfo[buttonid][Pos][2],
  630. ButtonInfo[buttonid][Pos][3]
  631. );
  632. }
  633. }
  634. #endif
  635. /*----------------------------------------------------------------------------*/
  636. public OnPlayerEditDynamicObject(playerid, objectid, response, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz) // Calling Fix by Winterfield - Do not remove
  637. {
  638. CallRemoteFunction("OnPlayerEditGate", "iddffffff", playerid, objectid, response, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
  639. }