Robo_N1X

[SA:MP 0.3e+] Player Attached Object Editor v0.4

Nov 28th, 2015
2,226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /** PLAYER ATTACHED OBJECT EDITOR
  2.   * - Author: Robo_N1X
  3.   * - Version: 0.4
  4.   * - Date: November 2015
  5.   * - Forum Topic: http://forum.sa-mp.com/showthread.php?t=416138
  6.   */
  7. /** This Source Code Form is subject to the terms of the Mozilla Public
  8.   * License, v. 2.0. If a copy of the MPL was not distributed with this
  9.   * file, You can obtain one at http://mozilla.org/MPL/2.0/
  10.   *
  11.   * Software distributed under the License is distributed on an "AS IS" basis,
  12.   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13.   * for the specific language governing rights and limitations under the
  14.   * License.
  15.   *
  16.   * Credits & thanks to: SA-MP Team, Scott/h02, Zeex, Y_Less,
  17.   * and whoever helped or made some part of code used in this script.
  18.   */
  19. #define FILTERSCRIPT    // Mark this as a filterscript
  20. // Includes
  21. #include <a_samp>       // v0.3e+ Credits to SA-MP team
  22. #include <sscanf2>      // v2.8.1 Credits to Y_Less
  23. #include <zcmd>         // v0.3.1 Credits to Zeex
  24. // Script configurations (defines and macros)
  25. #define AOE_FILE_NAME                   "%s_pao.txt"            // Player attached object file (%s = name) located in '\scriptfiles' folder by default
  26. #define AOE_VERSION                     "0.4 - November 2015"   // Version string
  27. #define AOE_SMALLER_SAVE                true                    // Wheter the editor should skip writing default/zero value in the function argument
  28. #define MAX_ATTACHED_OBJECT_BONES       (18)                    // Not necessary to change unless there is change in SA:MP.
  29. #define MAX_ATTACHED_OBJECT_BONE_NAME   (16)                    // Max attached object bone name length
  30. #define MAX_ATTACHED_OBJECT_OFFSET      300.0                   // Max (+) attached object offset limit
  31. #define MIN_ATTACHED_OBJECT_OFFSET      -300.0                  // Min (-) attached object offset limit
  32. #define MAX_ATTACHED_OBJECT_ROTATION    360.0                   // Max (+) attached object rotation limit
  33. #define MIN_ATTACHED_OBJECT_ROTATION    -360.0                  // Min (-) attached object rotation limit
  34. #define MAX_ATTACHED_OBJECT_SIZE        100.0                   // Max (+) attached object scale limit
  35. #define MIN_ATTACHED_OBJECT_SIZE        -100.0                  // Min (-) attached object scale limit
  36. #define HexPrintFormat(%0) %0 >>> 16, %0 & 0xFFFF               // printf fix for hex (format: 0x%04x%04x) - credits to Y_Less
  37. #define strupdate(%0,%1) %0[0] = EOS, strins(%0,%1,0)           // To replace whole string
  38. // Color defines
  39. #define AOE_COLOR0      (0xFFFFFFFF) // White
  40. #define AOE_COLOR1      (0xCC0033FF) // Red
  41. #define AOE_COLOR2      (0x00CC00FF) // Green
  42. #define AOE_COLOR3      (0x0066FFFF) // Blue
  43. #define AOE_COLOR4      (0xFFFF33FF) // Yellow
  44. #define AOE_COLOR5      (0x33FFFFFF) // Cyan
  45. // Common non-format message defines
  46. #define AOE_M_ACCEPTABLE_OFFSET     "** Offset (X/Y/Z) greater than or equal to "#MAX_ATTACHED_OBJECT_OFFSET" and less than or equal to "#MIN_ATTACHED_OBJECT_OFFSET";"
  47. #define AOE_M_ACCEPTABLE_ROTATION   "** Rotation (RX/RY/RZ) greater than or equal to "#MAX_ATTACHED_OBJECT_OFFSET" and less than or equal to "#MIN_ATTACHED_OBJECT_OFFSET";"
  48. #define AOE_M_ACCEPTABLE_SCALE      "** Scale (SX/SY/SZ) greater than or equal to "#MAX_ATTACHED_OBJECT_OFFSET" and less than or equal to "#MIN_ATTACHED_OBJECT_OFFSET";"
  49. #define AOE_M_CANT_EDIT             "* Sorry, you can't use this command right now."
  50. #define AOE_M_COMMENT_INFO          "** Valid comment length is equal or less than 64 characters and only contains alphabet letter or number."
  51. #define AOE_M_COMMENT_INVALID       "* Warning: Comment contains invalid character, ignoring anyway."
  52. #define AOE_M_CREATE_CANCEL         "* You've canceled creating attached object."
  53. #define AOE_M_CREATE_FAIL           "* Failed to create attached object due to error."
  54. #define AOE_M_DELETE_ADMIN_ONLY     "* Sorry, only Server Administrator can delete player attached object(s) file."
  55. #define AOE_M_DELETE_CANCEL         "* You've canceled deleting attached object file."
  56. #define AOE_M_DELETING              "* Deleting attached object(s) file, please wait..."
  57. #define AOE_M_DIALOG_CLOSE          "* You've closed attached object editor dialog."
  58. #define AOE_M_DUPLICATE_FAIL        "* Failed to duplicate attached object due to error."
  59. #define AOE_M_DUPLICATE_INFO        "** Allows you to duplicate your existing attached object to another slot."
  60. #define AOE_M_DUPLICATE_USAGE       "* Usage: /duplicateattachedobject <FromAttachedObjectIndex> <ToAttachedObjectIndex>"
  61. #define AOE_M_EDIT_CANCEL           "* You've canceled editing attached object."
  62. #define AOE_M_EDIT_HINT_ONFOOT      "** Hint: Use {FFFFFF}~k~~PED_SPRINT~{FFFF33} key to look around."
  63. #define AOE_M_EDIT_HINT_VEHICLE     "** Hint: Use {FFFFFF}~k~~VEHICLE_ACCELERATE~{FFFF33} key to look around."
  64. #define AOE_M_EDIT_INFO             "** Allows you to adjust your attached object from specified slot with your cursor."
  65. #define AOE_M_EDIT_NOTHING          "* Sorry, you don't have any attached object to edit!"
  66. #define AOE_M_EDIT_NOTICE           "* Please finish (Save) or cancel (ESC) the edit first!"
  67. #define AOE_M_EDIT_SKIP             "* You've skipped to edit your attached object."
  68. #define AOE_M_EDIT_SKIP_INFO        "** Note: use /editattachedobject command to edit your attached object."
  69. #define AOE_M_EDIT_USAGE            "* Usage: /editattachedobject <AttachedObjectIndex>"
  70. #define AOE_M_ERROR                 "* There was an error when performing this action."
  71. #define AOE_M_FILE_CANCEL           "* You've canceled managing attached object(s) file."
  72. #define AOE_M_INVALID_COLOR         "* Sorry, you've entered invalid new color value."
  73. #define AOE_M_INVALID_XYZ           "* Sorry, you've entered invalid new value."
  74. #define AOE_M_LOADING               "* Loading attached object file, please wait..."
  75. #define AOE_M_LOADING_SET           "* Loading attached object(s) set file, please wait..."
  76. #define AOE_M_MAX_SLOT_INFO         "* You can only hold "#MAX_PLAYER_ATTACHED_OBJECTS" attached object(s) at one time, please remove some."
  77. #define AOE_M_NO_ATTACHED_OBJECT    "* Sorry, you don't have any attached object."
  78. #define AOE_M_NO_ENOUGH_SLOT        "* Sorry, you can't have more attached object(s) (Limit exceeded)."
  79. #define AOE_M_OBJECT_DATA_PRINT     "* As you're an admin, you can print this attached object properties & usage to the console."
  80. #define AOE_M_OBJECT_DATA_S_PRINT   "SERVER: Attached object properties has been printed to server console!"
  81. #define AOE_M_OVERWRITE             "* As you're an admin, you can replace an existed attached object file"
  82. #define AOE_M_PROPERTIES_CLOSE      "* You've closed your attached object properties dialog."
  83. #define AOE_M_PROPERTIES_INFO       "** Allows you to view your or another player's attached object properties."
  84. #define AOE_M_PROPERTIES_USAGE      "* Usage: /attachedobjectproperties <AttachedObjectIndex> <Optional:Player>"
  85. #define AOE_M_REFRESH_INFO          "** Allows you to load another player's attached object from specified slot."
  86. #define AOE_M_REFRESH_OWN           "* Sorry, you can't refresh your own attached object."
  87. #define AOE_M_REFRESH_USAGE         "* Usage: /refreshattachedobject <PlayerName/ID> <AttachedObjectIndex>"
  88. #define AOE_M_REFRESH_WARNING       "* Warning: You are attempting to load another player's attached object on your existing attached object index."
  89. #define AOE_M_REMOVE_ALL_CANCEL     "* You've canceled removing all your attached object(s)."
  90. #define AOE_M_REMOVE_INFO           "** Allows you to remove your attached object from specified slot."
  91. #define AOE_M_REMOVE_USAGE          "* Usage: /removeattachedobject <AttachedObjectIndex>"
  92. #define AOE_M_RESET_ADMIN_ONLY      "* Sorry, only Server Administrator can reset player's attached object editor variable."
  93. #define AOE_M_RESET_INFO            "** Allows you to reset a player's attached object editor variable(s) to its first state. Only use when needed (in rare case)"
  94. #define AOE_M_RESET_USAGE           "* Usage: /resetattachedobjecteditor <PlayerName/ID> <Optional:AttachedObjectIndex>"
  95. #define AOE_M_SAVE_ERROR            "* Error: Invalid attached object data, save canceled."
  96. #define AOE_M_SAVE_FAILED           "* Error: Invalid attached object(s) data, save canceled."
  97. #define AOE_M_SAVE_OVERWRITE        "** The attached object data on file has been overwritten (Re-Created)."
  98. #define AOE_M_SAVE_SET_ERROR        "** Error: file saving was canceled because there were no valid attached object!"
  99. #define AOE_M_SAVE_SET_OVERWRITE    "** The attached object(s) data on file has been overwritten (Re-Created)."
  100. #define AOE_M_SAVING                "* Saving attached object file, please wait..."
  101. #define AOE_M_SAVING_SET            "* Saving attached object(s) set file, please wait..."
  102. #define AOE_M_SET_BONE_INFO         "** Allows you to change your attached object bone to another bone, valid bone numbers are 1 to "#MAX_ATTACHED_OBJECT_BONE"."
  103. #define AOE_M_SET_BONE_USAGE        "* Usage: /setattachedobjectbone <AttachedObjectIndex> <BoneName/ID>"
  104. #define AOE_M_SET_COLOR1_INFO       "** Allows you to set your attached object color (Material:1) with specified parameters."
  105. #define AOE_M_SET_COLOR1_USAGE      "* Usage: /setattachedobjectmc1 <AttachedObjectIndex> <MaterialColor>"
  106. #define AOE_M_SET_COLOR2_INFO       "** Allows you to set your attached object color (Material:2) with specified parameters."
  107. #define AOE_M_SET_COLOR2_USAGE      "* Usage: /setattachedobjectmc2 <AttachedObjectIndex> <MaterialColor>"
  108. #define AOE_M_SET_COLOR_INFO        "** Allows you to set your attached object material color(s) with specified parameters."
  109. #define AOE_M_SET_COLOR_USAGE       "* Usage: /setattachedobjectmc <AttachedObjectIndex> <MaterialColor1> <MaterialColor2>"
  110. #define AOE_M_SET_MODEL_FAIL        "* Failed to change attached object model due to error."
  111. #define AOE_M_SET_MODEL_INFO        "** Allows you to change your attached object model with another model (must be valid GTA:SA/SA-MP object model)."
  112. #define AOE_M_SET_MODEL_USAGE       "* Usage: /setattachedobjectmodel <AttachedObjectIndex> <ObjectModel>"
  113. #define AOE_M_SET_OFFSET_INFO       "** Allows you to set your attached object position/offset with specified parameters."
  114. #define AOE_M_SET_OFFSET_USAGE      "* Usage: /setattachedobjectoffset <AttachedObjectIndex> <X/Y/Z> <Float:OffsetValue>"
  115. #define AOE_M_SET_ROTATION_INFO     "** Allows you to set your attached object rotation with specified parameters."
  116. #define AOE_M_SET_ROTATION_USAGE    "* Usage: /setattachedobjectrot <AttachedObjectIndex> <X/Y/Z> <Float:RotationValue>"
  117. #define AOE_M_SET_SCALE_INFO        "** Allows you to set your attached object scale/size with specified parameters."
  118. #define AOE_M_SET_SCALE_USAGE       "* Usage: /setattachedobjectscale <AttachedObjectIndex> <X/Y/Z> <Float:ScaleValue>"
  119. #define AOE_M_SET_SLOT_FAIL         "* Failed to change attached object slot due to error."
  120. #define AOE_M_SET_SLOT_INFO         "** Allows you to change your attached object slot to another slot, valid slot numbers are 0 to 9."
  121. #define AOE_M_SET_SLOT_USAGE        "* Usage: /setattachedobjectindex <OldAttachedObjectIndex> <NewAttachedObjectIndex>"
  122. #define AOE_M_TARGET_NOT_ONLINE     "* Sorry, the target player is not connected."
  123. #define AOE_M_UNDELETE_HINT         "** Hint: Leave the command parameter empty to restore last deleted object."
  124. #define AOE_M_UNDELETE_NOTHING      "* Sorry, you don't have any attached object to restore."
  125. #define AOE_M_UNDELETE_NO_PARAM     "* No parameter given, attempting to restore the last removed attached object..."
  126. #define AOE_M_UNKNOWN_DATA          "* Warning: This attached object has unknown data, please save it first to refresh the data!"
  127. #define AOE_M_VALID_NAME_INFO1      "** Valid length is greater than or equal to 1 and less than or equal to 24 characters."
  128. #define AOE_M_VALID_NAME_INFO2      "** Valid characters are: A to Z or a to z, 0 to 9 and @$()_=[] symbols for the next character."
  129. #define AOE_M_VALID_OFFSET          "** Allowed float (Offset) value is larger than "#MIN_ATTACHED_OBJECT_OFFSET" and less than "#MAX_ATTACHED_OBJECT_OFFSET"."
  130. #define AOE_M_VALID_ROTATION        "** Allowed float (Rotation) value is larger than "#MIN_ATTACHED_OBJECT_ROTATION" and less than "#MAX_ATTACHED_OBJECT_ROTATION"."
  131. #define AOE_M_VALID_SCALE           "** Allowed float (Scale) value is larger than "#MIN_ATTACHED_OBJECT_SIZE" and less than "#MAX_ATTACHED_OBJECT_SIZE"."
  132. // Common non-format gametext defines
  133. #define AOE_G_COLOR_UPDATED         "~g~Attached object color updated!"
  134. #define AOE_G_OFFSET_UPDATED        "~g~Attached object position updated!"
  135. #define AOE_G_ROTATION_UPDATED      "~g~Attached object rotation updated!"
  136. #define AOE_G_SCALE_UPDATED         "~g~Attached object size updated!"
  137. #define AOE_G_DOH                   "~y~DOH!"
  138. #define AOE_G_CANT_RESTORE          "~r~~h~Can't restore attached object!"
  139. #define AOE_G_FILE_DELETED          "~r~~h~Attached object file deleted!"
  140. #define AOE_G_FILE_EXISTED          "~r~~h~File already exists!"
  141. #define AOE_G_FILE_NOT_EXIST        "~r~~h~File does not exist!"
  142. #define AOE_G_INVALID_BONE          "~r~~h~Invalid attached object bone!"
  143. #define AOE_G_INVALID_DATA          "~r~~h~Invalid attached object data!"
  144. #define AOE_G_INVALID_FILE_NAME     "~r~~h~Invalid file name!"
  145. #define AOE_G_INVALID_MODEL         "~r~~h~Invalid object model!"
  146. #define AOE_G_INVALID_OFFSET        "~r~~h~Invalid attached object offset value!"
  147. #define AOE_G_INVALID_ROTATION      "~r~~h~Invalid attached object rotation value!"
  148. #define AOE_G_INVALID_SCALE         "~r~~h~Invalid attached object size value!"
  149. #define AOE_G_INVALID_SLOT          "~r~~h~Invalid attached object slot!"
  150. #define AOE_G_NO_ATTACHED_OBJECT    "~r~~h~Found no attached object!"
  151. #define AOE_G_NO_ENOUGH_SLOT        "~r~~h~Too many attached objects!"
  152. #define AOE_G_NO_RESTORE            "~r~~h~No attached object can be restored!"
  153. // Dialog ID defines
  154. #define AOE_D                   400         // Main Menu ID
  155. #define AOE_D_CREATE_SLOT       (AOE_D+1)
  156. #define AOE_D_CREATE_MODEL      (AOE_D+2)
  157. #define AOE_D_CREATE_BONE       (AOE_D+3)
  158. #define AOE_D_CREATE_REPLACE    (AOE_D+4)
  159. #define AOE_D_CREATE_EDIT       (AOE_D+5)
  160. #define AOE_D_FILE              (AOE_D+6)
  161. #define AOE_D_LOAD              (AOE_D+7)
  162. #define AOE_D_LOAD_SLOT         (AOE_D+8)
  163. #define AOE_D_LOAD_REPLACE      (AOE_D+9)
  164. #define AOE_D_LOAD2             (AOE_D+10)
  165. #define AOE_D_SAVE_SLOT         (AOE_D+11)
  166. #define AOE_D_SAVE              (AOE_D+12)
  167. #define AOE_D_SAVE_REPLACE      (AOE_D+13)
  168. #define AOE_D_SAVE2             (AOE_D+14)
  169. #define AOE_D_SAVE2_REPLACE     (AOE_D+15)
  170. #define AOE_D_DELETE            (AOE_D+16)
  171. #define AOE_D_EDIT_SLOT         (AOE_D+17)
  172. #define AOE_D_EDIT              (AOE_D+18)
  173. #define AOE_D_EDIT_PROPERTIES   (AOE_D+19)
  174. #define AOE_D_SET_SLOT          (AOE_D+20)
  175. #define AOE_D_SET_SLOT_REPLACE  (AOE_D+21)
  176. #define AOE_D_SET_MODEL         (AOE_D+22)
  177. #define AOE_D_SET_BONE          (AOE_D+23)
  178. #define AOE_D_EDIT_XYZ          (AOE_D+24)
  179. #define AOE_D_EDIT_COLOR        (AOE_D+25)
  180. #define AOE_D_PROPERTIES        (AOE_D+26)
  181. #define AOE_D_DUPLICATE_SLOT    (AOE_D+27)
  182. #define AOE_D_DUPLICATE_REPLACE (AOE_D+28)
  183. #define AOE_D_REMOVE_ALL        (AOE_D+29)
  184. #define AOE_D_REFRESH           (AOE_D+30)
  185. #define AOE_D_REFRESH_REPLACE   (AOE_D+31)
  186. // Dialog class defines
  187. #define AOE_C                   (0)
  188. #define AOE_C_FILE              (1)
  189. #define AOE_C_EDIT              (2)
  190. #define AOE_C_HELP              (3)
  191. #define AOE_C_ABOUT             (4)
  192. #define AOE_C_SLOT_EMPTY        (5)
  193. #define AOE_C_SLOT_USED         (6)
  194. #define AOE_C_SLOT_ALL          (7)
  195. #define AOE_C_REFRESH           (8)
  196. #define AOE_C_MODEL             (9)
  197. #define AOE_C_BONE              (10)
  198. #define AOE_C_CREATE_FINAL      (11)
  199. #define AOE_C_REMOVE_ALL        (12)
  200. #define AOE_C_PROPERTIES        (13)
  201. #define AOE_C_EDIT_PROPERTIES   (14)
  202. #define AOE_C_EDIT_XYZ          (15)
  203. #define AOE_C_EDIT_COLOR        (16)
  204. #define AOE_C_DUPLICATE_REPLACE (17)
  205. #define AOE_C_CREATE_REPLACE    (18)
  206. #define AOE_C_SET_INDEX_REPLACE (19)
  207. #define AOE_C_REFRESH_REPLACE   (20)
  208. #define AOE_C_LOAD_REPLACE      (21)
  209. #define AOE_C_SAVE_REPLACE      (22)
  210. #define AOE_C_SAVE              (23)
  211. #define AOE_C_LOAD              (24)
  212. #define AOE_C_DELETE            (25)
  213. // Common non-format dialog title defines
  214. #define AOE_T               "Attached Object Editor"
  215. #define AOE_T_ABOUT         "About Attached Object Editor"
  216. #define AOE_T_CREATE        "Create Attached Object"
  217. #define AOE_T_CREATE_EDIT   "Create Attached Object (Edit)"
  218. #define AOE_T_DELETE        "Delete Attached Object(s) File"
  219. #define AOE_T_DUPLICATE     "Duplicate Attached Object"
  220. #define AOE_T_EDIT          "Edit Attached Object"
  221. #define AOE_T_FILE          "Manage Attached Object File"
  222. #define AOE_T_HELP          "Attached Object Editor Help"
  223. #define AOE_T_LOAD          "Load Attached Object"
  224. #define AOE_T_LOAD_SET      "Load Attached Object(s) Set"
  225. #define AOE_T_REFRESH       "Refresh Attached Object"
  226. #define AOE_T_REMOVE_ALL    "Clear All Attached Object(s)"
  227. #define AOE_T_SAVE          "Save Attached Object"
  228. #define AOE_T_SAVE_SET      "Save Attached Object(s) Set"
  229. #define AOE_T_SET_BONE      "Set Attached Object Bone"
  230. #define AOE_T_SET_INDEX     "Set Attached Object Index"
  231. #define AOE_T_SET_MODEL     "Set Attached Object Model"
  232. #define AOE_T_REPLACE       " (Replace)"
  233. // Common non-format dialog info text defines
  234. #define AOE_I_ENTER_MODEL \
  235.     "Please enter a valid GTA:SA/SA:MP object model id/number below:"
  236. #define AOE_I_LOAD_NAME \
  237.     "Please enter an valid and existing attached object file name below,\n\n"#AOE_I_VALID_NAME
  238. #define AOE_I_SAVE_NAME \
  239.     "Please enter a valid file name to save this attached object below,\n\n"#AOE_I_VALID_NAME
  240. #define AOE_I_VALID_NAME \
  241.     "Please note that valid characters are:\nA to Z or a to z, 0 to 9 and @, $, (, ), [, ], _, =\nand the length must be 1-24 characters long"
  242. // Common non-format dialog button defines
  243. #define AOE_B_BACK          "Back"
  244. #define AOE_B_CANCEL        "Cancel"
  245. #define AOE_B_CLOSE         "Close"
  246. #define AOE_B_DELETE        "Delete"
  247. #define AOE_B_DUPLICATE     "Duplicate"
  248. #define AOE_B_EDIT          "Edit"
  249. #define AOE_B_EDIT_CREATE   "Edit/Create"
  250. #define AOE_B_ENTER         "Enter"
  251. #define AOE_B_LOAD          "Load"
  252. #define AOE_B_PRINT         "Print"
  253. #define AOE_B_SAVE          "Save"
  254. #define AOE_B_SELECT        "Select"
  255. #define AOE_B_SELECT_INDEX  "Sel. Index"
  256. #define AOE_B_SELECT_MODEL  "Sel. Model"
  257. #define AOE_B_SET           "Set"
  258. #define AOE_B_SKIP          "Skip"
  259. #define AOE_B_YES           "Yes"
  260. // =============================================================================
  261. new AOE_STR[128];
  262. enum E_ATTACHED_OBJECT
  263. {
  264.     AO_STATUS, AO_MODEL_ID, AO_BONE_ID,
  265.     Float:AO_X, Float:AO_Y, Float:AO_Z,
  266.     Float:AO_RX, Float:AO_RY, Float:AO_RZ,
  267.     Float:AO_SX, Float:AO_SY, Float:AO_SZ,
  268.     hex:AO_MC1, hex:AO_MC2
  269. }
  270. new PAO[MAX_PLAYERS][MAX_PLAYER_ATTACHED_OBJECTS][E_ATTACHED_OBJECT];
  271. enum E_EDITOR_PVAR
  272. {
  273.     PAO_INDEX1, PAO_INDEX2, PAO_MODEL_ID, PAO_BONE_ID, PAO_LAST_REMOVED,
  274.     PAO_NAME[24], PAO_EDITING, PAO_TARGET
  275. }
  276. new EPV[MAX_PLAYERS][E_EDITOR_PVAR];
  277. new const AttachedObjectBones[MAX_ATTACHED_OBJECT_BONES][MAX_ATTACHED_OBJECT_BONE_NAME] =
  278. {
  279.     {"Spine"},
  280.     {"Head"},
  281.     {"Left upper arm"}, {"Right upper arm"},
  282.     {"Left hand"}, {"Right hand"},
  283.     {"Left thigh"}, {"Right thigh"},
  284.     {"Left foot"}, {"Right foot"},
  285.     {"Right calf"}, {"Left calf"},
  286.     {"Left forearm"}, {"Right forearm"},
  287.     {"Left clavicle"}, {"Right clavicle"},
  288.     {"Neck"},
  289.     {"Jaw"}
  290. };
  291. new AOSelection, AOSlot, AOModel, AOBone, Float:AOAxis, hex:AOMC,
  292.     AOTarget, pName[MAX_PLAYER_NAME], AOFileName[32+1], Float:AOFileLen, AOComment[64];
  293. forward AOE_GetPVar(playerid, varname[]);
  294. // =============================================================================
  295. public OnFilterScriptInit()
  296. {
  297.     print("  Attached Object Editor by Robo_N1X\n  -------------loading--------------\n  >> Version: "#AOE_VERSION" for SA:MP 0.3e+");
  298.     new totalAttachedObjects;
  299.     for(new i = 0; i < MAX_PLAYERS; i++)
  300.     {
  301.         if(IsPlayerConnected(i))
  302.         {
  303.             for(new x = 0; x < MAX_PLAYER_ATTACHED_OBJECTS; x++)
  304.             {
  305.                 if(IsPlayerAttachedObjectSlotUsed(i, x))
  306.                 {
  307.                     PAO[i][x][AO_STATUS] = 0;
  308.                     totalAttachedObjects++;
  309.                 }
  310.                 else AOE_UnsetValues(i, x);
  311.             }
  312.             EPV[i][PAO_LAST_REMOVED] = MAX_PLAYER_ATTACHED_OBJECTS;
  313.         }
  314.     }
  315.     printf("  >> Player attached objects count: %d", totalAttachedObjects);
  316.     return 1;
  317. }
  318.  
  319. public OnFilterScriptExit()
  320. {
  321.     print("  Attached Object Editor by Robo_N1X\n  -------------unloading------------\n  >> Version: "#AOE_VERSION" for SA:MP 0.3e+");
  322.     new totalAttachedObjects;
  323.     for(new i = 0; i < MAX_PLAYERS; i++)
  324.     {
  325.         if(IsPlayerConnected(i))
  326.         {
  327.             for(new x = 0; x < MAX_PLAYER_ATTACHED_OBJECTS; x++)
  328.             {
  329.                 totalAttachedObjects += IsPlayerAttachedObjectSlotUsed(i, x);
  330.                 if(PAO[i][x][AO_STATUS] == 1 && !IsPlayerAdmin(i))
  331.                     RemovePlayerAttachedObjectEx(i, x);
  332.             }
  333.             AOE_UnsetVars(i);
  334.         }
  335.     }
  336.     printf("  >> Player attached objects count: %d", totalAttachedObjects);
  337.     return 1;
  338. }
  339.  
  340. public OnPlayerConnect(playerid)
  341. {
  342.     for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  343.     {
  344.         if(IsPlayerAttachedObjectSlotUsed(playerid, i)) PAO[playerid][i][AO_STATUS] = 1;
  345.         else
  346.         {
  347.             RemovePlayerAttachedObject(playerid, i);
  348.             EPV[playerid][PAO_LAST_REMOVED] = MAX_PLAYER_ATTACHED_OBJECTS;
  349.         }
  350.     }
  351.     return 1;
  352. }
  353.  
  354. public OnPlayerDisconnect(playerid, reason)
  355. {
  356.     for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  357.     {
  358.         AOE_UnsetValues(playerid, i);
  359.     }
  360.     AOE_UnsetVars(playerid);
  361.     return 1;
  362. }
  363.  
  364. public OnPlayerSpawn(playerid)
  365. {
  366.     new slots;
  367.     for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  368.     {
  369.         if(PAO[playerid][i][AO_STATUS] == 1)
  370.             slots += RestorePlayerAttachedObject(playerid, i);
  371.     }
  372.     if(slots > 0)
  373.     {
  374.         format(AOE_STR, sizeof AOE_STR, "* Automatically restored your attached object(s) ({FFFFFF}Total: %d{%06x}).", slots, AOE_COLOR2 >>> 8);
  375.         SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  376.     }
  377.     return 1;
  378. }
  379. // -----------------------------------------------------------------------------
  380. CMD:attachedobjecteditor(playerid, params[])
  381. {
  382.     #pragma unused params
  383.     if(AOE_CanEdit(playerid)) AOE_ShowPlayerDialog(playerid, AOE_C, AOE_D, AOE_T, AOE_B_SELECT, AOE_B_CLOSE);
  384.     return 1;
  385. }
  386. CMD:aoe(playerid, params[]) return cmd_attachedobjecteditor(playerid, params);
  387.  
  388. CMD:removeattachedobjects(playerid, params[])
  389. {
  390.     #pragma unused params
  391.     if(AOE_CanEdit(playerid))
  392.     {
  393.         if(AOE_HasAttachedObject(playerid)) AOE_ShowPlayerDialog(playerid, AOE_C_REMOVE_ALL, AOE_D_REMOVE_ALL, AOE_T_REMOVE_ALL, AOE_B_YES, AOE_B_CANCEL);
  394.     }
  395.     return 1;
  396. }
  397. CMD:raos(playerid, params[]) return cmd_removeattachedobjects(playerid, params);
  398.  
  399. CMD:createattachedobject(playerid, params[])
  400. {
  401.     if(AOE_CanEdit(playerid))
  402.     {
  403.         if(AOE_HasFreeSlot(playerid))
  404.         {
  405.             new bonename[MAX_ATTACHED_OBJECT_BONE_NAME];
  406.             if(sscanf(params, "dD(-1)S()[16]", AOSlot, AOModel, bonename)) AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_CREATE_SLOT, AOE_T_CREATE, AOE_B_SELECT, AOE_B_CANCEL);
  407.             else
  408.             {
  409.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  410.                 {
  411.                     EPV[playerid][PAO_INDEX1] = AOSlot;
  412.                     if(IsPlayerAttachedObjectSlotUsed(playerid, AOSlot)) AOE_ShowPlayerDialog(playerid, AOE_C_CREATE_REPLACE, AOE_D_CREATE_REPLACE, AOE_T_CREATE#AOE_T_REPLACE, AOE_B_YES,AOE_B_BACK);
  413.                     else
  414.                     {
  415.                         if(AOModel == -1) AOE_ShowPlayerDialog(playerid, AOE_C_MODEL, AOE_D_CREATE_MODEL, AOE_T_CREATE, AOE_B_ENTER, AOE_B_SELECT_INDEX);
  416.                         else
  417.                         {
  418.                             if(AOE_EnteredValidModel(playerid, AOModel))
  419.                             {
  420.                                 EPV[playerid][PAO_MODEL_ID] = AOModel;
  421.                                 if(isnull(bonename)) AOE_ShowPlayerDialog(playerid, AOE_C_BONE, AOE_D_CREATE_BONE, AOE_T_CREATE, AOE_B_SELECT, AOE_B_SELECT_MODEL);
  422.                                 else
  423.                                 {
  424.                                     if(AOE_EnteredValidBone(playerid, bonename))
  425.                                     {
  426.                                         AOBone = GetAttachedObjectBone(bonename);
  427.                                         EPV[playerid][PAO_BONE_ID] = AOBone;
  428.                                         if(UpdatePlayerAttachedObjectEx(playerid, AOSlot, AOModel, AOBone))
  429.                                         {
  430.                                             format(AOE_STR, sizeof AOE_STR, "* Created attached object model %d at bone %s (%d) in slot number {FFFFFF}%d{%06x}.", AOModel, GetAttachedObjectBoneName(AOBone), AOBone, AOSlot, AOE_COLOR3 >>> 8);
  431.                                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  432.                                             format(AOE_STR, sizeof AOE_STR, "~b~Created attached object~n~~w~index number: %d~n~Model: %d ~ Bone: %d.", AOSlot, AOModel, AOBone);
  433.                                             AOE_GameTextForPlayer(playerid, AOE_STR);
  434.                                             AOE_ShowPlayerDialog(playerid, AOE_C_CREATE_FINAL, AOE_D_CREATE_EDIT, AOE_T_CREATE_EDIT, AOE_B_EDIT, AOE_B_SKIP);
  435.                                         }
  436.                                         else SendClientMessage(playerid, AOE_COLOR1, AOE_M_CREATE_FAIL);
  437.                                     }
  438.                                 }
  439.                             }
  440.                         }
  441.                     }
  442.                 }
  443.             }
  444.         }
  445.     }
  446.     return 1;
  447. }
  448.  
  449. CMD:cao(playerid, params[]) return cmd_createattachedobject(playerid, params);
  450.  
  451. CMD:editattachedobject(playerid, params[])
  452. {
  453.     new playerState = GetPlayerState(playerid);
  454.     if(EPV[playerid][PAO_EDITING] >= 1) CancelEdit(playerid);
  455.     else if(playerState == PLAYER_STATE_WASTED || playerState == PLAYER_STATE_SPECTATING)
  456.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_CANT_EDIT);
  457.     else
  458.     {
  459.         if(AOE_HasAttachedObject(playerid))
  460.         {
  461.             if(sscanf(params, "d", AOSlot))
  462.             {
  463.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_EDIT_USAGE);
  464.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_EDIT_INFO);
  465.             }
  466.             else
  467.             {
  468.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  469.                 {
  470.                     if(AOE_HasSlot(playerid, AOSlot))
  471.                     {
  472.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  473.                         EditAttachedObject(playerid, AOSlot);
  474.                         PAO[playerid][AOSlot][AO_STATUS] = 2;
  475.                         format(AOE_STR, sizeof AOE_STR, "* You're now editing your attached object at index number {FFFFFF}%d{%06x}.", AOSlot, AOE_COLOR5 >>> 8);
  476.                         SendClientMessage(playerid, AOE_COLOR5, AOE_STR);
  477.                         format(AOE_STR, sizeof AOE_STR, "~b~~h~Editing your attached object~n~~w~index number: %d", AOSlot);
  478.                         AOE_GameTextForPlayer(playerid, AOE_STR);
  479.                         if(IsValidPlayerAttachedObject(playerid, AOSlot) != 1)
  480.                         {
  481.                             SendClientMessage(playerid, AOE_COLOR1, AOE_M_UNKNOWN_DATA);
  482.                             EPV[playerid][PAO_EDITING] = 2;
  483.                         }
  484.                         else EPV[playerid][PAO_EDITING] = 1;
  485.                         if(IsPlayerInAnyVehicle(playerid)) SendClientMessage(playerid, AOE_COLOR4, AOE_M_EDIT_HINT_VEHICLE);
  486.                         else SendClientMessage(playerid, AOE_COLOR4, AOE_M_EDIT_HINT_ONFOOT);
  487.                     }
  488.                 }
  489.                 else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_USED, AOE_D_EDIT_SLOT, AOE_T_EDIT, AOE_B_EDIT_CREATE, AOE_B_CANCEL);
  490.             }
  491.         }
  492.     }
  493.     return 1;
  494. }
  495.  
  496. CMD:eao(playerid, params[]) return cmd_editattachedobject(playerid, params);
  497.  
  498. CMD:removeattachedobject(playerid, params[])
  499. {
  500.     if(AOE_CanEdit(playerid))
  501.     {
  502.         if(AOE_HasAttachedObject(playerid))
  503.         {
  504.             if(sscanf(params, "d", AOSlot))
  505.             {
  506.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_REMOVE_USAGE);
  507.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_REMOVE_INFO);
  508.             }
  509.             else
  510.             {
  511.                 if(AOSlot == MAX_PLAYER_ATTACHED_OBJECTS) cmd_removeattachedobjects(playerid, "");
  512.                 else
  513.                 {
  514.                     if(AOE_EnteredValidSlot(playerid, AOSlot))
  515.                     {
  516.                         if(AOE_HasSlot(playerid, AOSlot))
  517.                         {
  518.                             EPV[playerid][PAO_INDEX1] = AOSlot;
  519.                             if(IsValidPlayerAttachedObject(playerid, AOSlot)) format(AOE_STR, sizeof AOE_STR, "* You've removed your attached object from index number {FFFFFF}%d{%06x} (/udao to undelete last).", AOSlot, AOE_COLOR2 >>> 8);
  520.                             else format(AOE_STR, sizeof AOE_STR, "* You've removed your attached object from index number {FFFFFF}%d{%06x}.", AOSlot, AOE_COLOR2 >>> 8);
  521.                             RemovePlayerAttachedObjectEx(playerid, AOSlot);
  522.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  523.                             format(AOE_STR, sizeof AOE_STR, "~b~~h~Removed your attached object~n~~w~index number: %d", AOSlot);
  524.                             AOE_GameTextForPlayer(playerid, AOE_STR);
  525.                         }
  526.                     }
  527.                 }
  528.             }
  529.         }
  530.     }
  531.     return 1;
  532. }
  533.  
  534. CMD:rao(playerid, params[]) return cmd_removeattachedobject(playerid, params);
  535.  
  536. CMD:undeleteattachedobject(playerid, params[])
  537. {
  538.     if(AOE_CanEdit(playerid))
  539.     {
  540.         if(AOE_HasFreeSlot(playerid))
  541.         {
  542.             if(sscanf(params, "D(-1)", AOSlot))
  543.             {
  544.                 format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object index number ({FFFFFF}%s{%06x}).", params, AOE_COLOR4 >>> 8);
  545.                 SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  546.                 AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SLOT);
  547.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_UNDELETE_HINT);
  548.             }
  549.             else
  550.             {
  551.                 if(0 <= EPV[playerid][PAO_LAST_REMOVED] < MAX_PLAYER_ATTACHED_OBJECTS)
  552.                 {
  553.                     if(AOSlot == -1)
  554.                     {
  555.                         AOSlot = EPV[playerid][PAO_LAST_REMOVED];
  556.                         valstr(AOE_STR, AOSlot);
  557.                         SendClientMessage(playerid, AOE_COLOR4, AOE_M_UNDELETE_NO_PARAM);
  558.                         cmd_undeleteattachedobject(playerid, AOE_STR);
  559.                     }
  560.                     else if(IsValidAttachedObjectSlot(AOSlot))
  561.                     {
  562.                         if(IsPlayerAttachedObjectSlotUsed(playerid, AOSlot))
  563.                         {
  564.                                 format(AOE_STR, sizeof AOE_STR, "* Sorry, you can't restore your removed attached object as it was replaced with another object in that slot already (%d).", AOSlot);
  565.                                 SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  566.                                 AOE_GameTextForPlayer(playerid, AOE_G_CANT_RESTORE);
  567.                         }
  568.                         else
  569.                         {
  570.                             EPV[playerid][PAO_INDEX1] = AOSlot;
  571.                             if(RestorePlayerAttachedObject(playerid, AOSlot))
  572.                             {
  573.                                 format(AOE_STR, sizeof AOE_STR, "* You've restored your attached object from index number {FFFFFF}%d{%06x} [Model: %d|Bone: %s (%d)]", AOSlot, AOE_COLOR3 >>> 8,
  574.                                 PAO[playerid][AOSlot][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[playerid][AOSlot][AO_BONE_ID]), PAO[playerid][AOSlot][AO_BONE_ID]);
  575.                                 SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  576.                                 format(AOE_STR, sizeof AOE_STR, "~b~Restored your attached object~n~~w~index number: %d~n~Model: %d ~ Bone: %d", AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID]);
  577.                                 AOE_GameTextForPlayer(playerid, AOE_STR);
  578.                             }
  579.                             else
  580.                             {
  581.                                 format(AOE_STR, sizeof AOE_STR, "* Sorry, you can't restore your removed attached object from index number %d as it's not valid.", AOSlot);
  582.                                 SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  583.                                 AOE_GameTextForPlayer(playerid, AOE_G_CANT_RESTORE);
  584.                             }
  585.                         }
  586.                     }
  587.                     else
  588.                     {
  589.                         format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object index number ({FFFFFF}%d{%06x}).", AOSlot, AOE_COLOR4 >>> 8);
  590.                         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  591.                         AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SLOT);
  592.                         SendClientMessage(playerid, AOE_COLOR0, AOE_M_UNDELETE_HINT);
  593.                     }
  594.                 }
  595.                 else
  596.                 {
  597.                     SendClientMessage(playerid, AOE_COLOR1, AOE_M_UNDELETE_NOTHING);
  598.                     AOE_GameTextForPlayer(playerid, AOE_G_NO_RESTORE);
  599.                 }
  600.             }
  601.         }
  602.     }
  603.     return 1;
  604. }
  605.  
  606. CMD:udao(playerid, params[]) return cmd_undeleteattachedobject(playerid, params);
  607.  
  608. CMD:refreshattachedobject(playerid, params[])
  609. {
  610.     if(AOE_CanEdit(playerid))
  611.     {
  612.         if(AOE_HasFreeSlot(playerid))
  613.         {
  614.             if(sscanf(params, "uD(-1)", AOTarget, AOSlot))
  615.             {
  616.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_REFRESH_USAGE);
  617.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_REFRESH_INFO);
  618.             }
  619.             else
  620.             {
  621.                 if(AOTarget == playerid) SendClientMessage(playerid, AOE_COLOR4, AOE_M_REFRESH_OWN);
  622.                 else
  623.                 {
  624.                     if(AOTarget == INVALID_PLAYER_ID) SendClientMessage(playerid, AOE_COLOR4, AOE_M_TARGET_NOT_ONLINE);
  625.                     else
  626.                     {
  627.                         EPV[playerid][PAO_TARGET] = AOTarget;
  628.                         GetPlayerName(AOTarget, pName, sizeof pName);
  629.                         if(GetPlayerAttachedObjectsCount(AOTarget))
  630.                         {
  631.                             if(AOSlot == -1) AOE_ShowPlayerDialog(playerid, AOE_C_REFRESH, AOE_D_REFRESH, AOE_T_REFRESH, AOE_B_SELECT, AOE_B_CANCEL);
  632.                             else
  633.                             {
  634.                                 if(AOE_TargetHasSlot(playerid, AOTarget, AOSlot))
  635.                                 {
  636.                                     EPV[playerid][PAO_INDEX1] = AOSlot;
  637.                                     if(IsPlayerAttachedObjectSlotUsed(playerid, AOSlot)) AOE_ShowPlayerDialog(playerid, AOE_C_REFRESH_REPLACE, AOE_D_REFRESH_REPLACE, AOE_T_REFRESH#AOE_T_REPLACE, AOE_B_YES, AOE_B_BACK);
  638.                                     else
  639.                                     {
  640.                                         if(RefreshPlayerAttachedObject(AOTarget, playerid, AOSlot))
  641.                                         {
  642.                                             format(AOE_STR, sizeof AOE_STR, "* You've refershed %s (ID:%d)'s attached object from index number %d [Model: %d|Bone: %s (%d)].",
  643.                                             pName, AOTarget, AOSlot, PAO[AOTarget][AOSlot][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[AOTarget][AOSlot][AO_BONE_ID]), PAO[AOTarget][AOSlot][AO_BONE_ID]);
  644.                                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  645.                                             format(AOE_STR, sizeof AOE_STR, "~b~~h~Refreshed ~w~%s~b~~h~'s~n~attached object from slot ~w~%d", pName, AOSlot);
  646.                                             AOE_GameTextForPlayer(playerid, AOE_STR);
  647.                                             GetPlayerName(playerid, pName, sizeof pName);
  648.                                             format(AOE_STR, sizeof AOE_STR, "* %s (ID:%d) has refreshed your attached object from index number %d [Model: %d|Bone: %s (%d)].",
  649.                                             pName, playerid, AOSlot, PAO[AOTarget][AOSlot][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[AOTarget][AOSlot][AO_BONE_ID]), PAO[AOTarget][AOSlot][AO_BONE_ID]);
  650.                                             SendClientMessage(AOTarget, AOE_COLOR2, AOE_STR);
  651.                                             format(AOE_STR, sizeof AOE_STR, "~w~%s~b~~h~ has refreshed~n~your attached object at slot ~w~%d", pName, AOSlot);
  652.                                             AOE_GameTextForPlayer(AOTarget, AOE_STR);
  653.                                         }
  654.                                         else SendClientMessage(playerid, AOE_COLOR1, AOE_M_ERROR);
  655.                                     }
  656.                                 }
  657.                             }
  658.                         }
  659.                         else
  660.                         {
  661.                             format(AOE_STR, sizeof AOE_STR, "* Sorry, %s (ID:%d) has no attached object.", pName, AOTarget);
  662.                             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  663.                             AOE_GameTextForPlayer(playerid, AOE_G_NO_ATTACHED_OBJECT);
  664.                         }
  665.                     }
  666.                 }
  667.             }
  668.         }
  669.     }
  670.     return 1;
  671. }
  672.  
  673. CMD:rpao(playerid, params[]) return cmd_refreshattachedobject(playerid, params);
  674.  
  675. CMD:saveattachedobject(playerid, params[])
  676. {
  677.     if(AOE_CanEdit(playerid))
  678.     {
  679.         if(AOE_HasAttachedObject(playerid))
  680.         {
  681.             if(sscanf(params,"dS()[25]S()[64]", AOSlot, AOFileName, AOComment)) AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_ALL, AOE_D_SAVE_SLOT, AOE_T_SAVE, AOE_B_SELECT, AOE_B_BACK);
  682.             else
  683.             {
  684.                 if(AOSlot == MAX_PLAYER_ATTACHED_OBJECTS)
  685.                 {
  686.                     format(params, sizeof AOE_STR, "%s %s", AOFileName, AOComment);
  687.                     cmd_saveallattachedobjects(playerid, params);
  688.                 }
  689.                 else
  690.                 {
  691.                     if(AOE_EnteredValidSlot(playerid, AOSlot))
  692.                     {
  693.                         if(AOE_HasSlot(playerid, AOSlot))
  694.                         {
  695.                             EPV[playerid][PAO_INDEX1] = AOSlot;
  696.                             if(isnull(AOFileName)) AOE_ShowPlayerDialog(playerid, AOE_C_SAVE, AOE_D_SAVE, AOE_T_SAVE, AOE_B_SAVE, AOE_B_SELECT_INDEX);
  697.                             else
  698.                             {
  699.                                 if(AOE_EnteredValidFileName(playerid, AOFileName))
  700.                                 {
  701.                                     strupdate(EPV[playerid][PAO_NAME], AOFileName);
  702.                                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, AOFileName);
  703.                                     if(AOE_EnteredNonExistFileName(playerid, AOFileName))
  704.                                     {
  705.                                         SendClientMessage(playerid, AOE_COLOR5, AOE_M_SAVING);
  706.                                         if(!IsValidComment(AOComment) && !isnull(AOComment))
  707.                                         {
  708.                                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_COMMENT_INVALID);
  709.                                             AOComment[0] = EOS;
  710.                                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_COMMENT_INFO);
  711.                                         }
  712.                                         if(AOE_SavePlayerAttachedObject(playerid, AOFileName, AOSlot, AOComment, AOFileLen))
  713.                                         {
  714.                                             format(AOE_STR, sizeof AOE_STR, "* Your attached object from index %d has been saved as \"{FFFFFF}%s{%06x}\".", AOSlot, EPV[playerid][PAO_NAME], AOE_COLOR2 >>> 8);
  715.                                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  716.                                             format(AOE_STR, sizeof AOE_STR, "** Model: %d ~ Bone: %s (%d) ~ For skin: %d ~ File size: %.2f KB.",
  717.                                             PAO[playerid][AOSlot][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[playerid][AOSlot][AO_BONE_ID]), PAO[playerid][AOSlot][AO_BONE_ID], GetPlayerSkin(playerid), AOFileLen);
  718.                                             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  719.                                             if(!isnull(AOComment))
  720.                                             {
  721.                                                 format(AOE_STR, sizeof AOE_STR, "** Comment: %s.", AOComment);
  722.                                                 SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  723.                                             }
  724.                                             format(AOE_STR, sizeof AOE_STR, "~b~~h~Attached object file saved~n~%s", EPV[playerid][PAO_NAME]);
  725.                                             AOE_GameTextForPlayer(playerid, AOE_STR);
  726.                                         }
  727.                                         else
  728.                                         {
  729.                                             SendClientMessage(playerid, AOE_COLOR1, AOE_M_SAVE_FAILED);
  730.                                             AOE_GameTextForPlayer(playerid, AOE_G_INVALID_DATA);
  731.                                         }
  732.                                     }
  733.                                 }
  734.                             }
  735.                         }
  736.                     }
  737.                 }
  738.             }
  739.         }
  740.     }
  741.     return 1;
  742. }
  743.  
  744. CMD:sao(playerid, params[]) return cmd_saveattachedobject(playerid, params);
  745.  
  746. CMD:saveallattachedobjects(playerid, params[])
  747. {
  748.     if(AOE_CanEdit(playerid))
  749.     {
  750.         if(AOE_HasAttachedObject(playerid))
  751.         {
  752.             if(sscanf(params, "s[25]S()[64]", AOFileName, AOComment)) AOE_ShowPlayerDialog(playerid, AOE_C_SAVE, AOE_D_SAVE2, AOE_T_SAVE_SET, AOE_B_SAVE, AOE_B_BACK);
  753.             else
  754.             {
  755.                 if(AOE_EnteredValidFileName(playerid, AOFileName))
  756.                 {
  757.                     strupdate(EPV[playerid][PAO_NAME], AOFileName);
  758.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, AOFileName);
  759.                     if(AOE_EnteredNonExistFileName2(playerid, AOFileName))
  760.                     {
  761.                         SendClientMessage(playerid, AOE_COLOR5, AOE_M_SAVING_SET);
  762.                         if(!IsValidComment(AOComment) && !isnull(AOComment))
  763.                         {
  764.                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_COMMENT_INVALID);
  765.                             AOComment[0] = EOS;
  766.                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_COMMENT_INFO);
  767.                         }
  768.                         new slots = AOE_SavePlayerAttachedObject(playerid, AOFileName, MAX_PLAYER_ATTACHED_OBJECTS, AOComment, AOFileLen);
  769.                         if(slots)
  770.                         {
  771.                             format(AOE_STR, sizeof AOE_STR, "* Your attached object set has been saved as \"{FFFFFF}%s{%06x}\".", EPV[playerid][PAO_NAME], AOE_COLOR2 >>> 8);
  772.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  773.                             format(AOE_STR, sizeof AOE_STR, "** Slots saved: %d ~ For skin: %d ~ File size: %.2f KB.", slots, GetPlayerSkin(playerid), AOFileLen);
  774.                             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  775.                             if(!isnull(AOComment))
  776.                             {
  777.                                 format(AOE_STR, sizeof AOE_STR, "** Comment: %s.", AOComment);
  778.                                 SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  779.                             }
  780.                             format(AOE_STR, sizeof AOE_STR, "~g~~h~Attached object(s) file saved~n~%s", EPV[playerid][PAO_NAME]);
  781.                             AOE_GameTextForPlayer(playerid, AOE_STR);
  782.                         }
  783.                         else SendClientMessage(playerid, AOE_COLOR1, AOE_M_SAVE_FAILED);
  784.                     }
  785.                 }
  786.             }
  787.         }
  788.     }
  789.     return 1;
  790. }
  791.  
  792. CMD:saao(playerid, params[]) return cmd_saveallattachedobjects(playerid, params);
  793.  
  794. CMD:loadattachedobject(playerid, params[])
  795. {
  796.     if(AOE_CanEdit(playerid))
  797.     {
  798.         if(AOE_HasFreeSlot(playerid))
  799.         {
  800.             if(sscanf(params, "s[25]D(-1)", AOFileName, AOSlot)) AOE_ShowPlayerDialog(playerid, AOE_C_LOAD, AOE_D_LOAD, AOE_T_LOAD, AOE_B_ENTER, AOE_B_BACK);
  801.             else
  802.             {
  803.                 if(AOE_EnteredValidFileName(playerid, AOFileName))
  804.                 {
  805.                     strupdate(EPV[playerid][PAO_NAME], AOFileName);
  806.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, EPV[playerid][PAO_NAME]);
  807.                     if(AOE_EnteredExistedFileName(playerid, AOFileName))
  808.                     {
  809.                         if(AOSlot == -1) AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_LOAD_SLOT, AOE_T_LOAD, AOE_B_LOAD, AOE_B_BACK);
  810.                         else
  811.                         {
  812.                             if(AOE_EnteredValidSlot(playerid, AOSlot))
  813.                             {
  814.                                 EPV[playerid][PAO_INDEX1] = AOSlot;
  815.                                 if(IsPlayerAttachedObjectSlotUsed(playerid, AOSlot)) AOE_ShowPlayerDialog(playerid, AOE_C_LOAD_REPLACE, AOE_D_LOAD_REPLACE, AOE_T_LOAD#AOE_T_REPLACE, AOE_B_YES, AOE_B_BACK);
  816.                                 else
  817.                                 {
  818.                                     SendClientMessage(playerid, AOE_COLOR5, AOE_M_LOADING);
  819.                                     if(AOE_LoadPlayerAttachedObject(playerid, AOFileName, AOSlot, AOComment))
  820.                                     {
  821.                                         format(AOE_STR, sizeof AOE_STR, "* You've loaded attached object from file \"{FFFFFF}%s{%06x}\" at index number %d.", EPV[playerid][PAO_NAME], AOE_COLOR2 >>> 8, AOSlot);
  822.                                         SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  823.                                         if(!isnull(AOComment))
  824.                                         {
  825.                                             format(AOE_STR, sizeof AOE_STR, "** Comment: %s.", AOComment);
  826.                                             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  827.                                         }
  828.                                         format(AOE_STR, sizeof AOE_STR, "~g~~h~Attached object file loaded~n~%s", EPV[playerid][PAO_NAME]);
  829.                                         AOE_GameTextForPlayer(playerid, AOE_STR);
  830.                                     }
  831.                                     else
  832.                                     {
  833.                                         format(AOE_STR, sizeof AOE_STR, "* Sorry, there is no valid attached object data found from file \"%s\" at index number %d.", EPV[playerid][PAO_NAME], AOSlot);
  834.                                         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  835.                                         AOE_GameTextForPlayer(playerid, AOE_G_INVALID_DATA);
  836.                                         AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_LOAD_SLOT, AOE_T_LOAD, AOE_B_LOAD, AOE_B_BACK);
  837.                                     }
  838.                                 }
  839.                             }
  840.                         }
  841.                     }
  842.                 }
  843.             }
  844.         }
  845.     }
  846.     return 1;
  847. }
  848.  
  849. CMD:lao(playerid, params[]) return cmd_loadattachedobject(playerid, params);
  850.  
  851. CMD:loadattachedobjects(playerid, params[])
  852. {
  853.     if(AOE_CanEdit(playerid))
  854.     {
  855.         if(AOE_HasFreeSlot(playerid))
  856.         {
  857.             if(sscanf(params, "s[25]", AOFileName)) AOE_ShowPlayerDialog(playerid, AOE_C_LOAD, AOE_D_LOAD2, AOE_T_LOAD_SET, AOE_B_LOAD, AOE_B_BACK);
  858.             else
  859.             {
  860.                 if(AOE_EnteredValidFileName(playerid, AOFileName))
  861.                 {
  862.                     strupdate(EPV[playerid][PAO_NAME], AOFileName);
  863.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, AOFileName);
  864.                     if(AOE_EnteredExistedFileName(playerid, AOFileName))
  865.                     {
  866.                         SendClientMessage(playerid, AOE_COLOR3, AOE_M_LOADING_SET);
  867.                         new slots = AOE_LoadPlayerAttachedObject(playerid, AOFileName, MAX_PLAYER_ATTACHED_OBJECTS, AOComment);
  868.                         if(slots)
  869.                         {
  870.                             format(AOE_STR, sizeof AOE_STR, "* You've loaded %d attached object(s) from file \"{FFFFFF}%s{%06x}\".", slots, EPV[playerid][PAO_NAME], AOE_COLOR2 >>> 8);
  871.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  872.                             if(!isnull(AOComment))
  873.                             {
  874.                                 format(AOE_STR, sizeof AOE_STR, "** Comment: %s.", AOComment);
  875.                                 SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  876.                             }
  877.                             format(AOE_STR, sizeof AOE_STR, "~g~~h~Attached object(s) file loaded~n~%s", EPV[playerid][PAO_NAME]);
  878.                             AOE_GameTextForPlayer(playerid, AOE_STR);
  879.                         }
  880.                         else
  881.                         {
  882.                             format(AOE_STR, sizeof AOE_STR, "* Sorry, there is no valid attached object data found from file \"%s\".", EPV[playerid][PAO_NAME]);
  883.                             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  884.                             AOE_GameTextForPlayer(playerid, AOE_G_INVALID_DATA);
  885.                         }
  886.                     }
  887.                 }
  888.             }
  889.         }
  890.     }
  891.     return 1;
  892. }
  893.  
  894. CMD:laos(playerid, params[]) return cmd_loadattachedobjects(playerid, params);
  895.  
  896. CMD:deleteattachedobjectfile(playerid, params[])
  897. {
  898.     if(IsPlayerAdmin(playerid))
  899.     {
  900.         if(sscanf(params, "s[25]", AOFileName)) AOE_ShowPlayerDialog(playerid, AOE_C_DELETE, AOE_D_DELETE, AOE_T_DELETE, AOE_B_DELETE, AOE_B_CANCEL);
  901.         else
  902.         {
  903.             if(AOE_EnteredValidFileName(playerid, AOFileName))
  904.             {
  905.                 format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, AOFileName);
  906.                 if(fexist(AOFileName))
  907.                 {
  908.                     SendClientMessage(playerid, AOE_COLOR1, AOE_M_DELETING);
  909.                     if(fremove(AOFileName))
  910.                     {
  911.                         format(AOE_STR, sizeof AOE_STR, "* You've deleted attached object(s) file \"{CCFFFF}%s{%06x}\".", AOFileName, AOE_COLOR1 >>> 8);
  912.                         AOE_GameTextForPlayer(playerid, AOE_G_FILE_DELETED);
  913.                     }
  914.                     else format(AOE_STR, sizeof AOE_STR, "* Failed to delete attached object(s) file \"{CCFFFF}%s{%06x}\"", AOFileName, AOE_COLOR1 >>> 8);
  915.                     SendClientMessage(playerid, AOE_COLOR1, AOE_STR);
  916.                 }
  917.                 else
  918.                 {
  919.                     format(AOE_STR, sizeof AOE_STR, "* Sorry, attached object(s) file \"{FFFFFF}%s{%06x}\" does not exist.", AOFileName, AOE_COLOR4 >>> 8);
  920.                     SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  921.                     AOE_GameTextForPlayer(playerid, AOE_G_FILE_NOT_EXIST);
  922.                 }
  923.             }
  924.         }
  925.     }
  926.     else SendClientMessage(playerid, AOE_COLOR4, AOE_M_DELETE_ADMIN_ONLY);
  927.     return 1;
  928. }
  929.  
  930. CMD:daof(playerid, params[]) return cmd_deleteattachedobjectfile(playerid, params);
  931.  
  932. CMD:resetattachedobjecteditor(playerid, params[])
  933. {
  934.     if(IsPlayerAdmin(playerid))
  935.     {
  936.         if(sscanf(params, "uD(-1)", AOTarget, AOSlot))
  937.         {
  938.             SendClientMessage(playerid, AOE_COLOR4, AOE_M_RESET_USAGE);
  939.             SendClientMessage(playerid, AOE_COLOR0, AOE_M_RESET_INFO);
  940.         }
  941.         else
  942.         {
  943.             if(AOTarget == INVALID_PLAYER_ID) SendClientMessage(playerid, AOE_COLOR4, AOE_M_TARGET_NOT_ONLINE);
  944.             else
  945.             {
  946.                 if(0 <= AOSlot <= MAX_PLAYER_ATTACHED_OBJECTS)
  947.                 {
  948.                     RemovePlayerAttachedObjectEx(AOTarget, AOSlot);
  949.                     if(AOSlot == MAX_PLAYER_ATTACHED_OBJECTS)
  950.                     {
  951.                         for(new x = 0; x < MAX_PLAYER_ATTACHED_OBJECTS; x++)
  952.                             AOE_UnsetValues(AOTarget, x);
  953.                     }
  954.                     else AOE_UnsetValues(AOTarget, AOSlot);
  955.                 }
  956.                 ShowPlayerDialog(AOTarget, -1, DIALOG_STYLE_MSGBOX, "", "", "", "");
  957.                 AOE_UnsetVars(AOTarget);
  958.                 format(AOE_STR, sizeof AOE_STR, "* Player's (ID:%d) attached object editor variable(s) has been reset!", AOTarget);
  959.                 SendClientMessage(playerid, AOE_COLOR1, AOE_STR);
  960.             }
  961.         }
  962.     }
  963.     else SendClientMessage(playerid, AOE_COLOR4, AOE_M_RESET_ADMIN_ONLY);
  964.     return 1;
  965. }
  966. CMD:raoepv(playerid, params[]) return cmd_resetattachedobjecteditor(playerid, params);
  967.  
  968. CMD:attachedobjectproperties(playerid, params[])
  969. {
  970.     if(AOE_CanEdit(playerid))
  971.     {
  972.         if(sscanf(params, "dU(-1)", AOSlot, AOTarget))
  973.         {
  974.             SendClientMessage(playerid, AOE_COLOR4, AOE_M_PROPERTIES_USAGE);
  975.             SendClientMessage(playerid, AOE_COLOR0, AOE_M_PROPERTIES_INFO);
  976.         }
  977.         else
  978.         {
  979.             if(AOE_EnteredValidSlot(playerid, AOSlot))
  980.             {
  981.                 if(AOTarget == -1) AOTarget = playerid;
  982.                 if(AOTarget == INVALID_PLAYER_ID) SendClientMessage(playerid, AOE_COLOR4, AOE_M_TARGET_NOT_ONLINE);
  983.                 else
  984.                 {
  985.                     EPV[playerid][PAO_TARGET] = AOTarget;
  986.                     GetPlayerName(AOTarget, pName, sizeof pName);
  987.                     if(0 < GetPlayerAttachedObjectsCount(AOTarget) <= MAX_PLAYER_ATTACHED_OBJECTS)
  988.                     {
  989.                         if(IsPlayerAttachedObjectSlotUsed(AOTarget, AOSlot))
  990.                         {
  991.                             EPV[playerid][PAO_INDEX1] = AOSlot;
  992.                             if(AOTarget == playerid) format(AOE_STR, sizeof AOE_STR, "Your Attached Object Properties (%d)", AOSlot);
  993.                             else format(AOE_STR, sizeof AOE_STR, "%s's Attached Object Properties (%d)", pName, AOSlot);
  994.                             AOE_ShowPlayerDialog(playerid, AOE_C_PROPERTIES, AOE_D_PROPERTIES, AOE_STR, AOE_B_PRINT, AOE_B_CLOSE);
  995.                         }
  996.                         else
  997.                         {
  998.                             if(AOTarget == playerid) format(AOE_STR, sizeof AOE_STR, "* Sorry, you have no attached object at index number %d.", AOSlot);
  999.                             else format(AOE_STR, sizeof AOE_STR, "* Sorry, %s has no attached object at index number %d.", pName, AOSlot);
  1000.                             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1001.                             format(AOE_STR, sizeof AOE_STR, "~r~~h~Unknown attached object~n~~w~index number: %d.", AOSlot);
  1002.                             AOE_GameTextForPlayer(playerid, AOE_STR);
  1003.                         }
  1004.                     }
  1005.                     else
  1006.                     {
  1007.                         if(AOTarget == playerid)
  1008.                         {
  1009.                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_NO_ATTACHED_OBJECT);
  1010.                             AOE_GameTextForPlayer(playerid, AOE_G_NO_ATTACHED_OBJECT);
  1011.                         }
  1012.                         else
  1013.                         {
  1014.                             format(AOE_STR, sizeof AOE_STR, "* Sorry, %s has no attached object.", pName);
  1015.                             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1016.                             format(AOE_STR, sizeof AOE_STR, "~r~~h~%s has no attached object", pName);
  1017.                             AOE_GameTextForPlayer(playerid, AOE_STR);
  1018.                         }
  1019.                     }
  1020.                 }
  1021.             }
  1022.         }
  1023.     }
  1024.     return 1;
  1025. }
  1026.  
  1027. CMD:aop(playerid, params[]) return cmd_attachedobjectproperties(playerid, params);
  1028. CMD:attachedobjectstatus(playerid, params[]) return cmd_attachedobjectproperties(playerid, params);
  1029. CMD:aos(playerid, params[]) return cmd_attachedobjectproperties(playerid, params);
  1030.  
  1031. CMD:duplicateattachedobject(playerid, params[])
  1032. {
  1033.     if(AOE_CanEdit(playerid))
  1034.     {
  1035.         if(AOE_HasAttachedObject(playerid))
  1036.         {
  1037.             new slot2;
  1038.             if(sscanf(params, "dD(-1)", AOSlot, slot2))
  1039.             {
  1040.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_DUPLICATE_USAGE);
  1041.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_DUPLICATE_INFO);
  1042.             }
  1043.             else
  1044.             {
  1045.                 if(IsValidAttachedObjectSlot(AOSlot))
  1046.                 {
  1047.                     if(AOE_HasSlot(playerid, AOSlot))
  1048.                     {
  1049.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1050.                         if(slot2 == -1) AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_DUPLICATE_SLOT, AOE_T_DUPLICATE, AOE_B_DUPLICATE, AOE_B_BACK);
  1051.                         else
  1052.                         {
  1053.                             if(IsValidAttachedObjectSlot(slot2))
  1054.                             {
  1055.                                 EPV[playerid][PAO_INDEX2] = slot2;
  1056.                                 if(slot2 == AOSlot)
  1057.                                 {
  1058.                                     format(AOE_STR, sizeof AOE_STR, "* Sorry, you cannot duplicate your attached object from slot %d to the same slot (%d) as it's already there?!", AOSlot, slot2);
  1059.                                     SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1060.                                     AOE_GameTextForPlayer(playerid, AOE_G_DOH);
  1061.                                 }
  1062.                                 else
  1063.                                 {
  1064.                                     if(IsPlayerAttachedObjectSlotUsed(playerid, slot2)) AOE_ShowPlayerDialog(playerid, AOE_C_DUPLICATE_REPLACE, AOE_D_DUPLICATE_REPLACE, AOE_T_DUPLICATE#AOE_T_REPLACE, AOE_B_DUPLICATE, AOE_B_SELECT_INDEX);
  1065.                                     else
  1066.                                     {
  1067.                                         if(DuplicatePlayerAttachedObject(playerid, AOSlot, slot2))
  1068.                                         {
  1069.                                             format(AOE_STR, sizeof AOE_STR, "* Duplicated your attached object from slot %d to %d.", AOSlot, slot2);
  1070.                                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1071.                                             format(AOE_STR, sizeof AOE_STR, "~g~Attached object duplicated~n~~w~index number:~n~%d to %d", AOSlot, slot2);
  1072.                                             AOE_GameTextForPlayer(playerid, AOE_STR);
  1073.                                         }
  1074.                                         else SendClientMessage(playerid, AOE_COLOR1, AOE_M_DUPLICATE_FAIL);
  1075.                                     }
  1076.                                 }
  1077.                             }
  1078.                             else
  1079.                             {
  1080.                                 format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object index #2 number (%d).", slot2);
  1081.                                 SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1082.                                 AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SLOT);
  1083.                             }
  1084.                         }
  1085.                     }
  1086.                 }
  1087.                 else
  1088.                 {
  1089.                     format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object index #1 number (%d).", AOSlot);
  1090.                     SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1091.                     AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SLOT);
  1092.                 }
  1093.             }
  1094.         }
  1095.     }
  1096.     return 1;
  1097. }
  1098.  
  1099. CMD:dao(playerid, params[]) return cmd_duplicateattachedobject(playerid, params);
  1100.  
  1101. CMD:setattachedobjectindex(playerid, params[])
  1102. {
  1103.     if(AOE_CanEdit(playerid))
  1104.     {
  1105.         if(AOE_HasAttachedObject(playerid))
  1106.         {
  1107.             new AOSlot2;
  1108.             if(sscanf(params, "dD(-1)", AOSlot, AOSlot2))
  1109.             {
  1110.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_SLOT_USAGE);
  1111.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_SLOT_INFO);
  1112.             }
  1113.             else
  1114.             {
  1115.                 if(IsValidAttachedObjectSlot(AOSlot))
  1116.                 {
  1117.                     if(AOE_HasSlot(playerid, AOSlot))
  1118.                     {
  1119.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1120.                         if(AOSlot2 == -1) AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_SET_SLOT, AOE_T_SET_INDEX, AOE_B_SET, AOE_B_BACK);
  1121.                         else
  1122.                         {
  1123.                             if(IsValidAttachedObjectSlot(AOSlot2))
  1124.                             {
  1125.                                 if(AOSlot2 == AOSlot)
  1126.                                 {
  1127.                                     format(AOE_STR, sizeof AOE_STR, "* Sorry, you can't move your attached object from slot %d to the same slot (%d) as it's already there?!", AOSlot, AOSlot2);
  1128.                                     SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1129.                                     AOE_GameTextForPlayer(playerid, AOE_G_DOH);
  1130.                                 }
  1131.                                 else
  1132.                                 {
  1133.                                     EPV[playerid][PAO_INDEX2] = AOSlot2;
  1134.                                     if(IsPlayerAttachedObjectSlotUsed(playerid, AOSlot2)) AOE_ShowPlayerDialog(playerid, AOE_C_SET_INDEX_REPLACE, AOE_D_SET_SLOT_REPLACE, AOE_T_SET_INDEX#AOE_T_REPLACE, AOE_B_YES, AOE_B_SELECT_INDEX);
  1135.                                     else
  1136.                                     {
  1137.                                         if(ChangePlayerAttachedObjectIndex(playerid, AOSlot, AOSlot2))
  1138.                                         {
  1139.                                             format(AOE_STR, sizeof AOE_STR, "* Moved your attached object from slot %d to {FFFFFF}%d{%06x}.", AOSlot, AOSlot2, AOE_COLOR2 >>> 8);
  1140.                                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1141.                                             format(AOE_STR, sizeof AOE_STR, "~g~Attached object moved~n~~w~index number:~n~%d to %d", AOSlot, AOSlot2);
  1142.                                             AOE_GameTextForPlayer(playerid, AOE_STR);
  1143.                                         }
  1144.                                         else SendClientMessage(playerid, AOE_COLOR1, AOE_M_SET_SLOT_FAIL);
  1145.                                     }
  1146.                                 }
  1147.                             }
  1148.                             else
  1149.                             {
  1150.                                 format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object new index number ({FFFFFF}%d{%06x}).", AOSlot2, AOE_COLOR4 >>> 8);
  1151.                                 SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1152.                                 AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SLOT);
  1153.                             }
  1154.                         }
  1155.                     }
  1156.                 }
  1157.                 else
  1158.                 {
  1159.                     format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object old index number ({FFFFFF}%d{%06x}).", AOSlot, AOE_COLOR4 >>> 8);
  1160.                     SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1161.                     AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SLOT);
  1162.                 }
  1163.             }
  1164.         }
  1165.     }
  1166.     return 1;
  1167. }
  1168.  
  1169. CMD:setattachedobjectslot(playerid, params[]) return cmd_setattachedobjectindex(playerid, params);
  1170.  
  1171. CMD:saoi(playerid, params[]) return cmd_setattachedobjectindex(playerid, params);
  1172.  
  1173. CMD:setattachedobjectmodel(playerid, params[])
  1174. {
  1175.     if(AOE_CanEdit(playerid))
  1176.     {
  1177.         if(AOE_HasAttachedObject(playerid))
  1178.         {
  1179.             if(sscanf(params, "dD(-1)", AOSlot, AOModel))
  1180.             {
  1181.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_MODEL_USAGE);
  1182.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_MODEL_INFO);
  1183.             }
  1184.             else
  1185.             {
  1186.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  1187.                 {
  1188.                     if(AOE_HasSlot(playerid, AOSlot))
  1189.                     {
  1190.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1191.                         if(AOModel == -1) AOE_ShowPlayerDialog(playerid, AOE_C_MODEL, AOE_D_SET_MODEL, AOE_T_SET_MODEL, AOE_B_SET, AOE_B_BACK);
  1192.                         else
  1193.                         {
  1194.                             if(AOE_EnteredValidModel(playerid, AOModel))
  1195.                             {
  1196.                                 EPV[playerid][PAO_MODEL_ID] = AOModel;
  1197.                                 if(AOModel == PAO[playerid][AOSlot][AO_MODEL_ID])
  1198.                                 {
  1199.                                     format(AOE_STR, sizeof AOE_STR, "* Sorry, you cannot change this attached object index %d model from %d to the same model (%d)!!", AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], AOModel);
  1200.                                     SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1201.                                     AOE_GameTextForPlayer(playerid, AOE_G_DOH);
  1202.                                 }
  1203.                                 else
  1204.                                 {
  1205.                                     if(UpdatePlayerAttachedObject(playerid, AOSlot, AOModel, PAO[playerid][AOSlot][AO_BONE_ID]))
  1206.                                     {
  1207.                                         format(AOE_STR, sizeof AOE_STR, "* Updated your attached object index %d model to {FFFFFF}%d{%06x}.", AOSlot, AOModel, AOE_COLOR2 >>> 8);
  1208.                                         SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1209.                                         format(AOE_STR, sizeof AOE_STR, "~g~Attached object model updated~n~~w~%d (ID:%d)", AOModel, AOSlot);
  1210.                                         AOE_GameTextForPlayer(playerid, AOE_STR);
  1211.                                     }
  1212.                                     else SendClientMessage(playerid, AOE_COLOR1, AOE_M_SET_MODEL_FAIL);
  1213.                                 }
  1214.                             }
  1215.                         }
  1216.                     }
  1217.                 }
  1218.             }
  1219.         }
  1220.     }
  1221.     return 1;
  1222. }
  1223.  
  1224. CMD:saom(playerid, params[]) return cmd_setattachedobjectmodel(playerid, params);
  1225.  
  1226. CMD:setattachedobjectbone(playerid, params[])
  1227. {
  1228.     if(AOE_CanEdit(playerid))
  1229.     {
  1230.         if(AOE_HasAttachedObject(playerid))
  1231.         {
  1232.             new bonename[MAX_ATTACHED_OBJECT_BONE_NAME];
  1233.             if(sscanf(params, "dS()[16]", AOSlot, bonename))
  1234.             {
  1235.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_BONE_USAGE);
  1236.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_BONE_INFO);
  1237.             }
  1238.             else
  1239.             {
  1240.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  1241.                 {
  1242.                     if(AOE_HasSlot(playerid, AOSlot))
  1243.                     {
  1244.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1245.                         if(isnull(bonename)) AOE_ShowPlayerDialog(playerid, AOE_C_BONE, AOE_D_SET_BONE, AOE_T_SET_BONE, AOE_B_SET, AOE_B_BACK);
  1246.                         else
  1247.                         {
  1248.                             if(AOE_EnteredValidBone(playerid, bonename))
  1249.                             {
  1250.                                 AOBone = GetAttachedObjectBone(bonename);
  1251.                                 EPV[playerid][PAO_BONE_ID] = AOBone;
  1252.                                 if(AOBone == PAO[playerid][AOSlot][AO_BONE_ID])
  1253.                                 {
  1254.                                     format(AOE_STR, sizeof AOE_STR, "* Sorry, you cannot change this attached object index %d bone from %s to the same bone (%d)!!", AOSlot, bonename, PAO[playerid][AOSlot][AO_BONE_ID]);
  1255.                                     SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1256.                                     AOE_GameTextForPlayer(playerid, AOE_G_DOH);
  1257.                                 }
  1258.                                 else
  1259.                                 {
  1260.                                     if(UpdatePlayerAttachedObject(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], AOBone))
  1261.                                     {
  1262.                                         if(IsNumeric(bonename)) bonename = GetAttachedObjectBoneName(AOBone);
  1263.                                         format(AOE_STR, sizeof AOE_STR, "* Updated your attached object index %d bone to {FFFFFF}%d{%06x} (%s).", AOSlot, AOBone, AOE_COLOR2 >>> 8, bonename);
  1264.                                         SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1265.                                         format(AOE_STR, sizeof AOE_STR, "~g~Attached object bone updated~n~~w~%d (ID:%d)", AOBone, AOSlot);
  1266.                                         AOE_GameTextForPlayer(playerid, AOE_STR);
  1267.                                     }
  1268.                                     else SendClientMessage(playerid, AOE_COLOR1, AOE_M_ERROR);
  1269.                                 }
  1270.                             }
  1271.                         }
  1272.                     }
  1273.                 }
  1274.             }
  1275.         }
  1276.     }
  1277.     return 1;
  1278. }
  1279.  
  1280. CMD:saob(playerid, params[]) return cmd_setattachedobjectbone(playerid, params);
  1281.  
  1282. CMD:setattachedobjectoffset(playerid, params[])
  1283. {
  1284.     if(AOE_CanEdit(playerid))
  1285.     {
  1286.         if(AOE_HasAttachedObject(playerid))
  1287.         {
  1288.             if(sscanf(params, "dcf", AOSlot, AOSelection, AOAxis))
  1289.             {
  1290.                 ErrorMessage:
  1291.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_OFFSET_USAGE);
  1292.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_OFFSET_INFO);
  1293.             }
  1294.             else
  1295.             {
  1296.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  1297.                 {
  1298.                     if(AOE_HasSlot(playerid, AOSlot))
  1299.                     {
  1300.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1301.                         if(IsPlayerAdmin(playerid) || MIN_ATTACHED_OBJECT_OFFSET <= AOAxis <= MAX_ATTACHED_OBJECT_OFFSET)
  1302.                         {
  1303.                             switch(AOSelection)
  1304.                             {
  1305.                                 case 'x', 'X': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], AOAxis, PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1306.                                                 PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY], PAO[playerid][AOSlot][AO_SZ],
  1307.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1308.                                 case 'y', 'Y': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], AOAxis, PAO[playerid][AOSlot][AO_Z],
  1309.                                                 PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY], PAO[playerid][AOSlot][AO_SZ],
  1310.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1311.                                 case 'z', 'Z': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], AOAxis,
  1312.                                                 PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY], PAO[playerid][AOSlot][AO_SZ],
  1313.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1314.                                 default: goto ErrorMessage;
  1315.                             }
  1316.                             format(AOE_STR, sizeof AOE_STR, "* Updated your attached object index %d position (Offset%c) to {FFFFFF}%.4f{%06x}.", AOSlot, toupper(AOSelection), AOAxis, AOE_COLOR2 >>> 8);
  1317.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1318.                             AOE_GameTextForPlayer(playerid, AOE_G_OFFSET_UPDATED);
  1319.                         }
  1320.                         else
  1321.                         {
  1322.                             format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object offset(%c) value ({FFFFFF}%f{%06x}).", toupper(AOSelection), AOAxis, AOE_COLOR4 >>> 8);
  1323.                             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1324.                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_VALID_OFFSET);
  1325.                             AOE_GameTextForPlayer(playerid, AOE_G_INVALID_OFFSET);
  1326.                         }
  1327.                     }
  1328.                 }
  1329.             }
  1330.         }
  1331.     }
  1332.     return 1;
  1333. }
  1334.  
  1335. CMD:saoo(playerid, params[]) return cmd_setattachedobjectoffset(playerid, params);
  1336.  
  1337. CMD:setattachedobjectrot(playerid, params[])
  1338. {
  1339.     if(AOE_CanEdit(playerid))
  1340.     {
  1341.         if(AOE_HasAttachedObject(playerid))
  1342.         {
  1343.             if(sscanf(params, "dcf", AOSlot, AOSelection, AOAxis))
  1344.             {
  1345.                 ErrorMessage:
  1346.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_ROTATION_USAGE);
  1347.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_ROTATION_INFO);
  1348.             }
  1349.             else
  1350.             {
  1351.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  1352.                 {
  1353.                     if(AOE_HasSlot(playerid, AOSlot))
  1354.                     {
  1355.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1356.                         if(IsPlayerAdmin(playerid) || MIN_ATTACHED_OBJECT_ROTATION <= AOAxis <= MAX_ATTACHED_OBJECT_ROTATION)
  1357.                         {
  1358.                             switch(AOSelection)
  1359.                             {
  1360.                                 case 'x', 'X': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1361.                                                 AOAxis, PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY], PAO[playerid][AOSlot][AO_SZ],
  1362.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1363.                                 case 'y', 'Y': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1364.                                                 PAO[playerid][AOSlot][AO_RX], AOAxis, PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY], PAO[playerid][AOSlot][AO_SZ],
  1365.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1366.                                 case 'z', 'Z': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1367.                                                 PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], AOAxis, PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY],PAO[playerid][AOSlot][AO_SZ],
  1368.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1369.                                 default: goto ErrorMessage;
  1370.                             }
  1371.                             format(AOE_STR, sizeof AOE_STR, "* Updated your attached object index %d rotation (Rot%c) to {FFFFFF}%.4f{%06x}.", AOSlot, toupper(AOSelection), AOAxis, AOE_COLOR2 >>> 8);
  1372.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1373.                             AOE_GameTextForPlayer(playerid, AOE_G_ROTATION_UPDATED);
  1374.                         }
  1375.                         else
  1376.                         {
  1377.                             format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered an invalid attached object rotation(%c) value ({FFFFFF}%f{%06x}).", toupper(AOSelection), AOAxis, AOE_COLOR4 >>> 8);
  1378.                             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1379.                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_VALID_ROTATION);
  1380.                             AOE_GameTextForPlayer(playerid, AOE_G_INVALID_ROTATION);
  1381.                         }
  1382.                     }
  1383.                 }
  1384.             }
  1385.         }
  1386.     }
  1387.     return 1;
  1388. }
  1389.  
  1390. CMD:saor(playerid, params[]) return cmd_setattachedobjectrot(playerid, params);
  1391.  
  1392. CMD:setattachedobjectscale(playerid, params[])
  1393. {
  1394.     if(AOE_CanEdit(playerid))
  1395.     {
  1396.         if(AOE_HasAttachedObject(playerid))
  1397.         {
  1398.             if(sscanf(params, "dcf", AOSlot, AOSelection, AOAxis))
  1399.             {
  1400.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_SCALE_USAGE);
  1401.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_SCALE_INFO);
  1402.             }
  1403.             else
  1404.             {
  1405.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  1406.                 {
  1407.                     if(AOE_HasSlot(playerid, AOSlot))
  1408.                     {
  1409.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1410.                         if(IsPlayerAdmin(playerid) || MIN_ATTACHED_OBJECT_SIZE <= AOAxis <= MAX_ATTACHED_OBJECT_SIZE)
  1411.                         {
  1412.                             switch(AOSelection)
  1413.                             {
  1414.                                 case 'x', 'X': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1415.                                                 PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], AOAxis, PAO[playerid][AOSlot][AO_SY], PAO[playerid][AOSlot][AO_SZ],
  1416.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1417.                                 case 'y', 'Y': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1418.                                                 PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], AOAxis, PAO[playerid][AOSlot][AO_SZ],
  1419.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1420.                                 case 'z', 'Z': UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1421.                                                 PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY], AOAxis,
  1422.                                                 PAO[playerid][AOSlot][AO_MC1], PAO[playerid][AOSlot][AO_MC2]);
  1423.                             }
  1424.                             format(AOE_STR, sizeof AOE_STR, "* Updated your attached object index %d size (Scale%c) to {FFFFFF}%.4f{%06x}.", AOSlot, toupper(AOSelection), AOAxis, AOE_COLOR2 >>> 8);
  1425.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1426.                             AOE_GameTextForPlayer(playerid, AOE_G_SCALE_UPDATED);
  1427.                         }
  1428.                         else
  1429.                         {
  1430.                             format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object scale(%c) value ({FFFFFF}%f{%06x}).", toupper(AOSelection), AOAxis, AOE_COLOR4 >>> 8);
  1431.                             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  1432.                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_VALID_SCALE);
  1433.                             AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SCALE);
  1434.                         }
  1435.                     }
  1436.                 }
  1437.             }
  1438.         }
  1439.     }
  1440.     return 1;
  1441. }
  1442.  
  1443. CMD:saos(playerid, params[]) return cmd_setattachedobjectscale(playerid, params);
  1444.  
  1445. CMD:setattachedobjectmc(playerid, params[])
  1446. {
  1447.     if(AOE_CanEdit(playerid))
  1448.     {
  1449.         if(AOE_HasAttachedObject(playerid))
  1450.         {
  1451.             new hex:MC2;
  1452.             if(sscanf(params, "dxx", AOSlot, AOMC, MC2))
  1453.             {
  1454.                 SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_COLOR_USAGE);
  1455.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_COLOR_INFO);
  1456.             }
  1457.             else
  1458.             {
  1459.                 if(AOE_EnteredValidSlot(playerid, AOSlot))
  1460.                 {
  1461.                     if(AOE_HasSlot(playerid, AOSlot))
  1462.                     {
  1463.                         EPV[playerid][PAO_INDEX1] = AOSlot;
  1464.                         if(AOMC != PAO[playerid][AOSlot][AO_MC1])
  1465.                         {
  1466.                             format(AOE_STR, sizeof AOE_STR, "* Updated your attached object index %d color #1 to {%06x}0x%x{%06x} (%i).", AOSlot, AOMC & 0xFFFFFF, AOMC, AOE_COLOR2 >>> 8, AOMC);
  1467.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1468.                         }
  1469.                         if(MC2 != PAO[playerid][AOSlot][AO_MC2])
  1470.                         {
  1471.                             format(AOE_STR, sizeof AOE_STR, "* Updated your attached object index %d color #2 to {%06x}0x%x{%06x} (%i).", AOSlot, MC2 & 0xFFFFFF, MC2, AOE_COLOR2 >>> 8, MC2);
  1472.                             SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1473.                         }
  1474.                         if(UpdatePlayerAttachedObjectEx(playerid, AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID], PAO[playerid][AOSlot][AO_BONE_ID], PAO[playerid][AOSlot][AO_X], PAO[playerid][AOSlot][AO_Y], PAO[playerid][AOSlot][AO_Z],
  1475.                             PAO[playerid][AOSlot][AO_RX], PAO[playerid][AOSlot][AO_RY], PAO[playerid][AOSlot][AO_RZ], PAO[playerid][AOSlot][AO_SX], PAO[playerid][AOSlot][AO_SY], PAO[playerid][AOSlot][AO_SZ], AOMC, MC2))
  1476.                         {
  1477.                             AOE_GameTextForPlayer(playerid, AOE_G_COLOR_UPDATED);
  1478.                         }
  1479.                         else SendClientMessage(playerid, AOE_COLOR1, AOE_M_ERROR);
  1480.                     }
  1481.                 }
  1482.             }
  1483.         }
  1484.     }
  1485.     return 1;
  1486. }
  1487.  
  1488. CMD:saomc(playerid, params[]) return cmd_setattachedobjectmc(playerid, params);
  1489.  
  1490. CMD:setattachedobjectmc1(playerid, params[])
  1491. {
  1492.     if(sscanf(params, "dx", AOSlot, AOMC))
  1493.     {
  1494.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_COLOR1_USAGE);
  1495.         SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_COLOR1_INFO);
  1496.         return 1;
  1497.     }
  1498.     format(params, sizeof AOE_STR, "%d %x %x", AOSlot, AOMC, PAO[playerid][AOSlot][AO_MC2]);
  1499.     return cmd_setattachedobjectmc(playerid, params);
  1500. }
  1501.  
  1502. CMD:saomc1(playerid, params[]) return cmd_setattachedobjectmc1(playerid, params);
  1503.  
  1504. CMD:setattachedobjectmc2(playerid, params[])
  1505. {
  1506.     if(sscanf(params, "dx", AOSlot, AOMC))
  1507.     {
  1508.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_SET_COLOR2_USAGE);
  1509.         SendClientMessage(playerid, AOE_COLOR0, AOE_M_SET_COLOR2_INFO);
  1510.         return 1;
  1511.     }
  1512.     format(params, sizeof AOE_STR, "%d %x %x", AOSlot, PAO[playerid][AOSlot][AO_MC1], AOMC);
  1513.     return cmd_setattachedobjectmc(playerid, params);
  1514. }
  1515.  
  1516. CMD:saomc2(playerid, params[]) return cmd_setattachedobjectmc2(playerid, params);
  1517. //------------------------------------------------------------------------------
  1518. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
  1519. {
  1520.     new slots;
  1521.     switch(dialogid)
  1522.     {
  1523.         case AOE_D:
  1524.         {
  1525.             if(response)
  1526.             {
  1527.                 switch(listitem)
  1528.                 {
  1529.                     case 0: cmd_createattachedobject(playerid, "");
  1530.                     case 1: AOE_ShowPlayerDialog(playerid, AOE_C_FILE, AOE_D_FILE, AOE_T_FILE, AOE_B_SELECT, AOE_B_CANCEL);
  1531.                     case 2:
  1532.                     {
  1533.                         if(GetPlayerAttachedObjectsCount(playerid) == 0)
  1534.                         {
  1535.                             SendClientMessage(playerid, AOE_COLOR4, AOE_M_EDIT_NOTHING);
  1536.                             AOE_GameTextForPlayer(playerid, AOE_G_NO_ATTACHED_OBJECT);
  1537.                         }
  1538.                         else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_USED, AOE_D_EDIT_SLOT, AOE_T_EDIT, AOE_B_EDIT_CREATE, AOE_B_CANCEL);
  1539.                     }
  1540.                     case 3: cmd_removeattachedobjects(playerid, "");
  1541.                     case 4: cmd_undeleteattachedobject(playerid, "");
  1542.                     case 5:
  1543.                     {
  1544.                         if(IsPlayerAdmin(playerid))
  1545.                         {
  1546.                             SendClientMessage(playerid, AOE_COLOR5, "-- Statistics & Debug ----------------------------------------------------");
  1547.                             SendClientMessage(playerid, AOE_COLOR3, "- Offset value limit: "#MIN_ATTACHED_OBJECT_OFFSET" to "#MAX_ATTACHED_OBJECT_OFFSET);
  1548.                             SendClientMessage(playerid, AOE_COLOR3, "- Rotation value limit: "#MIN_ATTACHED_OBJECT_ROTATION" to "#MAX_ATTACHED_OBJECT_ROTATION);
  1549.                             SendClientMessage(playerid, AOE_COLOR3, "- Scale value limit: "#MIN_ATTACHED_OBJECT_SIZE" to "#MAX_ATTACHED_OBJECT_SIZE);
  1550.                             strupdate(AOE_STR, AOE_FILE_NAME);
  1551.                             strdel(AOE_STR, 0, 2);
  1552.                             format(AOE_STR, sizeof AOE_STR, "- File format: %s", AOE_STR);
  1553.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1554.                             SendClientMessage(playerid, AOE_COLOR3, "- Smaller save size: "#AOE_SMALLER_SAVE);
  1555.                             format(AOE_STR, sizeof AOE_STR, "- Last attached object file name: %s", AOFileName);
  1556.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1557.                             format(AOE_STR, sizeof AOE_STR, "- Last saved attached object file length: %f", AOFileLen);
  1558.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1559.                             format(AOE_STR, sizeof AOE_STR, "- Last attached object file comment: %s", AOComment);
  1560.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1561.                             format(AOE_STR, sizeof AOE_STR, "- Last editor player name: %s", pName);
  1562.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1563.                             format(AOE_STR, sizeof AOE_STR, "- Last editor target id: %d", AOTarget);
  1564.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1565.                             format(AOE_STR, sizeof AOE_STR, "- Last selection edit: %d", AOSelection);
  1566.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1567.                             format(AOE_STR, sizeof AOE_STR, "- Last attached object slot: %d", AOSlot);
  1568.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1569.                             format(AOE_STR, sizeof AOE_STR, "- Last attached object model: %d", AOModel);
  1570.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1571.                             format(AOE_STR, sizeof AOE_STR, "- Last attached object bone: %d", AOBone);
  1572.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1573.                             format(AOE_STR, sizeof AOE_STR, "- Last attached object xyz axis value: %f", AOAxis);
  1574.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1575.                             format(AOE_STR, sizeof AOE_STR, "- Last attached object material color: %x (%i)", AOMC, AOMC);
  1576.                             SendClientMessage(playerid, AOE_COLOR3, AOE_STR);
  1577.                         }
  1578.                         else
  1579.                         {
  1580.                             SendClientMessage(playerid, AOE_COLOR5, "-- Statistics --------------------------------------------------------------");
  1581.                         }
  1582.                         new maxplayers = GetMaxPlayers(), attachedobjectscount, attachedobjectscount2;
  1583.                         if(maxplayers > MAX_PLAYERS) maxplayers = MAX_PLAYERS;
  1584.                         for(new i = 0; i < maxplayers; i++)
  1585.                         {
  1586.                             if(IsPlayerConnected(i))
  1587.                             {
  1588.                                 for(new x = 0; x < MAX_PLAYER_ATTACHED_OBJECTS; x++)
  1589.                                 {
  1590.                                     attachedobjectscount += IsPlayerAttachedObjectSlotUsed(i, x);
  1591.                                     if(PAO[i][x][AO_STATUS] == 1) attachedobjectscount2++;
  1592.                                 }
  1593.                             }
  1594.                         }
  1595.                         format(AOE_STR, sizeof AOE_STR, "- Total attached object(s) in the server: %d (%d by editor)", attachedobjectscount, attachedobjectscount2);
  1596.                         SendClientMessage(playerid, AOE_COLOR5, AOE_STR);
  1597.                         format(AOE_STR, sizeof AOE_STR, "- Total attached object(s) attached on you: %d", GetPlayerAttachedObjectsCount(playerid));
  1598.                         SendClientMessage(playerid, AOE_COLOR5, AOE_STR);
  1599.                         SendClientMessage(playerid, AOE_COLOR5, "--------------------------------------------------------------------------------");
  1600.                     }
  1601.                     case 6: AOE_ShowPlayerDialog(playerid, AOE_C_HELP, AOE_D, AOE_T_HELP, AOE_B_CLOSE);
  1602.                     case 7: AOE_ShowPlayerDialog(playerid, AOE_C_ABOUT, AOE_D, AOE_T_ABOUT, AOE_B_CLOSE);
  1603.                 }
  1604.             }
  1605.             else SendClientMessage(playerid, AOE_COLOR0, AOE_M_DIALOG_CLOSE);
  1606.         }
  1607.         case AOE_D_CREATE_SLOT:
  1608.         {
  1609.             if(response)
  1610.             {
  1611.                 valstr(AOE_STR, listitem);
  1612.                 cmd_createattachedobject(playerid, AOE_STR);
  1613.             }
  1614.             else SendClientMessage(playerid, AOE_COLOR0, AOE_M_CREATE_CANCEL);
  1615.         }
  1616.         case AOE_D_CREATE_MODEL:
  1617.         {
  1618.             if(response)
  1619.             {
  1620.                 AOModel = strval(inputtext), EPV[playerid][PAO_MODEL_ID] = AOModel;
  1621.                 if(AOE_EnteredValidModel(playerid, AOModel)) AOE_ShowPlayerDialog(playerid, AOE_C_BONE, AOE_D_CREATE_BONE, AOE_T_CREATE, AOE_B_SELECT, AOE_B_SELECT_MODEL);
  1622.                 else AOE_ShowPlayerDialog(playerid, AOE_C_MODEL, AOE_D_CREATE_MODEL, AOE_T_CREATE, AOE_B_ENTER, AOE_B_SELECT_INDEX);
  1623.             }
  1624.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_CREATE_SLOT, AOE_T_CREATE, AOE_B_SELECT, AOE_B_CANCEL);
  1625.         }
  1626.         case AOE_D_CREATE_BONE:
  1627.         {
  1628.             if(response)
  1629.             {
  1630.                 EPV[playerid][PAO_BONE_ID] = listitem+1;
  1631.                 if(UpdatePlayerAttachedObjectEx(playerid, EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_MODEL_ID], EPV[playerid][PAO_BONE_ID]))
  1632.                 {
  1633.                     format(AOE_STR, sizeof AOE_STR, "* Created attached object model %d at index number %d [Bone: %s (%d)]!", EPV[playerid][PAO_MODEL_ID], EPV[playerid][PAO_INDEX1], GetAttachedObjectBoneName(EPV[playerid][PAO_BONE_ID]), EPV[playerid][PAO_BONE_ID]);
  1634.                     SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1635.                     format(AOE_STR, sizeof AOE_STR, "~b~Created attached object~n~~w~index/number: %d~n~Model: %d - Bone: %d", EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_MODEL_ID], EPV[playerid][PAO_BONE_ID]);
  1636.                     AOE_GameTextForPlayer(playerid, AOE_STR);
  1637.                     AOE_ShowPlayerDialog(playerid, AOE_C_CREATE_FINAL, AOE_D_CREATE_EDIT, AOE_T_CREATE_EDIT, AOE_B_EDIT, AOE_B_SKIP);
  1638.                 }
  1639.                 else SendClientMessage(playerid, AOE_COLOR1, AOE_M_CREATE_FAIL);
  1640.             }
  1641.             else AOE_ShowPlayerDialog(playerid, AOE_C_MODEL, AOE_D_CREATE_MODEL, AOE_T_CREATE, AOE_B_ENTER, AOE_B_SELECT_INDEX);
  1642.         }
  1643.         case AOE_D_CREATE_REPLACE:
  1644.         {
  1645.             if(response) AOE_ShowPlayerDialog(playerid, AOE_C_MODEL, AOE_D_CREATE_MODEL, AOE_T_CREATE#AOE_T_REPLACE, AOE_B_ENTER, AOE_B_SELECT_INDEX);
  1646.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_CREATE_SLOT, AOE_T_CREATE, AOE_B_SELECT, AOE_B_CANCEL);
  1647.         }
  1648.         case AOE_D_CREATE_EDIT:
  1649.         {
  1650.             if(response)
  1651.             {
  1652.                 valstr(AOE_STR, EPV[playerid][PAO_INDEX1]);
  1653.                 cmd_editattachedobject(playerid, AOE_STR);
  1654.             }
  1655.             else
  1656.             {
  1657.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_EDIT_SKIP);
  1658.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_EDIT_SKIP_INFO);
  1659.             }
  1660.         }
  1661.         case AOE_D_FILE:
  1662.         {
  1663.             if(response)
  1664.             {
  1665.                 switch(listitem)
  1666.                 {
  1667.                     case 0: cmd_loadattachedobject(playerid, "");
  1668.                     case 1: cmd_loadattachedobjects(playerid, "");
  1669.                     case 2: cmd_saveattachedobject(playerid, "");
  1670.                     case 3: cmd_deleteattachedobjectfile(playerid, "");
  1671.                 }
  1672.             }
  1673.             else SendClientMessage(playerid, AOE_COLOR0, AOE_M_FILE_CANCEL);
  1674.         }
  1675.         case AOE_D_LOAD:
  1676.         {
  1677.             if(response)
  1678.             {
  1679.                 if(AOE_EnteredValidFileName(playerid, inputtext))
  1680.                 {
  1681.                     strupdate(EPV[playerid][PAO_NAME], inputtext);
  1682.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, inputtext);
  1683.                     if(AOE_EnteredExistedFileName(playerid, AOFileName)) AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_LOAD_SLOT, AOE_T_LOAD, AOE_B_LOAD, AOE_B_BACK);
  1684.                     else AOE_ShowPlayerDialog(playerid, AOE_C_LOAD, AOE_D_LOAD, AOE_T_LOAD, AOE_B_ENTER, AOE_B_BACK);
  1685.                 }
  1686.                 else if(isnull(inputtext)) AOE_ShowPlayerDialog(playerid, AOE_C_LOAD, AOE_D_LOAD, AOE_T_LOAD, AOE_B_ENTER, AOE_B_BACK);
  1687.             }
  1688.             else AOE_ShowPlayerDialog(playerid, AOE_C_FILE, AOE_D_FILE, AOE_T_FILE, AOE_B_SELECT, AOE_B_CANCEL);
  1689.         }
  1690.         case AOE_D_LOAD_SLOT:
  1691.         {
  1692.             if(response)
  1693.             {
  1694.                 format(AOE_STR, sizeof AOE_STR, "%s %d", EPV[playerid][PAO_NAME], strval(inputtext));
  1695.                 cmd_loadattachedobject(playerid, AOE_STR);
  1696.             }
  1697.             else AOE_ShowPlayerDialog(playerid, AOE_C_LOAD, AOE_D_LOAD, AOE_T_LOAD, AOE_B_ENTER, AOE_B_BACK);
  1698.         }
  1699.         case AOE_D_LOAD_REPLACE:
  1700.         {
  1701.             if(response)
  1702.             {
  1703.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_LOADING);
  1704.                 format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, EPV[playerid][PAO_NAME]);
  1705.                 if(AOE_LoadPlayerAttachedObject(playerid, AOFileName, EPV[playerid][PAO_INDEX1], AOComment))
  1706.                 {
  1707.                     format(AOE_STR, sizeof AOE_STR, "* You've loaded & replaced your attached object from file \"{FFFFFF}%s{%06x}\" [Index: %d|Model: %d|Bone: %d]!",
  1708.                     EPV[playerid][PAO_NAME], AOE_COLOR2 >>> 8, EPV[playerid][PAO_INDEX1], PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MODEL_ID], PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_BONE_ID]);
  1709.                     SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1710.                     if(!isnull(AOComment))
  1711.                     {
  1712.                         format(AOE_STR, sizeof AOE_STR, "** Comment: %s.", AOComment);
  1713.                         SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  1714.                     }
  1715.                     format(AOE_STR, sizeof AOE_STR, "~g~~h~Attached object file loaded~n~%s", EPV[playerid][PAO_NAME]);
  1716.                     AOE_GameTextForPlayer(playerid, AOE_STR);
  1717.                 }
  1718.                 else SendClientMessage(playerid, AOE_COLOR1, AOE_M_ERROR);
  1719.             }
  1720.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_LOAD_SLOT, AOE_T_LOAD, AOE_B_LOAD, AOE_B_BACK);
  1721.         }
  1722.         case AOE_D_LOAD2:
  1723.         {
  1724.             if(response)
  1725.             {
  1726.                 if(AOE_EnteredValidFileName(playerid, inputtext))
  1727.                 {
  1728.                     strupdate(EPV[playerid][PAO_NAME], inputtext);
  1729.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, inputtext);
  1730.                     if(AOE_EnteredExistedFileName(playerid, AOFileName)) cmd_loadattachedobjects(playerid, inputtext);
  1731.                     else AOE_ShowPlayerDialog(playerid, AOE_C_LOAD, AOE_D_LOAD2, AOE_T_LOAD_SET, AOE_B_LOAD, AOE_B_BACK);
  1732.                 }
  1733.                 else if(isnull(inputtext)) AOE_ShowPlayerDialog(playerid, AOE_C_LOAD, AOE_D_LOAD2, AOE_T_LOAD_SET, AOE_B_LOAD, AOE_B_BACK);
  1734.             }
  1735.             else AOE_ShowPlayerDialog(playerid, AOE_C_FILE, AOE_D_FILE, AOE_T_FILE, AOE_B_SELECT, AOE_B_CANCEL);
  1736.         }
  1737.         case AOE_D_SAVE_SLOT:
  1738.         {
  1739.             if(response)
  1740.             {
  1741.                 if(listitem == 10) cmd_saveallattachedobjects(playerid, "");
  1742.                 else
  1743.                 {
  1744.                     if(AOE_HasSlot(playerid, listitem))
  1745.                     {
  1746.                         valstr(AOE_STR, listitem);
  1747.                         cmd_saveattachedobject(playerid, AOE_STR);
  1748.                     }
  1749.                     else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_ALL, AOE_D_SAVE_SLOT, AOE_T_SAVE, AOE_B_SELECT, AOE_B_BACK);
  1750.                 }
  1751.             }
  1752.             else AOE_ShowPlayerDialog(playerid, AOE_C_FILE, AOE_D_FILE, AOE_T_FILE, AOE_B_SELECT, AOE_B_CANCEL);
  1753.         }
  1754.         case AOE_D_SAVE:
  1755.         {
  1756.             if(response)
  1757.             {
  1758.                 if(AOE_EnteredValidFileName(playerid, inputtext))
  1759.                 {
  1760.                     strupdate(EPV[playerid][PAO_NAME], inputtext);
  1761.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, inputtext);
  1762.                     if(AOE_EnteredNonExistFileName(playerid, AOFileName))
  1763.                     {
  1764.                         format(AOE_STR, sizeof AOE_STR, "%d %s", EPV[playerid][PAO_INDEX1], inputtext);
  1765.                         cmd_saveattachedobject(playerid, AOE_STR);
  1766.                     }
  1767.                 }
  1768.                 else AOE_ShowPlayerDialog(playerid, AOE_C_SAVE, AOE_D_SAVE, AOE_T_SAVE, AOE_B_SAVE, AOE_B_BACK);
  1769.             }
  1770.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_ALL, AOE_D_SAVE_SLOT, AOE_T_SAVE, AOE_B_SELECT, AOE_B_SELECT_INDEX);
  1771.         }
  1772.         case AOE_D_SAVE_REPLACE:
  1773.         {
  1774.             if(response)
  1775.             {
  1776.                 format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, EPV[playerid][PAO_NAME]);
  1777.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SAVING);
  1778.                 if(AOE_SavePlayerAttachedObject(playerid, AOFileName, EPV[playerid][PAO_INDEX1], "", AOFileLen))
  1779.                 {
  1780.                     format(AOE_STR, sizeof AOE_STR, "* Your attached object from index %d has been saved as \"{FFFFFF}%s{%06x}\" [Model: %d|Bone: %d|%.2f KB]!",
  1781.                         EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_NAME], AOE_COLOR2 >>> 8, PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MODEL_ID], PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_BONE_ID], AOFileLen);
  1782.                     SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1783.                     SendClientMessage(playerid, AOE_COLOR2, AOE_M_SAVE_OVERWRITE);
  1784.                     format(AOE_STR, sizeof AOE_STR, "~g~~h~Attached object file saved~n~%s", EPV[playerid][PAO_NAME]);
  1785.                     AOE_GameTextForPlayer(playerid, AOE_STR);
  1786.                 }
  1787.                 else
  1788.                 {
  1789.                     SendClientMessage(playerid, AOE_COLOR1, AOE_M_SAVE_ERROR);
  1790.                     AOE_GameTextForPlayer(playerid, AOE_G_INVALID_DATA);
  1791.                 }
  1792.             }
  1793.             else AOE_ShowPlayerDialog(playerid, AOE_C_SAVE, AOE_D_SAVE, AOE_T_SAVE, AOE_B_SAVE, AOE_B_BACK);
  1794.         }
  1795.         case AOE_D_SAVE2:
  1796.         {
  1797.             if(response)
  1798.             {
  1799.                 if(AOE_EnteredValidFileName(playerid, inputtext))
  1800.                 {
  1801.                     strupdate(EPV[playerid][PAO_NAME], inputtext);
  1802.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, inputtext);
  1803.                     if(AOE_EnteredNonExistFileName2(playerid, AOFileName)) cmd_saveallattachedobjects(playerid, inputtext);
  1804.                 }
  1805.                 else AOE_ShowPlayerDialog(playerid, AOE_C_SAVE, AOE_D_SAVE2, AOE_T_SAVE_SET, AOE_B_SAVE, AOE_B_BACK);
  1806.             }
  1807.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_ALL, AOE_D_SAVE_SLOT, AOE_T_SAVE_SET, AOE_B_SELECT, AOE_B_SELECT_INDEX);
  1808.         }
  1809.         case AOE_D_SAVE2_REPLACE:
  1810.         {
  1811.             if(response)
  1812.             {
  1813.                 format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, EPV[playerid][PAO_NAME]);
  1814.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_SAVING_SET);
  1815.                 slots = AOE_SavePlayerAttachedObject(playerid, AOFileName, MAX_PLAYER_ATTACHED_OBJECTS, "", AOFileLen);
  1816.                 if(slots)
  1817.                 {
  1818.                     format(AOE_STR, sizeof AOE_STR, "* Your attached object set has been saved as \"{FFFFFF}%s{%06x}\" (Total: %d|Size: %.2f KB)!", EPV[playerid][PAO_NAME], AOE_COLOR2 >>> 8, slots, AOFileLen);
  1819.                     SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1820.                     SendClientMessage(playerid, AOE_COLOR2, AOE_M_SAVE_SET_OVERWRITE);
  1821.                     format(AOE_STR, sizeof AOE_STR, "~g~~h~Attached object(s) file saved~n~%s", EPV[playerid][PAO_NAME]);
  1822.                     AOE_GameTextForPlayer(playerid, AOE_STR);
  1823.                 }
  1824.                 else SendClientMessage(playerid, AOE_COLOR1, AOE_M_SAVE_SET_ERROR);
  1825.             }
  1826.             else AOE_ShowPlayerDialog(playerid, AOE_C_SAVE, AOE_D_SAVE2, AOE_T_SAVE_SET, AOE_B_SAVE, AOE_B_BACK);
  1827.         }
  1828.         case AOE_D_DELETE:
  1829.         {
  1830.             if(response)
  1831.             {
  1832.                 if(AOE_EnteredValidFileName(playerid, inputtext))
  1833.                 {
  1834.                     format(AOFileName, sizeof AOFileName, AOE_FILE_NAME, inputtext);
  1835.                     if(AOE_EnteredExistedFileName(playerid, AOFileName))
  1836.                     {
  1837.                         cmd_deleteattachedobjectfile(playerid, inputtext);
  1838.                     }
  1839.                     else AOE_ShowPlayerDialog(playerid, AOE_C_DELETE, AOE_D_DELETE, AOE_T_DELETE, AOE_B_DELETE, AOE_B_CANCEL);
  1840.                 }
  1841.                 else if(isnull(inputtext)) AOE_ShowPlayerDialog(playerid, AOE_C_DELETE, AOE_D_DELETE, AOE_T_DELETE, AOE_B_DELETE, AOE_B_CANCEL);
  1842.             }
  1843.             else SendClientMessage(playerid, AOE_COLOR4, AOE_M_DELETE_CANCEL);
  1844.         }
  1845.         case AOE_D_EDIT_SLOT:
  1846.         {
  1847.             if(response)
  1848.             {
  1849.                 if(IsPlayerAttachedObjectSlotUsed(playerid, listitem))
  1850.                 {
  1851.                     EPV[playerid][PAO_INDEX1] = listitem;
  1852.                     format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", listitem);
  1853.                     AOE_ShowPlayerDialog(playerid, AOE_C_EDIT, AOE_D_EDIT, AOE_STR, AOE_B_SELECT, AOE_B_CANCEL);
  1854.                 }
  1855.                 else
  1856.                 {
  1857.                     valstr(AOE_STR, listitem);
  1858.                     cmd_createattachedobject(playerid, AOE_STR);
  1859.                 }
  1860.             }
  1861.             else SendClientMessage(playerid, AOE_COLOR0, AOE_M_EDIT_CANCEL);
  1862.         }
  1863.         case AOE_D_EDIT:
  1864.         {
  1865.             if(response)
  1866.             {
  1867.                 valstr(AOE_STR, EPV[playerid][PAO_INDEX1]);
  1868.                 switch(listitem)
  1869.                 {
  1870.                     case 0: cmd_editattachedobject(playerid, AOE_STR);
  1871.                     case 1:
  1872.                     {
  1873.                         format(AOE_STR, sizeof AOE_STR, "Edit Attached Object Properties (%d)", listitem);
  1874.                         AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_PROPERTIES, AOE_D_EDIT_PROPERTIES, AOE_STR, AOE_B_EDIT, AOE_B_CANCEL);
  1875.                     }
  1876.                     case 2: cmd_attachedobjectproperties(playerid, AOE_STR);
  1877.                     case 3: cmd_duplicateattachedobject(playerid, AOE_STR);
  1878.                     case 4: cmd_removeattachedobject(playerid, AOE_STR);
  1879.                 }
  1880.             }
  1881.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_USED, AOE_D_EDIT_SLOT, AOE_T_EDIT, AOE_B_SELECT, AOE_B_CLOSE);
  1882.         }
  1883.         case AOE_D_EDIT_PROPERTIES:
  1884.         {
  1885.             if(response)
  1886.             {
  1887.                 valstr(AOE_STR, EPV[playerid][PAO_INDEX1]);
  1888.                 if(3 <= listitem <= 13) EPV[playerid][PAO_EDITING] = listitem;
  1889.                 switch(listitem)
  1890.                 {
  1891.                     case 0: cmd_setattachedobjectindex(playerid, AOE_STR);
  1892.                     case 1: cmd_setattachedobjectmodel(playerid, AOE_STR);
  1893.                     case 2: cmd_setattachedobjectbone(playerid, AOE_STR);
  1894.                     case 3..5: // offset
  1895.                     {
  1896.                         format(AOE_STR, sizeof AOE_STR, "Edit Attached Object %c (%d)", ('X'-3)+listitem, EPV[playerid][PAO_INDEX1]);
  1897.                         AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_XYZ, AOE_D_EDIT_XYZ, AOE_STR, AOE_B_ENTER, AOE_B_BACK);
  1898.                     }
  1899.                     case 6..8: // rotation
  1900.                     {
  1901.                         format(AOE_STR, sizeof AOE_STR, "Edit Attached Object R%c (%d)", ('X'-6)+listitem, EPV[playerid][PAO_INDEX1]);
  1902.                         AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_XYZ, AOE_D_EDIT_XYZ, AOE_STR, AOE_B_ENTER, AOE_B_BACK);
  1903.                     }
  1904.                     case 9..11: // scale
  1905.                     {
  1906.                         format(AOE_STR, sizeof AOE_STR, "Edit Attached Object S%c (%d)", ('X'-9)+listitem, EPV[playerid][PAO_INDEX1]);
  1907.                         AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_XYZ, AOE_D_EDIT_XYZ, AOE_STR, AOE_B_ENTER, AOE_B_BACK);
  1908.                     }
  1909.                     case 12..13: // color
  1910.                     {
  1911.                         format(AOE_STR, sizeof AOE_STR, "Edit Attached Object Color %c (%d)", ('1'-12)+listitem, EPV[playerid][PAO_INDEX1]);
  1912.                         AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_COLOR, AOE_D_EDIT_COLOR, AOE_STR, AOE_B_ENTER, AOE_B_BACK);
  1913.                     }
  1914.                 }
  1915.             }
  1916.             else
  1917.             {
  1918.                 format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", EPV[playerid][PAO_INDEX1]);
  1919.                 AOE_ShowPlayerDialog(playerid, AOE_C_EDIT, AOE_D_EDIT, AOE_STR, AOE_B_SELECT, AOE_B_CANCEL);
  1920.             }
  1921.         }
  1922.         case AOE_D_SET_SLOT:
  1923.         {
  1924.             if(response)
  1925.             {
  1926.                 format(AOE_STR, sizeof AOE_STR, "%d %d", EPV[playerid][PAO_INDEX1], listitem);
  1927.                 cmd_setattachedobjectindex(playerid, AOE_STR);
  1928.             }
  1929.             else
  1930.             {
  1931.                 format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", EPV[playerid][PAO_INDEX1]);
  1932.                 AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_PROPERTIES, AOE_D_EDIT_PROPERTIES, AOE_STR, AOE_B_SELECT, AOE_B_BACK);
  1933.             }
  1934.         }
  1935.         case AOE_D_SET_SLOT_REPLACE:
  1936.         {
  1937.             if(response)
  1938.             {
  1939.                 if(ChangePlayerAttachedObjectIndex(playerid, EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]))
  1940.                 {
  1941.                     format(AOE_STR, sizeof AOE_STR, "* Moved & replaced your attached object from index number %d to %d!", EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]);
  1942.                     SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  1943.                     format(AOE_STR, sizeof AOE_STR, "~g~Attached object moved~n~~w~index/number:~n~%d to %d", EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]);
  1944.                     AOE_GameTextForPlayer(playerid, AOE_STR);
  1945.                 }
  1946.                 else SendClientMessage(playerid, AOE_COLOR1, AOE_M_SET_SLOT_FAIL);
  1947.             }
  1948.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_SET_SLOT, AOE_T_SET_INDEX, AOE_B_SELECT, AOE_B_BACK);
  1949.         }
  1950.         case AOE_D_SET_MODEL:
  1951.         {
  1952.             if(response)
  1953.             {
  1954.                 format(AOE_STR, sizeof AOE_STR, "%d %d", EPV[playerid][PAO_INDEX1], strval(inputtext));
  1955.                 cmd_setattachedobjectmodel(playerid, AOE_STR);
  1956.             }
  1957.             else
  1958.             {
  1959.                 format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", EPV[playerid][PAO_INDEX1]);
  1960.                 AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_PROPERTIES, AOE_D_EDIT_PROPERTIES, AOE_STR, AOE_B_SELECT, AOE_B_BACK);
  1961.             }
  1962.         }
  1963.         case AOE_D_SET_BONE:
  1964.         {
  1965.             if(response)
  1966.             {
  1967.                 format(AOE_STR, sizeof AOE_STR, "%d %d", EPV[playerid][PAO_INDEX1], listitem+1);
  1968.                 cmd_setattachedobjectbone(playerid, AOE_STR);
  1969.             }
  1970.             else
  1971.             {
  1972.                 format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", EPV[playerid][PAO_INDEX1]);
  1973.                 AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_PROPERTIES, AOE_D_EDIT_PROPERTIES, AOE_STR, AOE_B_SELECT, AOE_B_BACK);
  1974.             }
  1975.         }
  1976.         case AOE_D_EDIT_XYZ:
  1977.         {
  1978.             AOSelection = EPV[playerid][PAO_EDITING];
  1979.             if(response)
  1980.             {
  1981.                 if(sscanf(inputtext, "f", AOAxis))
  1982.                 {
  1983.                     SendClientMessage(playerid, AOE_COLOR4, AOE_M_INVALID_XYZ);
  1984.                     format(AOE_STR, sizeof AOE_STR, "Edit Attached Object XYZ (%d)", EPV[playerid][PAO_INDEX1]);
  1985.                     AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_XYZ, AOE_D_EDIT_XYZ, AOE_STR, AOE_B_ENTER, AOE_B_BACK);
  1986.                 }
  1987.                 else
  1988.                 {
  1989.                     EPV[playerid][PAO_EDITING] = 0;
  1990.                     switch(AOSelection)
  1991.                     {
  1992.                         case 3..5:
  1993.                         {
  1994.                             format(AOE_STR, sizeof AOE_STR, "%d %c %f", EPV[playerid][PAO_INDEX1], ('x'-3)+AOSelection, AOAxis);
  1995.                             cmd_setattachedobjectoffset(playerid, AOE_STR);
  1996.                         }
  1997.                         case 6..8:
  1998.                         {
  1999.                             format(AOE_STR, sizeof AOE_STR, "%d %c %f", EPV[playerid][PAO_INDEX1], ('x'-6)+AOSelection, AOAxis);
  2000.                             cmd_setattachedobjectrot(playerid, AOE_STR);
  2001.                         }
  2002.                         case 9..11:
  2003.                         {
  2004.                             format(AOE_STR, sizeof AOE_STR, "%d %c %f", EPV[playerid][PAO_INDEX1], ('x'-9)+AOSelection, AOAxis);
  2005.                             cmd_setattachedobjectscale(playerid, AOE_STR);
  2006.                         }
  2007.                     }
  2008.                 }
  2009.             }
  2010.             else
  2011.             {
  2012.                 EPV[playerid][PAO_EDITING] = 0;
  2013.                 format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", EPV[playerid][PAO_INDEX1]);
  2014.                 AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_PROPERTIES, AOE_D_EDIT_PROPERTIES, AOE_STR, AOE_B_SELECT, AOE_B_BACK);
  2015.             }
  2016.         }
  2017.         case AOE_D_EDIT_COLOR:
  2018.         {
  2019.             AOSelection = EPV[playerid][PAO_EDITING];
  2020.             if(response)
  2021.             {
  2022.                 if(sscanf(inputtext, "x", AOMC))
  2023.                 {
  2024.                     SendClientMessage(playerid, AOE_COLOR4, AOE_M_INVALID_COLOR);
  2025.                     format(AOE_STR, sizeof AOE_STR, "Edit Attached Object Color (%d)", EPV[playerid][PAO_INDEX1]);
  2026.                     AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_COLOR, AOE_D_EDIT_COLOR, AOE_STR, AOE_B_ENTER, AOE_B_BACK);
  2027.                 }
  2028.                 else
  2029.                 {
  2030.                     EPV[playerid][PAO_EDITING] = 0;
  2031.                     format(AOE_STR, sizeof AOE_STR, "%d %x", EPV[playerid][PAO_INDEX1], AOMC);
  2032.                     switch(AOSelection)
  2033.                     {
  2034.                         case 12: cmd_setattachedobjectmc1(playerid, AOE_STR);
  2035.                         case 13: cmd_setattachedobjectmc2(playerid, AOE_STR);
  2036.                     }
  2037.                 }
  2038.             }
  2039.             else
  2040.             {
  2041.                 EPV[playerid][PAO_EDITING] = 0;
  2042.                 format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", EPV[playerid][PAO_INDEX1]);
  2043.                 AOE_ShowPlayerDialog(playerid, AOE_C_EDIT_PROPERTIES, AOE_D_EDIT_PROPERTIES, AOE_STR, AOE_B_SELECT, AOE_B_BACK);
  2044.             }
  2045.         }
  2046.         case AOE_D_PROPERTIES:
  2047.         {
  2048.             if(response && IsPlayerAdmin(playerid))
  2049.             {
  2050.                 AOSlot = EPV[playerid][PAO_INDEX1], AOTarget = EPV[playerid][PAO_TARGET];
  2051.                 GetPlayerName(playerid, pName, sizeof pName);
  2052.                 printf("  >> Admin %s (ID:%d) has requested to print attached object properties", pName, playerid);
  2053.                 GetPlayerName(AOTarget, pName, sizeof pName);
  2054.                 printf("  Player: %s (ID:%d)\n  Attached object index number: %d\n  - Model ID/type number: %d\n  - Bone: %s (%d)\n  - Offsets:\n  -- X: %.2f ~ Y: %.2f ~ Z: %.2f\n  - Rotations:\n  -- RX: %.2f ~ RY: %.2f ~ RZ: %.2f\
  2055.                 \n  - Scales:\n  -- SX: %.2f ~ SY: %.2f ~ SZ: %.2f\n  - Material Colors:\n  -- Color 1: 0x%04x%04x (%i) ~ Color 2: 0x%04x%04x (%i)", pName, AOTarget, AOSlot, PAO[AOTarget][AOSlot][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[AOTarget][AOSlot][AO_BONE_ID]),
  2056.                 PAO[AOTarget][AOSlot][AO_BONE_ID], PAO[AOTarget][AOSlot][AO_X], PAO[AOTarget][AOSlot][AO_Y], PAO[AOTarget][AOSlot][AO_Z], PAO[AOTarget][AOSlot][AO_RX], PAO[AOTarget][AOSlot][AO_RY], PAO[AOTarget][AOSlot][AO_RZ],
  2057.                 PAO[AOTarget][AOSlot][AO_SX], PAO[AOTarget][AOSlot][AO_SY], PAO[AOTarget][AOSlot][AO_SZ], HexPrintFormat(PAO[AOTarget][AOSlot][AO_MC1]), PAO[AOTarget][AOSlot][AO_MC1], HexPrintFormat(PAO[AOTarget][AOSlot][AO_MC2], PAO[AOTarget][AOSlot][AO_MC2]));
  2058.                 printf("  Skin: %d ~ Code usage (playerid = %d):\n  SetPlayerAttachedObject(playerid, %d, %d, %d, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %d);", GetPlayerSkin(AOTarget), AOTarget,
  2059.                 AOSlot, PAO[AOTarget][AOSlot][AO_MODEL_ID], PAO[AOTarget][AOSlot][AO_BONE_ID], PAO[AOTarget][AOSlot][AO_X], PAO[AOTarget][AOSlot][AO_Y], PAO[AOTarget][AOSlot][AO_Z], PAO[AOTarget][AOSlot][AO_RX], PAO[AOTarget][AOSlot][AO_RY], PAO[AOTarget][AOSlot][AO_RZ],
  2060.                 PAO[AOTarget][AOSlot][AO_SX], PAO[AOTarget][AOSlot][AO_SY], PAO[AOTarget][AOSlot][AO_SZ], PAO[AOTarget][AOSlot][AO_MC1], PAO[AOTarget][AOSlot][AO_MC2]);
  2061.                 SendClientMessage(playerid, AOE_COLOR0, AOE_M_OBJECT_DATA_S_PRINT);
  2062.             }
  2063.             else SendClientMessage(playerid, AOE_COLOR0, AOE_M_PROPERTIES_CLOSE);
  2064.         }
  2065.         case AOE_D_DUPLICATE_SLOT:
  2066.         {
  2067.             if(response)
  2068.             {
  2069.                 format(AOE_STR, sizeof AOE_STR, "%d %d", EPV[playerid][PAO_INDEX1], listitem);
  2070.                 cmd_duplicateattachedobject(playerid, AOE_STR);
  2071.             }
  2072.             else
  2073.             {
  2074.                 format(AOE_STR, sizeof AOE_STR, "Edit Attached Object (%d)", EPV[playerid][PAO_INDEX1]);
  2075.                 AOE_ShowPlayerDialog(playerid, AOE_C_EDIT, AOE_D_EDIT, AOE_STR, AOE_B_SELECT, AOE_B_CANCEL);
  2076.             }
  2077.         }
  2078.         case AOE_D_DUPLICATE_REPLACE:
  2079.         {
  2080.             if(response)
  2081.             {
  2082.                 DuplicatePlayerAttachedObject(playerid, EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]);
  2083.                 format(AOE_STR, sizeof AOE_STR, "* Duplicated your attached object from index number %d to %d!", EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]);
  2084.                 SendClientMessage(playerid, AOE_COLOR2, AOE_STR);
  2085.                 format(AOE_STR, sizeof AOE_STR, "~g~Attached object duplicated~n~~w~index/number:~n~%d to %d", EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]);
  2086.                 AOE_GameTextForPlayer(playerid, AOE_STR);
  2087.             }
  2088.             else AOE_ShowPlayerDialog(playerid, AOE_C_SLOT_EMPTY, AOE_D_DUPLICATE_SLOT, AOE_T_DUPLICATE, AOE_B_SELECT, AOE_B_BACK);
  2089.         }
  2090.         case AOE_D_REMOVE_ALL:
  2091.         {
  2092.             if(response)
  2093.             {
  2094.                 slots = RemovePlayerAttachedObjectEx(playerid, MAX_PLAYER_ATTACHED_OBJECTS);
  2095.                 format(AOE_STR, sizeof AOE_STR, "* You've removed all %d of your attached object(s)!", slots);
  2096.                 SendClientMessage(playerid, AOE_COLOR1, AOE_STR);
  2097.                 format(AOE_STR, sizeof AOE_STR, "~r~Removed all your attached object(s)~n~~w~Total: %d", slots);
  2098.                 AOE_GameTextForPlayer(playerid, AOE_STR);
  2099.             }
  2100.             else SendClientMessage(playerid, AOE_COLOR0, AOE_M_REMOVE_ALL_CANCEL);
  2101.         }
  2102.         case AOE_D_REFRESH:
  2103.         {
  2104.             AOTarget = EPV[playerid][PAO_TARGET];
  2105.             if(response)
  2106.             {
  2107.                 if(AOE_TargetHasSlot(playerid, AOTarget, listitem))
  2108.                 {
  2109.                     format(AOE_STR, sizeof AOE_STR, "%d %d", AOTarget, listitem);
  2110.                     cmd_refreshattachedobject(playerid, AOE_STR);
  2111.                 }
  2112.                 else AOE_ShowPlayerDialog(playerid, AOE_C_REFRESH, AOE_D_REFRESH, AOE_T_REFRESH, AOE_B_SELECT, AOE_B_CANCEL);
  2113.             }
  2114.             else
  2115.             {
  2116.                 GetPlayerName(AOTarget, pName, sizeof pName);
  2117.                 format(AOE_STR, sizeof AOE_STR, "* You've canceled loading %s (ID:%d)'s attached object from index %d.", pName, EPV[playerid][PAO_TARGET], listitem);
  2118.                 SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2119.             }
  2120.         }
  2121.         case AOE_D_REFRESH_REPLACE:
  2122.         {
  2123.             AOTarget = EPV[playerid][PAO_TARGET];
  2124.             if(response)
  2125.             {
  2126.                 format(AOE_STR, sizeof AOE_STR, "%d %d", AOTarget, EPV[playerid][PAO_INDEX1]);
  2127.                 RemovePlayerAttachedObject(playerid, EPV[playerid][PAO_INDEX1]);
  2128.                 cmd_refreshattachedobject(playerid, AOE_STR);
  2129.             }
  2130.             else AOE_ShowPlayerDialog(playerid, AOE_C_REFRESH, AOE_D_REFRESH, AOE_T_REFRESH, AOE_B_SELECT, AOE_B_CANCEL);
  2131.         }
  2132.     }
  2133.     return 0;
  2134. }
  2135.  
  2136. public OnPlayerEditAttachedObject(playerid, response, index, modelid, boneid, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fScaleX, Float:fScaleY, Float:fScaleZ)
  2137. {
  2138.     if(response == EDIT_RESPONSE_FINAL)
  2139.     {
  2140.         if(MAX_ATTACHED_OBJECT_OFFSET <= fOffsetX <= MIN_ATTACHED_OBJECT_OFFSET || MAX_ATTACHED_OBJECT_OFFSET <= fOffsetY <= MIN_ATTACHED_OBJECT_OFFSET || MAX_ATTACHED_OBJECT_OFFSET <= fOffsetZ <= MIN_ATTACHED_OBJECT_OFFSET
  2141.             || MAX_ATTACHED_OBJECT_ROTATION <= fRotX <= MIN_ATTACHED_OBJECT_ROTATION || MAX_ATTACHED_OBJECT_ROTATION <= fRotY <= MIN_ATTACHED_OBJECT_ROTATION || MAX_ATTACHED_OBJECT_ROTATION <= fRotZ <= MIN_ATTACHED_OBJECT_ROTATION
  2142.             || MAX_ATTACHED_OBJECT_SIZE <= fScaleX <= MIN_ATTACHED_OBJECT_SIZE || MAX_ATTACHED_OBJECT_SIZE <= fScaleY <= MIN_ATTACHED_OBJECT_SIZE || MAX_ATTACHED_OBJECT_SIZE <= fScaleZ <= MIN_ATTACHED_OBJECT_SIZE)
  2143.         {
  2144.             format(AOE_STR, sizeof AOE_STR, "* Sorry your edit on index %d was aborted, because you cannot edit with value of:", index);
  2145.             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2146.             SendClientMessage(playerid, AOE_COLOR0, AOE_M_ACCEPTABLE_OFFSET);
  2147.             SendClientMessage(playerid, AOE_COLOR0, AOE_M_ACCEPTABLE_ROTATION);
  2148.             SendClientMessage(playerid, AOE_COLOR0, AOE_M_ACCEPTABLE_SCALE);
  2149.             format(AOE_STR, sizeof AOE_STR, "* Edit was: X=%.2f|Y=%.2f|Z=%.2f|RX=%.2f|RY=%.2f|RZ=%.2f|SX=%.2f|SY=%.2f|SZ=%.2f", fOffsetX, fOffsetY, fOffsetZ, fRotX, fRotY, fRotZ, fScaleX, fScaleY, fScaleZ);
  2150.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2151.             SetPlayerAttachedObject(playerid, index, PAO[playerid][index][AO_MODEL_ID], PAO[playerid][index][AO_BONE_ID], PAO[playerid][index][AO_X], PAO[playerid][index][AO_Y], PAO[playerid][index][AO_Z],
  2152.             PAO[playerid][index][AO_RX], PAO[playerid][index][AO_RY], PAO[playerid][index][AO_RZ], PAO[playerid][index][AO_SX], PAO[playerid][index][AO_SY], PAO[playerid][index][AO_SZ], PAO[playerid][index][AO_MC1], PAO[playerid][index][AO_MC2]);
  2153.             PAO[playerid][index][AO_STATUS] = 1;
  2154.         }
  2155.         else
  2156.         {
  2157.             if(IsValidPlayerAttachedObject(playerid, index) != 1)
  2158.             {
  2159.                 format(AOE_STR, sizeof AOE_STR, "* Refreshing attached object (ID:%d) data (excluding material colors)...", index);
  2160.                 SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2161.             }
  2162.             if(EPV[playerid][PAO_EDITING] == 2)
  2163.             {
  2164.                 PAO[playerid][index][AO_STATUS] = 1;
  2165.                 PAO[playerid][index][AO_MODEL_ID] = modelid;
  2166.                 PAO[playerid][index][AO_BONE_ID] = boneid;
  2167.             }
  2168.             PAO[playerid][index][AO_X] = fOffsetX, PAO[playerid][index][AO_Y] = fOffsetY, PAO[playerid][index][AO_Z] = fOffsetZ;
  2169.             PAO[playerid][index][AO_RX] = fRotX, PAO[playerid][index][AO_RY] = fRotY, PAO[playerid][index][AO_RZ] = fRotZ;
  2170.             PAO[playerid][index][AO_SX] = fScaleX, PAO[playerid][index][AO_SY] = fScaleY, PAO[playerid][index][AO_SZ] = fScaleZ;
  2171.             format(AOE_STR, sizeof AOE_STR, "* You've edited your attached object from index number %d.", index);
  2172.             SendClientMessage(playerid, AOE_COLOR5, AOE_STR);
  2173.             format(AOE_STR, sizeof AOE_STR, "~b~~h~Edited your attached object~n~~w~index/number: %d", index);
  2174.             AOE_GameTextForPlayer(playerid, AOE_STR);
  2175.         }
  2176.     }
  2177.     if(response == EDIT_RESPONSE_CANCEL)
  2178.     {
  2179.         SetPlayerAttachedObject(playerid, index, PAO[playerid][index][AO_MODEL_ID], PAO[playerid][index][AO_BONE_ID], PAO[playerid][index][AO_X], PAO[playerid][index][AO_Y], PAO[playerid][index][AO_Z],
  2180.         PAO[playerid][index][AO_RX], PAO[playerid][index][AO_RY], PAO[playerid][index][AO_RZ], PAO[playerid][index][AO_SX], PAO[playerid][index][AO_SY], PAO[playerid][index][AO_SZ], PAO[playerid][index][AO_MC1], PAO[playerid][index][AO_MC2]);
  2181.         PAO[playerid][index][AO_STATUS] = 1;
  2182.         format(AOE_STR, sizeof AOE_STR, "* You've canceled editing your attached object from index number %d.", index);
  2183.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2184.         format(AOE_STR, sizeof AOE_STR, "~r~~h~Canceled editing your attached object~n~~w~index/number: %d", index);
  2185.         AOE_GameTextForPlayer(playerid, AOE_STR);
  2186.     }
  2187.     EPV[playerid][PAO_EDITING] = 0;
  2188.     return 1;
  2189. }
  2190. // =============================================================================
  2191. public AOE_GetPVar(playerid, varname[])
  2192. {
  2193.     if(!strcmp(varname, "PAO_INDEX1")) return EPV[playerid][PAO_INDEX1];
  2194.     else if(!strcmp(varname, "PAO_INDEX2")) return EPV[playerid][PAO_INDEX2];
  2195.     else if(!strcmp(varname, "PAO_MODEL_ID")) return EPV[playerid][PAO_MODEL_ID];
  2196.     else if(!strcmp(varname, "PAO_BONE_ID")) return EPV[playerid][PAO_BONE_ID];
  2197.     else if(!strcmp(varname, "PAO_EDITING")) return EPV[playerid][PAO_EDITING];
  2198.     else if(!strcmp(varname, "PAO_TARGET")) return EPV[playerid][PAO_TARGET];
  2199.     else if(!strcmp(varname, "PAO_LAST_REMOVED")) return EPV[playerid][PAO_LAST_REMOVED];
  2200.     else if(!strcmp(varname, "PAO_NAME")) return EPV[playerid][PAO_NAME];
  2201.     return -1;
  2202. }
  2203.  
  2204. AOE_UnsetValues(playerid, index)
  2205. {
  2206.     PAO[playerid][index][AO_STATUS] = 0;
  2207.     PAO[playerid][index][AO_MODEL_ID] = 0, PAO[playerid][index][AO_BONE_ID] = 0;
  2208.     PAO[playerid][index][AO_X] = 0.0, PAO[playerid][index][AO_Y] = 0.0, PAO[playerid][index][AO_Z] = 0.0;
  2209.     PAO[playerid][index][AO_RX] = 0.0, PAO[playerid][index][AO_RY] = 0.0, PAO[playerid][index][AO_RZ] = 0.0;
  2210.     PAO[playerid][index][AO_SX] = 0.0, PAO[playerid][index][AO_SY] = 0.0, PAO[playerid][index][AO_SZ] = 0.0;
  2211.     PAO[playerid][index][AO_MC1] = 0, PAO[playerid][index][AO_MC2] = 0;
  2212. }
  2213.  
  2214. AOE_UnsetVars(playerid)
  2215. {
  2216.     if(EPV[playerid][PAO_EDITING] >= 1) CancelEdit(playerid);
  2217.     EPV[playerid][PAO_INDEX1] = 0;
  2218.     EPV[playerid][PAO_INDEX2] = 0;
  2219.     EPV[playerid][PAO_MODEL_ID] = 0;
  2220.     EPV[playerid][PAO_BONE_ID] = 0;
  2221.     EPV[playerid][PAO_EDITING] = 0;
  2222.     EPV[playerid][PAO_TARGET] = 0;
  2223.     EPV[playerid][PAO_NAME][0] = EOS;
  2224.     EPV[playerid][PAO_LAST_REMOVED] = MAX_PLAYER_ATTACHED_OBJECTS;
  2225. }
  2226.  
  2227. AOE_ShowPlayerDialog(playerid, class, dialogid, caption[], button1[], button2[] = "")
  2228. {
  2229.     new slots, AOE_STR2[1430];
  2230.     switch(class)
  2231.     {
  2232.         case AOE_C: // Menu
  2233.         {
  2234.             slots = GetPlayerAttachedObjectsCount(playerid);
  2235.             if(slots) format(AOE_STR, sizeof AOE_STR, "Edit...\nClear all [%d]", slots);
  2236.             else AOE_STR = "{808080}Edit...\n{808080}Clear all";
  2237.             if(0 <= EPV[playerid][PAO_LAST_REMOVED] < MAX_PLAYER_ATTACHED_OBJECTS)
  2238.             {
  2239.                 if(IsPlayerAttachedObjectSlotUsed(playerid, EPV[playerid][PAO_LAST_REMOVED])) format(AOE_STR2, sizeof AOE_STR2, "{FF3333}Restore last deleted", EPV[playerid][PAO_LAST_REMOVED]);
  2240.                 else format(AOE_STR2, sizeof AOE_STR2, "Restore last deleted [index: %d]", EPV[playerid][PAO_LAST_REMOVED]);
  2241.             }
  2242.             else AOE_STR2 = "{808080}Restore last deleted";
  2243.             format(AOE_STR2, sizeof AOE_STR2, "%sCreate...\nFile...\n%s\n%s\n%sStatistics\nHelp commands\nAbout this editor",
  2244.                 (slots == MAX_PLAYER_ATTACHED_OBJECTS ? ("{FF3333}") : ("")), AOE_STR, AOE_STR2, (IsPlayerAdmin(playerid) ? ("{006699}") : ("")));
  2245.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2246.         }
  2247.         case AOE_C_FILE: // File menu
  2248.         {
  2249.             slots = GetPlayerAttachedObjectsCount(playerid);
  2250.             if(slots == MAX_PLAYER_ATTACHED_OBJECTS) AOE_STR2 = "{FF3333}Load an attached object\n{FF3333}Load attached object(s) set\nSave attached object";
  2251.             else if(slots == 0) AOE_STR2 = "Load an attached object\nLoad attached object(s) set\n{808080}Save attached object";
  2252.             else AOE_STR2 = "Load an attached object\nLoad attached object(s) set\nSave attached object";
  2253.             if(IsPlayerAdmin(playerid)) strcat(AOE_STR2, "\n{FFFF66}Delete attached object file");
  2254.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2255.         }
  2256.         case AOE_C_EDIT: // Edit menu
  2257.         {
  2258.             slots = GetPlayerAttachedObjectsCount(playerid);
  2259.             format(AOE_STR2, sizeof AOE_STR2, "Adjust\nEdit Properties\nView Properties\n%sDuplicate\n%sRemove",
  2260.                 (slots == MAX_PLAYER_ATTACHED_OBJECTS ? ("{FF3333}") : ("")), (slots == MAX_PLAYER_ATTACHED_OBJECTS ? ("{FFFFFF}") : ("")));
  2261.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2262.         }
  2263.         case AOE_C_HELP: // Help
  2264.         {
  2265.             AOE_STR2 = "/attachedobjecteditor (/aoe): Shows attached object editor menu dialog\n\
  2266.                 /createattachedobject (/cao): Create your attached object\n\
  2267.                 /editattachedobject (/eao): Edit your attached object\n\
  2268.                 /duplicateattachedobject (/dao): Duplicate your attached object\n";
  2269.             strcat(AOE_STR2, "/removeattachedobject (/rao): Remove your attached object\n\
  2270.                 /removeattachedobjects (/raos): Remove all of your attached object(s)\n\
  2271.                 /undeleteattachedobject (/udao): Restore your deleted attached object\n\
  2272.                 /saveattachedobject (/sao): Save your attached object to a file\n");
  2273.             strcat(AOE_STR2, "/saveattachedobjects (/saos): Save all of your attached object(s) to a set file\n\
  2274.                 /loadattachedobject (/lao): Load existing attached object file\n\
  2275.                 /loadattachedobjects (/laos): Load existing attached object(s) set file\n\
  2276.                 /attachedobjectstats (/aos): Shows a player or your attached object stats\n");
  2277.             strcat(AOE_STR2, "/refreshattachedobject (/rpao): Refresh another player's attached object\n\
  2278.                 /setattachedobjectindex (/saoi): Set your attached object index\n\
  2279.                 /setattachedobjectmodel (/saom): Set your attached object model\n");
  2280.             strcat(AOE_STR2, "/setattachedobjectbone (/saob): Set your attached object bone\n\
  2281.                 /setattachedobjectoffset (/saoo): Set your attached object offset [X/Y/Z]\n\
  2282.                 /setattachedobjectrot (/saor): Set your attached object rotation [RX/RY/RZ]\n");
  2283.             strcat(AOE_STR2, "/setattachedobjectscale (/saos): Set your attached object size [SX/SY/SZ]\n\
  2284.                 /setattachedobjectmc (/saomc[1/2]): Set your attached object material color [#1/#2]");
  2285.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR2, button1, button2);
  2286.         }
  2287.         case AOE_C_ABOUT: // About
  2288.         {
  2289.             GetPlayerName(playerid, pName, sizeof pName);
  2290.             format(AOE_STR2, sizeof AOE_STR2, "[FilterScript] Attached Object Editor for SA:MP 0.3e or upper\nAn editor for player attachment\n\nVersion: %s\nCreated by: Robo_N1X\nhttp://forum.sa-mp.com/showthread.php?t=416138\n\nCredits & Thanks to:\n\
  2291.             > SA:MP Team (www.sa-mp.com)\n> Scott: attachments editor idea\n> Y_Less (y-less.com)\n> Zeex: ZCMD\n> SA:MP Wiki Contributors (wiki.sa-mp.com)\nAnd whoever that made useful function for this script\nAlso you, %s for using this editor!",
  2292.             AOE_VERSION, pName); // Keep the script form like this or the compiler will crash!
  2293.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR2, button1, button2);
  2294.         }
  2295.         case AOE_C_SLOT_EMPTY: // Free slot list
  2296.         {
  2297.             for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  2298.             {
  2299.                 if(IsValidPlayerAttachedObject(playerid, i) == -1) format(AOE_STR2, sizeof AOE_STR2, "%s{FFFFFF}%d. None\n", AOE_STR2, i);
  2300.                 else if(!IsValidPlayerAttachedObject(playerid, i)) format(AOE_STR2, sizeof AOE_STR2, "%s{808080}%d. Unknown - Invalid attached object info\n", AOE_STR2, i);
  2301.                 else format(AOE_STR2, sizeof AOE_STR2, "%s{FF3333}%d. %d - %s (Bone:%d) - (Used)\n", AOE_STR2, i, PAO[playerid][i][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[playerid][i][AO_BONE_ID]), PAO[playerid][i][AO_BONE_ID]);
  2302.             }
  2303.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2304.             if(!strcmp(button1, AOE_B_SELECT, true)) format(AOE_STR, sizeof AOE_STR, "* %s: Please select attached object index number...", caption);
  2305.             else format(AOE_STR, sizeof AOE_STR, "* %s: Please select attached object index number to %s...", caption, button1);
  2306.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2307.         }
  2308.         case AOE_C_SLOT_USED: // Used slot list
  2309.         {
  2310.             for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  2311.             {
  2312.                 if(IsValidPlayerAttachedObject(playerid, i) == -1) format(AOE_STR2, sizeof AOE_STR2, "%s{FF3333}%d. None - (Not Used)\n", AOE_STR2, i);
  2313.                 else if(!IsValidPlayerAttachedObject(playerid, i)) format(AOE_STR2, sizeof AOE_STR2, "%s{CCCCCC}%d. Unknown - Invalid attached object info\n", AOE_STR2, i);
  2314.                 else format(AOE_STR2, sizeof AOE_STR2, "%s{FFFFFF}%d. %d - %s (Bone:%d)\n", AOE_STR2, i, PAO[playerid][i][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[playerid][i][AO_BONE_ID]), PAO[playerid][i][AO_BONE_ID]);
  2315.             }
  2316.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2317.             if(!strcmp(button1, AOE_B_SELECT, true)) format(AOE_STR, sizeof AOE_STR, "* %s: Please select attached object index number...", caption);
  2318.             else format(AOE_STR, sizeof AOE_STR, "* %s: Please select attached object index number to %s...", caption, button1);
  2319.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2320.         }
  2321.         case AOE_C_SLOT_ALL: // Used slot list + all
  2322.         {
  2323.             for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  2324.             {
  2325.                 if(IsValidPlayerAttachedObject(playerid, i) == -1) format(AOE_STR2, sizeof AOE_STR2, "%s{FF3333}%d. None - (Not Used)\n", AOE_STR2, i);
  2326.                 else if(!IsValidPlayerAttachedObject(playerid, i))
  2327.                 {
  2328.                     format(AOE_STR2, sizeof AOE_STR2, "%s{808080}%d. Unknown - Invalid attached object info\n", AOE_STR2, i);
  2329.                     slots++;
  2330.                 }
  2331.                 else
  2332.                 {
  2333.                     format(AOE_STR2, sizeof AOE_STR2, "%s{FFFFFF}%d. %d - %s (Bone:%d)\n", AOE_STR2, i, PAO[playerid][i][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[playerid][i][AO_BONE_ID]), PAO[playerid][i][AO_BONE_ID]);
  2334.                     slots++;
  2335.                 }
  2336.             }
  2337.             format(AOE_STR2, sizeof AOE_STR2, "%s{CCFFFF}%s all used attached object index (%d)", AOE_STR2, button1, slots);
  2338.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2339.             if(!strcmp(button1, AOE_B_SELECT, true)) format(AOE_STR, sizeof AOE_STR, "* %s: Please select attached object index number...", caption);
  2340.             else format(AOE_STR, sizeof AOE_STR, "* %s: Please select attached object index number to %s...", caption, button1);
  2341.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2342.         }
  2343.         case AOE_C_REFRESH: // Target's used slot list
  2344.         {
  2345.             AOTarget = EPV[playerid][PAO_TARGET];
  2346.             for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  2347.             {
  2348.                 if(IsValidPlayerAttachedObject(AOTarget, i) == -1) format(AOE_STR2, sizeof AOE_STR2, "%s{FF3333}%d. None - (Not Used)\n", AOE_STR2, i);
  2349.                 else if(!IsValidPlayerAttachedObject(AOTarget, i)) format(AOE_STR2, sizeof AOE_STR2, "%s{CCCCCC}%d. Unknown - Invalid attached object info\n", AOE_STR2, i);
  2350.                 else format(AOE_STR2, sizeof AOE_STR2, "%s{FFFFFF}%d. %d - %s (Bone:%d)\n", AOE_STR2, i, PAO[AOTarget][i][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[AOTarget][i][AO_BONE_ID]), PAO[AOTarget][i][AO_BONE_ID]);
  2351.             }
  2352.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2353.             format(AOE_STR, sizeof AOE_STR, "* Refresh Attached Object: Please select attached object index number from target player...", caption);
  2354.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2355.         }
  2356.         case AOE_C_MODEL: // Object model input
  2357.         {
  2358.             format(AOE_STR, sizeof AOE_STR, "* %s: Please enter object model id/number...", caption);
  2359.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_INPUT, caption, AOE_I_ENTER_MODEL, button1, button2);
  2360.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2361.         }
  2362.         case AOE_C_BONE: // Bone list
  2363.         {
  2364.             for(new i = 1; i <= MAX_ATTACHED_OBJECT_BONES; i++)
  2365.             {
  2366.                 format(AOE_STR2, sizeof AOE_STR2, "%s%d. %s\n", AOE_STR2, i, GetAttachedObjectBoneName(i));
  2367.             }
  2368.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, AOE_STR2, button1, button2);
  2369.             format(AOE_STR, sizeof AOE_STR, "* %s: Please select attached object bone...", caption);
  2370.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2371.         }
  2372.         case AOE_C_CREATE_FINAL: // Final create
  2373.         {
  2374.             format(AOE_STR2, sizeof AOE_STR2, "You've created your attached object\nat index number: %d\nModel: %d\nBone: %s (%d)\n\nDo you want to edit your attached object?", EPV[playerid][PAO_INDEX1],
  2375.             EPV[playerid][PAO_MODEL_ID], GetAttachedObjectBoneName(EPV[playerid][PAO_BONE_ID]), EPV[playerid][PAO_BONE_ID]);
  2376.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR2, button1, button2);
  2377.         }
  2378.         case AOE_C_REMOVE_ALL: // Remove all
  2379.         {
  2380.             format(AOE_STR2, sizeof AOE_STR2, "You're about to remove all of your attached object(s)\nTotal: %d\nAre you sure you want to remove them?\n(This action can't be undone)", GetPlayerAttachedObjectsCount(playerid));
  2381.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR2, button1, button2);
  2382.         }
  2383.         case AOE_C_PROPERTIES: // View properties
  2384.         {
  2385.             AOSlot = EPV[playerid][PAO_INDEX1], AOTarget = EPV[playerid][PAO_TARGET];
  2386.             GetPlayerName(AOTarget, pName, sizeof pName);
  2387.             format(AOE_STR2, sizeof AOE_STR2, "Attached object index number %d properties...\n\nStatus: %s\nModel ID/Number/Type: %d\nBone: %s (%d)\n\nOffsets\nX Offset: %f\nY Offset: %f\nZ Offset: %f\n\nRotations\nX Rotation: %f\nY Rotation: %f\
  2388.             \nZ Rotation: %f\n\nScales\nX Scale: %f\nY Scale: %f\nZ Scale: %f\n\nMaterials\nColor 1: 0x%x (%i) {%06x}{A9C4E4}\nColor 2: 0x%x (%i) {%06x}{A9C4E4}\n\nSkin ID: %d\nTotal of %s's attached object(s): %d", AOSlot,
  2389.             ((PAO[AOTarget][AOSlot][AO_STATUS] == 0) ? ("Invalid data") : ((PAO[AOTarget][AOSlot][AO_STATUS] == 1) ? ("Valid Data") : ("Editing"))), PAO[AOTarget][AOSlot][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[AOTarget][AOSlot][AO_BONE_ID]), PAO[AOTarget][AOSlot][AO_BONE_ID],
  2390.             PAO[AOTarget][AOSlot][AO_X], PAO[AOTarget][AOSlot][AO_Y], PAO[AOTarget][AOSlot][AO_Z], PAO[AOTarget][AOSlot][AO_RX], PAO[AOTarget][AOSlot][AO_RY], PAO[AOTarget][AOSlot][AO_RZ], PAO[AOTarget][AOSlot][AO_SX], PAO[AOTarget][AOSlot][AO_SY], PAO[AOTarget][AOSlot][AO_SZ],
  2391.             PAO[AOTarget][AOSlot][AO_MC1], PAO[AOTarget][AOSlot][AO_MC1], PAO[AOTarget][AOSlot][AO_MC1] & 0xFFFFFF, PAO[AOTarget][AOSlot][AO_MC2], PAO[AOTarget][AOSlot][AO_MC2], PAO[AOTarget][AOSlot][AO_MC2] & 0xFFFFFF, GetPlayerSkin(AOTarget), pName, GetPlayerAttachedObjectsCount(AOTarget));
  2392.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR2, (IsPlayerAdmin(playerid) ? button1 : button2), (IsPlayerAdmin(playerid) ? button2 : "")); // Only show close button for non-admin
  2393.             if(AOTarget == playerid) format(AOE_STR, sizeof AOE_STR, "* You're viewing your attached object properties from index number %d.", AOSlot);
  2394.             else format(AOE_STR, sizeof AOE_STR, "* You're viewing %s's attached object properties from index number %d.", pName, AOSlot);
  2395.             SendClientMessage(playerid, AOE_COLOR5, AOE_STR);
  2396.             if(IsPlayerAdmin(playerid)) SendClientMessage(playerid, AOE_COLOR0, AOE_M_OBJECT_DATA_PRINT);
  2397.         }
  2398.         case AOE_C_EDIT_PROPERTIES: // Edit properties
  2399.         {
  2400.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_LIST, caption, "Change index\nChange model\nChange bone\nChange X offset\nChange Y offset\nChange Z offset\n\
  2401.                 Change X rotation\nChange Y rotation\nChange Z rotation\nChange X scale\nChange Y scale\nChange Z scale\nChange #1 material color\nChange #2 material color", button1, button2);
  2402.         }
  2403.         case AOE_C_EDIT_XYZ: // Edit property value
  2404.         {
  2405.             new xyz_selection[3];
  2406.             switch(EPV[playerid][PAO_EDITING])
  2407.             {
  2408.                 case 3:
  2409.                 {
  2410.                     xyz_selection = "X";
  2411.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_X];
  2412.                 }
  2413.                 case 4:
  2414.                 {
  2415.                     xyz_selection = "Y";
  2416.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_Y];
  2417.                 }
  2418.                 case 5:
  2419.                 {
  2420.                     xyz_selection = "Z";
  2421.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_Z];
  2422.                 }
  2423.                 case 6:
  2424.                 {
  2425.                     xyz_selection = "RX";
  2426.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_RX];
  2427.                 }
  2428.                 case 7:
  2429.                 {
  2430.                     xyz_selection = "RY";
  2431.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_RY];
  2432.                 }
  2433.                 case 8:
  2434.                 {
  2435.                     xyz_selection = "RZ";
  2436.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_RZ];
  2437.                 }
  2438.                 case 9:
  2439.                 {
  2440.                     xyz_selection = "SX";
  2441.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_SX];
  2442.                 }
  2443.                 case 10:
  2444.                 {
  2445.                     xyz_selection = "SY";
  2446.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_SY];
  2447.                 }
  2448.                 case 11:
  2449.                 {
  2450.                     xyz_selection = "SZ";
  2451.                     AOAxis = PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_SZ];
  2452.                 }
  2453.                 default: return;
  2454.             }
  2455.             format(AOE_STR2, sizeof AOE_STR2, "Current %s value is %.4f\nEnter a new value below:", xyz_selection, AOAxis);
  2456.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_INPUT, caption, AOE_STR2, button1, button2);
  2457.         }
  2458.         case AOE_C_EDIT_COLOR: // Edit color
  2459.         {
  2460.             switch(EPV[playerid][PAO_EDITING])
  2461.             {
  2462.                 case 12:
  2463.                 {
  2464.                     format(AOE_STR2, sizeof AOE_STR2, "Current material color (#1) value is: 0x%x (%i) {%06x}{A9C4E4}\n\nEnter a new value below:",
  2465.                         PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MC1], PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MC1], PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MC1] & 0xFFFFFF);
  2466.                 }
  2467.                 case 13:
  2468.                 {
  2469.                     format(AOE_STR2, sizeof AOE_STR2, "Current material color (#2) value is: 0x%x (%i) {%06x}{A9C4E4}\n\nEnter a new value below:",
  2470.                         PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MC2], PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MC2], PAO[playerid][EPV[playerid][PAO_INDEX1]][AO_MC2] & 0xFFFFFF);
  2471.                 }
  2472.                 default: return;
  2473.             }
  2474.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_INPUT, caption, AOE_STR2, button1, button2);
  2475.  
  2476.         }
  2477.         case AOE_C_DUPLICATE_REPLACE: // Replace duplicate
  2478.         {
  2479.             format(AOE_STR, sizeof AOE_STR, "You already have attached object at index number %d!\nDo you want to replace it with attached object from slot %d?", EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]);
  2480.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR, button1, button2);
  2481.         }
  2482.         case AOE_C_CREATE_REPLACE: // Replace create
  2483.         {
  2484.             format(AOE_STR, sizeof AOE_STR, "Sorry, attached object index number %d\nis already used, do you want to replace it?\n(This action can't be undone)", EPV[playerid][PAO_INDEX1]);
  2485.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR, button1, button2);
  2486.         }
  2487.         case AOE_C_SET_INDEX_REPLACE: // Replace set index
  2488.         {
  2489.             format(AOE_STR, sizeof AOE_STR, "You already have attached object at index number %d!\nDo you want to replace it with attached object from slot %d?", EPV[playerid][PAO_INDEX1], EPV[playerid][PAO_INDEX2]);
  2490.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR, button1, button2);
  2491.         }
  2492.         case AOE_C_REFRESH_REPLACE: // Replace refresh
  2493.         {
  2494.             AOSlot = EPV[playerid][PAO_INDEX1], AOTarget = EPV[playerid][PAO_TARGET];
  2495.             GetPlayerName(AOTarget, pName, sizeof pName);
  2496.             format(AOE_STR2, sizeof AOE_STR2, "You are about to replace your attached object,\nIndex: %d, Model: %d, Bone: %s (%d)\nwith %s (ID:%d)'s attached object,\nIndex: %d, Model: %d, Bone: %s (%d)\n\nContinue?", AOSlot, PAO[playerid][AOSlot][AO_MODEL_ID],
  2497.             GetAttachedObjectBoneName(PAO[playerid][AOSlot][AO_BONE_ID]), PAO[playerid][AOSlot][AO_BONE_ID], pName, AOTarget, AOSlot, PAO[AOTarget][AOSlot][AO_MODEL_ID], GetAttachedObjectBoneName(PAO[AOTarget][AOSlot][AO_BONE_ID]), PAO[AOTarget][AOSlot][AO_BONE_ID]);
  2498.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR2, button1, button2);
  2499.             SendClientMessage(playerid, AOE_COLOR4, AOE_M_REFRESH_WARNING);
  2500.         }
  2501.         case AOE_C_LOAD_REPLACE: // Replace load
  2502.         {
  2503.             format(AOE_STR, sizeof AOE_STR, "You already have attached object at index number %d!\nDo you want to continue loading and replace it?", EPV[playerid][PAO_INDEX1]);
  2504.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR, button1, button2);
  2505.         }
  2506.         case AOE_C_SAVE_REPLACE: // Replace save
  2507.         {
  2508.             format(AOE_STR2, sizeof AOE_STR2, "The file \"{FFFFFF}%s{A9C4E4}\" is already exist!\nDo you want to replace and overwrite it?\n(This action can't be undone)", EPV[playerid][PAO_NAME]);
  2509.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_MSGBOX, caption, AOE_STR2, button1, button2);
  2510.             SendClientMessage(playerid, AOE_COLOR0, AOE_M_OVERWRITE);
  2511.         }
  2512.         case AOE_C_SAVE: // Save
  2513.         {
  2514.             format(AOE_STR, sizeof AOE_STR, "* %s: Please enter attached object file name to save...", caption);
  2515.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_INPUT, caption, AOE_I_SAVE_NAME, button1, button2);
  2516.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2517.         }
  2518.         case AOE_C_LOAD: // Load
  2519.         {
  2520.             format(AOE_STR, sizeof AOE_STR, "* %s: Please enter attached object file name to load...", caption);
  2521.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_INPUT, caption, AOE_I_LOAD_NAME, button1, button2);
  2522.             SendClientMessage(playerid, AOE_COLOR0, AOE_STR);
  2523.         }
  2524.         case AOE_C_DELETE: // Delete
  2525.         {
  2526.             ShowPlayerDialog(playerid, dialogid, DIALOG_STYLE_INPUT, caption, "Please enter attached object file name below\n\nName length must be 1-24 characters without extension\n\
  2527.                 Valid characters are: A to Z or a to z, 0 to 9 and @, $, (, ), [, ], _, =\n\nPlease note that the file will be deleted permanently and can't be restored", button1, button2);
  2528.         }
  2529.     }
  2530. }
  2531.  
  2532. AOE_GameTextForPlayer(playerid, const string[])
  2533.     return GameTextForPlayer(playerid, string, 3000, 3);
  2534.  
  2535. AOE_CanEdit(playerid)
  2536. {
  2537.     new playerState = GetPlayerState(playerid);
  2538.     if(playerState == PLAYER_STATE_WASTED || playerState == PLAYER_STATE_SPECTATING)
  2539.     {
  2540.         SendClientMessage(playerid, AOE_COLOR1, AOE_M_CANT_EDIT);
  2541.         return false;
  2542.     }
  2543.     else if(EPV[playerid][PAO_EDITING] != 0)
  2544.     {
  2545.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_EDIT_NOTICE);
  2546.         return false;
  2547.     }
  2548.     else return true;
  2549. }
  2550.  
  2551. AOE_HasFreeSlot(playerid)
  2552. {
  2553.     if(GetPlayerAttachedObjectsCount(playerid) == MAX_PLAYER_ATTACHED_OBJECTS)
  2554.     {
  2555.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_NO_ENOUGH_SLOT);
  2556.         AOE_GameTextForPlayer(playerid, AOE_G_NO_ENOUGH_SLOT);
  2557.         SendClientMessage(playerid, AOE_COLOR0, AOE_M_MAX_SLOT_INFO);
  2558.         return false;
  2559.     }
  2560.     else return true;
  2561. }
  2562.  
  2563. AOE_HasSlot(playerid, index)
  2564. {
  2565.     if(!IsPlayerAttachedObjectSlotUsed(playerid, index))
  2566.     {
  2567.         format(AOE_STR, sizeof AOE_STR, "* Sorry, you don't have attached object at index number %d.", index);
  2568.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2569.         format(AOE_STR, sizeof AOE_STR, "~r~~h~You have no attached object~n~~w~index number: %d", index);
  2570.         AOE_GameTextForPlayer(playerid, AOE_STR);
  2571.         return false;
  2572.     }
  2573.     return true;
  2574. }
  2575.  
  2576. AOE_TargetHasSlot(playerid, targetid, index)
  2577. {
  2578.     if(!IsPlayerAttachedObjectSlotUsed(targetid, index))
  2579.     {
  2580.         GetPlayerName(targetid, pName, sizeof pName);
  2581.         format(AOE_STR, sizeof AOE_STR, "* Sorry, %s (ID:%d) has no attached object at index number {FFFFFF}%d{%06x}.", pName, targetid, index, AOE_COLOR4 >>> 8);
  2582.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2583.         return false;
  2584.     }
  2585.     return true;
  2586. }
  2587.  
  2588. AOE_HasAttachedObject(playerid)
  2589. {
  2590.     if(GetPlayerAttachedObjectsCount(playerid) == 0)
  2591.     {
  2592.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_NO_ATTACHED_OBJECT);
  2593.         AOE_GameTextForPlayer(playerid, AOE_G_NO_ATTACHED_OBJECT);
  2594.         return false;
  2595.     }
  2596.     return true;
  2597. }
  2598.  
  2599. AOE_EnteredValidSlot(playerid, index)
  2600. {
  2601.     if(!IsValidAttachedObjectSlot(index))
  2602.     {
  2603.         format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object index number (%d).", index);
  2604.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2605.         AOE_GameTextForPlayer(playerid, AOE_G_INVALID_SLOT);
  2606.         return false;
  2607.     }
  2608.     return true;
  2609. }
  2610.  
  2611. AOE_EnteredValidModel(playerid, modelid)
  2612. {
  2613.     if(!IsValidObjectModel(modelid))
  2614.     {
  2615.         format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid object model number (%d).", modelid);
  2616.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2617.         AOE_GameTextForPlayer(playerid, AOE_G_INVALID_MODEL);
  2618.         return false;
  2619.     }
  2620.     return true;
  2621. }
  2622.  
  2623. AOE_EnteredValidBone(playerid, const bone[])
  2624. {
  2625.     if(!IsValidAttachedObjectBoneName(bone))
  2626.     {
  2627.         format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object bone name/number (%s).", bone);
  2628.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2629.         AOE_GameTextForPlayer(playerid, AOE_G_INVALID_BONE);
  2630.         return false;
  2631.     }
  2632.     return true;
  2633. }
  2634.  
  2635. AOE_EnteredValidFileName(playerid, const filename[])
  2636. {
  2637.     if(!IsValidFileName(filename))
  2638.     {
  2639.         format(AOE_STR, sizeof AOE_STR, "* Sorry, you've entered invalid attached object(s) file name ({FFFFFF}%s{%06x}).", filename, AOE_COLOR4 >>> 8);
  2640.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2641.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_VALID_NAME_INFO1);
  2642.         SendClientMessage(playerid, AOE_COLOR4, AOE_M_VALID_NAME_INFO2);
  2643.         AOE_GameTextForPlayer(playerid, AOE_G_INVALID_FILE_NAME);
  2644.         return false;
  2645.     }
  2646.     return true;
  2647. }
  2648.  
  2649. AOE_EnteredExistedFileName(playerid, filename[])
  2650. {
  2651.     if(!fexist(filename))
  2652.     {
  2653.         new len = strlen(filename);
  2654.         strdel(filename, len-(strlen(AOE_FILE_NAME)-2), len);
  2655.         format(AOE_STR, sizeof AOE_STR, "* Sorry, attached object(s) file \"{FFFFFF}%s{%06x}\" does not exist.", filename, AOE_COLOR4 >>> 8);
  2656.         SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2657.         AOE_GameTextForPlayer(playerid, AOE_G_FILE_NOT_EXIST);
  2658.         return false;
  2659.     }
  2660.     return true;
  2661. }
  2662.  
  2663. AOE_EnteredNonExistFileName(playerid, filename[])
  2664. {
  2665.     if(fexist(filename))
  2666.     {
  2667.         if(IsPlayerAdmin(playerid)) AOE_ShowPlayerDialog(playerid, AOE_C_SAVE_REPLACE, AOE_D_SAVE_REPLACE, AOE_T_SAVE#AOE_T_REPLACE, AOE_B_YES, AOE_B_BACK);
  2668.         else
  2669.         {
  2670.             new len = strlen(filename);
  2671.             strdel(filename, len-(strlen(AOE_FILE_NAME)-2), len);
  2672.             format(AOE_STR, sizeof AOE_STR, "* Sorry, attached object file \"{FFFFFF}%s{%06x}\" already exists.", filename, AOE_COLOR4 >>> 8);
  2673.             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2674.             AOE_GameTextForPlayer(playerid, AOE_G_FILE_EXISTED);
  2675.         }
  2676.         return false;
  2677.     }
  2678.     return true;
  2679. }
  2680.  
  2681. AOE_EnteredNonExistFileName2(playerid, filename[])
  2682. {
  2683.     if(fexist(filename))
  2684.     {
  2685.         if(IsPlayerAdmin(playerid)) AOE_ShowPlayerDialog(playerid, AOE_C_SAVE_REPLACE, AOE_D_SAVE2_REPLACE, AOE_T_SAVE_SET#AOE_T_REPLACE, AOE_B_YES, AOE_B_BACK);
  2686.         else
  2687.         {
  2688.             new len = strlen(filename);
  2689.             strdel(filename, len-(strlen(AOE_FILE_NAME)-2), len);
  2690.             format(AOE_STR, sizeof AOE_STR, "* Sorry, attached object(s) set file \"{FFFFFF}%s{%06x}\" already exists.", filename, AOE_COLOR4 >>> 8);
  2691.             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2692.             AOE_GameTextForPlayer(playerid, AOE_G_FILE_EXISTED);
  2693.         }
  2694.         return false;
  2695.     }
  2696.     return true;
  2697. }
  2698.  
  2699. AOE_SavePlayerAttachedObject(playerid, const filename[], index, const comment[] = "", &Float:filelen) // MAX_PLAYER_ATTACHED_OBJECTS for all slot
  2700. {
  2701.     if(!IsPlayerConnected(playerid)) return INVALID_PLAYER_ID;
  2702.     new File:SAO = fopen(filename, io_write), slots;
  2703.     if(SAO)
  2704.     {
  2705.         new year, month, day, hour, minute, second, AOE_STR2[256];
  2706.         GetPlayerName(playerid, pName, sizeof pName);
  2707.         getdate(year, month, day);
  2708.         gettime(hour, minute, second);
  2709.         if(isnull(comment))
  2710.         {
  2711.             format(AOE_STR2, sizeof AOE_STR2, "// Created by %s (Skin ID %d) on %02d/%02d/%d %02d:%02d:%02d (server time)", pName, GetPlayerSkin(playerid), day, month, year, hour, minute, second);
  2712.             fwrite(SAO, AOE_STR2);
  2713.         }
  2714.         new i = ((index == MAX_PLAYER_ATTACHED_OBJECTS) ? (0) : (index));
  2715.         SaveLoop:
  2716.         {
  2717.             if(IsValidPlayerAttachedObject(playerid, i) == 1)
  2718.             {
  2719.                 #if AOE_SMALLER_SAVE true
  2720.                 if(PAO[playerid][i][AO_MC1] == 0 && PAO[playerid][i][AO_MC2] == 0)
  2721.                 {
  2722.                     if(PAO[playerid][i][AO_SX] == 1.0 && PAO[playerid][i][AO_SY] == 1.0 && PAO[playerid][i][AO_SZ] == 1.0)
  2723.                     {
  2724.                         if(PAO[playerid][i][AO_RX] == 0.0 && PAO[playerid][i][AO_RY] == 0.0 && PAO[playerid][i][AO_RZ] == 0.0)
  2725.                         {
  2726.                             if(PAO[playerid][i][AO_X] == 0.0 && PAO[playerid][i][AO_Y] == 0.0 && PAO[playerid][i][AO_Z] == 0.0)
  2727.                             {
  2728.                                 format(AOE_STR2, sizeof AOE_STR2, "\r\nSetPlayerAttachedObject(playerid, %d, %d, %d);", i, PAO[playerid][i][AO_MODEL_ID], PAO[playerid][i][AO_BONE_ID]);
  2729.                             }
  2730.                             else
  2731.                             {
  2732.                                 format(AOE_STR2, sizeof AOE_STR2, "\r\nSetPlayerAttachedObject(playerid, %d, %d, %d, %f, %f, %f);", i,
  2733.                                     PAO[playerid][i][AO_MODEL_ID], PAO[playerid][i][AO_BONE_ID],PAO[playerid][i][AO_X], PAO[playerid][i][AO_Y], PAO[playerid][i][AO_Z]);
  2734.                             }
  2735.                         }
  2736.                         else
  2737.                         {
  2738.                             format(AOE_STR2, sizeof AOE_STR2, "\r\nSetPlayerAttachedObject(playerid, %d, %d, %d, %f, %f, %f, %f, %f, %f);", i, PAO[playerid][i][AO_MODEL_ID], PAO[playerid][i][AO_BONE_ID],
  2739.                             PAO[playerid][i][AO_X], PAO[playerid][i][AO_Y], PAO[playerid][i][AO_Z], PAO[playerid][i][AO_RX], PAO[playerid][i][AO_RY], PAO[playerid][i][AO_RZ]);
  2740.                         }
  2741.                     }
  2742.                     else
  2743.                     {
  2744.                         format(AOE_STR2, sizeof AOE_STR2, "\r\nSetPlayerAttachedObject(playerid, %d, %d, %d, %f, %f, %f, %f, %f, %f, %f, %f, %f);", i,
  2745.                             PAO[playerid][i][AO_MODEL_ID], PAO[playerid][i][AO_BONE_ID], PAO[playerid][i][AO_X], PAO[playerid][i][AO_Y], PAO[playerid][i][AO_Z],
  2746.                             PAO[playerid][i][AO_RX], PAO[playerid][i][AO_RY], PAO[playerid][i][AO_RZ], PAO[playerid][i][AO_SX], PAO[playerid][i][AO_SY], PAO[playerid][i][AO_SZ]);
  2747.                     }
  2748.                 }
  2749.                 else
  2750.                 {
  2751.                 #endif
  2752.                     format(AOE_STR2, sizeof AOE_STR2, "\r\nSetPlayerAttachedObject(playerid, %d, %d, %d, %f, %f, %f, %f, %f, %f, %f, %f, %f, 0x%x, 0x%x);", i, PAO[playerid][i][AO_MODEL_ID], PAO[playerid][i][AO_BONE_ID],
  2753.                         PAO[playerid][i][AO_X], PAO[playerid][i][AO_Y], PAO[playerid][i][AO_Z], PAO[playerid][i][AO_RX], PAO[playerid][i][AO_RY], PAO[playerid][i][AO_RZ],
  2754.                         PAO[playerid][i][AO_SX], PAO[playerid][i][AO_SY], PAO[playerid][i][AO_SZ], PAO[playerid][i][AO_MC1], PAO[playerid][i][AO_MC2]);
  2755.                 #if AOE_SMALLER_SAVE true
  2756.                 }
  2757.                 #endif
  2758.                 fwrite(SAO, AOE_STR2);
  2759.                 slots++;
  2760.             }
  2761.         }
  2762.         if(index == MAX_PLAYER_ATTACHED_OBJECTS && i < MAX_PLAYER_ATTACHED_OBJECTS)
  2763.         {
  2764.             i++;
  2765.             goto SaveLoop;
  2766.         }
  2767.         fclose(SAO);
  2768.         if(fexist(filename))
  2769.         {
  2770.             if(!slots) fremove(filename);
  2771.             else
  2772.             {
  2773.                 SAO = fopen(filename, io_read);
  2774.                 if(SAO)
  2775.                 {
  2776.                     filelen = float(flength(SAO))/1024.0;
  2777.                     fclose(SAO);
  2778.                 }
  2779.             }
  2780.         }
  2781.     }
  2782.     return slots;
  2783. }
  2784.  
  2785. AOE_LoadPlayerAttachedObject(playerid, const filename[], index, const comment[])
  2786. {
  2787.     #pragma unused comment
  2788.     if(!IsPlayerConnected(playerid)) return INVALID_PLAYER_ID;
  2789.     if(!fexist(filename)) return 0;
  2790.     new File:LAO = fopen(filename, io_read), slots;
  2791.     if(LAO)
  2792.     {
  2793.         AOComment[0] = EOS;
  2794.         new idx, replaced, LAOD[E_ATTACHED_OBJECT], AOE_STR2[256];
  2795.         while(fread(LAO, AOE_STR2) && slots != MAX_PLAYER_ATTACHED_OBJECTS)
  2796.         {
  2797.             if(!unformat(AOE_STR2, "'SetPlayerAttachedObject'P<();,>{s[3]}{s[32]}dddF(0.0)F(0.0)F(0.0)F(0.0)F(0.0)F(0.0)F(1.0)F(1.0)F(1.0)X(0)X(0)", idx, LAOD[AO_MODEL_ID], LAOD[AO_BONE_ID],
  2798.                 LAOD[AO_X], LAOD[AO_Y], LAOD[AO_Z], LAOD[AO_RX], LAOD[AO_RY], LAOD[AO_RZ], LAOD[AO_SX], LAOD[AO_SY], LAOD[AO_SZ], LAOD[AO_MC1], LAOD[AO_MC2]))
  2799.             {
  2800.                 if(IsValidAttachedObjectSlot(idx) && IsValidObjectModel(LAOD[AO_MODEL_ID]) && IsValidAttachedObjectBone(LAOD[AO_BONE_ID]))
  2801.                 {
  2802.                     if(index == MAX_PLAYER_ATTACHED_OBJECTS)
  2803.                     {
  2804.                         if(IsPlayerAttachedObjectSlotUsed(playerid, idx))
  2805.                         {
  2806.                             switch(replaced++)
  2807.                             {
  2808.                                 case 0: format(AOE_STR, sizeof AOE_STR, "** Attached object index number %d", idx);
  2809.                                 default: format(AOE_STR, sizeof AOE_STR, "%s, %d", AOE_STR, idx);
  2810.                             }
  2811.                         }
  2812.                         slots += UpdatePlayerAttachedObjectEx(playerid, idx, LAOD[AO_MODEL_ID], LAOD[AO_BONE_ID], LAOD[AO_X], LAOD[AO_Y], LAOD[AO_Z],
  2813.                                     LAOD[AO_RX], LAOD[AO_RY], LAOD[AO_RZ], LAOD[AO_SX], LAOD[AO_SY], LAOD[AO_SZ], LAOD[AO_MC1], LAOD[AO_MC2]);
  2814.                     }
  2815.                     else
  2816.                     {
  2817.                         if(index == idx)
  2818.                         {
  2819.                             slots += UpdatePlayerAttachedObjectEx(playerid, idx, LAOD[AO_MODEL_ID], LAOD[AO_BONE_ID], LAOD[AO_X], LAOD[AO_Y], LAOD[AO_Z],
  2820.                                         LAOD[AO_RX], LAOD[AO_RY], LAOD[AO_RZ], LAOD[AO_SX], LAOD[AO_SY], LAOD[AO_SZ], LAOD[AO_MC1], LAOD[AO_MC2]);
  2821.                             break;
  2822.                         }
  2823.                     }
  2824.                 }
  2825.             }
  2826.             else if(!unformat(AOE_STR2, "'/*'s[251]'*/'", comment) || !unformat(AOE_STR2, "'//'s[253]", comment)) { }
  2827.         }
  2828.         if(0 < replaced < MAX_PLAYER_ATTACHED_OBJECTS)
  2829.         {
  2830.             format(AOE_STR, sizeof AOE_STR, "%s was replaced (Total: %d).", AOE_STR, replaced);
  2831.             SendClientMessage(playerid, AOE_COLOR4, AOE_STR);
  2832.         }
  2833.         fclose(LAO);
  2834.     }
  2835.     return slots;
  2836. }
  2837. //------------------------------------------------------------------------------
  2838. UpdatePlayerAttachedObject(playerid, index, modelid, boneid)
  2839.     return UpdatePlayerAttachedObjectEx(playerid, index, modelid, boneid, PAO[playerid][index][AO_X], PAO[playerid][index][AO_Y], PAO[playerid][index][AO_Z], PAO[playerid][index][AO_RX], PAO[playerid][index][AO_RY], PAO[playerid][index][AO_RZ],
  2840.     PAO[playerid][index][AO_SX], PAO[playerid][index][AO_SY], PAO[playerid][index][AO_SZ], PAO[playerid][index][AO_MC1], PAO[playerid][index][AO_MC2]);
  2841.  
  2842. UpdatePlayerAttachedObjectEx(playerid, index, modelid, boneid, Float:fOffsetX = 0.0, Float:fOffsetY = 0.0, Float:fOffsetZ = 0.0, Float:fRotX = 0.0, Float:fRotY = 0.0, Float:fRotZ = 0.0, Float:fScaleX = 1.0, Float:fScaleY = 1.0, Float:fScaleZ = 1.0, materialcolor1 = 0, materialcolor2 = 0)
  2843. {
  2844.     if(IsValidAttachedObjectSlot(index) || IsValidObjectModel(modelid) || IsValidAttachedObjectBone(boneid))
  2845.     {
  2846.         if(SetPlayerAttachedObject(playerid, index, modelid, boneid, fOffsetX, fOffsetY, fOffsetZ, fRotX, fRotY, fRotZ, fScaleX, fScaleY, fScaleZ, materialcolor1, materialcolor2))
  2847.         {
  2848.             PAO[playerid][index][AO_MODEL_ID] = modelid;
  2849.             PAO[playerid][index][AO_BONE_ID] = boneid;
  2850.             PAO[playerid][index][AO_X] = fOffsetX, PAO[playerid][index][AO_Y] = fOffsetY, PAO[playerid][index][AO_Z] = fOffsetZ;
  2851.             PAO[playerid][index][AO_RX] = fRotX, PAO[playerid][index][AO_RY] = fRotY, PAO[playerid][index][AO_RZ] = fRotZ;
  2852.             PAO[playerid][index][AO_SX] = fScaleX, PAO[playerid][index][AO_SY] = fScaleY, PAO[playerid][index][AO_SZ] = fScaleZ;
  2853.             PAO[playerid][index][AO_MC1] = materialcolor1, PAO[playerid][index][AO_MC2] = materialcolor2;
  2854.             PAO[playerid][index][AO_STATUS] = 1;
  2855.             return 1;
  2856.         }
  2857.     }
  2858.     return 0;
  2859. }
  2860.  
  2861. DuplicatePlayerAttachedObject(playerid, fromindex, asindex)
  2862. {
  2863.     if(IsValidAttachedObjectSlot(fromindex) && IsValidAttachedObjectSlot(asindex))
  2864.     {
  2865.         return UpdatePlayerAttachedObjectEx(playerid, asindex, PAO[playerid][fromindex][AO_MODEL_ID], PAO[playerid][fromindex][AO_BONE_ID], PAO[playerid][fromindex][AO_X], PAO[playerid][fromindex][AO_Y], PAO[playerid][fromindex][AO_Z],
  2866.         PAO[playerid][fromindex][AO_RX], PAO[playerid][fromindex][AO_RY], PAO[playerid][fromindex][AO_RZ], PAO[playerid][fromindex][AO_SX], PAO[playerid][fromindex][AO_SY], PAO[playerid][fromindex][AO_SZ], PAO[playerid][fromindex][AO_MC1], PAO[playerid][fromindex][AO_MC2]);
  2867.     }
  2868.     return 0;
  2869. }
  2870.  
  2871. ChangePlayerAttachedObjectIndex(playerid, fromindex, toindex)
  2872. {
  2873.     if(IsValidAttachedObjectSlot(toindex) && IsValidPlayerAttachedObject(playerid, fromindex))
  2874.     {
  2875.         if(IsPlayerAttachedObjectSlotUsed(playerid, fromindex)) RemovePlayerAttachedObject(playerid, fromindex), PAO[playerid][fromindex][AO_STATUS] = 0;
  2876.         return UpdatePlayerAttachedObjectEx(playerid, toindex, PAO[playerid][fromindex][AO_MODEL_ID], PAO[playerid][fromindex][AO_BONE_ID], PAO[playerid][fromindex][AO_X], PAO[playerid][fromindex][AO_Y], PAO[playerid][fromindex][AO_Z],
  2877.         PAO[playerid][fromindex][AO_RX], PAO[playerid][fromindex][AO_RY], PAO[playerid][fromindex][AO_RZ], PAO[playerid][fromindex][AO_SX], PAO[playerid][fromindex][AO_SY], PAO[playerid][fromindex][AO_SZ], PAO[playerid][fromindex][AO_MC1], PAO[playerid][fromindex][AO_MC2]);
  2878.     }
  2879.     return 0;
  2880. }
  2881.  
  2882. RefreshPlayerAttachedObject(playerid, forplayerid, index)
  2883. {
  2884.     if(IsValidPlayerAttachedObject(playerid, index) == 1)
  2885.     {
  2886.         return UpdatePlayerAttachedObjectEx(forplayerid, index, PAO[playerid][index][AO_MODEL_ID], PAO[playerid][index][AO_BONE_ID], PAO[playerid][index][AO_X], PAO[playerid][index][AO_Y], PAO[playerid][index][AO_Z],
  2887.         PAO[playerid][index][AO_RX], PAO[playerid][index][AO_RY], PAO[playerid][index][AO_RZ], PAO[playerid][index][AO_SX], PAO[playerid][index][AO_SY], PAO[playerid][index][AO_SZ], PAO[playerid][index][AO_MC1], PAO[playerid][index][AO_MC2]);
  2888.     }
  2889.     return 0;
  2890. }
  2891.  
  2892. RestorePlayerAttachedObject(playerid, index)
  2893. {
  2894.     if(IsValidAttachedObjectSlot(index) && IsValidObjectModel(PAO[playerid][index][AO_MODEL_ID]) && IsValidAttachedObjectBone(PAO[playerid][index][AO_BONE_ID]))
  2895.     {
  2896.         if(SetPlayerAttachedObject(playerid, index, PAO[playerid][index][AO_MODEL_ID], PAO[playerid][index][AO_BONE_ID], PAO[playerid][index][AO_X], PAO[playerid][index][AO_Y], PAO[playerid][index][AO_Z],
  2897.             PAO[playerid][index][AO_RX], PAO[playerid][index][AO_RY], PAO[playerid][index][AO_RZ], PAO[playerid][index][AO_SX], PAO[playerid][index][AO_SY], PAO[playerid][index][AO_SZ], PAO[playerid][index][AO_MC1], PAO[playerid][index][AO_MC2]))
  2898.         {
  2899.             PAO[playerid][index][AO_STATUS] = 1;
  2900.             return 1;
  2901.         }
  2902.     }
  2903.     return 0;
  2904. }
  2905.  
  2906. RemovePlayerAttachedObjectEx(playerid, index) // MAX_PLAYER_ATTACHED_OBJECTS for all slot
  2907. {
  2908.     new attachedobjectsremoved;
  2909.     if(index == MAX_PLAYER_ATTACHED_OBJECTS)
  2910.     {
  2911.         for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  2912.         {
  2913.             if(IsPlayerAttachedObjectSlotUsed(playerid, i))
  2914.             {
  2915.                 attachedobjectsremoved += RemovePlayerAttachedObject(playerid, i);
  2916.                 if(PAO[playerid][i][AO_STATUS] == 0)
  2917.                 {
  2918.                     AOE_UnsetValues(playerid, i);
  2919.                 }
  2920.                 else
  2921.                 {
  2922.                     PAO[playerid][i][AO_STATUS] = 0;
  2923.                     EPV[playerid][PAO_LAST_REMOVED] = i;
  2924.                 }
  2925.             }
  2926.         }
  2927.     }
  2928.     else
  2929.     {
  2930.         if(!IsValidAttachedObjectSlot(index)) return 0;
  2931.         if(IsPlayerAttachedObjectSlotUsed(playerid, index))
  2932.         {
  2933.             attachedobjectsremoved += RemovePlayerAttachedObject(playerid, index);
  2934.             if(PAO[playerid][index][AO_STATUS] == 0)
  2935.             {
  2936.                 AOE_UnsetValues(playerid, index);
  2937.             }
  2938.             else
  2939.             {
  2940.                 PAO[playerid][index][AO_STATUS] = 0;
  2941.                 EPV[playerid][PAO_LAST_REMOVED] = index;
  2942.             }
  2943.         }
  2944.     }
  2945.     return attachedobjectsremoved;
  2946. }
  2947.  
  2948. GetAttachedObjectBoneName(boneid)
  2949. {
  2950.     new attachedobjectbonename[MAX_ATTACHED_OBJECT_BONE_NAME];
  2951.     if(!IsValidAttachedObjectBone(boneid)) attachedobjectbonename = "Invalid Bone ID";
  2952.     else attachedobjectbonename = AttachedObjectBones[boneid-1];
  2953.     return attachedobjectbonename;
  2954. }
  2955.  
  2956. GetAttachedObjectBone(const bonename[])
  2957. {
  2958.     if(!IsValidAttachedObjectBoneName(bonename)) return 0;
  2959.     if(IsNumeric(bonename)) return strval(bonename);
  2960.     for(new i = 0; i < sizeof AttachedObjectBones; i++)
  2961.     {
  2962.         if(strfind(AttachedObjectBones[i], bonename, true) != -1) return i+1;
  2963.     }
  2964.     return 0;
  2965. }
  2966.  
  2967. GetPlayerAttachedObjectsCount(playerid)
  2968. {
  2969.     new playerattachedobjectscount;
  2970.     for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
  2971.     {
  2972.         playerattachedobjectscount += IsPlayerAttachedObjectSlotUsed(playerid, i);
  2973.     }
  2974.     return playerattachedobjectscount;
  2975. }
  2976.  
  2977. IsValidPlayerAttachedObject(playerid, index)
  2978. {
  2979.     if(!IsPlayerConnected(playerid)) return INVALID_PLAYER_ID; // Player is offline
  2980.     if(!IsPlayerAttachedObjectSlotUsed(playerid, index)) return -1; // Not used
  2981.     if(!IsValidAttachedObjectSlot(index) || !IsValidObjectModel(PAO[playerid][index][AO_MODEL_ID]) || !IsValidAttachedObjectBone(PAO[playerid][index][AO_BONE_ID]) || !PAO[playerid][index][AO_STATUS]) return 0; // Invalid data
  2982.     return 1;
  2983. }
  2984.  
  2985. IsValidAttachedObjectSlot(slotid)
  2986.     return (0 <= slotid < MAX_PLAYER_ATTACHED_OBJECTS);
  2987.  
  2988. IsValidAttachedObjectBone(boneid)
  2989.     return (1 <= boneid <= MAX_ATTACHED_OBJECT_BONES);
  2990.  
  2991. IsValidAttachedObjectBoneName(const bonename[])
  2992. {
  2993.     new len = strlen(bonename);
  2994.     if(len < 1 || len >= MAX_ATTACHED_OBJECT_BONE_NAME) return false;
  2995.     for(new i = 0; i < sizeof AttachedObjectBones; i++)
  2996.     {
  2997.         if(!strcmp(bonename, AttachedObjectBones[i], true)) return true;
  2998.     }
  2999.     if(IsNumeric(bonename) && IsValidAttachedObjectBone(strval(bonename))) return true;
  3000.     return false;
  3001. }
  3002.  
  3003. IsValidComment(const comment[])
  3004. {
  3005.     new len = strlen(comment);
  3006.     if(len < 1 || len >= sizeof AOComment) return false;
  3007.     for(new j = 0; j < len; j++)
  3008.     {
  3009.         if((comment[j] < 'A' || comment[j] > 'Z') && (comment[j] < 'a' || comment[j] > 'z') && (comment[j] < '0' || comment[j] > '9')
  3010.             && comment[j] != ' ') return false;
  3011.     }
  3012.     return true;
  3013. }
  3014.  
  3015. IsValidFileName(const filename[])
  3016. {
  3017.     new len = strlen(filename);
  3018.     if(!(1 <= len <= 24)) return false;
  3019.     for(new j = 0; j < len; j++)
  3020.     {
  3021.         if((filename[j] < 'A' || filename[j] > 'Z') && (filename[j] < 'a' || filename[j] > 'z') && (filename[j] < '0' || filename[j] > '9')
  3022.             && (filename[j] != '@' || filename[j] != '$' || filename[j] != '(' || filename[j] != ')' || filename[j] != '['
  3023.             || filename[j] != ']' || filename[j] != '_' || filename[j] != '=')) return false;
  3024.     }
  3025.     return true;
  3026. }
  3027.  
  3028. IsValidObjectModel(modelid)
  3029. {
  3030.     return((321 <= modelid <= 328)
  3031.     || (330 <= modelid <= 331)
  3032.     || (333 <= modelid <= 339)
  3033.     || (341 <= modelid <= 373)
  3034.     || (615 <= modelid <= 698)
  3035.     || (700 <= modelid <= 1193)
  3036.     || (1207 <= modelid <= 1698)
  3037.     || (1700 <= modelid <= 4762)
  3038.     || (4806 <= modelid <= 6525)
  3039.     || (6863 <= modelid <= 11681)
  3040.     || (11682 <= modelid <= 12799) // SA:MP 0.3.7 Objects
  3041.     || (12800 <= modelid <= 13890)
  3042.     || (14383 <= modelid <= 14898)
  3043.     || (14900 <= modelid <= 14903)
  3044.     || (15025 <= modelid <= 15064)
  3045.     || (15065 <= modelid <= 15999) // SA:MP Custom IMG Objects
  3046.     || (16000 <= modelid <= 16790)
  3047.     || (17000 <= modelid <= 18630)
  3048.     || (18631 <= modelid <= 19999)); // SA:MP 0.3.7 Objects
  3049. }
  3050.  
  3051. IsNumeric(const string[])
  3052. {
  3053.     new len = strlen(string);
  3054.     if(len == 0) return false;
  3055.     for(new i = 0; i < len; i++)
  3056.     {
  3057.         if(string[i] > '9' || string[i] < '0') return false;
  3058.     }
  3059.     return true;
  3060. }
Add Comment
Please, Sign In to add comment