mangle.pwn 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. #tryinclude <colandreas>
  2. #if !defined COLANDREAS
  3. #endinput
  4. #endif
  5. #define MANGLE
  6. public OnFilterScriptInit()
  7. {
  8. CA_Init();
  9. #if defined MA_OnFilterScriptInit
  10. MA_OnFilterScriptInit();
  11. #endif
  12. return 1;
  13. }
  14. #if defined _ALS_OnFilterScriptInit
  15. #undef OnFilterScriptInit
  16. #else
  17. #define _ALS_OnFilterScriptInit
  18. #endif
  19. #define OnFilterScriptInit MA_OnFilterScriptInit
  20. #if defined MA_OnFilterScriptInit
  21. forward MA_OnFilterScriptInit();
  22. #endif
  23. new Float:GroupSlopeRX[MAX_PLAYERS], Float:GroupSlopeRY[MAX_PLAYERS];
  24. /* Debug Command
  25. YCMD:gs(playerid, arg[], help)
  26. {
  27. new Float:x, Float:y, Float:z, line[128];
  28. GetPlayerPos(playerid, x, y, z);
  29. CalcSlopeAtPoint(x, y, x, y);
  30. format(line, sizeof(line), "Slope X:%3.4f | Slope Y:%3.4f", x, y);
  31. SendClientMessage(playerid, -1, line);
  32. return 1;
  33. }*/
  34. // Load a prefab specify a filename
  35. YCMD:prefabsets(playerid, arg[], help)
  36. {
  37. if(help)
  38. {
  39. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  40. SendClientMessage(playerid, STEALTH_GREEN, "Load a prefabricated group of objects rotated according to the ground slope.");
  41. return 1;
  42. }
  43. MapOpenCheck();
  44. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  45. if(isnull(arg)) ShowPrefabs(playerid);
  46. else
  47. {
  48. new mapname[128];
  49. format(mapname, sizeof(mapname), "tstudio/PreFabs/%s.db", arg);
  50. if(fexist(mapname))
  51. {
  52. PrefabDB = db_open_persistent(mapname);
  53. sqlite_LoadPrefab(playerid);
  54. db_free_persistent(PrefabDB);
  55. new Float:x, Float:y, Float:z;
  56. GetPlayerPos(playerid, x, y, z);
  57. //CalcSlopeAtPoint(x, y, GroupSlopeRX[playerid], GroupSlopeRY[playerid]);
  58. CA_RayCastLineAngle(x, y, 1200.0, x, y, -100.0, z, z, z, GroupSlopeRX[playerid], GroupSlopeRY[playerid], z);
  59. GroupRotate(playerid, GroupSlopeRX[playerid], GroupSlopeRY[playerid], 0.0);
  60. SendClientMessage(playerid, STEALTH_GREEN, "Prefab loaded and set to your group selection");
  61. }
  62. else SendClientMessage(playerid, STEALTH_YELLOW, "That prefab does not exist!");
  63. }
  64. return 1;
  65. }
  66. // Rotate group on ground slope
  67. YCMD:gsets(playerid, arg[], help)
  68. {
  69. if(help)
  70. {
  71. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  72. SendClientMessage(playerid, STEALTH_GREEN, "Rotate all currently selected objects accordingly to ground slope.");
  73. return 1;
  74. }
  75. MapOpenCheck();
  76. new time = GetTickCount();
  77. // We need to get the map center as the rotation node
  78. new bool:value, Float:gCenterX, Float:gCenterY, Float:gCenterZ;
  79. if(PivotPointOn[playerid])
  80. {
  81. new bool:hasgroup;
  82. foreach(new i : Objects)
  83. {
  84. if(GroupedObjects[playerid][i])
  85. {
  86. gCenterX = PivotPoint[playerid][xPos];
  87. gCenterY = PivotPoint[playerid][yPos];
  88. gCenterZ = PivotPoint[playerid][zPos];
  89. value = true;
  90. hasgroup = true;
  91. break;
  92. }
  93. }
  94. if(!hasgroup)
  95. {
  96. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  97. SendClientMessage(playerid, STEALTH_YELLOW, "There is not enough objects for this command to work");
  98. }
  99. }
  100. else if(GetGroupCenter(playerid, gCenterX, gCenterY, gCenterZ)) value = true;
  101. if(value)
  102. {
  103. new Float:x, Float:y, Float:z;
  104. GetPlayerPos(playerid, x, y, z);
  105. //CalcSlopeAtPoint(x, y, GroupSlopeRX[playerid], GroupSlopeRY[playerid]);
  106. CA_RayCastLineAngle(x, y, 1200.0, x, y, -100.0, z, z, z, GroupSlopeRX[playerid], GroupSlopeRY[playerid], z);
  107. // Loop through all objects and perform rotation calculations
  108. db_begin_transaction(EditMap);
  109. foreach(new i : Objects)
  110. {
  111. if(GroupedObjects[playerid][i])
  112. {
  113. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  114. AttachObjectToPoint(i, gCenterX, gCenterY, gCenterZ, GroupSlopeRX[playerid], GroupSlopeRY[playerid], 0.0, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  115. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  116. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  117. UpdateObject3DText(i);
  118. sqlite_UpdateObjectPos(i);
  119. }
  120. }
  121. db_end_transaction(EditMap);
  122. // Update the Group GUI
  123. UpdatePlayerGSelText(playerid);
  124. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  125. SendClientMessage(playerid, STEALTH_GREEN, "Group RZ rotation complete ");
  126. }
  127. else
  128. {
  129. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  130. SendClientMessage(playerid, STEALTH_YELLOW, "There is not enough objects for this command to work");
  131. }
  132. return 1;
  133. }
  134. // Edit a group
  135. YCMD:editgroups(playerid, arg[], help)
  136. {
  137. if(help)
  138. {
  139. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  140. SendClientMessage(playerid, STEALTH_GREEN, "Edit currently edited objects simultaneously.");
  141. SendClientMessage(playerid, STEALTH_GREEN, "Hold 'Walk Key' to set the group rotation pivot, you can only do this once per edit.");
  142. return 1;
  143. }
  144. MapOpenCheck();
  145. NoEditingMode(playerid);
  146. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  147. if(PlayerHasGroup(playerid))
  148. {
  149. GetGroupCenter(playerid, LastPivot[playerid][xPos], LastPivot[playerid][yPos], LastPivot[playerid][zPos]);
  150. LastGroupPosition[playerid][xPos] = LastPivot[playerid][xPos];
  151. LastGroupPosition[playerid][yPos] = LastPivot[playerid][yPos];
  152. LastGroupPosition[playerid][zPos] = LastPivot[playerid][zPos];
  153. PivotOffset[playerid][xPos] = 0.0;
  154. PivotOffset[playerid][yPos] = 0.0;
  155. PivotOffset[playerid][zPos] = 0.0;
  156. new Float:x, Float:y, Float:z;
  157. GetPlayerPos(playerid, x, y, z);
  158. CA_RayCastLineAngle(x, y, 1200.0, x, y, -100.0, z, z, z, GroupSlopeRX[playerid], GroupSlopeRY[playerid], z);
  159. PivotObject[playerid] = CreateDynamicObject(1974, LastPivot[playerid][xPos], LastPivot[playerid][yPos], LastPivot[playerid][zPos], GroupSlopeRX[playerid], GroupSlopeRY[playerid], z, -1, -1, playerid);
  160. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, PivotObject[playerid], E_STREAMER_DRAW_DISTANCE, 3000.0);
  161. SetDynamicObjectMaterial(PivotObject[playerid], 0, 10765, "airportgnd_sfse", "white", -256);
  162. Streamer_Update(playerid);
  163. EditingMode[playerid] = true;
  164. PivotReset[playerid] = true;
  165. SetEditMode(playerid, EDIT_MODE_OBJECTGROUP);
  166. EditDynamicObject(playerid, PivotObject[playerid]);
  167. SendClientMessage(playerid, STEALTH_GREEN, "Editing your group");
  168. }
  169. else SendClientMessage(playerid, STEALTH_YELLOW, "You must have at least one object grouped");
  170. return 1;
  171. }
  172. // Rotate object on ground slope
  173. YCMD:osets(playerid, arg[], help)
  174. {
  175. if(help)
  176. {
  177. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  178. SendClientMessage(playerid, STEALTH_GREEN, "Rotate currently selected object according to ground slope.");
  179. return 1;
  180. }
  181. MapOpenCheck();
  182. EditCheck(playerid);
  183. NoEditingMode(playerid);
  184. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  185. new Float:x, Float:y, Float:z;
  186. GetPlayerPos(playerid, x, y, z);
  187. CA_RayCastLineAngle(x, y, 1200.0, x, y, -100.0, z, z, z, GroupSlopeRX[playerid], GroupSlopeRY[playerid], z);
  188. if(PivotPointOn[playerid])
  189. {
  190. new i = CurrObject[playerid];
  191. AttachObjectToPoint(i, PivotPoint[playerid][xPos], PivotPoint[playerid][yPos], PivotPoint[playerid][zPos], GroupSlopeRX[playerid], GroupSlopeRY[playerid], 0.0, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  192. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  193. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  194. UpdateObject3DText(CurrObject[playerid]);
  195. }
  196. else
  197. {
  198. ObjectData[CurrObject[playerid]][oRX] += GroupSlopeRX[playerid];
  199. ObjectData[CurrObject[playerid]][oRY] += GroupSlopeRY[playerid];
  200. SetDynamicObjectRot(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oRX], ObjectData[CurrObject[playerid]][oRY], ObjectData[CurrObject[playerid]][oRZ]);
  201. }
  202. sqlite_UpdateObjectPos(CurrObject[playerid]);
  203. return 1;
  204. }
  205. /*
  206. // Load a prefab specify a filename adjust to facing angle
  207. YCMD:pmaf(playerid, arg[], help)
  208. {
  209. MapOpenCheck();
  210. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  211. if(isnull(arg)) ShowPrefabs(playerid);
  212. else
  213. {
  214. new Float:zrot, mapname[128];
  215. if(sscanf(arg, "s[128]f", mapname, zrot)) return SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /pmaf <prefab> <zrot>");
  216. format(mapname, sizeof(mapname), "tstudio/PreFabs/%s.db", mapname);
  217. if(fexist(mapname))
  218. {
  219. PrefabDB = db_open_persistent(mapname);
  220. sqlite_LoadPrefab(playerid, false);
  221. db_free_persistent(PrefabDB);
  222. new Float:x, Float:y, Float:z, Float:rx, Float:ry;
  223. // Find the slope
  224. GetPlayerPos(playerid, x, y, z);
  225. CalcSlopeAtPoint(x, y, rx, ry);
  226. // Translate new rotation offsets
  227. GroupRotate(playerid, 0.0, 0.0, zrot);
  228. // Translate new rotation to slope
  229. GroupRotate(playerid, rx, ry, 0.0);
  230. SendClientMessage(playerid, STEALTH_GREEN, "Prefab loaded and set to your group selection");
  231. }
  232. else SendClientMessage(playerid, STEALTH_YELLOW, "That prefab does not exist!");
  233. }
  234. return 1;
  235. }
  236. */
  237. YCMD:cobjectsets(playerid, arg[], help)
  238. {
  239. if(help)
  240. {
  241. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  242. SendClientMessage(playerid, STEALTH_GREEN, "Creates a rotated object according to the map slope and selects it.");
  243. return 1;
  244. }
  245. MapOpenCheck();
  246. NoEditingMode(playerid);
  247. new modelid, Float:RZAngle;
  248. if(sscanf(arg, "iF(0.0)", modelid, RZAngle))
  249. {
  250. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  251. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /csobject <modelid>");
  252. return 1;
  253. }
  254. // Set the initial object position
  255. new Float:px, Float:py, Float:pz, Float:fa, Float:RXAngle, Float:RYAngle;
  256. new Float:colradius = GetColSphereRadius(modelid);
  257. GetPosFaInFrontOfPlayer(playerid, colradius + 1.0, px, py, pz, fa);
  258. pz -= 1.0;
  259. // Calculate rotation
  260. //CalcSlopeAtPoint(px, py, RXAngle, RYAngle);
  261. CA_RayCastLineAngle(px, py, 1200.0, px, py, -100.0, fa, fa, fa, RXAngle, RYAngle, RZAngle);
  262. //new Float:angle = float(random(360));
  263. //ObjectRotateZ(RXAngle, RYAngle, RZAngle, angle, RXAngle, RYAngle, RZAngle);
  264. // Create the object
  265. SetCurrObject(playerid, AddDynamicObject(modelid, px, py, pz, RXAngle, RYAngle, RZAngle));
  266. // Object was created
  267. if(CurrObject[playerid] != -1)
  268. {
  269. // Update the streamer for this player
  270. Streamer_Update(playerid);
  271. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_CREATED);
  272. // Show output message
  273. new line[128];
  274. new modelarray = GetModelArray(modelid);
  275. if(modelarray > -1) format(line, sizeof(line), "Created Object Index: %i Model Name: %s", CurrObject[playerid], GetModelName(modelarray));
  276. else format(line, sizeof(line), "Created Object Index: %i Model Name: Unknown", CurrObject[playerid]);
  277. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  278. SendClientMessage(playerid, STEALTH_GREEN, line);
  279. }
  280. // Too many objects already created
  281. else
  282. {
  283. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  284. SendClientMessage(playerid, STEALTH_YELLOW, "You have too many objects created to create anymore!");
  285. }
  286. return 1;
  287. }
  288. tsfunc CalcSlopeAtPoint(Float:x, Float:y, &Float:RXAngle, &Float:RYAngle)
  289. {
  290. new Float:North[3], Float:South[3], Float:East[3], Float:West[3], Float:opposite, Float:hypotenuse;
  291. // Set slope positions
  292. North[0] = x;
  293. North[1] = y + 1;
  294. South[0] = x;
  295. South[1] = y - 1;
  296. East[0] = x + 1;
  297. East[1] = y;
  298. West[0] = x - 1;
  299. West[1] = y;
  300. // Use ColAndreas to get Z Values
  301. CA_FindZ_For2DCoord(North[0], North[1], North[2]);
  302. CA_FindZ_For2DCoord(South[0], South[1], South[2]);
  303. CA_FindZ_For2DCoord(East[0], East[1], East[2]);
  304. CA_FindZ_For2DCoord(West[0], West[1], West[2]);
  305. // Calculate Slope angles
  306. // North South RX
  307. hypotenuse = getdist3d(North[0], North[1], North[2], South[0], South[1], South[2]);
  308. opposite = getdist3d(North[0], North[1], North[2], North[0], North[1], South[2]);
  309. RXAngle = asin(floatdiv(opposite, hypotenuse));
  310. if(South[2] > North[2]) RXAngle *= -1;
  311. // West East RY
  312. hypotenuse = getdist3d(West[0], West[1], West[2], East[0], East[1], East[2]);
  313. opposite = getdist3d(West[0], West[1], West[2], West[0], West[1], East[2]);
  314. RYAngle = asin(floatdiv(opposite, hypotenuse));
  315. if(East[2] > West[2]) RYAngle *= -1;
  316. return 1;
  317. }
  318. tsfunc ObjectRotateZ(Float:RX, Float:RY, Float:RZ, Float:rot_z, &Float:NewRX, &Float:NewRY, &Float:NewRZ)
  319. {
  320. new
  321. Float:sinx,
  322. Float:siny,
  323. Float:sinz,
  324. Float:cosx,
  325. Float:cosy,
  326. Float:cosz;
  327. FloatConvertValue(RX, RY, RZ, sinx, siny, sinz, cosx, cosy, cosz);
  328. // Convert from one euler angle sequence (ZXY) to another and add the rotation
  329. FloatConvertValue(asin(cosx * cosy), atan2(sinx, cosx * siny) + rot_z, atan2(cosy * cosz * sinx - siny * sinz, cosz * siny - cosy * sinx * -sinz),
  330. sinx, siny, sinz, cosx, cosy, cosz);
  331. // Convert back to the original euler angle sequence and apply the new rotation to the object
  332. NewRX = asin(cosx * siny),
  333. NewRY = atan2(cosx * cosy, sinx),
  334. NewRZ = atan2(cosz * sinx * siny - cosy * sinz, cosy * cosz + sinx * siny * sinz);
  335. return 1;
  336. }
  337. tsfunc FloatConvertValue(Float:rot_x, Float:rot_y, Float:rot_z, &Float:sinx, &Float:siny, &Float:sinz, &Float:cosx, &Float:cosy, &Float:cosz)
  338. {
  339. sinx = floatsin(rot_x, degrees);
  340. siny = floatsin(rot_y, degrees);
  341. sinz = floatsin(rot_z, degrees);
  342. cosx = floatcos(rot_x, degrees);
  343. cosy = floatcos(rot_y, degrees);
  344. cosz = floatcos(rot_z, degrees);
  345. return 1;
  346. }
  347. /* MEDIT Prefab import
  348. // Import function
  349. // Load prefab
  350. #define MAX_MATERIAL_INDEX 16
  351. YCMD:cpf(playerid, arg[], help)
  352. {
  353. new dir:dHandle = dir_open("./scriptfiles/tstudio/medit/importpf/");
  354. new item[40], type;
  355. new extension[6];
  356. // Create a load list
  357. while(dir_list(dHandle, item, type))
  358. {
  359. if(type != FM_DIR)
  360. {
  361. // We need to check extension
  362. if(strlen(item) > 3)
  363. {
  364. format(extension, sizeof(extension), "%s%s%s%s%s", item[strlen(item) - 5], item[strlen(item) - 4], item[strlen(item) - 3], item[strlen(item) - 2],item[strlen(item) - 1]);
  365. // File is apparently a prefab
  366. new tempmap[64];
  367. strmid(tempmap, item, 0, strlen(item) - 6, 64);
  368. printf(tempmap);
  369. if(!strcmp(extension, "mpfab")) ConvertMeditPrefab(tempmap);
  370. }
  371. }
  372. }
  373. return 1;
  374. }
  375. // Old medit enum
  376. enum object_info {
  377. object_id,
  378. medit_modelid,
  379. Text3D:medit_Text3D[MAX_OBJECTS],
  380. Float:pfox,
  381. Float:pfoy,
  382. Float:pfoz,
  383. Float:pfrx,
  384. Float:pfry,
  385. Float:pfrz,
  386. Material_Index[MAX_MATERIAL_INDEX],
  387. Material_Color[MAX_MATERIAL_INDEX],
  388. usetext[MAX_MATERIAL_INDEX],
  389. Material_FontFace[MAX_MATERIAL_INDEX],
  390. Material_FontSize[MAX_MATERIAL_INDEX],
  391. Material_FontBold[MAX_MATERIAL_INDEX],
  392. Material_FontColor[MAX_MATERIAL_INDEX],
  393. Material_BackColor[MAX_MATERIAL_INDEX],
  394. Material_Alignment[MAX_MATERIAL_INDEX],
  395. Material_TextFontSize[MAX_MATERIAL_INDEX]
  396. }
  397. new DB: PrefabImportDB;
  398. new DBStatement:insertprefabimpstmt;
  399. new tempobject[object_info];
  400. new temp_Material_Object_Text[MAX_MATERIAL_INDEX][64];
  401. ConvertMeditPrefab(tempmap[64])
  402. {
  403. new templine[256];
  404. new Float:ZOffSet;
  405. new openmap[64];
  406. new opendb[64];
  407. // Create import database
  408. format(opendb, 64, "tstudio/medit/convertpf/%s.db", tempmap);
  409. PrefabImportDB = db_open_persistent(opendb);
  410. new NewImportString[512];
  411. strimplode(" ",
  412. NewImportString,
  413. sizeof(NewImportString),
  414. "CREATE TABLE IF NOT EXISTS `Objects`",
  415. "(ModelID INTEGER,",
  416. "xPos REAL,",
  417. "yPos REAL,",
  418. "zPos REAL,",
  419. "rxRot REAL,",
  420. "ryRot REAL,",
  421. "rzRot REAL,",
  422. "TextureIndex TEXT,",
  423. "ColorIndex TEXT,",
  424. "usetext INTEGER,",
  425. "FontFace INTEGER,",
  426. "FontSize INTEGER,",
  427. "FontBold INTEGER,",
  428. "FontColor INTEGER,",
  429. "BackColor INTEGER,",
  430. "Alignment INTEGER,",
  431. "TextFontSize INTEGER,",
  432. "ObjectText TEXT);"
  433. );
  434. db_exec(PrefabImportDB, NewImportString);
  435. // Prefab extra info
  436. db_exec(PrefabImportDB, "CREATE TABLE IF NOT EXISTS `PrefabInfo` (zOFF REAL);");
  437. db_exec(PrefabImportDB, "INSERT INTO `PrefabInfo` VALUES(0.0);");
  438. // Prepare query
  439. new ImportPrefabInsert[1024];
  440. strimplode(" ",
  441. ImportPrefabInsert,
  442. sizeof(ImportPrefabInsert),
  443. "INSERT INTO `Objects`",
  444. "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
  445. );
  446. // Prepare data base for writing
  447. insertprefabimpstmt = db_prepare(PrefabImportDB, ImportPrefabInsert);
  448. // Read in map info new style format and get the prefab center for correcting
  449. format(openmap, 64, "tstudio/medit/importpf/%s.mpfab", tempmap);
  450. new Float:pfx, Float:pfy, Float:pfz;
  451. GetPrefabCenter(openmap, pfx, pfy, pfz);
  452. new File:f;
  453. f = fopen(openmap,io_read);
  454. // Check Version
  455. fread(f,templine,sizeof(templine),false);
  456. // This is a new medit version use new load routine
  457. new index;
  458. // new version load
  459. if(!strcmp(strtok(templine,index), "420medit-Version:"))
  460. {
  461. ZOffSet = floatstr(strtok(templine,index));
  462. ZOffSet = floatstr(strtok(templine,index));
  463. format(templine, sizeof(templine), "ZOffSet: %f", ZOffSet);
  464. while(fread(f,templine,sizeof(templine),false)) {
  465. index = 0;
  466. tempobject[object_id] = INVALID_OBJECT_ID;
  467. tempobject[medit_modelid] = strval(strtok(templine,index));
  468. tempobject[pfox] = floatstr(strtok(templine,index))-pfx;
  469. tempobject[pfoy] = floatstr(strtok(templine,index))-pfy;
  470. tempobject[pfoz] = floatstr(strtok(templine,index))-pfz;
  471. tempobject[pfrx] = floatstr(strtok(templine,index));
  472. tempobject[pfry] = floatstr(strtok(templine,index));
  473. tempobject[pfrz] = floatstr(strtok(templine,index));
  474. for(new i = 0; i < MAX_MATERIAL_INDEX; i++)
  475. {
  476. tempobject[Material_Index][i] = strval(strtok(templine,index));
  477. tempobject[Material_Color][i] = strval(strtok(templine,index));
  478. }
  479. // Load Text Data // Only only use first slot anyways
  480. for(new i = 0; i < MAX_MATERIAL_INDEX; i++)
  481. {
  482. index = 0;
  483. fread(f,templine,sizeof(templine),false);
  484. tempobject[usetext][i] = strval(strtok(templine,index));
  485. tempobject[Material_FontFace][i] = strval(strtok(templine,index));
  486. tempobject[Material_FontSize][i] = strval(strtok(templine,index));
  487. tempobject[Material_FontBold][i] = strval(strtok(templine,index));
  488. tempobject[Material_FontColor][i] = strval(strtok(templine,index));
  489. tempobject[Material_BackColor][i] = strval(strtok(templine,index));
  490. tempobject[Material_Alignment][i] = strval(strtok(templine,index));
  491. tempobject[Material_TextFontSize][i] = strval(strtok(templine,index));
  492. new bool:done;
  493. temp_Material_Object_Text[i] = "";
  494. while(done == false)
  495. {
  496. new tmptext[64];
  497. tmptext = strtok(templine,index);
  498. if(!strcmp(tmptext, "E\r\n")) done = true;
  499. else format(temp_Material_Object_Text[i], 64, "%s%s ",temp_Material_Object_Text[i], tmptext);
  500. }
  501. }
  502. // Object read save object to new prefab format
  503. stmt_bind_value(insertprefabimpstmt, 0, DB::TYPE_INT, tempobject[medit_modelid]);
  504. stmt_bind_value(insertprefabimpstmt, 1, DB::TYPE_FLOAT, tempobject[pfox]);
  505. stmt_bind_value(insertprefabimpstmt, 2, DB::TYPE_FLOAT, tempobject[pfoy]);
  506. stmt_bind_value(insertprefabimpstmt, 3, DB::TYPE_FLOAT, tempobject[pfoz]);
  507. stmt_bind_value(insertprefabimpstmt, 4, DB::TYPE_FLOAT, tempobject[pfrx]);
  508. stmt_bind_value(insertprefabimpstmt, 5, DB::TYPE_FLOAT, tempobject[pfry]);
  509. stmt_bind_value(insertprefabimpstmt, 6, DB::TYPE_FLOAT, tempobject[pfrz]);
  510. stmt_bind_value(insertprefabimpstmt, 7, DB::TYPE_ARRAY, tempobject[Material_Index], MAX_MATERIALS);
  511. stmt_bind_value(insertprefabimpstmt, 8, DB::TYPE_ARRAY, tempobject[Material_Color], MAX_MATERIALS);
  512. stmt_bind_value(insertprefabimpstmt, 9, DB::TYPE_INT, tempobject[usetext][0]);
  513. stmt_bind_value(insertprefabimpstmt, 10, DB::TYPE_INT, tempobject[Material_FontFace][0]);
  514. stmt_bind_value(insertprefabimpstmt, 11, DB::TYPE_INT, tempobject[Material_FontSize][0]);
  515. stmt_bind_value(insertprefabimpstmt, 12, DB::TYPE_INT, tempobject[Material_FontBold][0]);
  516. stmt_bind_value(insertprefabimpstmt, 13, DB::TYPE_INT, tempobject[Material_FontColor][0]);
  517. stmt_bind_value(insertprefabimpstmt, 14, DB::TYPE_INT, tempobject[Material_BackColor][0]);
  518. stmt_bind_value(insertprefabimpstmt, 15, DB::TYPE_INT, tempobject[Material_Alignment][0]);
  519. stmt_bind_value(insertprefabimpstmt, 16, DB::TYPE_INT, tempobject[Material_TextFontSize][0]);
  520. stmt_bind_value(insertprefabimpstmt, 17, DB::TYPE_STRING, temp_Material_Object_Text[0], MAX_TEXT_LENGTH);
  521. stmt_execute(insertprefabimpstmt);
  522. }
  523. }
  524. // Old version load
  525. else
  526. {
  527. fclose(f);
  528. f = fopen(openmap,io_read);
  529. while(fread(f,templine,sizeof(templine),false)) {
  530. index = 0;
  531. tempobject[object_id] = INVALID_OBJECT_ID;
  532. tempobject[medit_modelid] = strval(strtok(templine,index));
  533. tempobject[pfox] = floatstr(strtok(templine,index))-pfx;
  534. tempobject[pfoy] = floatstr(strtok(templine,index))-pfy;
  535. tempobject[pfoz] = floatstr(strtok(templine,index))-pfz;
  536. tempobject[pfrx] = floatstr(strtok(templine,index));
  537. tempobject[pfry] = floatstr(strtok(templine,index));
  538. tempobject[pfrz] = floatstr(strtok(templine,index));
  539. for(new i = 0; i < MAX_MATERIAL_INDEX; i++) { tempobject[Material_Index][i] = strval(strtok(templine,index)); }
  540. // Bind our reults
  541. stmt_bind_value(insertprefabimpstmt, 0, DB::TYPE_INT, tempobject[medit_modelid]);
  542. stmt_bind_value(insertprefabimpstmt, 1, DB::TYPE_FLOAT, tempobject[pfox]);
  543. stmt_bind_value(insertprefabimpstmt, 2, DB::TYPE_FLOAT, tempobject[pfoy]);
  544. stmt_bind_value(insertprefabimpstmt, 3, DB::TYPE_FLOAT, tempobject[pfoz]);
  545. stmt_bind_value(insertprefabimpstmt, 4, DB::TYPE_FLOAT, tempobject[pfrx]);
  546. stmt_bind_value(insertprefabimpstmt, 5, DB::TYPE_FLOAT, tempobject[pfry]);
  547. stmt_bind_value(insertprefabimpstmt, 6, DB::TYPE_FLOAT, tempobject[pfrz]);
  548. stmt_bind_value(insertprefabimpstmt, 7, DB::TYPE_ARRAY, tempobject[Material_Index], MAX_MATERIALS);
  549. stmt_bind_value(insertprefabimpstmt, 8, DB::TYPE_ARRAY, tempobject[Material_Color], MAX_MATERIALS);
  550. stmt_bind_value(insertprefabimpstmt, 9, DB::TYPE_INT, 0);
  551. stmt_bind_value(insertprefabimpstmt, 10, DB::TYPE_INT, 0);
  552. stmt_bind_value(insertprefabimpstmt, 11, DB::TYPE_INT, 0);
  553. stmt_bind_value(insertprefabimpstmt, 12, DB::TYPE_INT, 0);
  554. stmt_bind_value(insertprefabimpstmt, 13, DB::TYPE_INT, 0);
  555. stmt_bind_value(insertprefabimpstmt, 14, DB::TYPE_INT, 0);
  556. stmt_bind_value(insertprefabimpstmt, 15, DB::TYPE_INT, 0);
  557. stmt_bind_value(insertprefabimpstmt, 16, DB::TYPE_INT, 20);
  558. stmt_bind_value(insertprefabimpstmt, 17, DB::TYPE_STRING, "None", MAX_TEXT_LENGTH);
  559. stmt_execute(insertprefabimpstmt);
  560. }
  561. }
  562. fclose(f);
  563. db_free_persistent(PrefabImportDB);
  564. return 1;
  565. }
  566. tsfunc GetPrefabCenter(openmap[64], &Float:pfx, &Float:pfy, &Float:pfz)
  567. {
  568. new File:f;
  569. f = fopen(openmap,io_read);
  570. new templine[256];
  571. new Float:ZOffSet;
  572. new Float:highX = -9999999.0;
  573. new Float:highY = -9999999.0;
  574. new Float:highZ = -9999999.0;
  575. new Float:lowX = 9999999.0;
  576. new Float:lowY = 9999999.0;
  577. new Float:lowZ = 9999999.0;
  578. // Check Version
  579. fread(f,templine,sizeof(templine),false);
  580. // This is a new medit version use new load routine
  581. new index;
  582. // new version load
  583. if(!strcmp(strtok(templine,index), "420medit-Version:"))
  584. {
  585. ZOffSet = floatstr(strtok(templine,index));
  586. ZOffSet = floatstr(strtok(templine,index));
  587. format(templine, sizeof(templine), "ZOffSet: %f", ZOffSet);
  588. while(fread(f,templine,sizeof(templine),false)) {
  589. index = 0;
  590. tempobject[object_id] = INVALID_OBJECT_ID;
  591. tempobject[medit_modelid] = strval(strtok(templine,index));
  592. tempobject[pfox] = floatstr(strtok(templine,index));
  593. tempobject[pfoy] = floatstr(strtok(templine,index));
  594. tempobject[pfoz] = floatstr(strtok(templine,index));
  595. tempobject[pfrx] = floatstr(strtok(templine,index));
  596. tempobject[pfry] = floatstr(strtok(templine,index));
  597. tempobject[pfrz] = floatstr(strtok(templine,index));
  598. for(new i = 0; i < MAX_MATERIAL_INDEX; i++)
  599. {
  600. tempobject[Material_Index][i] = strval(strtok(templine,index));
  601. tempobject[Material_Color][i] = strval(strtok(templine,index));
  602. }
  603. // Load Text Data // Only only use first slot anyways
  604. for(new i = 0; i < MAX_MATERIAL_INDEX; i++)
  605. {
  606. index = 0;
  607. fread(f,templine,sizeof(templine),false);
  608. tempobject[usetext][i] = strval(strtok(templine,index));
  609. tempobject[Material_FontFace][i] = strval(strtok(templine,index));
  610. tempobject[Material_FontSize][i] = strval(strtok(templine,index));
  611. tempobject[Material_FontBold][i] = strval(strtok(templine,index));
  612. tempobject[Material_FontColor][i] = strval(strtok(templine,index));
  613. tempobject[Material_BackColor][i] = strval(strtok(templine,index));
  614. tempobject[Material_Alignment][i] = strval(strtok(templine,index));
  615. tempobject[Material_TextFontSize][i] = strval(strtok(templine,index));
  616. new bool:done;
  617. temp_Material_Object_Text[i] = "";
  618. while(done == false)
  619. {
  620. new tmptext[64];
  621. tmptext = strtok(templine,index);
  622. if(!strcmp(tmptext, "E\r\n")) done = true;
  623. else format(temp_Material_Object_Text[i], 64, "%s%s ",temp_Material_Object_Text[i], tmptext);
  624. }
  625. }
  626. // Calculate group center
  627. if(tempobject[pfox] > highX) highX = tempobject[pfox];
  628. if(tempobject[pfoy] > highY) highY = tempobject[pfoy];
  629. if(tempobject[pfoz] > highZ) highZ = tempobject[pfoz];
  630. if(tempobject[pfox] < lowX) lowX = tempobject[pfox];
  631. if(tempobject[pfoy] < lowY) lowY = tempobject[pfoy];
  632. if(tempobject[pfoz] < lowZ) lowZ = tempobject[pfoz];
  633. }
  634. }
  635. // Old version load
  636. else
  637. {
  638. fclose(f);
  639. f = fopen(openmap,io_read);
  640. while(fread(f,templine,sizeof(templine),false)) {
  641. index = 0;
  642. tempobject[object_id] = INVALID_OBJECT_ID;
  643. tempobject[medit_modelid] = strval(strtok(templine,index));
  644. tempobject[pfox] = floatstr(strtok(templine,index));
  645. tempobject[pfoy] = floatstr(strtok(templine,index));
  646. tempobject[pfoz] = floatstr(strtok(templine,index));
  647. tempobject[pfrx] = floatstr(strtok(templine,index));
  648. tempobject[pfry] = floatstr(strtok(templine,index));
  649. tempobject[pfrz] = floatstr(strtok(templine,index));
  650. for(new i = 0; i < MAX_MATERIAL_INDEX; i++) { tempobject[Material_Index][i] = strval(strtok(templine,index)); }
  651. // Calculate group center
  652. if(tempobject[pfox] > highX) highX = tempobject[pfox];
  653. if(tempobject[pfoy] > highY) highY = tempobject[pfoy];
  654. if(tempobject[pfoz] > highZ) highZ = tempobject[pfoz];
  655. if(tempobject[pfox] < lowX) lowX = tempobject[pfox];
  656. if(tempobject[pfoy] < lowY) lowY = tempobject[pfoy];
  657. if(tempobject[pfoz] < lowZ) lowZ = tempobject[pfoz];
  658. }
  659. }
  660. pfx = (highX + lowX) / 2;
  661. pfy = (highY + lowY) / 2;
  662. pfz = (highZ + lowZ) / 2;
  663. fclose(f);
  664. return 1;
  665. }
  666. */