tsmain.pwn 166 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389
  1. ////////////////////////////////////////////////////////////////////////////////
  2. /// Standard Callbacks /////////////////////////////////////////////////////////
  3. ////////////////////////////////////////////////////////////////////////////////
  4. public OnFilterScriptInit()
  5. {
  6. print("----------------------------------------------");
  7. print("----Texture Studio By [uL]Pottus and Crayder--");
  8. print("------------------------------------Loaded----");
  9. SystemDB = db_open_persistent("tstudio/system.db");
  10. ThemeDataDB = db_open_persistent("tstudio/themedata.db");
  11. sqlite_ThemeSetup();
  12. sqlite_LoadBindString();
  13. ResetSettings();
  14. Streamer_ToggleErrorCallback(1); // Enable Streammer Error Callback
  15. #if defined AddSimpleModel // DL-SUPPORT
  16. Streamer_SetVisibleItems(STREAMER_TYPE_OBJECT, 1500);
  17. #endif
  18. return 1;
  19. }
  20. public OnFilterScriptExit()
  21. {
  22. print("----------------------------------------------");
  23. print("----Texture Studio By [uL]Pottus and Crayder--");
  24. print("------------------------------------Unloaded--");
  25. // Delete all map objects
  26. DeleteMapObjects(false);
  27. // Clear all removed buildings
  28. ClearRemoveBuildings();
  29. foreach(new i : Player)
  30. {
  31. ClearCopyBuffer(i);
  32. }
  33. // Always close map
  34. if(MapOpen)
  35. {
  36. db_free_persistent(EditMap);
  37. sqlite_UpdateSettings();
  38. }
  39. db_free_persistent(SystemDB);
  40. db_free_persistent(ThemeDataDB);
  41. foreach(new i : Player)
  42. {
  43. CancelSelectTextDraw(i);
  44. }
  45. return 1;
  46. }
  47. public OnPlayerConnect(playerid)
  48. {
  49. RemoveAllBuildings(playerid);
  50. SendClientMessage(playerid, STEALTH_GREEN, "Welcome to Texture Studio!");
  51. SendClientMessage(playerid, STEALTH_GREEN, sprintf("There are currently %i commands registered, check \"/thelp\" to see them!", Command_GetPlayerCommandCount(playerid)));
  52. new bool:found, bool:warn, string[36];
  53. for (new i, j = Command_GetPlayerCommandCount(playerid); i < j; i++)
  54. {
  55. format(string, 36, "%s", Command_GetNext(i, playerid));
  56. //foreach(new c : Command()) {
  57. for(new k; k < sizeof(Commands); k++) {
  58. if(!strcmp(Commands[k][cName], string)) {
  59. found = true;
  60. break;
  61. }
  62. }
  63. if(!found) {
  64. printf(" /thelp missing command: %s", string);
  65. warn = true;
  66. }
  67. else
  68. found = false;
  69. }
  70. if(warn)
  71. printf("Warning: There's something missing or extra in /thelp for player %i.\n (Report to Crayder on SA-MP Discord if this message ever shows)", playerid);
  72. return 1;
  73. }
  74. public OnPlayerDisconnect(playerid, reason)
  75. {
  76. CurrObject[playerid] = -1;
  77. EditingMode[playerid] = false;
  78. TextDrawOpen[playerid] = false;
  79. PivotPointOn[playerid] = false;
  80. SetEditMode(playerid, EDIT_MODE_NONE);
  81. SetCurrTextDraw(playerid, TEXTDRAW_NONE);
  82. ClearCopyBuffer(playerid);
  83. return 1;
  84. }
  85. public OnPlayerClickMap(playerid, Float:fX, Float:fY, Float:fZ) return 0;
  86. SetCurrObject(playerid, index)
  87. {
  88. if(CanSelectObject(playerid, index))
  89. {
  90. CurrObject[playerid] = index;
  91. CallLocalFunction("OnPlayerObjectSelectChange", "ii", playerid, index);
  92. return 1;
  93. }
  94. return 0;
  95. }
  96. OnPlayerKeyStateChangeOEdit(playerid,newkeys,oldkeys)
  97. {
  98. #pragma unused oldkeys
  99. if(GetEditMode(playerid) == EDIT_MODE_OBJECT)
  100. {
  101. // Clone object
  102. if(newkeys & KEY_WALK)
  103. {
  104. Edit_SetObjectPos(CurrObject[playerid], CurrEditPos[playerid][0], CurrEditPos[playerid][1], CurrEditPos[playerid][2], CurrEditPos[playerid][3], CurrEditPos[playerid][4], CurrEditPos[playerid][5], true);
  105. SetCurrObject(playerid, CloneObject(CurrObject[playerid]));
  106. EditDynamicObject(playerid, ObjectData[CurrObject[playerid]][oID]);
  107. SendClientMessage(playerid, STEALTH_GREEN, "Object has been cloned");
  108. }
  109. // Update object position
  110. else if(newkeys & KEY_SECONDARY_ATTACK)
  111. {
  112. Edit_SetObjectPos(CurrObject[playerid], CurrEditPos[playerid][0], CurrEditPos[playerid][1], CurrEditPos[playerid][2], CurrEditPos[playerid][3], CurrEditPos[playerid][4], CurrEditPos[playerid][5], true);
  113. SendClientMessage(playerid, STEALTH_GREEN, "Object position updated and saved");
  114. }
  115. }
  116. return 0;
  117. }
  118. // player finished editing an object; Fix For new streamer version
  119. public OnPlayerEditObject(playerid, playerobject, objectid, response, Float:fX, Float:fY, Float:fZ, Float:fRotX, Float:fRotY, Float:fRotZ) return 0;
  120. // player finished editing an object
  121. public OnPlayerEditDynamicObject(playerid, objectid, response, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
  122. {
  123. //printf("%i, %i, %i, %i", playerid, objectid, response, GetEditMode(playerid));
  124. switch(GetEditMode(playerid))
  125. {
  126. case EDIT_MODE_OBJECT:
  127. {
  128. // Player finished editing an object
  129. if(response == EDIT_RESPONSE_FINAL)
  130. {
  131. Edit_SetObjectPos(CurrObject[playerid], x, y, z, rx, ry, rz, true);
  132. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  133. SendClientMessage(playerid, STEALTH_GREEN, "Object edit has been saved");
  134. EditingMode[playerid] = false;
  135. SetEditMode(playerid, EDIT_MODE_NONE);
  136. }
  137. else if(response == EDIT_RESPONSE_UPDATE)
  138. {
  139. CurrEditPos[playerid][0] = x;
  140. CurrEditPos[playerid][1] = y;
  141. CurrEditPos[playerid][2] = z;
  142. CurrEditPos[playerid][3] = rx;
  143. CurrEditPos[playerid][4] = ry;
  144. CurrEditPos[playerid][5] = rz;
  145. }
  146. // Cancel editing
  147. else if(response == EDIT_RESPONSE_CANCEL)
  148. {
  149. SetDynamicObjectPos(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oX], ObjectData[CurrObject[playerid]][oY], ObjectData[CurrObject[playerid]][oZ]);
  150. SetDynamicObjectRot(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oRX], ObjectData[CurrObject[playerid]][oRY], ObjectData[CurrObject[playerid]][oRZ]);
  151. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  152. SendClientMessage(playerid, STEALTH_YELLOW, "Cancelled object editing");
  153. EditingMode[playerid] = false;
  154. SetEditMode(playerid, EDIT_MODE_NONE);
  155. }
  156. }
  157. case EDIT_MODE_PIVOT:
  158. {
  159. if(response == EDIT_RESPONSE_FINAL)
  160. {
  161. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  162. SendClientMessage(playerid, STEALTH_GREEN, "Pivot has been saved");
  163. DestroyDynamicObject(PivotObject[playerid]);
  164. PivotPoint[playerid][xPos] = x;
  165. PivotPoint[playerid][yPos] = y;
  166. PivotPoint[playerid][zPos] = z;
  167. EditingMode[playerid] = false;
  168. SetEditMode(playerid, EDIT_MODE_NONE);
  169. }
  170. else if(response == EDIT_RESPONSE_CANCEL)
  171. {
  172. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  173. SendClientMessage(playerid, STEALTH_YELLOW, "Cancelled Pivot editing");
  174. DestroyDynamicObject(PivotObject[playerid]);
  175. EditingMode[playerid] = false;
  176. SetEditMode(playerid, EDIT_MODE_NONE);
  177. }
  178. }
  179. case EDIT_MODE_OBJECTGROUP: OnPlayerEditDOGroup(playerid, objectid, response, x, y, z, rx, ry, rz);
  180. case EDIT_MODE_OBM: OnPlayerEditDOOBM(playerid, objectid, response, x, y, z, rx, ry, rz);
  181. case EDIT_MODE_VOBJECT: OnPlayerEditVObject(playerid, objectid, response, x, y, z, rx, ry, rz);
  182. }
  183. #if defined MA_OnPlayerEditDynamicObject
  184. MA_OnPlayerEditDynamicObject(playerid, objectid, response, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
  185. #endif
  186. return 0;
  187. }
  188. #if defined _ALS_OnPlayerEditDynamicObject
  189. #undef OnPlayerEditDynamicObject
  190. #else
  191. #define _ALS_OnPlayerEditDynamicObject
  192. #endif
  193. #define OnPlayerEditDynamicObject MA_OnPlayerEditDynamicObject
  194. #if defined MA_OnPlayerEditDynamicObject
  195. forward MA_OnPlayerEditDynamicObject(playerid, objectid, response, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
  196. #endif
  197. // Player clicked a dynamic object; Fix For new streamer version
  198. public OnPlayerSelectObject(playerid, type, objectid, modelid, Float:fX, Float:fY, Float:fZ) return 0;
  199. // Player clicked a dynamic object
  200. public OnPlayerSelectDynamicObject(playerid, objectid, modelid, Float:x, Float:y, Float:z)
  201. {
  202. switch(GetEditMode(playerid))
  203. {
  204. case EDIT_MODE_SELECTION:
  205. {
  206. new Keys,ud,lr,index;
  207. GetPlayerKeys(playerid,Keys,ud,lr);
  208. // Find edit object
  209. foreach(new i : Objects)
  210. {
  211. // Object found
  212. if(ObjectData[i][oID] == objectid)
  213. {
  214. index = i;
  215. break;
  216. }
  217. }
  218. if(Keys & KEY_CTRL_BACK || (InFlyMode(playerid) && (Keys & KEY_SECONDARY_ATTACK)))
  219. //if(Keys & KEY_CTRL_BACK)
  220. {
  221. CopyCopyBuffer(playerid, index);
  222. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  223. SendClientMessage(playerid, STEALTH_GREEN, "Copied object textures/color/text to buffer");
  224. }
  225. else if(Keys & KEY_WALK)
  226. {
  227. PasteCopyBuffer(playerid, index);
  228. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  229. SendClientMessage(playerid, STEALTH_GREEN, "Pasted your copy buffer to object");
  230. }
  231. else
  232. {
  233. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  234. if(SetCurrObject(playerid, index)) {
  235. new line[128];
  236. format(line, sizeof(line), "You have selected object index %i for editing", index);
  237. SendClientMessage(playerid, STEALTH_GREEN, line);
  238. }
  239. else
  240. SendClientMessage(playerid, STEALTH_YELLOW, "You can not select objects in this object's group");
  241. }
  242. }
  243. }
  244. return 0;
  245. }
  246. // Streamer Error Log
  247. public Streamer_OnPluginError(const error[])
  248. {
  249. printf("Streamer Plugin Error: %s", error);
  250. }
  251. // Player clicked textdraw
  252. public OnPlayerClickTextDraw(playerid, Text:clickedid)
  253. {
  254. // Text editing mode
  255. if(GetCurrTextDraw(playerid) == TEXTDRAW_TEXTEDIT) if(ClickTextDrawEditText(playerid, Text:clickedid)) return 1;
  256. if(GetCurrTextDraw(playerid) == TEXTDRAW_MATERIALS) if(ClickTextDrawEditMat(playerid, Text:clickedid)) return 1;
  257. if(GetCurrTextDraw(playerid) == TEXTDRAW_LISTSEL) if(ClickTextDrawListSel(playerid, Text:clickedid)) return 1;
  258. if(GetCurrTextDraw(playerid) == TEXTDRAW_OSEARCH) if(ClickTextDrawOSearch(playerid, Text:clickedid)) return 1;
  259. #if defined MA_OnPlayerClickTextDraw
  260. return MA_OnPlayerClickTextDraw(playerid, Text:clickedid);
  261. #endif
  262. return 0;
  263. }
  264. #if defined _ALS_OnPlayerClickTextDraw
  265. #undef OnPlayerClickTextDraw
  266. #else
  267. #define _ALS_OnPlayerClickTextDraw
  268. #endif
  269. #define OnPlayerClickTextDraw MA_OnPlayerClickTextDraw
  270. #if defined MA_OnPlayerClickTextDraw
  271. forward MA_OnPlayerClickTextDraw(playerid, Text:clickedid);
  272. #endif
  273. // Player clicked player textdraw
  274. public OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid)
  275. {
  276. // Text editing mode
  277. if(GetCurrTextDraw(playerid) == TEXTDRAW_TEXTEDIT) if(ClickPlayerTextDrawEditText(playerid, PlayerText:playertextid)) return 1;
  278. if(GetCurrTextDraw(playerid) == TEXTDRAW_MATERIALS) if(ClickPlayerTextDrawEditMat(playerid, PlayerText:playertextid)) return 1;
  279. if(GetCurrTextDraw(playerid) == TEXTDRAW_LISTSEL) if(ClickPlayerTextListSel(playerid, PlayerText:playertextid)) return 1;
  280. if(GetCurrTextDraw(playerid) == TEXTDRAW_OSEARCH) if(ClickPlayerTextDrawOSearch(playerid, PlayerText:playertextid)) return 1;
  281. #if defined MA_OnPlayerClickPlayerTextDraw
  282. return MA_OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid);
  283. #endif
  284. return 0;
  285. }
  286. #if defined _ALS_OnPlayerClickPlayerTD
  287. #undef OnPlayerClickPlayerTextDraw
  288. #else
  289. #define _ALS_OnPlayerClickPlayerTD
  290. #endif
  291. #define OnPlayerClickPlayerTextDraw MA_OnPlayerClickPlayerTextDraw
  292. #if defined MA_OnPlayerClickPlayerTextDraw
  293. forward MA_OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid);
  294. #endif
  295. public OnPlayerKeyStateChange(playerid,newkeys,oldkeys)
  296. {
  297. if(OnPlayerKeyStateChangeOEdit(playerid,newkeys,oldkeys)) return 1;
  298. if(OnPlayerKeyStateChange3DMenu(playerid,newkeys,oldkeys)) return 1;
  299. if(OnPlayerKeyStateGroupChange(playerid, newkeys, oldkeys)) return 1;
  300. if(OnPlayerKeyStateMenuChange(playerid, newkeys, oldkeys)) return 1;
  301. if(OnPlayerKeyStateChangeTex(playerid,newkeys,oldkeys)) return 1;
  302. if(OnPlayerKeyStateChangeLSel(playerid,newkeys,oldkeys)) return 1;
  303. if(OnPlayerKeyStateChangeCMD(playerid,newkeys,oldkeys)) return 1;
  304. return 1;
  305. }
  306. ////////////////////////////////////////////////////////////////////////////////
  307. /// Standard Callbacks End//////////////////////////////////////////////////////
  308. ////////////////////////////////////////////////////////////////////////////////
  309. ////////////////////////////////////////////////////////////////////////////////
  310. /// Sqlite query functions /////////////////////////////////////////////////////
  311. ////////////////////////////////////////////////////////////////////////////////
  312. // Load query stmt
  313. static DBStatement:loadstmt;
  314. // Loads map objects from a data base
  315. sqlite_LoadMapObjects()
  316. {
  317. new tmpobject[OBJECTINFO];
  318. new currindex;
  319. loadstmt = db_prepare(EditMap, "SELECT * FROM `Objects`");
  320. // Bind our results
  321. stmt_bind_result_field(loadstmt, 0, DB::TYPE_INT, currindex);
  322. stmt_bind_result_field(loadstmt, 1, DB::TYPE_INT, tmpobject[oModel]);
  323. stmt_bind_result_field(loadstmt, 2, DB::TYPE_FLOAT, tmpobject[oX]);
  324. stmt_bind_result_field(loadstmt, 3, DB::TYPE_FLOAT, tmpobject[oY]);
  325. stmt_bind_result_field(loadstmt, 4, DB::TYPE_FLOAT, tmpobject[oZ]);
  326. stmt_bind_result_field(loadstmt, 5, DB::TYPE_FLOAT, tmpobject[oRX]);
  327. stmt_bind_result_field(loadstmt, 6, DB::TYPE_FLOAT, tmpobject[oRY]);
  328. stmt_bind_result_field(loadstmt, 7, DB::TYPE_FLOAT, tmpobject[oRZ]);
  329. stmt_bind_result_field(loadstmt, 8, DB::TYPE_ARRAY, tmpobject[oTexIndex], MAX_MATERIALS);
  330. stmt_bind_result_field(loadstmt, 9, DB::TYPE_ARRAY, tmpobject[oColorIndex], MAX_MATERIALS);
  331. stmt_bind_result_field(loadstmt, 10, DB::TYPE_INT, tmpobject[ousetext]);
  332. stmt_bind_result_field(loadstmt, 11, DB::TYPE_INT, tmpobject[oFontFace]);
  333. stmt_bind_result_field(loadstmt, 12, DB::TYPE_INT, tmpobject[oFontSize]);
  334. stmt_bind_result_field(loadstmt, 13, DB::TYPE_INT, tmpobject[oFontBold]);
  335. stmt_bind_result_field(loadstmt, 14, DB::TYPE_INT, tmpobject[oFontColor]);
  336. stmt_bind_result_field(loadstmt, 15, DB::TYPE_INT, tmpobject[oBackColor]);
  337. stmt_bind_result_field(loadstmt, 16, DB::TYPE_INT, tmpobject[oAlignment]);
  338. stmt_bind_result_field(loadstmt, 17, DB::TYPE_INT, tmpobject[oTextFontSize]);
  339. stmt_bind_result_field(loadstmt, 18, DB::TYPE_STRING, tmpobject[oObjectText], MAX_TEXT_LENGTH);
  340. stmt_bind_result_field(loadstmt, 19, DB::TYPE_INT, tmpobject[oGroup]);
  341. stmt_bind_result_field(loadstmt, 20, DB::TYPE_STRING, tmpobject[oNote], 64);
  342. stmt_bind_result_field(loadstmt, 21, DB::TYPE_FLOAT, tmpobject[oDD]);
  343. // Execute query
  344. if(stmt_execute(loadstmt))
  345. {
  346. new count;
  347. while(stmt_fetch_row(loadstmt))
  348. {
  349. // Load object into database at specified index (Don't save to sqlite database)
  350. AddDynamicObject(tmpobject[oModel], tmpobject[oX], tmpobject[oY], tmpobject[oZ], tmpobject[oRX], tmpobject[oRY], tmpobject[oRZ], currindex, false, .dd = tmpobject[oDD]);
  351. // Set textures and colors
  352. for(new i = 0; i < MAX_MATERIALS; i++)
  353. {
  354. ObjectData[currindex][oTexIndex][i] = tmpobject[oTexIndex][i];
  355. ObjectData[currindex][oColorIndex][i] = tmpobject[oColorIndex][i];
  356. }
  357. // Get all text settings
  358. ObjectData[currindex][ousetext] = tmpobject[ousetext];
  359. ObjectData[currindex][oFontFace] = tmpobject[oFontFace];
  360. ObjectData[currindex][oFontSize] = tmpobject[oFontSize];
  361. ObjectData[currindex][oFontBold] = tmpobject[oFontBold];
  362. ObjectData[currindex][oFontColor] = tmpobject[oFontColor];
  363. ObjectData[currindex][oBackColor] = tmpobject[oBackColor];
  364. ObjectData[currindex][oAlignment] = tmpobject[oAlignment];
  365. ObjectData[currindex][oTextFontSize] = tmpobject[oTextFontSize];
  366. ObjectData[currindex][oGroup] = tmpobject[oGroup];
  367. // Get any text string
  368. format(ObjectData[currindex][oObjectText], MAX_TEXT_LENGTH, "%s", tmpobject[oObjectText]);
  369. format(ObjectData[currindex][oNote], MAX_TEXT_LENGTH, "%s", tmpobject[oNote]);
  370. // We need to update textures and materials
  371. UpdateMaterial(currindex);
  372. // Update the object text
  373. UpdateObjectText(currindex);
  374. // Update 3d text
  375. UpdateObject3DText(currindex, true);
  376. count++;
  377. }
  378. stmt_close(loadstmt);
  379. return count;
  380. }
  381. stmt_close(loadstmt);
  382. return 0;
  383. }
  384. // Insert stmt statement
  385. new DBStatement:insertstmt;
  386. new InsertObjectString[512];
  387. // Sqlite query functions
  388. sqlite_InsertObject(index)
  389. {
  390. // Inserts a new index
  391. if(!InsertObjectString[0])
  392. {
  393. // Prepare query
  394. strimplode(" ",
  395. InsertObjectString,
  396. sizeof(InsertObjectString),
  397. "INSERT INTO `Objects`",
  398. "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
  399. );
  400. // Prepare data base for writing
  401. }
  402. insertstmt = db_prepare(EditMap, InsertObjectString);
  403. // Bind values
  404. // Bind our results
  405. stmt_bind_value(insertstmt, 0, DB::TYPE_INT, index);
  406. stmt_bind_value(insertstmt, 1, DB::TYPE_INT, ObjectData[index][oModel]);
  407. stmt_bind_value(insertstmt, 2, DB::TYPE_FLOAT, ObjectData[index][oX]);
  408. stmt_bind_value(insertstmt, 3, DB::TYPE_FLOAT, ObjectData[index][oY]);
  409. stmt_bind_value(insertstmt, 4, DB::TYPE_FLOAT, ObjectData[index][oZ]);
  410. stmt_bind_value(insertstmt, 5, DB::TYPE_FLOAT, ObjectData[index][oRX]);
  411. stmt_bind_value(insertstmt, 6, DB::TYPE_FLOAT, ObjectData[index][oRY]);
  412. stmt_bind_value(insertstmt, 7, DB::TYPE_FLOAT, ObjectData[index][oRZ]);
  413. stmt_bind_value(insertstmt, 8, DB::TYPE_ARRAY, ObjectData[index][oTexIndex], MAX_MATERIALS);
  414. stmt_bind_value(insertstmt, 9, DB::TYPE_ARRAY, ObjectData[index][oColorIndex], MAX_MATERIALS);
  415. stmt_bind_value(insertstmt, 10, DB::TYPE_INT, ObjectData[index][ousetext]);
  416. stmt_bind_value(insertstmt, 11, DB::TYPE_INT, ObjectData[index][oFontFace]);
  417. stmt_bind_value(insertstmt, 12, DB::TYPE_INT, ObjectData[index][oFontSize]);
  418. stmt_bind_value(insertstmt, 13, DB::TYPE_INT, ObjectData[index][oFontBold]);
  419. stmt_bind_value(insertstmt, 14, DB::TYPE_INT, ObjectData[index][oFontColor]);
  420. stmt_bind_value(insertstmt, 15, DB::TYPE_INT, ObjectData[index][oBackColor]);
  421. stmt_bind_value(insertstmt, 16, DB::TYPE_INT, ObjectData[index][oAlignment]);
  422. stmt_bind_value(insertstmt, 17, DB::TYPE_INT, ObjectData[index][oTextFontSize]);
  423. stmt_bind_value(insertstmt, 18, DB::TYPE_STRING, ObjectData[index][oObjectText], MAX_TEXT_LENGTH);
  424. stmt_bind_value(insertstmt, 19, DB::TYPE_INT, ObjectData[index][oGroup]);
  425. stmt_bind_value(insertstmt, 20, DB::TYPE_STRING, ObjectData[index][oNote]);
  426. stmt_bind_value(insertstmt, 21, DB::TYPE_FLOAT, ObjectData[index][oDD]);
  427. stmt_execute(insertstmt);
  428. stmt_close(insertstmt);
  429. }
  430. // Remove a object from the database
  431. sqlite_RemoveObject(index)
  432. {
  433. new Query[128];
  434. format(Query, sizeof(Query), "DELETE FROM `Objects` WHERE `IndexID` = '%i'", index);
  435. db_free_result(db_query(EditMap, Query));
  436. return 1;
  437. }
  438. sqlite_CreateNewMap()
  439. {
  440. sqlite_CreateMapDB();
  441. sqlite_CreateRBDB();
  442. sqlite_CreateVehicle();
  443. sqlite_CreateSettings();
  444. sqlite_InitSettings();
  445. }
  446. new NewMapString[512];
  447. sqlite_CreateMapDB()
  448. {
  449. if(!NewMapString[0])
  450. {
  451. strimplode(" ",
  452. NewMapString,
  453. sizeof(NewMapString),
  454. "CREATE TABLE IF NOT EXISTS `Objects`",
  455. "(IndexID INTEGER,",
  456. "ModelID INTEGER,",
  457. "xPos REAL,",
  458. "yPos REAL,",
  459. "zPos REAL,",
  460. "rxRot REAL,",
  461. "ryRot REAL,",
  462. "rzRot REAL,",
  463. "TextureIndex TEXT,",
  464. "ColorIndex TEXT,",
  465. "usetext INTEGER,",
  466. "FontFace INTEGER,",
  467. "FontSize INTEGER,",
  468. "FontBold INTEGER,",
  469. "FontColor INTEGER,",
  470. "BackColor INTEGER,",
  471. "Alignment INTEGER,",
  472. "TextFontSize INTEGER,",
  473. "ObjectText TEXT,",
  474. "GroupID INTEGER,",
  475. "Note TEXT,",
  476. "DrawDistance REAL DEFAULT 300.0);"
  477. );
  478. }
  479. db_exec(EditMap, NewMapString);
  480. }
  481. // Version 1.2 removebuilding import lines
  482. new NewRemoveString[512];
  483. sqlite_CreateRBDB()
  484. {
  485. if(!NewRemoveString[0])
  486. {
  487. strimplode(" ",
  488. NewRemoveString,
  489. sizeof(NewRemoveString),
  490. "CREATE TABLE IF NOT EXISTS `RemovedBuildings`",
  491. "(ModelID INTEGER,",
  492. "xPos REAL,",
  493. "yPos REAL,",
  494. "zPos REAL,",
  495. "Range REAL);"
  496. );
  497. }
  498. db_exec(EditMap, NewRemoveString);
  499. }
  500. new NewSettingsString[512];
  501. sqlite_CreateSettings()
  502. {
  503. if(!NewSettingsString[0])
  504. {
  505. strimplode(" ",
  506. NewSettingsString,
  507. sizeof(NewSettingsString),
  508. "CREATE TABLE IF NOT EXISTS `Settings`",
  509. "(Version INTEGER DEFAULT 0,",
  510. "LastTime INTEGER DEFAULT 0,",
  511. "Author TEXT DEFAULT 'Creator',",
  512. "SpawnX REAL DEFAULT 0.0,",
  513. "SpawnY REAL DEFAULT 0.0,",
  514. "SpawnZ REAL DEFAULT 0.0,",
  515. "Interior INTEGER DEFAULT -1,",
  516. "VirtualWorld INTEGER DEFAULT -1);"
  517. );
  518. }
  519. db_exec(EditMap, NewSettingsString);
  520. }
  521. new DBStatement:insertsettingstmt;
  522. new InitSettingsString[512];
  523. sqlite_InitSettings()
  524. {
  525. // Insert the initial values
  526. if(!InitSettingsString[0])
  527. {
  528. // Prepare query
  529. strimplode(" ",
  530. InitSettingsString,
  531. sizeof(InitSettingsString),
  532. "INSERT INTO `Settings`",
  533. "VALUES(?, ?, ?, ?, ?, ?, ?, ?)"
  534. );
  535. // Prepare data base for writing
  536. }
  537. insertsettingstmt = db_prepare(EditMap, InitSettingsString);
  538. // Bind our results
  539. stmt_bind_value(insertsettingstmt, 0, DB::TYPE_INT, MapSetting[mVersion]);
  540. stmt_bind_value(insertsettingstmt, 1, DB::TYPE_INT, MapSetting[mLastEdit]);
  541. stmt_bind_value(insertsettingstmt, 2, DB::TYPE_STRING, MapSetting[mAuthor]);
  542. stmt_bind_value(insertsettingstmt, 3, DB::TYPE_FLOAT, MapSetting[mSpawn][xPos]);
  543. stmt_bind_value(insertsettingstmt, 4, DB::TYPE_FLOAT, MapSetting[mSpawn][yPos]);
  544. stmt_bind_value(insertsettingstmt, 5, DB::TYPE_FLOAT, MapSetting[mSpawn][zPos]);
  545. stmt_bind_value(insertsettingstmt, 6, DB::TYPE_INT, MapSetting[mInterior]);
  546. stmt_bind_value(insertsettingstmt, 7, DB::TYPE_INT, MapSetting[mVirtualWorld]);
  547. stmt_execute(insertsettingstmt);
  548. stmt_close(insertsettingstmt);
  549. }
  550. // Makes any version updates
  551. sqlite_UpdateDB()
  552. {
  553. sqlite_CreateRBDB();
  554. sqlite_CreateVehicle();
  555. new dbver = db_query_int(EditMap, "SELECT Version FROM Settings");
  556. new major = (dbver >> 16) & 0xFF, minor = (dbver >> 8) & 0xFF, patch = (dbver & 0xFF) + 96;
  557. #pragma unused major, minor, patch
  558. if(minor < 9)
  559. {
  560. ResetSettings();
  561. sqlite_CreateSettings();
  562. sqlite_InitSettings();
  563. // Version 1.3
  564. if(!ColumnExists(EditMap, "Objects", "GroupID")) db_exec(EditMap, "ALTER TABLE `Objects` ADD COLUMN `GroupID` INTEGER DEFAULT 0");
  565. // Version 1.9
  566. if(!ColumnExists(EditMap, "Objects", "Note"))
  567. {
  568. db_exec(EditMap, "ALTER TABLE `Objects` ADD COLUMN `Note` TEXT DEFAULT ''");
  569. db_exec(EditMap, "ALTER TABLE `Objects` ADD COLUMN `DrawDistance` REAL DEFAULT 300.0");
  570. db_exec(EditMap, "ALTER TABLE `Vehicles` ADD COLUMN `CarSiren` INTEGER DEFAULT 0");
  571. }
  572. }
  573. /* example: Less than 1.9b
  574. if(major <= 1 && minor <= 9 && patch <= 'b'))
  575. {
  576. print("worked");
  577. sqlite_CreateRangeRemoved();
  578. sqlite_InitSettings();
  579. }*/
  580. /*new dbver = db_query_int(EditMap, "SELECT Version FROM Settings");
  581. if(dbver != TS_VERSION)
  582. {
  583. printf("Map version (%i.%i%c) does not match TS version (%i.%i%c)",
  584. (dbver & 0x00FF0000), (dbver & 0x0000FF00), (dbver & 0x000000FF) + 96,
  585. (TS_VERSION & 0x00FF0000), (TS_VERSION & 0x0000FF00), (TS_VERSION & 0x000000FF) + 96);
  586. if((dbver & 0x00FF0000) > (TS_VERSION & 0x00FF0000)) // Major version, changes were made that are needed to edit this map
  587. printf("Map major version is higher than TS version, update TS to edit this map.");
  588. else if((dbver & 0x0000FF00) > (TS_VERSION & 0x0000FF00)) // Minor version, changes were made that affect this map
  589. printf("Map minor version is higher than TS version, update TS to edit this map correctly.");
  590. else if((dbver & 0x000000FF) > (TS_VERSION & 0x000000FF)) // Patch, backwards compatible
  591. printf("Your version of TS is old, consider updating.");
  592. if((dbver & 0x00FF0000) < (TS_VERSION & 0x00FF0000)) // Major version, making updates
  593. printf("Map major version is lower than TS version, updating map.");
  594. else if((dbver & 0x0000FF00) < (TS_VERSION & 0x0000FF00)) // Minor version, making updates
  595. printf("Map minor version is lower than TS version, updating map.");
  596. else if((dbver & 0x000000FF) < (TS_VERSION & 0x000000FF)) // Patch, backwards compatible
  597. printf("Map version is compatible with TS version.");
  598. }*/
  599. sqlite_UpdateSettings();
  600. return 1;
  601. }
  602. new DBStatement:texturestmt;
  603. new TextureUpdateString[512];
  604. // Saves a specific texture index to DB
  605. sqlite_SaveMaterialIndex(index)
  606. {
  607. // Inserts a new index
  608. if(!TextureUpdateString[0])
  609. {
  610. // Prepare query
  611. strimplode(" ",
  612. TextureUpdateString,
  613. sizeof(TextureUpdateString),
  614. "UPDATE `Objects` SET",
  615. "`TextureIndex` = ?",
  616. "WHERE `IndexID` = ?"
  617. );
  618. }
  619. texturestmt = db_prepare(EditMap, TextureUpdateString);
  620. // Bind values
  621. stmt_bind_value(texturestmt, 0, DB::TYPE_ARRAY, ObjectData[index][oTexIndex], MAX_MATERIALS);
  622. stmt_bind_value(texturestmt, 1, DB::TYPE_INT, index);
  623. // Execute stmt
  624. stmt_execute(texturestmt);
  625. stmt_close(texturestmt);
  626. return 1;
  627. }
  628. new DBStatement:colorstmt;
  629. new ColorUpdateString[512];
  630. // Saves a specific texture index to DB
  631. sqlite_SaveColorIndex(index)
  632. {
  633. // Inserts a new index
  634. if(!ColorUpdateString[0])
  635. {
  636. // Prepare query
  637. strimplode(" ",
  638. ColorUpdateString,
  639. sizeof(ColorUpdateString),
  640. "UPDATE `Objects` SET",
  641. "`ColorIndex` = ?",
  642. "WHERE `IndexID` = ?"
  643. );
  644. }
  645. colorstmt = db_prepare(EditMap, ColorUpdateString);
  646. // Bind values
  647. stmt_bind_value(colorstmt, 0, DB::TYPE_ARRAY, ObjectData[index][oColorIndex], MAX_MATERIALS);
  648. stmt_bind_value(colorstmt, 1, DB::TYPE_INT, index);
  649. // Execute stmt
  650. stmt_execute(colorstmt);
  651. stmt_close(colorstmt);
  652. return 1;
  653. }
  654. new DBStatement:posupdatestmt;
  655. new PosUpdateString[512];
  656. sqlite_UpdateObjectPos(index)
  657. {
  658. // Inserts a new index
  659. if(!PosUpdateString[0])
  660. {
  661. // Prepare query
  662. strimplode(" ",
  663. PosUpdateString,
  664. sizeof(PosUpdateString),
  665. "UPDATE `Objects` SET",
  666. "`xPos` = ?,",
  667. "`yPos` = ?,",
  668. "`zPos` = ?,",
  669. "`rxRot` = ?,",
  670. "`ryRot` = ?,",
  671. "`rzRot` = ?",
  672. "WHERE `IndexID` = ?"
  673. );
  674. }
  675. posupdatestmt = db_prepare(EditMap, PosUpdateString);
  676. // Bind values
  677. stmt_bind_value(posupdatestmt, 0, DB::TYPE_FLOAT, ObjectData[index][oX]);
  678. stmt_bind_value(posupdatestmt, 1, DB::TYPE_FLOAT, ObjectData[index][oY]);
  679. stmt_bind_value(posupdatestmt, 2, DB::TYPE_FLOAT, ObjectData[index][oZ]);
  680. stmt_bind_value(posupdatestmt, 3, DB::TYPE_FLOAT, ObjectData[index][oRX]);
  681. stmt_bind_value(posupdatestmt, 4, DB::TYPE_FLOAT, ObjectData[index][oRY]);
  682. stmt_bind_value(posupdatestmt, 5, DB::TYPE_FLOAT, ObjectData[index][oRZ]);
  683. stmt_bind_value(posupdatestmt, 6, DB::TYPE_INT, index);
  684. // Execute stmt
  685. stmt_execute(posupdatestmt);
  686. stmt_close(posupdatestmt);
  687. foreach(new i : Player)
  688. {
  689. if(CurrObject[i] == index) OnObjectUpdatePos(i, index);
  690. }
  691. return 1;
  692. }
  693. new DBStatement:ddupdatestmt;
  694. new DDUpdateString[512];
  695. sqlite_UpdateObjectDD(index)
  696. {
  697. // Inserts a new index
  698. if(!DDUpdateString[0])
  699. {
  700. // Prepare query
  701. strimplode(" ",
  702. DDUpdateString,
  703. sizeof(DDUpdateString),
  704. "UPDATE `Objects` SET",
  705. "`DrawDistance` = ?",
  706. "WHERE `IndexID` = ?"
  707. );
  708. }
  709. ddupdatestmt = db_prepare(EditMap, DDUpdateString);
  710. // Bind values
  711. stmt_bind_value(ddupdatestmt, 0, DB::TYPE_FLOAT, ObjectData[index][oDD]);
  712. stmt_bind_value(ddupdatestmt, 1, DB::TYPE_INT, index);
  713. // Execute stmt
  714. stmt_execute(ddupdatestmt);
  715. stmt_close(ddupdatestmt);
  716. return 1;
  717. }
  718. // Update sql object text
  719. new DBStatement:objecttextallsave;
  720. new ObjectTextSave[512];
  721. sqlite_SaveAllObjectText(index)
  722. {
  723. if(!ObjectTextSave[0])
  724. {
  725. strimplode(" ",
  726. ObjectTextSave,
  727. sizeof(ObjectTextSave),
  728. "UPDATE `Objects` SET",
  729. "`usetext` = ?,",
  730. "`FontFace` = ?,",
  731. "`FontSize` = ?,",
  732. "`FontBold` = ?,",
  733. "`FontColor` = ?,",
  734. "`BackColor` = ?,",
  735. "`Alignment` = ?,",
  736. "`TextFontSize` = ?,",
  737. "`ObjectText` = ?",
  738. "WHERE `IndexID` = ?"
  739. );
  740. }
  741. objecttextallsave = db_prepare(EditMap, ObjectTextSave);
  742. // Bind values
  743. stmt_bind_value(objecttextallsave, 0, DB::TYPE_INT, ObjectData[index][ousetext]);
  744. stmt_bind_value(objecttextallsave, 1, DB::TYPE_INT, ObjectData[index][oFontFace]);
  745. stmt_bind_value(objecttextallsave, 2, DB::TYPE_INT, ObjectData[index][oFontSize]);
  746. stmt_bind_value(objecttextallsave, 3, DB::TYPE_INT, ObjectData[index][oFontBold]);
  747. stmt_bind_value(objecttextallsave, 4, DB::TYPE_INT, ObjectData[index][oFontColor]);
  748. stmt_bind_value(objecttextallsave, 5, DB::TYPE_INT, ObjectData[index][oBackColor]);
  749. stmt_bind_value(objecttextallsave, 6, DB::TYPE_INT, ObjectData[index][oAlignment]);
  750. stmt_bind_value(objecttextallsave, 7, DB::TYPE_INT, ObjectData[index][oTextFontSize]);
  751. stmt_bind_value(objecttextallsave, 8, DB::TYPE_STRING, ObjectData[index][oObjectText]);
  752. stmt_bind_value(objecttextallsave, 9, DB::TYPE_INT, index);
  753. stmt_execute(objecttextallsave);
  754. stmt_close(objecttextallsave);
  755. }
  756. // Update sql use text
  757. new DBStatement:usetextupdatestmt;
  758. new UseTextString[512];
  759. sqlite_ObjUseText(index)
  760. {
  761. if(!UseTextString[0])
  762. {
  763. strimplode(" ",
  764. UseTextString,
  765. sizeof(UseTextString),
  766. "UPDATE `Objects` SET",
  767. "`usetext` = ?",
  768. "WHERE `IndexID` = ?"
  769. );
  770. }
  771. usetextupdatestmt = db_prepare(EditMap, UseTextString);
  772. // Bind values
  773. stmt_bind_value(usetextupdatestmt, 0, DB::TYPE_INT, ObjectData[index][ousetext]);
  774. stmt_bind_value(usetextupdatestmt, 1, DB::TYPE_INT, index);
  775. // Execute stmt
  776. stmt_execute(usetextupdatestmt);
  777. stmt_close(usetextupdatestmt);
  778. return 1;
  779. }
  780. // Update sql fontface
  781. new DBStatement:fontfaceupdatestmt;
  782. new FontFaceString[512];
  783. sqlite_ObjFontFace(index)
  784. {
  785. if(!FontFaceString[0])
  786. {
  787. strimplode(" ",
  788. FontFaceString,
  789. sizeof(FontFaceString),
  790. "UPDATE `Objects` SET",
  791. "`FontFace` = ?",
  792. "WHERE `IndexID` = ?"
  793. );
  794. }
  795. fontfaceupdatestmt = db_prepare(EditMap, FontFaceString);
  796. // Bind values
  797. stmt_bind_value(fontfaceupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oFontFace]);
  798. stmt_bind_value(fontfaceupdatestmt, 1, DB::TYPE_INT, index);
  799. // Execute stmt
  800. stmt_execute(fontfaceupdatestmt);
  801. stmt_close(fontfaceupdatestmt);
  802. return 1;
  803. }
  804. // Update sql fontsize
  805. new DBStatement:fontsizeupdatestmt;
  806. new FontSizeString[512];
  807. sqlite_ObjFontSize(index)
  808. {
  809. if(!FontSizeString[0])
  810. {
  811. strimplode(" ",
  812. FontSizeString,
  813. sizeof(FontSizeString),
  814. "UPDATE `Objects` SET",
  815. "`FontSize` = ?",
  816. "WHERE `IndexID` = ?"
  817. );
  818. }
  819. fontsizeupdatestmt = db_prepare(EditMap, FontSizeString);
  820. // Bind values
  821. stmt_bind_value(fontsizeupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oFontSize]);
  822. stmt_bind_value(fontsizeupdatestmt, 1, DB::TYPE_INT, index);
  823. // Execute stmt
  824. stmt_execute(fontsizeupdatestmt);
  825. stmt_close(fontsizeupdatestmt);
  826. return 1;
  827. }
  828. // Update sql fontbold
  829. new DBStatement:fontboldupdatestmt;
  830. new FontBoldString[512];
  831. sqlite_ObjFontBold(index)
  832. {
  833. if(!FontBoldString[0])
  834. {
  835. strimplode(" ",
  836. FontBoldString,
  837. sizeof(FontBoldString),
  838. "UPDATE `Objects` SET",
  839. "`FontBold` = ?",
  840. "WHERE `IndexID` = ?"
  841. );
  842. }
  843. fontboldupdatestmt = db_prepare(EditMap, FontBoldString);
  844. // Bind values
  845. stmt_bind_value(fontboldupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oFontBold]);
  846. stmt_bind_value(fontboldupdatestmt, 1, DB::TYPE_INT, index);
  847. // Execute stmt
  848. stmt_execute(fontboldupdatestmt);
  849. stmt_close(fontboldupdatestmt);
  850. return 1;
  851. }
  852. // Update sql fontcolor
  853. new DBStatement:fontcolorupdatestmt;
  854. new FontColorString[512];
  855. sqlite_ObjFontColor(index)
  856. {
  857. if(!FontColorString[0])
  858. {
  859. strimplode(" ",
  860. FontColorString,
  861. sizeof(FontColorString),
  862. "UPDATE `Objects` SET",
  863. "`FontColor` = ?",
  864. "WHERE `IndexID` = ?"
  865. );
  866. }
  867. fontcolorupdatestmt = db_prepare(EditMap, FontColorString);
  868. // Bind values
  869. stmt_bind_value(fontcolorupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oFontColor]);
  870. stmt_bind_value(fontcolorupdatestmt, 1, DB::TYPE_INT, index);
  871. // Execute stmt
  872. stmt_execute(fontcolorupdatestmt);
  873. stmt_close(fontcolorupdatestmt);
  874. return 1;
  875. }
  876. // Update sql backcolor
  877. new DBStatement:backcolorupdatestmt;
  878. new BackColorString[512];
  879. sqlite_ObjBackColor(index)
  880. {
  881. if(!BackColorString[0])
  882. {
  883. strimplode(" ",
  884. BackColorString,
  885. sizeof(BackColorString),
  886. "UPDATE `Objects` SET",
  887. "`BackColor` = ?",
  888. "WHERE `IndexID` = ?"
  889. );
  890. }
  891. backcolorupdatestmt = db_prepare(EditMap, BackColorString);
  892. // Bind values
  893. stmt_bind_value(backcolorupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oBackColor]);
  894. stmt_bind_value(backcolorupdatestmt, 1, DB::TYPE_INT, index);
  895. // Execute stmt
  896. stmt_execute(backcolorupdatestmt);
  897. stmt_close(backcolorupdatestmt);
  898. return 1;
  899. }
  900. // Update sql alignment
  901. new DBStatement:alignmentupdatestmt;
  902. new AlignmentString[512];
  903. sqlite_ObjAlignment(index)
  904. {
  905. if(!AlignmentString[0])
  906. {
  907. strimplode(" ",
  908. AlignmentString,
  909. sizeof(AlignmentString),
  910. "UPDATE `Objects` SET",
  911. "`Alignment` = ?",
  912. "WHERE `IndexID` = ?"
  913. );
  914. }
  915. alignmentupdatestmt = db_prepare(EditMap, AlignmentString);
  916. // Bind values
  917. stmt_bind_value(alignmentupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oAlignment]);
  918. stmt_bind_value(alignmentupdatestmt, 1, DB::TYPE_INT, index);
  919. // Execute stmt
  920. stmt_execute(alignmentupdatestmt);
  921. stmt_close(alignmentupdatestmt);
  922. return 1;
  923. }
  924. // Update sql textsize
  925. new DBStatement:textsizeupdatestmt;
  926. new TextSizeString[512];
  927. sqlite_ObjFontTextSize(index)
  928. {
  929. if(!TextSizeString[0])
  930. {
  931. strimplode(" ",
  932. TextSizeString,
  933. sizeof(TextSizeString),
  934. "UPDATE `Objects` SET",
  935. "`TextFontSize` = ?",
  936. "WHERE `IndexID` = ?"
  937. );
  938. }
  939. textsizeupdatestmt = db_prepare(EditMap, TextSizeString);
  940. // Bind values
  941. stmt_bind_value(textsizeupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oTextFontSize]);
  942. stmt_bind_value(textsizeupdatestmt, 1, DB::TYPE_INT, index);
  943. // Execute stmt
  944. stmt_execute(textsizeupdatestmt);
  945. stmt_close(textsizeupdatestmt);
  946. return 1;
  947. }
  948. // Update sql object text
  949. new DBStatement:objecttextupdatestmt;
  950. new ObjectTextString[512];
  951. sqlite_ObjObjectText(index)
  952. {
  953. if(!ObjectTextString[0])
  954. {
  955. strimplode(" ",
  956. ObjectTextString,
  957. sizeof(ObjectTextString),
  958. "UPDATE `Objects` SET",
  959. "`ObjectText` = ?",
  960. "WHERE `IndexID` = ?"
  961. );
  962. }
  963. objecttextupdatestmt = db_prepare(EditMap, ObjectTextString);
  964. // Bind values
  965. stmt_bind_value(objecttextupdatestmt, 0, DB::TYPE_STRING, ObjectData[index][oObjectText]);
  966. stmt_bind_value(objecttextupdatestmt, 1, DB::TYPE_INT, index);
  967. // Execute stmt
  968. stmt_execute(objecttextupdatestmt);
  969. stmt_close(objecttextupdatestmt);
  970. return 1;
  971. }
  972. // Update sql object group
  973. new DBStatement:objectgroupupdatestmt;
  974. new ObjectGroupString[512];
  975. sqlite_ObjGroup(index)
  976. {
  977. if(!ObjectTextString[0])
  978. {
  979. strimplode(" ",
  980. ObjectGroupString,
  981. sizeof(ObjectGroupString),
  982. "UPDATE `Objects` SET",
  983. "`GroupID` = ?",
  984. "WHERE `IndexID` = ?"
  985. );
  986. }
  987. objectgroupupdatestmt = db_prepare(EditMap, ObjectGroupString);
  988. // Bind values
  989. stmt_bind_value(objectgroupupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oGroup]);
  990. stmt_bind_value(objectgroupupdatestmt, 1, DB::TYPE_INT, index);
  991. // Execute stmt
  992. stmt_execute(objectgroupupdatestmt);
  993. stmt_close(objectgroupupdatestmt);
  994. return 1;
  995. }
  996. // Update sql object model
  997. new DBStatement:objectmodelupdatestmt;
  998. new ObjectModelString[512];
  999. sqlite_ObjModel(index)
  1000. {
  1001. if(!ObjectModelString[0])
  1002. {
  1003. strimplode(" ",
  1004. ObjectModelString,
  1005. sizeof(ObjectModelString),
  1006. "UPDATE `Objects` SET",
  1007. "`ModelID` = ?",
  1008. "WHERE `IndexID` = ?"
  1009. );
  1010. }
  1011. objectmodelupdatestmt = db_prepare(EditMap, ObjectModelString);
  1012. // Bind values
  1013. stmt_bind_value(objectmodelupdatestmt, 0, DB::TYPE_INT, ObjectData[index][oModel]);
  1014. stmt_bind_value(objectmodelupdatestmt, 1, DB::TYPE_INT, index);
  1015. // Execute stmt
  1016. stmt_execute(objectmodelupdatestmt);
  1017. stmt_close(objectmodelupdatestmt);
  1018. return 1;
  1019. }
  1020. // Update sql object note
  1021. new DBStatement:objectnoteupdatestmt;
  1022. new ObjectNoteString[512];
  1023. sqlite_ObjNote(index)
  1024. {
  1025. if(!ObjectNoteString[0])
  1026. {
  1027. strimplode(" ",
  1028. ObjectNoteString,
  1029. sizeof(ObjectNoteString),
  1030. "UPDATE `Objects` SET",
  1031. "`Note` = ?",
  1032. "WHERE `IndexID` = ?"
  1033. );
  1034. }
  1035. objectnoteupdatestmt = db_prepare(EditMap, ObjectNoteString);
  1036. // Bind values
  1037. stmt_bind_value(objectnoteupdatestmt, 0, DB::TYPE_STRING, ObjectData[index][oNote]);
  1038. stmt_bind_value(objectnoteupdatestmt, 1, DB::TYPE_INT, index);
  1039. // Execute stmt
  1040. stmt_execute(objectnoteupdatestmt);
  1041. stmt_close(objectnoteupdatestmt);
  1042. return 1;
  1043. }
  1044. // Insert a remove building to DB
  1045. new DBStatement:insertremovebuldingstmt;
  1046. new InsertRemoveBuildingString[256];
  1047. sqlite_InsertRemoveBuilding(index)
  1048. {
  1049. // Inserts a new index
  1050. if(!InsertRemoveBuildingString[0])
  1051. {
  1052. // Prepare query
  1053. strimplode(" ",
  1054. InsertRemoveBuildingString,
  1055. sizeof(InsertRemoveBuildingString),
  1056. "INSERT INTO `RemovedBuildings`",
  1057. "VALUES(?, ?, ?, ?, ?)"
  1058. );
  1059. // Prepare data base for writing
  1060. }
  1061. insertremovebuldingstmt = db_prepare(EditMap, InsertRemoveBuildingString);
  1062. // Bind our results
  1063. stmt_bind_value(insertremovebuldingstmt, 0, DB::TYPE_INT, RemoveData[index][rModel]);
  1064. stmt_bind_value(insertremovebuldingstmt, 1, DB::TYPE_FLOAT, RemoveData[index][rX]);
  1065. stmt_bind_value(insertremovebuldingstmt, 2, DB::TYPE_FLOAT, RemoveData[index][rY]);
  1066. stmt_bind_value(insertremovebuldingstmt, 3, DB::TYPE_FLOAT, RemoveData[index][rZ]);
  1067. stmt_bind_value(insertremovebuldingstmt, 4, DB::TYPE_FLOAT, RemoveData[index][rRange]);
  1068. stmt_execute(insertremovebuldingstmt);
  1069. stmt_close(insertremovebuldingstmt);
  1070. }
  1071. // Update settings in DB
  1072. new DBStatement:updatesettingstmt;
  1073. new InsertSettingsString[256];
  1074. sqlite_UpdateSettings()
  1075. {
  1076. if(!InsertSettingsString[0])
  1077. {
  1078. strimplode(" ",
  1079. InsertSettingsString,
  1080. sizeof(InsertSettingsString),
  1081. "UPDATE `Settings` SET",
  1082. "`Version` = ?,",
  1083. "`LastTime` = ?,",
  1084. "`Author` = ?,",
  1085. "`SpawnX` = ?,",
  1086. "`SpawnY` = ?,",
  1087. "`SpawnZ` = ?,",
  1088. "`Interior` = ?,",
  1089. "`VirtualWorld` = ?",
  1090. // Hacky way to change all of the data without a unique, pointless column
  1091. "WHERE `Version` in (SELECT `Version` FROM Settings LIMIT 1)"
  1092. );
  1093. }
  1094. updatesettingstmt = db_prepare(EditMap, InsertSettingsString);
  1095. // Bind our results
  1096. stmt_bind_value(updatesettingstmt, 0, DB::TYPE_INT, TS_VERSION);
  1097. stmt_bind_value(updatesettingstmt, 1, DB::TYPE_INT, gettime());
  1098. stmt_bind_value(updatesettingstmt, 2, DB::TYPE_STRING, MapSetting[mAuthor]);
  1099. stmt_bind_value(updatesettingstmt, 3, DB::TYPE_FLOAT, MapSetting[mSpawn][xPos]);
  1100. stmt_bind_value(updatesettingstmt, 4, DB::TYPE_FLOAT, MapSetting[mSpawn][yPos]);
  1101. stmt_bind_value(updatesettingstmt, 5, DB::TYPE_FLOAT, MapSetting[mSpawn][zPos]);
  1102. stmt_bind_value(updatesettingstmt, 6, DB::TYPE_INT, MapSetting[mInterior]);
  1103. stmt_bind_value(updatesettingstmt, 7, DB::TYPE_INT, MapSetting[mVirtualWorld]);
  1104. // Execute statement
  1105. stmt_execute(updatesettingstmt);
  1106. stmt_close(updatesettingstmt);
  1107. }
  1108. // Load any remove buildings
  1109. new DBStatement:loadremovebuldingstmt;
  1110. sqlite_LoadRemoveBuildings()
  1111. {
  1112. new tmpremove[REMOVEINFO];
  1113. loadremovebuldingstmt = db_prepare(EditMap, "SELECT * FROM `RemovedBuildings`");
  1114. // Bind our results
  1115. stmt_bind_result_field(loadremovebuldingstmt, 0, DB::TYPE_INT, tmpremove[rModel]);
  1116. stmt_bind_result_field(loadremovebuldingstmt, 1, DB::TYPE_FLOAT, tmpremove[rX]);
  1117. stmt_bind_result_field(loadremovebuldingstmt, 2, DB::TYPE_FLOAT, tmpremove[rY]);
  1118. stmt_bind_result_field(loadremovebuldingstmt, 3, DB::TYPE_FLOAT, tmpremove[rZ]);
  1119. stmt_bind_result_field(loadremovebuldingstmt, 4, DB::TYPE_FLOAT, tmpremove[rRange]);
  1120. // Execute query
  1121. if(stmt_execute(loadremovebuldingstmt))
  1122. {
  1123. new count;
  1124. while(stmt_fetch_row(loadremovebuldingstmt))
  1125. {
  1126. // Add the removed building
  1127. AddRemoveBuilding(tmpremove[rModel], tmpremove[rX], tmpremove[rY], tmpremove[rZ], tmpremove[rRange], false);
  1128. count++;
  1129. }
  1130. stmt_close(loadremovebuldingstmt);
  1131. return count;
  1132. }
  1133. stmt_close(loadremovebuldingstmt);
  1134. return 0;
  1135. }
  1136. // Load settings
  1137. new DBStatement:loadsettingstmt;
  1138. sqlite_LoadSettings()
  1139. {
  1140. new tmpsetting[MAPOPTIONS];
  1141. loadsettingstmt = db_prepare(EditMap, "SELECT * FROM `Settings`");
  1142. // Bind our results
  1143. stmt_bind_result_field(loadsettingstmt, 0, DB::TYPE_INT, tmpsetting[mVersion]);
  1144. stmt_bind_result_field(loadsettingstmt, 1, DB::TYPE_INT, tmpsetting[mLastEdit]);
  1145. stmt_bind_result_field(loadsettingstmt, 2, DB::TYPE_STRING, tmpsetting[mAuthor], MAX_PLAYER_NAME);
  1146. stmt_bind_result_field(loadsettingstmt, 3, DB::TYPE_FLOAT, tmpsetting[mSpawn][xPos]);
  1147. stmt_bind_result_field(loadsettingstmt, 4, DB::TYPE_FLOAT, tmpsetting[mSpawn][yPos]);
  1148. stmt_bind_result_field(loadsettingstmt, 5, DB::TYPE_FLOAT, tmpsetting[mSpawn][zPos]);
  1149. stmt_bind_result_field(loadsettingstmt, 6, DB::TYPE_INT, tmpsetting[mInterior]);
  1150. stmt_bind_result_field(loadsettingstmt, 7, DB::TYPE_INT, tmpsetting[mVirtualWorld]);
  1151. // Set to default
  1152. //ResetSettings();
  1153. // Execute query
  1154. if(stmt_execute(loadsettingstmt))
  1155. {
  1156. if(stmt_fetch_row(loadsettingstmt))
  1157. {
  1158. // Set to loaded data
  1159. MapSetting = tmpsetting;
  1160. return 1;
  1161. }
  1162. }
  1163. stmt_close(loadsettingstmt);
  1164. return 0;
  1165. }
  1166. ////////////////////////////////////////////////////////////////////////////////
  1167. /// Sqlite query functions end /////////////////////////////////////////////////
  1168. ////////////////////////////////////////////////////////////////////////////////
  1169. ////////////////////////////////////////////////////////////////////////////////
  1170. /// Support functions //////////////////////////////////////////////////////////
  1171. ////////////////////////////////////////////////////////////////////////////////
  1172. // Resets all data on a object slot
  1173. ResetObjectIndex(index)
  1174. {
  1175. new tmpobject[OBJECTINFO];
  1176. ObjectData[index] = tmpobject;
  1177. return 1;
  1178. }
  1179. // Sets the material/and or color of an object
  1180. UpdateMaterial(index)
  1181. {
  1182. for(new i = 0; i < MAX_MATERIALS; i++)
  1183. {
  1184. if(ObjectData[index][oTexIndex][i] != 0) SetDynamicObjectMaterial(ObjectData[index][oID], i, GetTModel(ObjectData[index][oTexIndex][i]), GetTXDName(ObjectData[index][oTexIndex][i]), GetTextureName(ObjectData[index][oTexIndex][i]), ObjectData[index][oColorIndex][i]);
  1185. else if(ObjectData[index][oColorIndex][i] != 0) SetDynamicObjectMaterial(ObjectData[index][oID], i, -1, "none", "none", ObjectData[index][oColorIndex][i]);
  1186. }
  1187. return 1;
  1188. }
  1189. // Highlights a object
  1190. HighlightObject(index)
  1191. {
  1192. for(new i = 0; i < MAX_MATERIALS; i++) SetDynamicObjectMaterial(ObjectData[index][oID], i, -1, "none", "none", HIGHLIGHT_OBJECT_COLOR);
  1193. return 1;
  1194. }
  1195. // Updates any text for an object
  1196. UpdateObjectText(index)
  1197. {
  1198. // Dialogs return literal values this will fix that issue to display correctly
  1199. new tmptext[MAX_TEXT_LENGTH];
  1200. strcat(tmptext, ObjectData[index][oObjectText], MAX_TEXT_LENGTH);
  1201. FixText(tmptext);
  1202. if(ObjectData[index][ousetext])
  1203. {
  1204. SetDynamicObjectMaterialText(ObjectData[index][oID],
  1205. 0,
  1206. tmptext,
  1207. FontSizes[ObjectData[index][oFontSize]],
  1208. FontNames[ObjectData[index][oFontFace]],
  1209. ObjectData[index][oTextFontSize],
  1210. ObjectData[index][oFontBold],
  1211. ObjectData[index][oFontColor],
  1212. ObjectData[index][oBackColor],
  1213. ObjectData[index][oAlignment]);
  1214. return 1;
  1215. }
  1216. return 0;
  1217. }
  1218. // Fixes new line and tabs in material text
  1219. FixText(text[])
  1220. {
  1221. new len = strlen(text);
  1222. if(len > 1)
  1223. {
  1224. for(new i = 0; i < len; i++)
  1225. {
  1226. if(text[i] == 92)
  1227. {
  1228. // New line
  1229. if(text[i+1] == 'n')
  1230. {
  1231. text[i] = '\n';
  1232. for(new j = i+1; j < len; j++) text[j] = text[j+1], text[j+1] = 0;
  1233. continue;
  1234. }
  1235. // Tab
  1236. if(text[i+1] == 't')
  1237. {
  1238. text[i] = '\t';
  1239. for(new j = i+1; j < len-1; j++) text[j] = text[j+1], text[j+1] = 0;
  1240. continue;
  1241. }
  1242. // Literal
  1243. if(text[i+1] == 92)
  1244. {
  1245. text[i] = 92;
  1246. for(new j = i+1; j < len-1; j++) text[j] = text[j+1], text[j+1] = 0;
  1247. }
  1248. }
  1249. }
  1250. }
  1251. return 1;
  1252. }
  1253. Edit_SetObjectPos(index, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, bool:save)
  1254. {
  1255. SaveUndoInfo(index, UNDO_TYPE_EDIT);
  1256. ObjectData[index][oX] = x;
  1257. ObjectData[index][oY] = y;
  1258. ObjectData[index][oZ] = z;
  1259. ObjectData[index][oRX] = rx;
  1260. ObjectData[index][oRY] = ry;
  1261. ObjectData[index][oRZ] = rz;
  1262. SetDynamicObjectPos(ObjectData[index][oID], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ]);
  1263. SetDynamicObjectRot(ObjectData[index][oID], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ]);
  1264. if(save)
  1265. {
  1266. // Update object 3d text position
  1267. UpdateObject3DText(index);
  1268. // Update the database
  1269. sqlite_UpdateObjectPos(index);
  1270. }
  1271. return 1;
  1272. }
  1273. UpdateObject3DText(index, bool:newobject=false)
  1274. {
  1275. OnUpdateGroup3DText(index);
  1276. if(!newobject) DestroyDynamic3DTextLabel(ObjectData[index][oTextID]);
  1277. if(!TextOption[tShowText] && !TextOption[tAlwaysShowNew] && newobject)
  1278. return 1;
  1279. // 3D Text Label (To identify objects)
  1280. new line[128];
  1281. format(line, sizeof(line), "Ind: {33DD11}%i%s", index,
  1282. (TextOption[tShowGroup] ? sprintf(" {FF8800}Grp:{33DD11} %i", ObjectData[index][oGroup]) : ("")));
  1283. // Append note
  1284. if(TextOption[tShowModel])
  1285. {
  1286. strcat(line, sprintf("\n{FF8800}Model: {33DD11}%i\n{FF8800}Name: {33DD11}%s", ObjectData[index][oModel], GetModelName(ObjectData[index][oModel])));
  1287. }
  1288. // Append note
  1289. if(TextOption[tShowNote] && strlen(ObjectData[index][oNote]))
  1290. {
  1291. strcat(line, sprintf("\n{FF8800}Note: {33DD11}%s", ObjectData[index][oNote]));
  1292. }
  1293. // Shows the models index
  1294. if(ObjectData[index][oAttachedVehicle] > -1)
  1295. {
  1296. ObjectData[index][oTextID] = CreateDynamic3DTextLabel(line, 0xFF8800FF, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], TEXT3D_DRAW_DIST, INVALID_PLAYER_ID, CarData[ObjectData[index][oAttachedVehicle]][CarID]);
  1297. Update3DAttachCarPos(index, ObjectData[index][oAttachedVehicle]);
  1298. }
  1299. else ObjectData[index][oTextID] = CreateDynamic3DTextLabel(line, 0xFF8800FF, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], TEXT3D_DRAW_DIST);
  1300. // Update the streamer
  1301. foreach(new i : Player)
  1302. {
  1303. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  1304. }
  1305. return 1;
  1306. }
  1307. // Rotation functions (Thanks to Stylock)
  1308. // Calculates group object / whole map rotations
  1309. tsfunc AttachObjectToPoint(objectid, Float:px, Float:py, Float:pz, Float:prx, Float:pry, Float:prz, &Float:RetX, &Float:RetY, &Float:RetZ, &Float:RetRX, &Float:RetRY, &Float:RetRZ, sync_rotation = 1)
  1310. {
  1311. new
  1312. Float:g_sin[3],
  1313. Float:g_cos[3],
  1314. Float:off_x,
  1315. Float:off_y,
  1316. Float:off_z;
  1317. EDIT_FloatEulerFix(prx, pry, prz);
  1318. off_x = ObjectData[objectid][oX] - px; // static offset
  1319. off_y = ObjectData[objectid][oY] - py; // static offset
  1320. off_z = ObjectData[objectid][oZ] - pz; // static offset
  1321. // Calculate the new position
  1322. EDIT_FloatConvertValue(prx, pry, prz, g_sin, g_cos);
  1323. RetX = px + off_x * g_cos[1] * g_cos[2] - off_x * g_sin[0] * g_sin[1] * g_sin[2] - off_y * g_cos[0] * g_sin[2] + off_z * g_sin[1] * g_cos[2] + off_z * g_sin[0] * g_cos[1] * g_sin[2];
  1324. RetY = py + off_x * g_cos[1] * g_sin[2] + off_x * g_sin[0] * g_sin[1] * g_cos[2] + off_y * g_cos[0] * g_cos[2] + off_z * g_sin[1] * g_sin[2] - off_z * g_sin[0] * g_cos[1] * g_cos[2];
  1325. RetZ = pz - off_x * g_cos[0] * g_sin[1] + off_y * g_sin[0] + off_z * g_cos[0] * g_cos[1];
  1326. if (sync_rotation)
  1327. {
  1328. // Calculate the new rotation
  1329. EDIT_FloatConvertValue(asin(g_cos[0] * g_cos[1]), atan2(g_sin[0], g_cos[0] * g_sin[1]) + ObjectData[objectid][oRZ], atan2(g_cos[1] * g_cos[2] * g_sin[0] - g_sin[1] * g_sin[2], g_cos[2] * g_sin[1] - g_cos[1] * g_sin[0] * -g_sin[2]), g_sin, g_cos);
  1330. EDIT_FloatConvertValue(asin(g_cos[0] * g_sin[1]), atan2(g_cos[0] * g_cos[1], g_sin[0]), atan2(g_cos[2] * g_sin[0] * g_sin[1] - g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
  1331. EDIT_FloatConvertValue(atan2(g_sin[0], g_cos[0] * g_cos[1]) + ObjectData[objectid][oRX], asin(g_cos[0] * g_sin[1]), atan2(g_cos[2] * g_sin[0] * g_sin[1] + g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] - g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
  1332. RetRX = asin(g_cos[1] * g_sin[0]);
  1333. RetRY = atan2(g_sin[1], g_cos[0] * g_cos[1]) + ObjectData[objectid][oRY];
  1334. RetRZ = atan2(g_cos[0] * g_sin[2] - g_cos[2] * g_sin[0] * g_sin[1], g_cos[0] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]);
  1335. }
  1336. }
  1337. tsfunc AttachObjectToPoint_GroupEdit(objectid, Float:offx, Float:offy, Float:offz, Float:px, Float:py, Float:pz, Float:prx, Float:pry, Float:prz, &Float:RetX, &Float:RetY, &Float:RetZ, &Float:RetRX, &Float:RetRY, &Float:RetRZ, sync_rotation = 1)
  1338. {
  1339. new
  1340. Float:g_sin[3],
  1341. Float:g_cos[3],
  1342. Float:off_x,
  1343. Float:off_y,
  1344. Float:off_z;
  1345. EDIT_FloatEulerFix(prx, pry, prz);
  1346. off_x = offx - px; // static offset
  1347. off_y = offy - py; // static offset
  1348. off_z = offz - pz; // static offset
  1349. // Calculate the new position
  1350. EDIT_FloatConvertValue(prx, pry, prz, g_sin, g_cos);
  1351. RetX = px + off_x * g_cos[1] * g_cos[2] - off_x * g_sin[0] * g_sin[1] * g_sin[2] - off_y * g_cos[0] * g_sin[2] + off_z * g_sin[1] * g_cos[2] + off_z * g_sin[0] * g_cos[1] * g_sin[2];
  1352. RetY = py + off_x * g_cos[1] * g_sin[2] + off_x * g_sin[0] * g_sin[1] * g_cos[2] + off_y * g_cos[0] * g_cos[2] + off_z * g_sin[1] * g_sin[2] - off_z * g_sin[0] * g_cos[1] * g_cos[2];
  1353. RetZ = pz - off_x * g_cos[0] * g_sin[1] + off_y * g_sin[0] + off_z * g_cos[0] * g_cos[1];
  1354. if (sync_rotation)
  1355. {
  1356. // Calculate the new rotation
  1357. EDIT_FloatConvertValue(asin(g_cos[0] * g_cos[1]), atan2(g_sin[0], g_cos[0] * g_sin[1]) + ObjectData[objectid][oRZ], atan2(g_cos[1] * g_cos[2] * g_sin[0] - g_sin[1] * g_sin[2], g_cos[2] * g_sin[1] - g_cos[1] * g_sin[0] * -g_sin[2]), g_sin, g_cos);
  1358. EDIT_FloatConvertValue(asin(g_cos[0] * g_sin[1]), atan2(g_cos[0] * g_cos[1], g_sin[0]), atan2(g_cos[2] * g_sin[0] * g_sin[1] - g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
  1359. EDIT_FloatConvertValue(atan2(g_sin[0], g_cos[0] * g_cos[1]) + ObjectData[objectid][oRX], asin(g_cos[0] * g_sin[1]), atan2(g_cos[2] * g_sin[0] * g_sin[1] + g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] - g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
  1360. RetRX = asin(g_cos[1] * g_sin[0]);
  1361. RetRY = atan2(g_sin[1], g_cos[0] * g_cos[1]) + ObjectData[objectid][oRY];
  1362. RetRZ = atan2(g_cos[0] * g_sin[2] - g_cos[2] * g_sin[0] * g_sin[1], g_cos[0] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]);
  1363. }
  1364. }
  1365. tsfunc AttachPoint(Float:offx, Float:offy, Float:offz, Float:offrx, Float:offry, Float:offrz, Float:px, Float:py, Float:pz, Float:prx, Float:pry, Float:prz, &Float:RetX, &Float:RetY, &Float:RetZ, &Float:RetRX, &Float:RetRY, &Float:RetRZ, sync_rotation = 1)
  1366. {
  1367. new
  1368. Float:g_sin[3],
  1369. Float:g_cos[3],
  1370. Float:off_x,
  1371. Float:off_y,
  1372. Float:off_z;
  1373. EDIT_FloatEulerFix(prx, pry, prz);
  1374. off_x = offx - px; // static offset
  1375. off_y = offy - py; // static offset
  1376. off_z = offz - pz; // static offset
  1377. // Calculate the new position
  1378. EDIT_FloatConvertValue(prx, pry, prz, g_sin, g_cos);
  1379. RetX = px + off_x * g_cos[1] * g_cos[2] - off_x * g_sin[0] * g_sin[1] * g_sin[2] - off_y * g_cos[0] * g_sin[2] + off_z * g_sin[1] * g_cos[2] + off_z * g_sin[0] * g_cos[1] * g_sin[2];
  1380. RetY = py + off_x * g_cos[1] * g_sin[2] + off_x * g_sin[0] * g_sin[1] * g_cos[2] + off_y * g_cos[0] * g_cos[2] + off_z * g_sin[1] * g_sin[2] - off_z * g_sin[0] * g_cos[1] * g_cos[2];
  1381. RetZ = pz - off_x * g_cos[0] * g_sin[1] + off_y * g_sin[0] + off_z * g_cos[0] * g_cos[1];
  1382. if (sync_rotation)
  1383. {
  1384. // Calculate the new rotation
  1385. EDIT_FloatConvertValue(asin(g_cos[0] * g_cos[1]), atan2(g_sin[0], g_cos[0] * g_sin[1]) + offrz, atan2(g_cos[1] * g_cos[2] * g_sin[0] - g_sin[1] * g_sin[2], g_cos[2] * g_sin[1] - g_cos[1] * g_sin[0] * -g_sin[2]), g_sin, g_cos);
  1386. EDIT_FloatConvertValue(asin(g_cos[0] * g_sin[1]), atan2(g_cos[0] * g_cos[1], g_sin[0]), atan2(g_cos[2] * g_sin[0] * g_sin[1] - g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
  1387. EDIT_FloatConvertValue(atan2(g_sin[0], g_cos[0] * g_cos[1]) + offrx, asin(g_cos[0] * g_sin[1]), atan2(g_cos[2] * g_sin[0] * g_sin[1] + g_cos[1] * g_sin[2], g_cos[1] * g_cos[2] - g_sin[0] * g_sin[1] * g_sin[2]), g_sin, g_cos);
  1388. RetRX = asin(g_cos[1] * g_sin[0]);
  1389. RetRY = atan2(g_sin[1], g_cos[0] * g_cos[1]) + offry;
  1390. RetRZ = atan2(g_cos[0] * g_sin[2] - g_cos[2] * g_sin[0] * g_sin[1], g_cos[0] * g_cos[2] + g_sin[0] * g_sin[1] * g_sin[2]);
  1391. }
  1392. }
  1393. tsfunc EDIT_FloatConvertValue(Float:rot_x, Float:rot_y, Float:rot_z, Float:sin[3], Float:cos[3])
  1394. {
  1395. sin[0] = floatsin(rot_x, degrees);
  1396. sin[1] = floatsin(rot_y, degrees);
  1397. sin[2] = floatsin(rot_z, degrees);
  1398. cos[0] = floatcos(rot_x, degrees);
  1399. cos[1] = floatcos(rot_y, degrees);
  1400. cos[2] = floatcos(rot_z, degrees);
  1401. return 1;
  1402. }
  1403. /*
  1404. * Fixes a bug that causes objects to not rotate
  1405. * correctly when rotating on the Z axis only.
  1406. */
  1407. tsfunc EDIT_FloatEulerFix(&Float:rot_x, &Float:rot_y, &Float:rot_z)
  1408. {
  1409. EDIT_FloatGetRemainder(rot_x, rot_y, rot_z);
  1410. if((!floatcmp(rot_x, 0.0) || !floatcmp(rot_x, 360.0))
  1411. && (!floatcmp(rot_y, 0.0) || !floatcmp(rot_y, 360.0)))
  1412. {
  1413. rot_y = 0.00000002;
  1414. }
  1415. return 1;
  1416. }
  1417. tsfunc EDIT_FloatGetRemainder(&Float:rot_x, &Float:rot_y, &Float:rot_z)
  1418. {
  1419. EDIT_FloatRemainder(rot_x, 360.0);
  1420. EDIT_FloatRemainder(rot_y, 360.0);
  1421. EDIT_FloatRemainder(rot_z, 360.0);
  1422. return 1;
  1423. }
  1424. tsfunc EDIT_FloatRemainder(&Float:remainder, Float:value)
  1425. {
  1426. if(remainder >= value)
  1427. {
  1428. while(remainder >= value)
  1429. {
  1430. remainder = remainder - value;
  1431. }
  1432. }
  1433. else if(remainder < 0.0)
  1434. {
  1435. while(remainder < 0.0)
  1436. {
  1437. remainder = remainder + value;
  1438. }
  1439. }
  1440. return 1;
  1441. }
  1442. // Gets the center of the map
  1443. GetMapCenter(&Float:X, &Float:Y, &Float:Z)
  1444. {
  1445. new Float:highX = -9999999.0;
  1446. new Float:highY = -9999999.0;
  1447. new Float:highZ = -9999999.0;
  1448. new Float:lowX = 9999999.0;
  1449. new Float:lowY = 9999999.0;
  1450. new Float:lowZ = 9999999.0;
  1451. new count;
  1452. foreach(new i : Objects)
  1453. {
  1454. if(ObjectData[i][oX] > highX) highX = ObjectData[i][oX];
  1455. if(ObjectData[i][oY] > highY) highY = ObjectData[i][oY];
  1456. if(ObjectData[i][oZ] > highZ) highZ = ObjectData[i][oZ];
  1457. if(ObjectData[i][oX] < lowX) lowX = ObjectData[i][oX];
  1458. if(ObjectData[i][oY] < lowY) lowY = ObjectData[i][oY];
  1459. if(ObjectData[i][oZ] < lowZ) lowZ = ObjectData[i][oZ];
  1460. count++;
  1461. }
  1462. // Not enough objects grouped
  1463. if(count < 2) return 0;
  1464. X = (highX + lowX) / 2;
  1465. Y = (highY + lowY) / 2;
  1466. Z = (highZ + lowZ) / 2;
  1467. return 1;
  1468. }
  1469. AddDynamicObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz, index = -1, bool:sqlsave = true, Float:dd = 300.0)
  1470. {
  1471. // Index was not specified get a free index
  1472. if(index == -1) index = Iter_Free(Objects);
  1473. //Found free index
  1474. if(index != -1)
  1475. {
  1476. // Add iterator
  1477. Iter_Add(Objects, index);
  1478. // Create object and set data
  1479. ObjectData[index][oID] = CreateDynamicObject(modelid, x, y, z, rx, ry, rz, MapSetting[mVirtualWorld], MapSetting[mInterior], -1, dd);
  1480. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, dd);
  1481. #if defined COMPILE_MANGLE
  1482. ObjectData[index][oCAID] = CA_CreateObject(modelid, x, y, z, rx, ry, rz, true);
  1483. #endif
  1484. // Update the streamer
  1485. foreach(new i : Player)
  1486. {
  1487. if(IsPlayerInRangeOfPoint(i, 300.0, x, y, z)) Streamer_Update(i);
  1488. }
  1489. ObjectData[index][oModel] = modelid;
  1490. ObjectData[index][oX] = x;
  1491. ObjectData[index][oY] = y;
  1492. ObjectData[index][oZ] = z;
  1493. ObjectData[index][oRX] = rx;
  1494. ObjectData[index][oRY] = ry;
  1495. ObjectData[index][oRZ] = rz;
  1496. ObjectData[index][oDD] = dd;
  1497. ObjectData[index][oAttachedVehicle] = -1;
  1498. if(sqlsave)
  1499. {
  1500. ObjectData[index][ousetext] = 0;
  1501. ObjectData[index][oFontFace] = 0;
  1502. ObjectData[index][oFontSize] = 0;
  1503. ObjectData[index][oFontBold] = 0;
  1504. ObjectData[index][oFontColor] = 0;
  1505. ObjectData[index][oBackColor] = 0;
  1506. ObjectData[index][oAlignment] = 0;
  1507. ObjectData[index][oTextFontSize] = 20;
  1508. ObjectData[index][oGroup] = 0;
  1509. format(ObjectData[index][oObjectText], MAX_TEXT_LENGTH, "%s", "None");
  1510. sqlite_InsertObject(index);
  1511. }
  1512. return index;
  1513. }
  1514. else print("Error: Tried to add too many dynamic objects");
  1515. return index;
  1516. }
  1517. DeleteDynamicObject(index, bool:sqlsave = true)
  1518. {
  1519. OnDeleteGroup3DText(index);
  1520. new next;
  1521. if(Iter_Contains(Objects, index))
  1522. {
  1523. if(ObjectData[index][oAttachedVehicle] > -1) UpdateAttachedObjectRef(ObjectData[index][oAttachedVehicle], index);
  1524. DestroyDynamicObject(ObjectData[index][oID]);
  1525. DestroyDynamic3DTextLabel(ObjectData[index][oTextID]);
  1526. Iter_SafeRemove(Objects, index, next);
  1527. ResetObjectIndex(index);
  1528. GroupUpdate(index);
  1529. #if defined COMPILE_MANGLE
  1530. CA_DestroyObject(ObjectData[index][oCAID]);
  1531. #endif
  1532. if(sqlsave) sqlite_RemoveObject(index);
  1533. return next;
  1534. }
  1535. print("Error: Tried to delete a object which does not exist");
  1536. return -1;
  1537. }
  1538. CloneObject(index, grouptask=0)
  1539. {
  1540. if(Iter_Contains(Objects, index))
  1541. {
  1542. new cindex = AddDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], .dd = ObjectData[index][oDD]);
  1543. ObjectData[cindex][ousetext] = ObjectData[index][ousetext];
  1544. ObjectData[cindex][oFontFace] = ObjectData[index][oFontFace];
  1545. ObjectData[cindex][oFontSize] = ObjectData[index][oFontSize];
  1546. ObjectData[cindex][oFontBold] = ObjectData[index][oFontBold];
  1547. ObjectData[cindex][oFontColor] = ObjectData[index][oFontColor];
  1548. ObjectData[cindex][oBackColor] = ObjectData[index][oBackColor];
  1549. ObjectData[cindex][oAlignment] = ObjectData[index][oAlignment];
  1550. ObjectData[cindex][oTextFontSize] = ObjectData[index][oTextFontSize];
  1551. ObjectData[cindex][oGroup] = ObjectData[index][oGroup];
  1552. for(new i = 0; i < MAX_MATERIALS; i++)
  1553. {
  1554. ObjectData[cindex][oTexIndex][i] = ObjectData[index][oTexIndex][i];
  1555. ObjectData[cindex][oColorIndex][i] = ObjectData[index][oColorIndex][i];
  1556. }
  1557. format(ObjectData[cindex][oNote], 64, "%s", ObjectData[index][oNote]);
  1558. format(ObjectData[cindex][oObjectText], MAX_TEXT_LENGTH, "%s", ObjectData[index][oObjectText]);
  1559. // Update the materials
  1560. UpdateMaterial(cindex);
  1561. // Update object text
  1562. UpdateObjectText(cindex);
  1563. // Update 3D text
  1564. UpdateObject3DText(cindex, true);
  1565. // Save materials to material database
  1566. sqlite_SaveMaterialIndex(cindex);
  1567. // Save colors to material database
  1568. sqlite_SaveColorIndex(cindex);
  1569. // Save any text
  1570. sqlite_SaveAllObjectText(cindex);
  1571. if(grouptask > 0) SaveUndoInfo(cindex, UNDO_TYPE_CREATED, grouptask);
  1572. else SaveUndoInfo(cindex, UNDO_TYPE_CREATED);
  1573. return cindex;
  1574. }
  1575. printf("ERROR: Tried to clone a non-existant object");
  1576. return -1;
  1577. }
  1578. // Deletes all map objects
  1579. DeleteMapObjects(bool:sqlsave)
  1580. {
  1581. if(sqlsave)
  1582. {
  1583. db_begin_transaction(EditMap);
  1584. foreach(new i : Objects)
  1585. {
  1586. i = DeleteDynamicObject(i, true);
  1587. }
  1588. db_end_transaction(EditMap);
  1589. }
  1590. else
  1591. {
  1592. foreach(new i : Objects)
  1593. {
  1594. i = DeleteDynamicObject(i, false);
  1595. }
  1596. }
  1597. // Reset any player variables
  1598. foreach(new i : Player)
  1599. {
  1600. SetCurrObject(i, -1);
  1601. }
  1602. return 1;
  1603. }
  1604. // Add a remove building
  1605. AddRemoveBuilding(model, Float:x, Float:y, Float:z, Float:range, savesql = true)
  1606. {
  1607. for(new i = 0; i < MAX_REMOVE_BUILDING; i++)
  1608. {
  1609. if(RemoveData[i][rModel] == 0)
  1610. {
  1611. RemoveData[i][rModel] = model;
  1612. RemoveData[i][rX] = x;
  1613. RemoveData[i][rY] = y;
  1614. RemoveData[i][rZ] = z;
  1615. RemoveData[i][rRange] = range;
  1616. if(savesql) sqlite_InsertRemoveBuilding(i);
  1617. foreach(new j : Player)
  1618. {
  1619. RemoveBuildingForPlayer(j, model, x, y, z, range);
  1620. }
  1621. return 1;
  1622. }
  1623. }
  1624. return 0;
  1625. }
  1626. ClearRemoveBuildings()
  1627. {
  1628. new count;
  1629. for(new i = 0; i < MAX_REMOVE_BUILDING; i++)
  1630. {
  1631. if(RemoveData[i][rModel] != 0)
  1632. {
  1633. RemoveData[i][rModel] = 0;
  1634. count++;
  1635. }
  1636. }
  1637. if(count)
  1638. {
  1639. SendClientMessageToAll(STEALTH_YELLOW, "Warning: The previous map had removed objects you will have to reconnect to see them");
  1640. ResetGTADeletedObjects();
  1641. }
  1642. return 1;
  1643. }
  1644. RemoveAllBuildings(playerid)
  1645. {
  1646. for(new i = 0; i < MAX_REMOVE_BUILDING; i++)
  1647. {
  1648. if(RemoveData[i][rModel] != 0)
  1649. {
  1650. RemoveBuildingForPlayer(playerid, RemoveData[i][rModel], RemoveData[i][rX], RemoveData[i][rY], RemoveData[i][rZ], RemoveData[i][rRange]);
  1651. }
  1652. }
  1653. }
  1654. // Is string a hexvalue
  1655. IsHexValue(hstring[])
  1656. {
  1657. if(strlen(hstring) < 10) return 0;
  1658. if(hstring[0] == 48 && hstring[1] == 120)
  1659. {
  1660. for(new i = 2; i < 10; i++)
  1661. {
  1662. if(hstring[i] == 48 || hstring[i] == 49 || hstring[i] == 50 || hstring[i] == 51 || hstring[i] == 52 ||
  1663. hstring[i] == 53 || hstring[i] == 54 || hstring[i] == 55 || hstring[i] == 56 || hstring[i] == 57 ||
  1664. hstring[i] == 65 || hstring[i] == 66 || hstring[i] == 67 || hstring[i] == 68 || hstring[i] == 69 ||
  1665. hstring[i] == 70) continue;
  1666. else return 0;
  1667. }
  1668. }
  1669. else return 0;
  1670. return 1;
  1671. }
  1672. // Get position in front of player also returns facing angle
  1673. GetPosFaInFrontOfPlayer(playerid, Float:OffDist, &Float:Pxx, &Float:Pyy, &Float:Pzz, &Float:Fa, Float:rotoff = 0.0)
  1674. {
  1675. if(!IsPlayerConnected(playerid)) return 0;
  1676. new
  1677. Float:playerpos[3],
  1678. Float:FacingA;
  1679. GetPlayerPos(playerid, playerpos[0], playerpos[1], playerpos[2]);
  1680. GetPlayerFacingAngle(playerid, FacingA);
  1681. FacingA += rotoff;
  1682. Pxx = (playerpos[0] + OffDist * floatsin(-FacingA,degrees));
  1683. Pyy = (playerpos[1] + OffDist * floatcos(-FacingA,degrees));
  1684. Pzz = playerpos[2];
  1685. Fa = (FacingA > 180) ? (FacingA - 180) : (FacingA + 180);
  1686. return 1;
  1687. }
  1688. ////////////////////////////////////////////////////////////////////////////////
  1689. /// Support functions end///////////////////////////////////////////////////////
  1690. ////////////////////////////////////////////////////////////////////////////////
  1691. ////////////////////////////////////////////////////////////////////////////////
  1692. /// Commands //////////////////////////////////////////////////////////////////
  1693. ////////////////////////////////////////////////////////////////////////////////
  1694. // Echo text to player useful for keybind (Autohotkey)
  1695. YCMD:echo(playerid, arg[], help)
  1696. {
  1697. if(help)
  1698. {
  1699. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1700. SendClientMessage(playerid, STEALTH_GREEN, "Echo text in the chat. Useful for binds and external keybinds.");
  1701. return 1;
  1702. }
  1703. SendClientMessage(playerid, -1, arg);
  1704. return 1;
  1705. }
  1706. // Pick a map to load
  1707. YCMD:loadmap(playerid, arg[], help)
  1708. {
  1709. if(help)
  1710. {
  1711. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1712. SendClientMessage(playerid, STEALTH_GREEN, "Load a saved map.");
  1713. return 1;
  1714. }
  1715. // Map was already open
  1716. if(MapOpen)
  1717. {
  1718. // Confirm open map
  1719. inline Confirm(cpid, cdialogid, cresponse, clistitem, string:ctext[])
  1720. {
  1721. #pragma unused clistitem, cdialogid, cpid, ctext
  1722. // Open a map
  1723. if(cresponse)
  1724. {
  1725. // Update map settings
  1726. sqlite_UpdateSettings();
  1727. // Close map
  1728. db_free_persistent(EditMap);
  1729. // Delete all map objects
  1730. DeleteMapObjects(false);
  1731. // Clear all removed buildings
  1732. ClearRemoveBuildings();
  1733. // Reset settings
  1734. ResetSettings();
  1735. // Clean up vehicles
  1736. ClearVehicles();
  1737. // Clear copy buffer
  1738. foreach(new i : Player)
  1739. {
  1740. ClearCopyBuffer(i);
  1741. }
  1742. // Load map
  1743. LoadMap(playerid);
  1744. }
  1745. }
  1746. Dialog_ShowCallback(playerid, using inline Confirm, DIALOG_STYLE_MSGBOX, "Texture Studio", "You have a map open are you sure you want to load another map?\n(Note: Your map is already saved)", "Ok", "Cancel");
  1747. }
  1748. else LoadMap(playerid);
  1749. return 1;
  1750. }
  1751. // Resets settings array
  1752. ResetSettings()
  1753. {
  1754. MapSetting[mVersion] = 0;
  1755. format(MapSetting[mAuthor], MAX_PLAYER_NAME, "Creator");
  1756. MapSetting[mLastEdit] = 0;
  1757. MapSetting[mInterior] = -1;
  1758. MapSetting[mVirtualWorld] = -1;
  1759. MapSetting[mSpawn][xPos] = 0.0;
  1760. MapSetting[mSpawn][yPos] = 0.0;
  1761. MapSetting[mSpawn][zPos] = 0.0;
  1762. return 1;
  1763. }
  1764. // Load map function call
  1765. LoadMap(playerid)
  1766. {
  1767. // Loop through saved maps
  1768. new dir:dHandle = dir_open("./scriptfiles/tstudio/SavedMaps/");
  1769. new item[40], type;
  1770. new line[1024];
  1771. new extension[3];
  1772. new fcount;
  1773. // Create a load list
  1774. while(dir_list(dHandle, item, type))
  1775. {
  1776. if(type != FM_DIR)
  1777. {
  1778. // We need to check extension
  1779. if(strlen(item) > 3)
  1780. {
  1781. format(extension, sizeof(extension), "%s%s", item[strlen(item) - 2],item[strlen(item) - 1]);
  1782. // File is apparently a db
  1783. if(!strcmp(extension, "db"))
  1784. {
  1785. format(line, sizeof(line), "%s\n%s", item, line);
  1786. fcount++;
  1787. }
  1788. }
  1789. }
  1790. }
  1791. // Files were found
  1792. if(fcount > 0)
  1793. {
  1794. inline Select(spid, sdialogid, sresponse, slistitem, string:stext[])
  1795. {
  1796. #pragma unused slistitem, sdialogid, spid
  1797. // Player selected map to load
  1798. if(sresponse)
  1799. {
  1800. ClearAllUndoInfo();
  1801. format(MapName, sizeof(MapName), "tstudio/SavedMaps/%s", stext);
  1802. // Map is now open
  1803. EditMap = db_open_persistent(MapName);
  1804. // Load the maps settings
  1805. sqlite_LoadSettings();
  1806. // Perform any version updates
  1807. sqlite_UpdateDB();
  1808. // Load the maps remove buildings
  1809. new rmcount = sqlite_LoadRemoveBuildings();
  1810. // Load the maps objects
  1811. new ocount = sqlite_LoadMapObjects();
  1812. // Load any vehicles
  1813. sqlite_LoadCars();
  1814. // Map is now open
  1815. MapOpen = true;
  1816. // Default editing mode
  1817. EditingMode[playerid] = false;
  1818. SetEditMode(playerid,EDIT_MODE_NONE);
  1819. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1820. SendClientMessage(playerid, STEALTH_GREEN, sprintf("You have loaded a map with %i objects and %i removed buildings.", ocount, rmcount));
  1821. new DBResult:timeResult = db_query(EditMap, sprintf("SELECT datetime(%i, 'unixepoch', 'localtime')", MapSetting[mLastEdit]));
  1822. new timestr[64];
  1823. db_get_field(timeResult, 0, timestr, 64);
  1824. db_free_result(timeResult);
  1825. if(MapSetting[mLastEdit])
  1826. {
  1827. SendClientMessage(playerid, STEALTH_GREEN, sprintf("This map was created by %s.", MapSetting[mAuthor]));
  1828. SendClientMessage(playerid, STEALTH_GREEN, sprintf("This map was last edited on %s.", timestr)); // by %s
  1829. }
  1830. // Update the maps settings, so the last edit time updates
  1831. sqlite_UpdateSettings();
  1832. }
  1833. }
  1834. Dialog_ShowCallback(playerid, using inline Select, DIALOG_STYLE_LIST, "Texture Studio (Load Map)", line, "Ok", "Cancel");
  1835. }
  1836. // No files found
  1837. else
  1838. {
  1839. inline CreateMap(cpid, cdialogid, cresponse, clistitem, string:ctext[])
  1840. {
  1841. #pragma unused clistitem, cdialogid, cpid, ctext
  1842. if(cresponse) NewMap(playerid);
  1843. }
  1844. Dialog_ShowCallback(playerid, using inline CreateMap, DIALOG_STYLE_MSGBOX, "Texture Studio", "There are no maps to load create a new map?", "Ok", "Cancel");
  1845. }
  1846. return 1;
  1847. }
  1848. // Rename a map
  1849. YCMD:renamemap(playerid, arg[], help)
  1850. {
  1851. if(help)
  1852. {
  1853. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1854. SendClientMessage(playerid, STEALTH_GREEN, "Rename a saved map.");
  1855. return 1;
  1856. }
  1857. MapOpenCheck();
  1858. // Confirm rename map
  1859. inline Confirm(cpid, cdialogid, cresponse, clistitem, string:ctext[])
  1860. {
  1861. #pragma unused clistitem, cdialogid, cpid
  1862. // Rename a map
  1863. if(cresponse)
  1864. {
  1865. if(!isnull(ctext))
  1866. {
  1867. new newname[128];
  1868. format(newname, 128, "tstudio/SavedMaps/%s.db", ctext);
  1869. if(!fexist(newname))
  1870. {
  1871. // Close the old map
  1872. db_free_persistent(EditMap);
  1873. // Rename the old map
  1874. file_copy(sprintf("./scriptfiles/%s", MapName), sprintf("./scriptfiles/%s", newname));
  1875. file_delete(sprintf("./scriptfiles/%s", MapName));
  1876. MapName = newname;
  1877. // Open the new map
  1878. EditMap = db_open_persistent(MapName);
  1879. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1880. SendClientMessage(playerid, STEALTH_GREEN, "You have renamed a map");
  1881. }
  1882. else
  1883. {
  1884. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1885. SendClientMessage(playerid, STEALTH_YELLOW, "A map with that name already exists");
  1886. Dialog_ShowCallback(playerid, using inline Confirm, DIALOG_STYLE_INPUT, "Texture Studio", "Enter a new name for the current map below.", "Ok", "Cancel");
  1887. }
  1888. }
  1889. else
  1890. {
  1891. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1892. SendClientMessage(playerid, STEALTH_YELLOW, "You must give your map a filename");
  1893. Dialog_ShowCallback(playerid, using inline Confirm, DIALOG_STYLE_INPUT, "Texture Studio", "Enter a new name for the current map below.", "Ok", "Cancel");
  1894. }
  1895. }
  1896. }
  1897. Dialog_ShowCallback(playerid, using inline Confirm, DIALOG_STYLE_INPUT, "Texture Studio", "Enter a new name for the current map below.", "Ok", "Cancel");
  1898. return 1;
  1899. }
  1900. // Delete a map
  1901. YCMD:deletemap(playerid, arg[], help)
  1902. {
  1903. if(help)
  1904. {
  1905. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1906. SendClientMessage(playerid, STEALTH_GREEN, "Delete a saved map. (Use with caution!)");
  1907. return 1;
  1908. }
  1909. MapOpenCheck();
  1910. // Confirm delete map
  1911. inline Confirm(cpid, cdialogid, cresponse, clistitem, string:ctext[])
  1912. {
  1913. #pragma unused clistitem, cdialogid, cpid, ctext
  1914. // Delete a map
  1915. if(cresponse)
  1916. {
  1917. // Close and delete map
  1918. db_free_persistent(EditMap);
  1919. fremove(MapName);
  1920. ClearAllUndoInfo();
  1921. // Delete all map objects
  1922. DeleteMapObjects(false);
  1923. // Clear all removed buildings
  1924. ClearRemoveBuildings();
  1925. // Clean up vehicles
  1926. ClearVehicles();
  1927. // No map open
  1928. MapOpen = false;
  1929. // Reset player variables
  1930. foreach(new i : Player)
  1931. {
  1932. CancelEdit(i);
  1933. EditingMode[i] = false;
  1934. SetCurrObject(playerid, -1);
  1935. ClearCopyBuffer(i);
  1936. }
  1937. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1938. SendClientMessage(playerid, STEALTH_GREEN, "You have deleted a map");
  1939. }
  1940. }
  1941. Dialog_ShowCallback(playerid, using inline Confirm, DIALOG_STYLE_MSGBOX, "Texture Studio", "Are you sure you want to delete this map?\n(Note: Once deleted, there is no going back)", "Ok", "Cancel");
  1942. return 1;
  1943. }
  1944. // Create a new map
  1945. YCMD:newmap(playerid, arg[], help)
  1946. {
  1947. if(help)
  1948. {
  1949. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  1950. SendClientMessage(playerid, STEALTH_GREEN, "Open a new map.");
  1951. return 1;
  1952. }
  1953. // Map was already open
  1954. if(MapOpen)
  1955. {
  1956. // Confirm open map
  1957. inline Confirm(cpid, cdialogid, cresponse, clistitem, string:ctext[])
  1958. {
  1959. #pragma unused clistitem, cdialogid, cpid, ctext
  1960. // Open a map
  1961. if(cresponse)
  1962. {
  1963. // Close map
  1964. db_free_persistent(EditMap);
  1965. ClearAllUndoInfo();
  1966. // Delete all map objects
  1967. DeleteMapObjects(false);
  1968. // Clear all removed buildings
  1969. ClearRemoveBuildings();
  1970. // Clean up vehicles
  1971. ClearVehicles();
  1972. // No map open
  1973. MapOpen = false;
  1974. // Load map
  1975. NewMap(playerid);
  1976. // Reset player variables
  1977. foreach(new i : Player)
  1978. {
  1979. CancelEdit(i);
  1980. EditingMode[i] = false;
  1981. SetCurrObject(playerid, -1);
  1982. ClearCopyBuffer(i);
  1983. }
  1984. }
  1985. }
  1986. Dialog_ShowCallback(playerid, using inline Confirm, DIALOG_STYLE_MSGBOX, "Texture Studio", "You have a map open are you sure you want to create a new map?\n(Note: Your map is already saved)", "Ok", "Cancel");
  1987. }
  1988. else NewMap(playerid);
  1989. return 1;
  1990. }
  1991. // New map function call
  1992. NewMap(playerid)
  1993. {
  1994. inline CreateMap(cpid, cdialogid, cresponse, clistitem, string:ctext[])
  1995. {
  1996. #pragma unused clistitem, cdialogid, cpid
  1997. if(cresponse)
  1998. {
  1999. if(!isnull(ctext))
  2000. {
  2001. format(MapName, sizeof(MapName), "tstudio/SavedMaps/%s.db", ctext);
  2002. if(!fexist(MapName))
  2003. {
  2004. // Open the map for editing
  2005. EditMap = db_open_persistent(MapName);
  2006. // Create new table for map
  2007. sqlite_CreateNewMap();
  2008. // Map is now open
  2009. MapOpen = true;
  2010. // Set map default settings
  2011. MapSetting[mVersion] = TS_VERSION;
  2012. MapSetting[mLastEdit] = gettime();
  2013. GetPlayerName(playerid, MapSetting[mAuthor], MAX_PLAYER_NAME);
  2014. MapSetting[mSpawn][xPos] = 0.0;
  2015. MapSetting[mSpawn][yPos] = 0.0;
  2016. MapSetting[mSpawn][zPos] = 0.0;
  2017. MapSetting[mInterior] = -1;
  2018. MapSetting[mVirtualWorld] = -1;
  2019. // Update the map settings, to set the last edit time and insert the player name
  2020. sqlite_UpdateSettings();
  2021. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2022. SendClientMessage(playerid, STEALTH_GREEN, "You have created a new map");
  2023. }
  2024. else
  2025. {
  2026. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2027. SendClientMessage(playerid, STEALTH_YELLOW, "A map with that name already exists");
  2028. NewMap(playerid);
  2029. }
  2030. }
  2031. else
  2032. {
  2033. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2034. SendClientMessage(playerid, STEALTH_YELLOW, "You must give your new map a filename");
  2035. NewMap(playerid);
  2036. }
  2037. }
  2038. }
  2039. Dialog_ShowCallback(playerid, using inline CreateMap, DIALOG_STYLE_INPUT, "Texture Studio", "Enter a new map name", "Ok", "Cancel");
  2040. }
  2041. // Imports CreateObject() or CreateDynamic() raw code
  2042. YCMD:importmap(playerid, arg[], help)
  2043. {
  2044. if(help)
  2045. {
  2046. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2047. SendClientMessage(playerid, STEALTH_GREEN, "Import a map from a text file.");
  2048. return 1;
  2049. }
  2050. if(MapOpen)
  2051. {
  2052. // The map already has objects
  2053. if(Iter_Count(Objects))
  2054. {
  2055. // Ask to load more objects
  2056. inline Import(ipid, idialogid, iresponse, ilistitem, string:itext[])
  2057. {
  2058. #pragma unused ilistitem, idialogid, ipid, itext
  2059. if(iresponse) ImportMap(playerid);
  2060. }
  2061. Dialog_ShowCallback(playerid, using inline Import, DIALOG_STYLE_MSGBOX, "Texture Studio", "This map has objects are you import more objects?", "Ok", "Cancel");
  2062. }
  2063. // No map loaded import a new map
  2064. else ImportMap(playerid);
  2065. }
  2066. else
  2067. {
  2068. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2069. SendClientMessage(playerid, STEALTH_YELLOW, "A map must be open before trying to import");
  2070. }
  2071. return 1;
  2072. }
  2073. // Import map function
  2074. ImportMap(playerid)
  2075. {
  2076. new dir:dHandle = dir_open("./scriptfiles/tstudio/ImportMaps/");
  2077. new templine[256];
  2078. new tempmap[256];
  2079. new item[40], itype;
  2080. new line[1024];
  2081. new fcount;
  2082. new templast, templastid[32];
  2083. new tmp[16];
  2084. new tmpobject[OBJECTINFO];
  2085. new tmpremove[REMOVEINFO];
  2086. // Create a load list
  2087. while(dir_list(dHandle, item, itype))
  2088. {
  2089. if(itype != FM_DIR)
  2090. {
  2091. format(line, sizeof(line), "%s\n%s", item, line);
  2092. fcount++;
  2093. }
  2094. }
  2095. // Found import files
  2096. if(fcount > 0)
  2097. {
  2098. inline Select(spid, sdialogid, sresponse, slistitem, string:stext[])
  2099. {
  2100. #pragma unused slistitem, sdialogid, spid
  2101. // Selected a file
  2102. if(sresponse)
  2103. {
  2104. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2105. SendClientMessage(playerid, STEALTH_GREEN, "Map importing has started, this make a while depending on map size");
  2106. format(tempmap, 64, "tstudio/ImportMaps/%s",stext);
  2107. new File:f;
  2108. new icount, rcount;
  2109. f = fopen(tempmap,io_read);
  2110. // Read lines and import data
  2111. db_begin_transaction(EditMap);
  2112. while(fread(f,templine,sizeof(templine),false))
  2113. {
  2114. strtrim(templine);
  2115. new type;
  2116. if(strfind(templine, "CreateObject(", true) != -1) type = 1;
  2117. else if(strfind(templine, "CreateDynamicObject(", true) != -1) type = 1;
  2118. else if(strfind(templine, "RemoveBuildingForPlayer(", true) != -1) type = 2;
  2119. else if(strfind(templine, "SetObjectMaterial(", true) != -1) type = 3;
  2120. else if(strfind(templine, "SetDynamicObjectMaterial(", true) != -1) type = 3;
  2121. else if(strfind(templine, "SetObjectMaterialText(", true) != -1) type = 4;
  2122. else if(strfind(templine, "SetDynamicObjectMaterialText(", true) != -1) type = 4;
  2123. else continue;
  2124. new assignment = strfind(templine, "=");
  2125. if(assignment != -1) {
  2126. strmid(templastid, templine, 0, assignment);
  2127. strtrim(templastid);
  2128. }
  2129. strmid(templine, templine, strfind(templine, "(") + 1, strfind(templine, ");"), sizeof(templine));
  2130. if(type == 1)
  2131. {
  2132. if(sscanf(templine, "p<,>iffffff", tmpobject[oModel], tmpobject[oX], tmpobject[oY], tmpobject[oZ], tmpobject[oRX], tmpobject[oRY], tmpobject[oRZ]))
  2133. continue;
  2134. // Create the new object
  2135. templast = AddDynamicObject(tmpobject[oModel], tmpobject[oX], tmpobject[oY], tmpobject[oZ], tmpobject[oRX], tmpobject[oRY], tmpobject[oRZ]);
  2136. icount++;
  2137. }
  2138. else if(type == 2)
  2139. {
  2140. if(sscanf(templine, "p<,>s[16]iffff", tmp, tmpremove[rModel], tmpremove[rX], tmpremove[rY], tmpremove[rZ], tmpremove[rRange]))
  2141. continue;
  2142. // Delete building
  2143. AddRemoveBuilding(tmpremove[rModel], tmpremove[rX], tmpremove[rY], tmpremove[rZ], tmpremove[rRange], true);
  2144. rcount++;
  2145. }
  2146. else if(type == 3)
  2147. {
  2148. strreplace(templine, "\"", "");//"
  2149. new tempindex, tempmodel, temptxd[32], temptexture[32], tempcolor;
  2150. if(sscanf(templine, "p<,>s[16]iis[32]s[32]h", tmp, tempindex, tempmodel, temptxd, temptexture, tempcolor))
  2151. continue;
  2152. if(strcmp(tmp, templastid)) // Stuff before '=' doesn't equal stuff in first param
  2153. continue;
  2154. ObjectData[templast][oColorIndex][tempindex] = tempcolor;
  2155. for(new i = 0; i < sizeof(ObjectTextures); i++)
  2156. {
  2157. if(!strcmp(ObjectTextures[i][TextureName], temptexture))
  2158. {
  2159. ObjectData[templast][oTexIndex][tempindex] = i;
  2160. break;
  2161. }
  2162. }
  2163. sqlite_SaveMaterialIndex(templast);
  2164. sqlite_SaveColorIndex(templast);
  2165. UpdateMaterial(templast);
  2166. }
  2167. else if(type == 4)
  2168. {
  2169. //SetObjectMaterialText(tmp, text[], index, mat_size, fontface[], fontsize, bold, color, backcolor, alignment)
  2170. // start by extracting text[], removing it from the parameters
  2171. // then sscanf all other params separate
  2172. }
  2173. UpdateObject3DText(templast, true);
  2174. }
  2175. db_end_transaction(EditMap);
  2176. format(templine, sizeof(templine), "%i objects were imported, %i removed buildings were imported", icount, rcount);
  2177. SendClientMessage(playerid, STEALTH_GREEN, templine);
  2178. // Were done importing
  2179. fclose(f);
  2180. }
  2181. }
  2182. Dialog_ShowCallback(playerid, using inline Select, DIALOG_STYLE_LIST, "Texture Studio (Import Map)", line, "Ok", "Cancel");
  2183. }
  2184. else
  2185. {
  2186. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2187. SendClientMessage(playerid, STEALTH_YELLOW, "There are no maps to import");
  2188. }
  2189. return 1;
  2190. }
  2191. YCMD:export(playerid, arg[], help)
  2192. {
  2193. if(help)
  2194. {
  2195. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2196. SendClientMessage(playerid, STEALTH_GREEN, "Export current map.");
  2197. return 1;
  2198. }
  2199. MapOpenCheck();
  2200. inline Export(epid, edialogid, eresponse, elistitem, string:etext[])
  2201. {
  2202. #pragma unused elistitem, edialogid, epid, etext
  2203. if(eresponse)
  2204. {
  2205. switch(elistitem)
  2206. {
  2207. case 0: BroadcastCommand(playerid, "/exportmap");
  2208. case 1: BroadcastCommand(playerid, "/exportallmap");
  2209. case 2: BroadcastCommand(playerid, "/avexport");
  2210. case 3: BroadcastCommand(playerid, "/avexportall");
  2211. }
  2212. }
  2213. }
  2214. Dialog_ShowCallback(playerid, using inline Export, DIALOG_STYLE_LIST, "Texture Studio (Export Mode)", "Export Map\nExport All Map To Filerscript\nExport Current Car\nExport All Cars", "Ok", "Cancel");
  2215. return 1;
  2216. }
  2217. // Export map to create object
  2218. YCMD:exportmap(playerid, arg[], help)
  2219. {
  2220. if(help)
  2221. {
  2222. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2223. SendClientMessage(playerid, STEALTH_GREEN, "Export current map to a text file.");
  2224. return 1;
  2225. }
  2226. MapOpenCheck();
  2227. // Ask for a map name
  2228. inline ExportMap(epid, edialogid, eresponse, elistitem, string:etext[])
  2229. {
  2230. #pragma unused elistitem, edialogid, epid
  2231. if(eresponse)
  2232. {
  2233. // Was a map name supplied ?
  2234. if(!isnull(etext))
  2235. {
  2236. // Get the draw distance
  2237. inline DrawDist(dpid, ddialogid, dresponse, dlistitem, string:dtext[])
  2238. {
  2239. #pragma unused dlistitem, ddialogid, dpid
  2240. new Float:dist;
  2241. // Set the drawdistance
  2242. if(dresponse)
  2243. {
  2244. if(sscanf(dtext, "f", dist)) dist = 300.0;
  2245. /*else foreach(new i : Objects)
  2246. {
  2247. if(ObjectData[i][oDD] == 300.0) // Default oDD
  2248. ObjectData[i][oDD] = dist;
  2249. }*/
  2250. }
  2251. else dist = 300.0;
  2252. new exportmap[256];
  2253. // Check map name length
  2254. if(strlen(etext) >= 20)
  2255. {
  2256. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2257. SendClientMessage(playerid, STEALTH_YELLOW, "Choose a shorter map name to export to...");
  2258. return 1;
  2259. }
  2260. // Format the output name
  2261. format(exportmap, sizeof(exportmap), "tstudio/ExportMaps/%s.txt", etext);
  2262. // Map exists ask to remove
  2263. if(fexist(exportmap))
  2264. {
  2265. inline RemoveMap(rpid, rdialogid, rresponse, rlistitem, string:rtext[])
  2266. {
  2267. #pragma unused rlistitem, rdialogid, rpid, rtext
  2268. // Remove map and export
  2269. if(rresponse)
  2270. {
  2271. fremove(exportmap);
  2272. MapExport(playerid, exportmap, dist);
  2273. }
  2274. }
  2275. Dialog_ShowCallback(playerid, using inline RemoveMap, DIALOG_STYLE_MSGBOX, "Texture Studio (Export Map)", "A export exists with this name replace?", "Ok", "Cancel");
  2276. }
  2277. // We can start the export
  2278. else MapExport(playerid, exportmap, dist);
  2279. }
  2280. Dialog_ShowCallback(playerid, using inline DrawDist, DIALOG_STYLE_INPUT, "Texture Studio (Map Export)", "Enter the draw distance for objects\n(Note: Default draw distance is 300.0)", "Ok", "Cancel");
  2281. }
  2282. else
  2283. {
  2284. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2285. SendClientMessage(playerid, STEALTH_YELLOW, "You can't export a map with no name");
  2286. Dialog_ShowCallback(playerid, using inline ExportMap, DIALOG_STYLE_INPUT, "Texture Studio (Map Export)", "Enter a export map name", "Ok", "Cancel");
  2287. }
  2288. }
  2289. }
  2290. Dialog_ShowCallback(playerid, using inline ExportMap, DIALOG_STYLE_INPUT, "Texture Studio (Map Export)", "Enter a export map name", "Ok", "Cancel");
  2291. return 1;
  2292. }
  2293. // Start exporting
  2294. MapExport(playerid, mapname[], Float:drawdist)
  2295. {
  2296. new exportmap[256];
  2297. format(exportmap, sizeof(exportmap), "%s", mapname);
  2298. inline ExportType(epid, edialogid, eresponse, elistitem, string:etext[])
  2299. {
  2300. #pragma unused edialogid, epid, etext
  2301. if(eresponse)
  2302. {
  2303. new mobjects;
  2304. new templine[256];
  2305. new File:f;
  2306. f = fopen(exportmap,io_write);
  2307. fwrite(f,"//Map Exported with Texture Studio By: [uL]Pottus////////////////////////////////////////////////////////////////\r\n");
  2308. fwrite(f,"//////////////////////////////////////////////and Crayder////////////////////////////////////////////////////////\r\n");
  2309. fwrite(f,"/////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2310. fwrite(f,"\r\n//Map Information////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2311. new DBResult:timeResult = db_query(EditMap, sprintf("SELECT datetime(%i, 'unixepoch', 'localtime')", gettime()));
  2312. new timestr[64];
  2313. db_get_field(timeResult, 0, timestr, 64);
  2314. db_free_result(timeResult);
  2315. fwrite(f,"/*\r\n");
  2316. fwrite(f,sprintf("\tExported on \"%s\" by \"%s\"\r\n", timestr, ReturnPlayerName(playerid)));
  2317. fwrite(f,sprintf("\tCreated by \"%s\"\r\n", MapSetting[mAuthor]));
  2318. if(MapSetting[mSpawn][xPos])
  2319. fwrite(f,sprintf("\tSpawn Position: %f, %f, %f\r\n", MapSetting[mSpawn][xPos], MapSetting[mSpawn][yPos], MapSetting[mSpawn][zPos]));
  2320. fwrite(f,"*/");
  2321. fwrite(f,"\r\n/////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2322. if(RemoveData[0][rModel] != 0) fwrite(f,"\r\n//Remove Buildings///////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2323. for(new i = 0; i < MAX_REMOVE_BUILDING; i++)
  2324. {
  2325. if(RemoveData[i][rModel] != 0)
  2326. {
  2327. format(templine, sizeof(templine), "RemoveBuildingForPlayer(playerid, %i, %.3f, %.3f, %.3f, %.3f);\r\n", RemoveData[i][rModel], RemoveData[i][rX], RemoveData[i][rY], RemoveData[i][rZ], RemoveData[i][rRange]);
  2328. fwrite(f,templine);
  2329. }
  2330. }
  2331. fwrite(f,"\r\n//Objects////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2332. // Temp object for setting materials
  2333. format(templine,sizeof(templine),"new tmpobjid;\r\n");
  2334. fwrite(f,templine);
  2335. // Write all objects with materials first
  2336. foreach(new i : Objects)
  2337. {
  2338. if(ObjectData[i][oAttachedVehicle] > -1) continue;
  2339. new bool:writeobject, Float:odd = (ObjectData[i][oDD] != 300.0 ? ObjectData[i][oDD] : drawdist);
  2340. // Does the object have materials?
  2341. for(new j = 0; j < MAX_MATERIALS; j++)
  2342. {
  2343. if(ObjectData[i][oTexIndex][j] != 0 || ObjectData[i][oColorIndex][j] != 0 || ObjectData[i][ousetext])
  2344. {
  2345. writeobject = true;
  2346. break;
  2347. }
  2348. }
  2349. // Object had materials we will write them to the export file
  2350. if(writeobject)
  2351. {
  2352. mobjects++;
  2353. // Write the create object line
  2354. if(elistitem == 0)
  2355. {
  2356. format(templine,sizeof(templine),"tmpobjid = CreateObject(%i, %f, %f, %f, %f, %f, %f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,
  2357. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2358. fwrite(f,templine);
  2359. }
  2360. // Write the create dynamic object line
  2361. else if(elistitem == 1)
  2362. {
  2363. format(templine,sizeof(templine),"tmpobjid = CreateDynamicObjectEx(%i, %f, %f, %f, %f, %f, %f, %.2f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,odd,
  2364. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2365. fwrite(f,templine);
  2366. }
  2367. else if(elistitem == 2)
  2368. {
  2369. format(templine,sizeof(templine),"tmpobjid = CreateDynamicObject(%i, %f, %f, %f, %f, %f, %f, -1, -1, -1, %.2f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,odd,
  2370. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2371. fwrite(f,templine);
  2372. }
  2373. // Write all materials and colors
  2374. for(new j = 0; j < MAX_MATERIALS; j++)
  2375. {
  2376. // Does object have a texture set?
  2377. if(ObjectData[i][oTexIndex][j] != 0)
  2378. {
  2379. if(elistitem == 0)
  2380. {
  2381. format(templine,sizeof(templine),"SetObjectMaterial(tmpobjid, %i, %i, %c%s%c, %c%s%c, 0x%X);\r\n", j, GetTModel(ObjectData[i][oTexIndex][j]), 34, GetTXDName(ObjectData[i][oTexIndex][j]), 34, 34,GetTextureName(ObjectData[i][oTexIndex][j]), 34, ObjectData[i][oColorIndex][j]);
  2382. fwrite(f,templine);
  2383. }
  2384. else if(elistitem == 1 || elistitem == 2)
  2385. {
  2386. format(templine,sizeof(templine),"SetDynamicObjectMaterial(tmpobjid, %i, %i, %c%s%c, %c%s%c, 0x%X);\r\n", j, GetTModel(ObjectData[i][oTexIndex][j]), 34, GetTXDName(ObjectData[i][oTexIndex][j]), 34, 34,GetTextureName(ObjectData[i][oTexIndex][j]), 34, ObjectData[i][oColorIndex][j]);
  2387. fwrite(f,templine);
  2388. }
  2389. }
  2390. // No texture how about a color?
  2391. else if(ObjectData[i][oColorIndex][j] != 0)
  2392. {
  2393. if(elistitem == 0)
  2394. {
  2395. format(templine,sizeof(templine),"SetObjectMaterial(tmpobjid, %i, -1, %c%s%c, %c%s%c, 0x%X);\r\n", j, 34, "none", 34, 34,"none", 34, ObjectData[i][oColorIndex][j]);
  2396. fwrite(f,templine);
  2397. }
  2398. else if(elistitem == 1 || elistitem == 2)
  2399. {
  2400. format(templine,sizeof(templine),"SetDynamicObjectMaterial(tmpobjid, %i, -1, %c%s%c, %c%s%c, 0x%X);\r\n", j, 34, "none", 34, 34,"none", 34, ObjectData[i][oColorIndex][j]);
  2401. fwrite(f,templine);
  2402. }
  2403. }
  2404. }
  2405. // Write any text
  2406. if(ObjectData[i][ousetext])
  2407. {
  2408. if(elistitem == 0)
  2409. {
  2410. format(templine,sizeof(templine),"SetObjectMaterialText(tmpobjid, %c%s%c, 0, %i, %c%s%c, %i, %i, 0x%X, 0x%X, %i);\r\n",
  2411. 34, ObjectData[i][oObjectText], 34,
  2412. FontSizes[ObjectData[i][oFontSize]],
  2413. 34, FontNames[ObjectData[i][oFontFace]], 34,
  2414. ObjectData[i][oTextFontSize],
  2415. ObjectData[i][oFontBold],
  2416. ObjectData[i][oFontColor],
  2417. ObjectData[i][oBackColor],
  2418. ObjectData[i][oAlignment]
  2419. );
  2420. }
  2421. else if(elistitem == 1 || elistitem == 2)
  2422. {
  2423. format(templine,sizeof(templine),"SetDynamicObjectMaterialText(tmpobjid, 0, %c%s%c, %i, %c%s%c, %i, %i, 0x%X, 0x%X, %i);\r\n",
  2424. 34, ObjectData[i][oObjectText], 34,
  2425. FontSizes[ObjectData[i][oFontSize]],
  2426. 34, FontNames[ObjectData[i][oFontFace]], 34,
  2427. ObjectData[i][oTextFontSize],
  2428. ObjectData[i][oFontBold],
  2429. ObjectData[i][oFontColor],
  2430. ObjectData[i][oBackColor],
  2431. ObjectData[i][oAlignment]
  2432. );
  2433. }
  2434. fwrite(f,templine);
  2435. }
  2436. }
  2437. }
  2438. if(mobjects)
  2439. {
  2440. fwrite(f,"/////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2441. fwrite(f,"/////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2442. fwrite(f,"/////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2443. }
  2444. // We need to write all of the objects that didn't have materials set now
  2445. foreach(new i : Objects)
  2446. {
  2447. if(ObjectData[i][oAttachedVehicle] > -1) continue;
  2448. new bool:writeobject = true, Float:odd = (ObjectData[i][oDD] != 300.0 ? ObjectData[i][oDD] : drawdist);
  2449. // Does the object have materials?
  2450. for(new j = 0; j < MAX_MATERIALS; j++)
  2451. {
  2452. // This object has already been written
  2453. if(ObjectData[i][oTexIndex][j] != 0 || ObjectData[i][oColorIndex][j] != 0 || ObjectData[i][ousetext])
  2454. {
  2455. writeobject = false;
  2456. break;
  2457. }
  2458. }
  2459. // Object has not been exported yet export
  2460. if(writeobject)
  2461. {
  2462. if(elistitem == 0)
  2463. {
  2464. format(templine,sizeof(templine),"tmpobjid = CreateObject(%i, %f, %f, %f, %f, %f, %f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,
  2465. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2466. fwrite(f,templine);
  2467. }
  2468. else if(elistitem == 1)
  2469. {
  2470. format(templine,sizeof(templine),"tmpobjid = CreateDynamicObjectEx(%i, %f, %f, %f, %f, %f, %f, %.2f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,odd,
  2471. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2472. fwrite(f,templine);
  2473. }
  2474. else if(elistitem == 2)
  2475. {
  2476. format(templine,sizeof(templine),"tmpobjid = CreateDynamicObject(%i, %f, %f, %f, %f, %f, %f, -1, -1, -1, %.2f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,odd,
  2477. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2478. fwrite(f,templine);
  2479. }
  2480. }
  2481. }
  2482. fclose(f);
  2483. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2484. format(templine, sizeof(templine), "Map has been exported to %s", exportmap);
  2485. SendClientMessage(playerid, STEALTH_GREEN, templine);
  2486. }
  2487. }
  2488. Dialog_ShowCallback(playerid, using inline ExportType, DIALOG_STYLE_LIST, "Texture Studio (Export Map)", "Type 1 - CreateObject()\nType 2 - CreateDynamicObjectEx()\nType 3 - CreateDynamicObject", "Ok", "Cancel");
  2489. return 1;
  2490. }
  2491. // Export map to create object
  2492. YCMD:exportallmap(playerid, arg[], help)
  2493. {
  2494. if(help)
  2495. {
  2496. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2497. SendClientMessage(playerid, STEALTH_GREEN, "Export current map to a filterscript.");
  2498. return 1;
  2499. }
  2500. MapOpenCheck();
  2501. // Ask for a map name
  2502. inline ExportMap(epid, edialogid, eresponse, elistitem, string:etext[])
  2503. {
  2504. #pragma unused elistitem, edialogid, epid
  2505. if(eresponse)
  2506. {
  2507. // Was a map name supplied ?
  2508. if(!isnull(etext))
  2509. {
  2510. // Get the draw distance
  2511. inline DrawDist(dpid, ddialogid, dresponse, dlistitem, string:dtext[])
  2512. {
  2513. #pragma unused dlistitem, ddialogid, dpid
  2514. new Float:dist;
  2515. // Set the drawdistance
  2516. if(dresponse)
  2517. {
  2518. if(sscanf(dtext, "f", dist)) dist = 300.0;
  2519. }
  2520. else dist = 300.0;
  2521. new exportmap[256];
  2522. // Check map name length
  2523. if(strlen(etext) >= 20)
  2524. {
  2525. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2526. SendClientMessage(playerid, STEALTH_YELLOW, "Choose a shorter map name to export to...");
  2527. return 1;
  2528. }
  2529. // Format the output name
  2530. format(exportmap, sizeof(exportmap), "tstudio/ExportMaps/%s.pwn", etext);
  2531. // Map exists ask to remove
  2532. if(fexist(exportmap))
  2533. {
  2534. inline RemoveMap(rpid, rdialogid, rresponse, rlistitem, string:rtext[])
  2535. {
  2536. #pragma unused rlistitem, rdialogid, rpid, rtext
  2537. // Remove map and export
  2538. if(rresponse)
  2539. {
  2540. fremove(exportmap);
  2541. MapExportAll(playerid, exportmap, dist);
  2542. }
  2543. }
  2544. Dialog_ShowCallback(playerid, using inline RemoveMap, DIALOG_STYLE_MSGBOX, "Texture Studio (Export Map)", "A export exists with this name replace?", "Ok", "Cancel");
  2545. }
  2546. // We can start the export
  2547. else MapExportAll(playerid, exportmap, dist);
  2548. }
  2549. Dialog_ShowCallback(playerid, using inline DrawDist, DIALOG_STYLE_INPUT, "Texture Studio (Map Export)", "Enter the draw distance for objects\n(Note: Default draw distance is 300.0)", "Ok", "Cancel");
  2550. }
  2551. else
  2552. {
  2553. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2554. SendClientMessage(playerid, STEALTH_YELLOW, "You can't export a map with no name");
  2555. Dialog_ShowCallback(playerid, using inline ExportMap, DIALOG_STYLE_INPUT, "Texture Studio (Map All Export)", "Enter a export map name", "Ok", "Cancel");
  2556. }
  2557. }
  2558. }
  2559. Dialog_ShowCallback(playerid, using inline ExportMap, DIALOG_STYLE_INPUT, "Texture Studio (Map All Export)", "Enter a export map name", "Ok", "Cancel");
  2560. return 1;
  2561. }
  2562. static MapExportAll(playerid, name[], Float:drawdist)
  2563. {
  2564. new File:f = fopen(name, io_write);
  2565. new templine[256];
  2566. new mobjects;
  2567. // Header
  2568. fwrite(f,"//Map Filterscript Exported with Texture Studio By: [uL]Pottus///////////////////////////////////////////////////\r\n");
  2569. fwrite(f,"///////////////////////////////////////////////////////////and Crayder///////////////////////////////////////////\r\n");
  2570. fwrite(f,"/////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2571. fwrite(f,"\r\n//Map Information////////////////////////////////////////////////////////////////////////////////////////////////\r\n");
  2572. new DBResult:timeResult = db_query(EditMap, sprintf("SELECT datetime(%i, 'unixepoch', 'localtime')", gettime()));
  2573. new timestr[64];
  2574. db_get_field(timeResult, 0, timestr, 64);
  2575. db_free_result(timeResult);
  2576. fwrite(f,"/*\r\n");
  2577. fwrite(f,sprintf("\tExported on \"%s\" by \"%s\"\r\n", timestr, ReturnPlayerName(playerid)));
  2578. fwrite(f,sprintf("\tCreated by \"%s\"\r\n", MapSetting[mAuthor]));
  2579. if(MapSetting[mSpawn][xPos])
  2580. fwrite(f,sprintf("\tSpawn Position: %f, %f, %f\r\n", MapSetting[mSpawn][xPos], MapSetting[mSpawn][yPos], MapSetting[mSpawn][zPos]));
  2581. fwrite(f,"*/");
  2582. fwrite(f,"\r\n/////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r\n\r\n");
  2583. // Includes
  2584. fwrite(f, "#include <a_samp>\r\n");
  2585. fwrite(f, "#include <streamer>\r\n\n");
  2586. new CarCount = Iter_Count(Cars);
  2587. new CurrCar;
  2588. // Car id
  2589. for(new i = 0; i < CarCount; i++)
  2590. {
  2591. format(templine, sizeof(templine), "new carvid_%i;\r\n", i);
  2592. fwrite(f, templine);
  2593. }
  2594. fwrite(f, "\n");
  2595. // Init script
  2596. fwrite(f, "public OnFilterScriptInit()\r\n");
  2597. fwrite(f, "{ \r\n");
  2598. fwrite(f," new tmpobjid;\r\n\n");
  2599. foreach(new i : Cars)
  2600. {
  2601. format(templine, sizeof(templine), " carvid_%i = CreateVehicle(%i,%.3f,%.3f,%.3f,%.3f,%i,%i,-1);\r\n",
  2602. CurrCar++, CarData[i][CarModel], CarData[i][CarSpawnX], CarData[i][CarSpawnY], CarData[i][CarSpawnZ], CarData[i][CarSpawnFA], CarData[i][CarColor1], CarData[i][CarColor2]
  2603. );
  2604. fwrite(f, templine);
  2605. }
  2606. CurrCar = 0;
  2607. fwrite(f, "\n");
  2608. foreach(new i : Cars)
  2609. {
  2610. // Mod components
  2611. for(new j = 0; j < MAX_CAR_COMPONENTS; j++)
  2612. {
  2613. if(CarData[i][CarComponents][j] > 0)
  2614. {
  2615. format(templine, sizeof(templine), " AddVehicleComponent(carvid_%i, %i);\r\n", CurrCar, CarData[i][CarComponents][j]);
  2616. fwrite(f, templine);
  2617. }
  2618. }
  2619. CurrCar++;
  2620. }
  2621. CurrCar = 0;
  2622. fwrite(f, "\n");
  2623. foreach(new i : Cars)
  2624. {
  2625. // Paintjob
  2626. if(CarData[i][CarPaintJob] < 3)
  2627. {
  2628. format(templine, sizeof(templine), " ChangeVehiclePaintjob(carvid_%i, %i);\r\n", CurrCar, CarData[i][CarPaintJob]);
  2629. fwrite(f, templine);
  2630. }
  2631. CurrCar++;
  2632. }
  2633. CurrCar = 0;
  2634. fwrite(f, "\n");
  2635. foreach(new i : Cars)
  2636. {
  2637. // Objects
  2638. for(new j = 0; j < MAX_CAR_OBJECTS; j++)
  2639. {
  2640. // No object
  2641. if(CarData[i][CarObjectRef][j] == -1) continue;
  2642. new oindex = CarData[i][CarObjectRef][j];
  2643. // Create object
  2644. format(templine,sizeof(templine)," tmpobjid = CreateDynamicObject(%i,0.0,0.0,-1000.0,0.0,0.0,0.0,-1,-1,-1,300.0,300.0); %s\r\n",ObjectData[oindex][oModel],
  2645. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2646. fwrite(f,templine);
  2647. // Write all materials and colors
  2648. for(new k = 0; k < MAX_MATERIALS; k++)
  2649. {
  2650. // Does object have a texture set?
  2651. if(ObjectData[oindex][oTexIndex][k] != 0)
  2652. {
  2653. format(templine,sizeof(templine)," SetDynamicObjectMaterial(tmpobjid, %i, %i, %c%s%c, %c%s%c, 0x%X);\r\n",
  2654. k, GetTModel(ObjectData[oindex][oTexIndex][k]), 34, GetTXDName(ObjectData[oindex][oTexIndex][k]), 34, 34,GetTextureName(ObjectData[oindex][oTexIndex][k]), 34, ObjectData[oindex][oColorIndex][k]
  2655. );
  2656. fwrite(f,templine);
  2657. }
  2658. // No texture how about a color?
  2659. else if(ObjectData[oindex][oColorIndex][k] != 0)
  2660. {
  2661. format(templine,sizeof(templine)," SetDynamicObjectMaterial(tmpobjid, %i, -1, %c%s%c, %c%s%c, 0x%X);\r\n", j, 34, "none", 34, 34,"none", 34, ObjectData[oindex][oColorIndex][k]);
  2662. fwrite(f,templine);
  2663. }
  2664. }
  2665. // Write any text
  2666. if(ObjectData[oindex][ousetext])
  2667. {
  2668. format(templine,sizeof(templine)," SetDynamicObjectMaterialText(tmpobjid, 0, %c%s%c, %i, %c%s%c, %i, %i, 0x%X, 0x%X, %i);\r\n",
  2669. 34, ObjectData[oindex][oObjectText], 34,
  2670. FontSizes[ObjectData[oindex][oFontSize]],
  2671. 34, FontNames[ObjectData[oindex][oFontFace]], 34,
  2672. ObjectData[oindex][oTextFontSize],
  2673. ObjectData[oindex][oFontBold],
  2674. ObjectData[oindex][oFontColor],
  2675. ObjectData[oindex][oBackColor],
  2676. ObjectData[oindex][oAlignment]
  2677. );
  2678. fwrite(f,templine);
  2679. }
  2680. // Attach object to vehicle
  2681. format(templine, sizeof(templine), " AttachDynamicObjectToVehicle(tmpobjid, carvid_%i, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f);\r\n",
  2682. CurrCar, CarData[i][COX], CarData[i][COY][j], CarData[i][COZ][j], CarData[i][CORX][j], CarData[i][CORY][j], CarData[i][CORZ][j]
  2683. );
  2684. fwrite(f,templine);
  2685. }
  2686. CurrCar++;
  2687. fwrite(f, "\n");
  2688. }
  2689. // Write Objects
  2690. // Write all objects with materials first
  2691. foreach(new i : Objects)
  2692. {
  2693. if(ObjectData[i][oAttachedVehicle] > -1) continue;
  2694. new bool:writeobject, Float:odd = (ObjectData[i][oDD] != 300.0 ? ObjectData[i][oDD] : drawdist);
  2695. // Does the object have materials?
  2696. for(new j = 0; j < MAX_MATERIALS; j++)
  2697. {
  2698. if(ObjectData[i][oTexIndex][j] != 0 || ObjectData[i][oColorIndex][j] != 0 || ObjectData[i][ousetext])
  2699. {
  2700. writeobject = true;
  2701. break;
  2702. }
  2703. }
  2704. // Object had materials we will write them to the export file
  2705. if(writeobject)
  2706. {
  2707. mobjects++;
  2708. format(templine,sizeof(templine)," tmpobjid = CreateDynamicObject(%i, %f, %f, %f, %f, %f, %f, -1, -1, -1, %.2f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,odd,
  2709. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2710. fwrite(f,templine);
  2711. // Write all materials and colors
  2712. for(new j = 0; j < MAX_MATERIALS; j++)
  2713. {
  2714. // Does object have a texture set?
  2715. if(ObjectData[i][oTexIndex][j] != 0)
  2716. {
  2717. format(templine,sizeof(templine)," SetDynamicObjectMaterial(tmpobjid, %i, %i, %c%s%c, %c%s%c, 0x%X);\r\n", j, GetTModel(ObjectData[i][oTexIndex][j]), 34, GetTXDName(ObjectData[i][oTexIndex][j]), 34, 34,GetTextureName(ObjectData[i][oTexIndex][j]), 34, ObjectData[i][oColorIndex][j]);
  2718. fwrite(f,templine);
  2719. }
  2720. // No texture how about a color?
  2721. else if(ObjectData[i][oColorIndex][j] != 0)
  2722. {
  2723. format(templine,sizeof(templine)," SetDynamicObjectMaterial(tmpobjid, %i, -1, %c%s%c, %c%s%c, 0x%X);\r\n", j, 34, "none", 34, 34,"none", 34, ObjectData[i][oColorIndex][j]);
  2724. fwrite(f,templine);
  2725. }
  2726. }
  2727. // Write any text
  2728. if(ObjectData[i][ousetext])
  2729. {
  2730. format(templine,sizeof(templine)," SetDynamicObjectMaterialText(tmpobjid, 0, %c%s%c, %i, %c%s%c, %i, %i, 0x%X, 0x%X, %i);\r\n",
  2731. 34, ObjectData[i][oObjectText], 34,
  2732. FontSizes[ObjectData[i][oFontSize]],
  2733. 34, FontNames[ObjectData[i][oFontFace]], 34,
  2734. ObjectData[i][oTextFontSize],
  2735. ObjectData[i][oFontBold],
  2736. ObjectData[i][oFontColor],
  2737. ObjectData[i][oBackColor],
  2738. ObjectData[i][oAlignment]
  2739. );
  2740. fwrite(f,templine);
  2741. }
  2742. }
  2743. }
  2744. // We need to write all of the objects that didn't have materials set now
  2745. foreach(new i : Objects)
  2746. {
  2747. if(ObjectData[i][oAttachedVehicle] > -1) continue;
  2748. new bool:writeobject = true, Float:odd = (ObjectData[i][oDD] != 300.0 ? ObjectData[i][oDD] : drawdist);
  2749. // Does the object have materials?
  2750. for(new j = 0; j < MAX_MATERIALS; j++)
  2751. {
  2752. // This object has already been written
  2753. if(ObjectData[i][oTexIndex][j] != 0 || ObjectData[i][oColorIndex][j] != 0 || ObjectData[i][ousetext])
  2754. {
  2755. writeobject = false;
  2756. break;
  2757. }
  2758. }
  2759. // Object has not been exported yet export
  2760. if(writeobject)
  2761. {
  2762. format(templine,sizeof(templine)," tmpobjid = CreateDynamicObject(%i, %f, %f, %f, %f, %f, %f, -1, -1, -1, %.2f, %.2f); %s\r\n",ObjectData[i][oModel],ObjectData[i][oX],ObjectData[i][oY],ObjectData[i][oZ],ObjectData[i][oRX],ObjectData[i][oRY],ObjectData[i][oRZ],odd,odd,
  2763. strlen(ObjectData[i][oNote]) ? sprintf("// %s", ObjectData[i][oNote]) : (""));
  2764. fwrite(f,templine);
  2765. }
  2766. }
  2767. fwrite(f, "\r\n");
  2768. fwrite(f, " for(new i = 0; i < MAX_PLAYERS; i++)\r\n");
  2769. fwrite(f, " { \r\n");
  2770. fwrite(f, " if(!IsPlayerConnected(i)) continue; \r\n");
  2771. fwrite(f, " OnPlayerConnect(i); \r\n");
  2772. fwrite(f, " } \r\n\n");
  2773. fwrite(f, " return 1; \r\n\n");
  2774. fwrite(f, "} \r\n\n");
  2775. CurrCar = 0;
  2776. // Exit script
  2777. fwrite(f, "public OnFilterScriptExit()\r\n");
  2778. fwrite(f, "{ \r\n");
  2779. foreach(new i : Cars)
  2780. {
  2781. format(templine, sizeof(templine), " DestroyVehicle(carvid_%i);\r\n", CurrCar);
  2782. fwrite(f, templine);
  2783. CurrCar++;
  2784. }
  2785. fwrite(f, "} \r\n\n");
  2786. // Remove building script
  2787. fwrite(f, "public OnPlayerConnect(playerid)\r\n");
  2788. fwrite(f, "{ \r\n");
  2789. for(new i = 0; i < MAX_REMOVE_BUILDING; i++)
  2790. {
  2791. if(RemoveData[i][rModel] != 0)
  2792. {
  2793. format(templine, sizeof(templine), " RemoveBuildingForPlayer(playerid, %i, %.3f, %.3f, %.3f, %.3f);\r\n", RemoveData[i][rModel], RemoveData[i][rX], RemoveData[i][rY], RemoveData[i][rZ], RemoveData[i][rRange]);
  2794. fwrite(f,templine);
  2795. }
  2796. }
  2797. fwrite(f, "} \r\n\n");
  2798. CurrCar = 0;
  2799. // Vehicle respawn
  2800. fwrite(f, "public OnVehicleSpawn(vehicleid)\r\n");
  2801. fwrite(f, "{ \r\n");
  2802. foreach(new i : Cars)
  2803. {
  2804. if(CurrCar == 0) format(templine, sizeof(templine), " if(vehicleid == carvid_%i)\r\n", CurrCar);
  2805. else format(templine, sizeof(templine), " else if(vehicleid == carvid_%i)\r\n", CurrCar);
  2806. fwrite(f, templine);
  2807. fwrite(f, " {\r\n");
  2808. // Mod components
  2809. for(new j = 0; j < MAX_CAR_COMPONENTS; j++)
  2810. {
  2811. if(CarData[i][CarComponents][j] > 0)
  2812. {
  2813. format(templine, sizeof(templine), " AddVehicleComponent(carvid_%i, %i);\r\n", CurrCar, CarData[i][CarComponents][i]);
  2814. fwrite(f, templine);
  2815. }
  2816. }
  2817. // Paintjob
  2818. if(CarData[i][CarPaintJob] < 3)
  2819. {
  2820. format(templine, sizeof(templine), " ChangeVehiclePaintjob(carvid_%i, %i);\r\n", CurrCar, CarData[i][CarPaintJob]);
  2821. fwrite(f, templine);
  2822. }
  2823. fwrite(f, " }\r\n");
  2824. CurrCar++;
  2825. }
  2826. fwrite(f, "} \r\n");
  2827. fclose(f);
  2828. format(templine, sizeof(templine), "Exported vehicles to filterscript %s", name);
  2829. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2830. SendClientMessage(playerid, STEALTH_GREEN, templine);
  2831. return 1;
  2832. }
  2833. // Selects a object for editing
  2834. YCMD:sel(playerid, arg[], help)
  2835. {
  2836. if(help)
  2837. {
  2838. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2839. SendClientMessage(playerid, STEALTH_GREEN, "Select an object by index.");
  2840. return 1;
  2841. }
  2842. NoEditingMode(playerid);
  2843. MapOpenCheck();
  2844. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2845. if(isnull(arg)) return SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /sel <index> selects a object to edit");
  2846. new index = strval(arg);
  2847. if(index < 0) return SendClientMessage(playerid, STEALTH_YELLOW, "The index can not be negative numbers");
  2848. if(Iter_Contains(Objects, index))
  2849. {
  2850. if(SetCurrObject(playerid, index)) {
  2851. new line[128];
  2852. format(line, sizeof(line), "You have selected object index %i for editing", index);
  2853. SendClientMessage(playerid, STEALTH_GREEN, line);
  2854. }
  2855. else
  2856. SendClientMessage(playerid, STEALTH_YELLOW, "You can not select objects in this object's group");
  2857. }
  2858. else SendClientMessage(playerid, STEALTH_YELLOW, "That object does not exist!");
  2859. return 1;
  2860. }
  2861. YCMD:dsel(playerid, arg[], help)
  2862. {
  2863. if(help)
  2864. {
  2865. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2866. SendClientMessage(playerid, STEALTH_GREEN, "Deselect current object.");
  2867. return 1;
  2868. }
  2869. MapOpenCheck();
  2870. EditCheck(playerid);
  2871. NoEditingMode(playerid);
  2872. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2873. SendClientMessage(playerid, STEALTH_GREEN, "Selection has been deselected");
  2874. SetCurrObject(playerid, -1);
  2875. return 1;
  2876. }
  2877. // Selects the closest object to player
  2878. YCMD:scsel(playerid, arg[], help)
  2879. {
  2880. if(help)
  2881. {
  2882. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2883. SendClientMessage(playerid, STEALTH_GREEN, "Selects closest object.");
  2884. return 1;
  2885. }
  2886. NoEditingMode(playerid);
  2887. MapOpenCheck();
  2888. new Float:dist = 9999999.0, Float:tmpdist, index = -1;
  2889. foreach(new i : Objects)
  2890. {
  2891. if(!CanSelectObject(playerid, i))
  2892. continue;
  2893. tmpdist = GetPlayerDistanceFromPoint(playerid, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  2894. if(tmpdist < dist)
  2895. {
  2896. dist = tmpdist;
  2897. index = i;
  2898. }
  2899. }
  2900. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2901. if(index > -1)
  2902. {
  2903. SetCurrObject(playerid, index);
  2904. new line[128];
  2905. format(line, sizeof(line), "You have selected object index %i for editing", index);
  2906. SendClientMessage(playerid, STEALTH_GREEN, line);
  2907. }
  2908. else SendClientMessage(playerid, STEALTH_YELLOW, "There are no objects");
  2909. return 1;
  2910. }
  2911. // Deletes the closest object to player
  2912. YCMD:dcsel(playerid, arg[], help)
  2913. {
  2914. if(help)
  2915. {
  2916. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2917. SendClientMessage(playerid, STEALTH_GREEN, "Destroy closest object.");
  2918. return 1;
  2919. }
  2920. NoEditingMode(playerid);
  2921. MapOpenCheck();
  2922. new Float:dist = 9999999.0, Float:tmpdist, index = -1;
  2923. foreach(new i : Objects)
  2924. {
  2925. if(!CanSelectObject(playerid, i))
  2926. continue;
  2927. tmpdist = GetPlayerDistanceFromPoint(playerid, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  2928. if(tmpdist < dist)
  2929. {
  2930. dist = tmpdist;
  2931. index = i;
  2932. }
  2933. }
  2934. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2935. if(index > -1)
  2936. {
  2937. SaveUndoInfo(index, UNDO_TYPE_DELETED);
  2938. DeleteDynamicObject(index);
  2939. foreach(new i : Player)
  2940. {
  2941. if(i == playerid) continue;
  2942. if(CurrObject[index] == CurrObject[i]) SetCurrObject(i, -1);
  2943. }
  2944. SetCurrObject(playerid, -1);
  2945. new line[128];
  2946. format(line, sizeof(line), "You have deleted object index %i", index);
  2947. SendClientMessage(playerid, STEALTH_GREEN, line);
  2948. }
  2949. else SendClientMessage(playerid, STEALTH_YELLOW, "There are no objects");
  2950. return 1;
  2951. }
  2952. YCMD:csel(playerid, arg[], help)
  2953. {
  2954. if(help)
  2955. {
  2956. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2957. SendClientMessage(playerid, STEALTH_GREEN, "Select an object using cursor.");
  2958. SendClientMessage(playerid, STEALTH_YELLOW, "Holding 'H' ('Enter' in /flymode) while clicking an object will copy properties to buffer.");
  2959. SendClientMessage(playerid, STEALTH_YELLOW, "Holding 'Walk Key' while clicking an object will paste properties from buffer.");
  2960. return 1;
  2961. }
  2962. NoEditingMode(playerid);
  2963. MapOpenCheck();
  2964. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2965. if(Iter_Count(Objects))
  2966. {
  2967. SetEditMode(playerid, EDIT_MODE_SELECTION);
  2968. SelectObject(playerid);
  2969. SendClientMessage(playerid, STEALTH_GREEN, "Entered Object Selection Mode");
  2970. }
  2971. else SendClientMessage(playerid, STEALTH_YELLOW, "There are no objects right now");
  2972. return 1;
  2973. }
  2974. // Set a material of an object
  2975. YCMD:mtset(playerid, arg[], help)
  2976. {
  2977. if(help)
  2978. {
  2979. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2980. SendClientMessage(playerid, STEALTH_GREEN, "Set the material of an object.");
  2981. return 1;
  2982. }
  2983. MapOpenCheck();
  2984. EditCheck(playerid);
  2985. if(GetEditMode(playerid) != EDIT_MODE_TEXTURING) NoEditingMode(playerid);
  2986. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  2987. new index = CurrObject[playerid];
  2988. new mindex;
  2989. new tref;
  2990. if(GetMaterials(playerid, arg, mindex, tref))
  2991. {
  2992. SaveUndoInfo(index, UNDO_TYPE_EDIT);
  2993. SetMaterials(index, mindex, tref);
  2994. UpdateObjectText(index);
  2995. UpdateTextureSlot(playerid, mindex);
  2996. if(ObjectData[index][oAttachedVehicle] > -1) UpdateAttachedVehicleObject(ObjectData[index][oAttachedVehicle], index, VEHICLE_REATTACH_UPDATE);
  2997. // Update the streamer
  2998. foreach(new i : Player)
  2999. {
  3000. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  3001. }
  3002. SendClientMessage(playerid, STEALTH_GREEN, "Changed Material");
  3003. }
  3004. return 1;
  3005. }
  3006. // Set all materials of a certain type
  3007. YCMD:mtsetall(playerid, arg[], help)
  3008. {
  3009. if(help)
  3010. {
  3011. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3012. SendClientMessage(playerid, STEALTH_GREEN, "Set the material of all objects of the same model.");
  3013. return 1;
  3014. }
  3015. MapOpenCheck();
  3016. EditCheck(playerid);
  3017. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3018. new index = CurrObject[playerid];
  3019. new mindex;
  3020. new tref;
  3021. new time = GetTickCount();
  3022. if(GetMaterials(playerid, arg, mindex, tref))
  3023. {
  3024. db_begin_transaction(EditMap);
  3025. foreach(new i : Objects)
  3026. {
  3027. if(ObjectData[i][oModel] == ObjectData[CurrObject[playerid]][oModel])
  3028. {
  3029. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  3030. SetMaterials(i, mindex, tref);
  3031. UpdateObjectText(i);
  3032. if(ObjectData[i][oAttachedVehicle] > -1) UpdateAttachedVehicleObject(ObjectData[i][oAttachedVehicle], i, VEHICLE_REATTACH_UPDATE);
  3033. }
  3034. }
  3035. db_end_transaction(EditMap);
  3036. SendClientMessage(playerid, STEALTH_GREEN, "Changed All Materials");
  3037. foreach(new i : Player)
  3038. {
  3039. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  3040. }
  3041. UpdateTextureSlot(playerid, mindex);
  3042. }
  3043. return 1;
  3044. }
  3045. YCMD:ogroup(playerid, arg[], help)
  3046. {
  3047. if(help)
  3048. {
  3049. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3050. SendClientMessage(playerid, STEALTH_GREEN, "Set the group ID of current object.");
  3051. return 1;
  3052. }
  3053. MapOpenCheck();
  3054. EditCheck(playerid);
  3055. NoEditingMode(playerid);
  3056. if (!(0 <= strval(arg) < MAX_GROUPS))
  3057. return SendClientMessage(playerid, STEALTH_YELLOW, sprintf("The group id must be from 0 to %d", MAX_GROUPS - 1));
  3058. new index = CurrObject[playerid];
  3059. SaveUndoInfo(index, UNDO_TYPE_EDIT);
  3060. ObjectData[index][oGroup] = strval(arg);
  3061. sqlite_ObjGroup(index);
  3062. UpdateObject3DText(index);
  3063. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3064. new line[128];
  3065. format(line, sizeof(line), "You have changed the group ID of this object to: %i", ObjectData[index][oGroup]);
  3066. SendClientMessage(playerid, STEALTH_GREEN, line);
  3067. return 1;
  3068. }
  3069. tsfunc ColumnExists(DB:database, table[], columnname[])
  3070. {
  3071. new q[128];
  3072. format(q, sizeof(q), "pragma table_info(%s)", table);
  3073. new DBResult:r = db_query(database, q);
  3074. new Field[64];
  3075. if(db_num_rows(r))
  3076. {
  3077. for(new i = 0; i < db_num_rows(r); i++)
  3078. {
  3079. db_get_field_assoc(r, "name", Field, 64);
  3080. if(!strcmp(Field, columnname))
  3081. {
  3082. db_free_result(r);
  3083. return 1;
  3084. }
  3085. db_next_row(r);
  3086. }
  3087. }
  3088. db_free_result(r);
  3089. return 0;
  3090. }
  3091. YCMD:clone(playerid, arg[], help)
  3092. {
  3093. if(help)
  3094. {
  3095. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3096. SendClientMessage(playerid, STEALTH_GREEN, "Clone current object with all properties.");
  3097. return 1;
  3098. }
  3099. MapOpenCheck();
  3100. EditCheck(playerid);
  3101. NoEditingMode(playerid);
  3102. SetCurrObject(playerid, CloneObject(CurrObject[playerid]));
  3103. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3104. SendClientMessage(playerid, STEALTH_GREEN, "Cloned your selected object the new object is now your selection");
  3105. return 1;
  3106. }
  3107. YCMD:copy(playerid, arg[], help)
  3108. {
  3109. if(help)
  3110. {
  3111. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3112. SendClientMessage(playerid, STEALTH_GREEN, "Copy an objects properties to the clipboard.");
  3113. return 1;
  3114. }
  3115. MapOpenCheck();
  3116. EditCheck(playerid);
  3117. NoEditingMode(playerid);
  3118. CopyCopyBuffer(playerid, CurrObject[playerid]);
  3119. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3120. SendClientMessage(playerid, STEALTH_GREEN, "Copied object textures/color/text to buffer");
  3121. return 1;
  3122. }
  3123. CopyCopyBuffer(playerid, index)
  3124. {
  3125. for(new i = 0; i < MAX_MATERIALS; i++)
  3126. {
  3127. CopyBuffer[playerid][cTexIndex][i] = ObjectData[index][oTexIndex][i];
  3128. CopyBuffer[playerid][cColorIndex][i] = ObjectData[index][oColorIndex][i];
  3129. CopyBuffer[playerid][cusetext] = ObjectData[index][ousetext];
  3130. CopyBuffer[playerid][cFontFace] = ObjectData[index][oFontFace];
  3131. CopyBuffer[playerid][cFontSize] = ObjectData[index][oFontSize];
  3132. CopyBuffer[playerid][cFontBold] = ObjectData[index][oFontBold];
  3133. CopyBuffer[playerid][cFontColor] = ObjectData[index][oFontColor];
  3134. CopyBuffer[playerid][cBackColor] = ObjectData[index][oBackColor];
  3135. CopyBuffer[playerid][cAlignment] = ObjectData[index][oAlignment];
  3136. CopyBuffer[playerid][cTextFontSize] = ObjectData[index][oTextFontSize];
  3137. strcat((CopyBuffer[playerid][cObjectText][0] = '\0', CopyBuffer[playerid][cObjectText]), ObjectData[index][oObjectText], MAX_TEXT_LENGTH);
  3138. }
  3139. return 1;
  3140. }
  3141. YCMD:clear(playerid, arg[], help)
  3142. {
  3143. if(help)
  3144. {
  3145. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3146. SendClientMessage(playerid, STEALTH_GREEN, "Clears current clipboard.");
  3147. return 1;
  3148. }
  3149. ClearCopyBuffer(playerid);
  3150. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3151. SendClientMessage(playerid, STEALTH_GREEN, "Cleared your copy buffer");
  3152. return 1;
  3153. }
  3154. YCMD:paste(playerid, arg[], help)
  3155. {
  3156. if(help)
  3157. {
  3158. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3159. SendClientMessage(playerid, STEALTH_GREEN, "Paste copied propeties to current object.");
  3160. return 1;
  3161. }
  3162. MapOpenCheck();
  3163. EditCheck(playerid);
  3164. NoEditingMode(playerid);
  3165. PasteCopyBuffer(playerid, CurrObject[playerid]);
  3166. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3167. SendClientMessage(playerid, STEALTH_GREEN, "Pasted your copy buffer to object");
  3168. return 1;
  3169. }
  3170. PasteCopyBuffer(playerid, index)
  3171. {
  3172. for(new i = 0; i < MAX_MATERIALS; i++)
  3173. {
  3174. ObjectData[index][oTexIndex][i] = CopyBuffer[playerid][cTexIndex][i];
  3175. ObjectData[index][oColorIndex][i] = CopyBuffer[playerid][cColorIndex][i];
  3176. }
  3177. ObjectData[index][ousetext] = CopyBuffer[playerid][cusetext];
  3178. ObjectData[index][oFontFace] = CopyBuffer[playerid][cFontFace];
  3179. ObjectData[index][oFontSize] = CopyBuffer[playerid][cFontSize];
  3180. ObjectData[index][oFontBold] = CopyBuffer[playerid][cFontBold];
  3181. ObjectData[index][oFontColor] = CopyBuffer[playerid][cFontColor];
  3182. ObjectData[index][oBackColor] = CopyBuffer[playerid][cBackColor];
  3183. ObjectData[index][oAlignment] = CopyBuffer[playerid][cAlignment];
  3184. ObjectData[index][oTextFontSize] = CopyBuffer[playerid][cTextFontSize];
  3185. strcat((ObjectData[index][oObjectText][0] = '\0', ObjectData[index][oObjectText]), CopyBuffer[playerid][cObjectText], MAX_TEXT_LENGTH);
  3186. // Destroy the object
  3187. DestroyDynamicObject(ObjectData[index][oID]);
  3188. // Re-create object
  3189. ObjectData[index][oID] = CreateDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  3190. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  3191. // Update the streamer
  3192. foreach(new i : Player)
  3193. {
  3194. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  3195. }
  3196. // Update the materials
  3197. UpdateMaterial(index);
  3198. // Update object text
  3199. UpdateObjectText(index);
  3200. if(ObjectData[index][oAttachedVehicle] > -1) UpdateAttachedVehicleObject(ObjectData[index][oAttachedVehicle], index, VEHICLE_REATTACH_UPDATE);
  3201. // Save materials to material database
  3202. sqlite_SaveMaterialIndex(index);
  3203. // Save colors to material database
  3204. sqlite_SaveColorIndex(index);
  3205. // Save all text
  3206. sqlite_SaveAllObjectText(index);
  3207. return 1;
  3208. }
  3209. ClearCopyBuffer(playerid)
  3210. {
  3211. for(new i = 0; i < MAX_MATERIALS; i++)
  3212. {
  3213. CopyBuffer[playerid][cTexIndex][i] = 0;
  3214. CopyBuffer[playerid][cColorIndex][i] = 0;
  3215. CopyBuffer[playerid][cusetext] = 0;
  3216. CopyBuffer[playerid][cFontFace] = 0;
  3217. CopyBuffer[playerid][cFontSize] = 0;
  3218. CopyBuffer[playerid][cFontBold] = 0;
  3219. CopyBuffer[playerid][cFontColor] = 0;
  3220. CopyBuffer[playerid][cBackColor] = 0;
  3221. CopyBuffer[playerid][cAlignment] = 0;
  3222. CopyBuffer[playerid][cTextFontSize] = 20;
  3223. format(CopyBuffer[playerid][cObjectText], MAX_TEXT_LENGTH, "None");
  3224. }
  3225. return 1;
  3226. }
  3227. // Gets the mindex and tref from command arguments
  3228. GetMaterials(playerid, arg[], &mindex, &tref)
  3229. {
  3230. if(sscanf(arg, "ii", mindex, tref))
  3231. {
  3232. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /mtset <material index> <texture array reference>");
  3233. return 0;
  3234. }
  3235. if(mindex < 0 || mindex > MAX_MATERIALS - 1)
  3236. {
  3237. new line[128];
  3238. format(line, sizeof(line), "The material selection must be between <0 - %i>", MAX_MATERIALS - 1);
  3239. SendClientMessage(playerid, STEALTH_YELLOW, line);
  3240. return 0;
  3241. }
  3242. if(tref < 0 || tref > MAX_TEXTURES - 1)
  3243. {
  3244. new line[128];
  3245. format(line, sizeof(line), "The texture reference must be between <0 - %i>", MAX_TEXTURES - 1);
  3246. SendClientMessage(playerid, STEALTH_YELLOW, line);
  3247. return 0;
  3248. }
  3249. return 1;
  3250. }
  3251. // Set the materials for an object
  3252. SetMaterials(index, mindex, tref)
  3253. {
  3254. // Set the texture
  3255. ObjectData[index][oTexIndex][mindex] = tref;
  3256. // Destroy the object
  3257. DestroyDynamicObject(ObjectData[index][oID]);
  3258. // Re-create object
  3259. ObjectData[index][oID] = CreateDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  3260. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  3261. // Update streamer for all
  3262. foreach(new i : Player) Streamer_UpdateEx(i, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ]);
  3263. // Update the materials
  3264. UpdateMaterial(index);
  3265. // Save this material index to the data base
  3266. sqlite_SaveMaterialIndex(index);
  3267. }
  3268. YCMD:ogoto(playerid, arg[], help)
  3269. {
  3270. if(help)
  3271. {
  3272. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3273. SendClientMessage(playerid, STEALTH_GREEN, "Moves camera to the current object's position.");
  3274. return 1;
  3275. }
  3276. MapOpenCheck();
  3277. EditCheck(playerid);
  3278. NoEditingMode(playerid);
  3279. if(!InFlyMode(playerid))
  3280. {
  3281. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3282. SendClientMessage(playerid, STEALTH_YELLOW, "You must be in flymode to use this command");
  3283. return 1;
  3284. }
  3285. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3286. SendClientMessage(playerid, STEALTH_GREEN, "Moved to object currently being edited");
  3287. SetFlyModePos(playerid, ObjectData[CurrObject[playerid]][oX], ObjectData[CurrObject[playerid]][oY], ObjectData[CurrObject[playerid]][oZ]);
  3288. return 1;
  3289. }
  3290. // Set a color of an object
  3291. YCMD:mtcolor(playerid, arg[], help)
  3292. {
  3293. if(help)
  3294. {
  3295. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3296. SendClientMessage(playerid, STEALTH_GREEN, "Set the color of an object.");
  3297. return 1;
  3298. }
  3299. MapOpenCheck();
  3300. EditCheck(playerid);
  3301. if(GetEditMode(playerid) != EDIT_MODE_TEXTURING) NoEditingMode(playerid);
  3302. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3303. new index = CurrObject[playerid];
  3304. new mindex;
  3305. new HexColor[12];
  3306. sscanf(arg, "is[12]", mindex, HexColor);
  3307. if(mindex < 0 || mindex > MAX_MATERIALS - 1)
  3308. {
  3309. new line[128];
  3310. format(line, sizeof(line), "The material selection must be between <0 - %i>", MAX_MATERIALS - 1);
  3311. return SendClientMessage(playerid, STEALTH_YELLOW, line);
  3312. }
  3313. if(IsHexValue(HexColor))
  3314. {
  3315. SaveUndoInfo(index, UNDO_TYPE_EDIT);
  3316. // Set the color
  3317. sscanf(HexColor, "h", ObjectData[index][oColorIndex][mindex]);
  3318. // Destroy the object
  3319. DestroyDynamicObject(ObjectData[index][oID]);
  3320. // Re-create object
  3321. ObjectData[index][oID] = CreateDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  3322. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  3323. // Update the materials
  3324. UpdateMaterial(index);
  3325. UpdateObjectText(index);
  3326. if(ObjectData[index][oAttachedVehicle] > -1) UpdateAttachedVehicleObject(ObjectData[index][oAttachedVehicle], index, VEHICLE_REATTACH_UPDATE);
  3327. // Save this material index to the data base
  3328. sqlite_SaveColorIndex(index);
  3329. // Update texture tool
  3330. UpdateTextureSlot(playerid, mindex);
  3331. // Update the streamer
  3332. foreach(new i : Player)
  3333. {
  3334. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  3335. }
  3336. SendClientMessage(playerid, STEALTH_GREEN, "Changed Color");
  3337. }
  3338. else
  3339. {
  3340. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3341. SendClientMessage(playerid, STEALTH_YELLOW, "Invalid hex color.");
  3342. }
  3343. return 1;
  3344. }
  3345. // Set a color of an object
  3346. YCMD:mtcolorall(playerid, arg[], help)
  3347. {
  3348. if(help)
  3349. {
  3350. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3351. SendClientMessage(playerid, STEALTH_GREEN, "Set the color of all objects of the same model.");
  3352. return 1;
  3353. }
  3354. MapOpenCheck();
  3355. EditCheck(playerid);
  3356. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3357. new index = CurrObject[playerid];
  3358. new mindex;
  3359. new HexColor[12];
  3360. sscanf(arg, "is[12]", mindex, HexColor);
  3361. if(mindex < 0 || mindex > MAX_MATERIALS - 1)
  3362. {
  3363. new line[128];
  3364. format(line, sizeof(line), "The material selection must be between <0 - %i>", MAX_MATERIALS - 1);
  3365. return SendClientMessage(playerid, STEALTH_YELLOW, line);
  3366. }
  3367. if(IsHexValue(HexColor))
  3368. {
  3369. new hcolor;
  3370. sscanf(HexColor, "h", hcolor);
  3371. new time = GetTickCount();
  3372. db_begin_transaction(EditMap);
  3373. foreach(new i : Objects)
  3374. {
  3375. if(ObjectData[i][oModel] == ObjectData[CurrObject[playerid]][oModel])
  3376. {
  3377. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  3378. ObjectData[i][oColorIndex][mindex] = hcolor;
  3379. // Destroy the object
  3380. DestroyDynamicObject(ObjectData[i][oID]);
  3381. // Re-create object
  3382. ObjectData[i][oID] = CreateDynamicObject(ObjectData[i][oModel], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  3383. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[i][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  3384. // Update the materials
  3385. UpdateMaterial(i);
  3386. UpdateObjectText(i);
  3387. if(ObjectData[i][oAttachedVehicle] > -1) UpdateAttachedVehicleObject(ObjectData[i][oAttachedVehicle], i, VEHICLE_REATTACH_UPDATE);
  3388. // Save this material index to the data base
  3389. sqlite_SaveColorIndex(i);
  3390. }
  3391. }
  3392. db_end_transaction(EditMap);
  3393. // Update the streamer
  3394. foreach(new i : Player)
  3395. {
  3396. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  3397. }
  3398. SendClientMessage(playerid, STEALTH_GREEN, "Changed All Color");
  3399. }
  3400. else
  3401. {
  3402. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3403. SendClientMessage(playerid, STEALTH_YELLOW, "Invalid hex color.");
  3404. }
  3405. return 1;
  3406. }
  3407. YCMD:oswap(playerid, arg[], help)
  3408. {
  3409. if(help)
  3410. {
  3411. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3412. SendClientMessage(playerid, STEALTH_GREEN, "Change the model of current object.");
  3413. return 1;
  3414. }
  3415. MapOpenCheck();
  3416. EditCheck(playerid);
  3417. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3418. new id = strval(arg);
  3419. if(id > 0 && id < 20000)
  3420. {
  3421. new index = CurrObject[playerid];
  3422. ObjectData[index][oModel] = id;
  3423. SaveUndoInfo(index, UNDO_TYPE_EDIT);
  3424. // Destroy the object
  3425. DestroyDynamicObject(ObjectData[index][oID]);
  3426. // Re-create object
  3427. ObjectData[index][oID] = CreateDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  3428. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  3429. // Update streamer for all
  3430. foreach(new i : Player) Streamer_UpdateEx(i, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ]);
  3431. // Update the materials
  3432. UpdateMaterial(index);
  3433. // Update the text
  3434. UpdateObjectText(index);
  3435. // Save changes to database
  3436. sqlite_ObjModel(index);
  3437. }
  3438. else SendClientMessage(playerid, STEALTH_YELLOW, "Invalid Model");
  3439. return 1;
  3440. }
  3441. // Reset all materials
  3442. YCMD:mtreset(playerid, arg[], help)
  3443. {
  3444. if(help)
  3445. {
  3446. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3447. SendClientMessage(playerid, STEALTH_GREEN, "Reset all materials and colors of current object.");
  3448. return 1;
  3449. }
  3450. MapOpenCheck();
  3451. EditCheck(playerid);
  3452. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3453. new index = CurrObject[playerid];
  3454. SaveUndoInfo(index, UNDO_TYPE_EDIT);
  3455. for(new i = 0; i < MAX_MATERIALS; i++)
  3456. {
  3457. ObjectData[index][oTexIndex][i] = 0;
  3458. ObjectData[index][oColorIndex][i] = 0;
  3459. UpdateTextureSlot(playerid, i);
  3460. }
  3461. UpdateMaterial(index);
  3462. sqlite_SaveMaterialIndex(index);
  3463. sqlite_SaveColorIndex(index);
  3464. return 1;
  3465. }
  3466. // Enter edit mode
  3467. YCMD:editobject(playerid, arg[], help)
  3468. {
  3469. if(help)
  3470. {
  3471. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3472. SendClientMessage(playerid, STEALTH_GREEN, "Edit current object.");
  3473. return 1;
  3474. }
  3475. MapOpenCheck();
  3476. EditCheck(playerid);
  3477. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3478. if(ObjectData[CurrObject[playerid]][oAttachedVehicle] > -1) return EditVehicleObject(playerid);
  3479. if(!EditingMode[playerid])
  3480. {
  3481. EditingMode[playerid] = true;
  3482. SetEditMode(playerid, EDIT_MODE_OBJECT);
  3483. EditDynamicObject(playerid, ObjectData[CurrObject[playerid]][oID]);
  3484. SendClientMessage(playerid, STEALTH_GREEN, "Entered Edit Object Mode");
  3485. CurrEditPos[playerid][0] = ObjectData[CurrObject[playerid]][oX];
  3486. CurrEditPos[playerid][1] = ObjectData[CurrObject[playerid]][oY];
  3487. CurrEditPos[playerid][2] = ObjectData[CurrObject[playerid]][oZ];
  3488. CurrEditPos[playerid][3] = ObjectData[CurrObject[playerid]][oRX];
  3489. CurrEditPos[playerid][4] = ObjectData[CurrObject[playerid]][oRY];
  3490. CurrEditPos[playerid][5] = ObjectData[CurrObject[playerid]][oRZ];
  3491. }
  3492. else SendClientMessage(playerid, STEALTH_YELLOW, "You are in editing mode already");
  3493. return 1;
  3494. }
  3495. // Create an object
  3496. YCMD:cobject(playerid, arg[], help)
  3497. {
  3498. if(help)
  3499. {
  3500. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3501. SendClientMessage(playerid, STEALTH_GREEN, "Creates an object and selects it.");
  3502. return 1;
  3503. }
  3504. MapOpenCheck();
  3505. NoEditingMode(playerid);
  3506. new modelid;
  3507. if(sscanf(arg, "i", modelid))
  3508. {
  3509. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3510. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /cobject <modelid>");
  3511. return 1;
  3512. }
  3513. // Set the initial object position
  3514. new Float:px, Float:py, Float:pz, Float:fa;
  3515. // Find the size of the object
  3516. new Float:colradius = GetColSphereRadius(modelid);
  3517. // Place in front of the player using collision radius
  3518. GetPosFaInFrontOfPlayer(playerid, colradius + 1.0, px, py, pz, fa);
  3519. pz -= 1.0;
  3520. // Create the object
  3521. SetCurrObject(playerid, AddDynamicObject(modelid, px, py, pz, 0.0, 0.0, 0.0));
  3522. // Create 3D label
  3523. UpdateObject3DText(CurrObject[playerid], true);
  3524. // Object was created
  3525. if(CurrObject[playerid] != -1)
  3526. {
  3527. // Update the streamer for this player
  3528. Streamer_Update(playerid);
  3529. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_CREATED);
  3530. // Show output message
  3531. new line[128];
  3532. new modelarray = GetModelArray(modelid);
  3533. if(modelarray > -1) format(line, sizeof(line), "Created Object Index: %i Model Name: %s", CurrObject[playerid], GetModelName(modelarray));
  3534. else format(line, sizeof(line), "Created Object Index: %i Model Name: Unknown", CurrObject[playerid]);
  3535. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3536. SendClientMessage(playerid, STEALTH_GREEN, line);
  3537. }
  3538. // Too many objects already created
  3539. else
  3540. {
  3541. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3542. SendClientMessage(playerid, STEALTH_YELLOW, "You have too many objects created to create anymore!");
  3543. }
  3544. return 1;
  3545. }
  3546. YCMD:dobject(playerid, arg[], help)
  3547. {
  3548. if(help)
  3549. {
  3550. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3551. SendClientMessage(playerid, STEALTH_GREEN, "Destroys current object and deselects it.");
  3552. return 1;
  3553. }
  3554. MapOpenCheck();
  3555. EditCheck(playerid);
  3556. NoEditingMode(playerid);
  3557. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_DELETED);
  3558. DeleteDynamicObject(CurrObject[playerid]);
  3559. foreach(new i : Player)
  3560. {
  3561. if(CurrObject[playerid] == CurrObject[i]) SetCurrObject(i, -1);
  3562. }
  3563. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3564. SendClientMessage(playerid, STEALTH_GREEN, "Your object has been destroyed");
  3565. return 1;
  3566. }
  3567. YCMD:rotreset(playerid, arg[], help)
  3568. {
  3569. if(help)
  3570. {
  3571. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3572. SendClientMessage(playerid, STEALTH_GREEN, "Reset all rotation axes of current object.");
  3573. return 1;
  3574. }
  3575. MapOpenCheck();
  3576. EditCheck(playerid);
  3577. NoEditingMode(playerid);
  3578. ObjectData[CurrObject[playerid]][oRX] = 0.0;
  3579. ObjectData[CurrObject[playerid]][oRY] = 0.0;
  3580. ObjectData[CurrObject[playerid]][oRZ] = 0.0;
  3581. SetDynamicObjectRot(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oRX], ObjectData[CurrObject[playerid]][oRY], ObjectData[CurrObject[playerid]][oRZ]);
  3582. sqlite_UpdateObjectPos(CurrObject[playerid]);
  3583. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3584. SendClientMessage(playerid, STEALTH_GREEN, "Your objects rotation has been reset");
  3585. return 1;
  3586. }
  3587. // Resets an objects materials and text
  3588. YCMD:robject(playerid, arg[], help)
  3589. {
  3590. if(help)
  3591. {
  3592. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3593. SendClientMessage(playerid, STEALTH_GREEN, "Reset all materials, colors, and text of current object.");
  3594. return 1;
  3595. }
  3596. MapOpenCheck();
  3597. EditCheck(playerid);
  3598. NoEditingMode(playerid);
  3599. new index = CurrObject[playerid];
  3600. for(new i = 0; i < MAX_MATERIALS; i++)
  3601. {
  3602. ObjectData[index][oTexIndex][i] = 0;
  3603. ObjectData[index][oColorIndex][i] = 0;
  3604. }
  3605. ObjectData[index][ousetext] = 0;
  3606. ObjectData[index][oFontFace] = 0;
  3607. ObjectData[index][oFontSize] = 0;
  3608. ObjectData[index][oFontBold] = 0;
  3609. ObjectData[index][oFontColor] = 0;
  3610. ObjectData[index][oBackColor] = 0;
  3611. ObjectData[index][oAlignment] = 0;
  3612. ObjectData[index][oTextFontSize] = 20;
  3613. format(ObjectData[index][oObjectText], MAX_TEXT_LENGTH, "None");
  3614. DestroyDynamicObject(ObjectData[index][oID]);
  3615. ObjectData[index][oID] = CreateDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  3616. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  3617. sqlite_SaveColorIndex(index);
  3618. sqlite_SaveMaterialIndex(index);
  3619. sqlite_ObjUseText(index);
  3620. sqlite_ObjFontFace(index);
  3621. sqlite_ObjFontSize(index);
  3622. sqlite_ObjFontBold(index);
  3623. sqlite_ObjFontColor(index);
  3624. sqlite_ObjBackColor(index);
  3625. sqlite_ObjAlignment(index);
  3626. sqlite_ObjFontTextSize(index);
  3627. sqlite_ObjObjectText(index);
  3628. // Update the streamer
  3629. foreach(new i : Player)
  3630. {
  3631. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  3632. }
  3633. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3634. SendClientMessage(playerid, STEALTH_GREEN, "Reset object materials and text");
  3635. return 1;
  3636. }
  3637. // Loops through all indexes and labels them with object text
  3638. enum INDEXCOLORINFO { FaceColor, BackColor }
  3639. stock const ShowIndexColors[MAX_MATERIALS][INDEXCOLORINFO] = {
  3640. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF000000, 0xFFFFFFFF },
  3641. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF800000, 0xFFFFFFFF },
  3642. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF008000, 0xFFFFFFFF },
  3643. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF000080, 0xFFFFFFFF },
  3644. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFFC0C0C0, 0xFF000000 },
  3645. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFFFF0000, 0xFF000000 },
  3646. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF00FF00, 0xFF000000 },
  3647. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF0000FF, 0xFF000000 },
  3648. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF808080, 0xFFFFFFFF },
  3649. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF800080, 0xFFFFFFFF },
  3650. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF808000, 0xFFFFFFFF },
  3651. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFF008080, 0xFFFFFFFF },
  3652. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFFFFFFFF, 0xFF000000 },
  3653. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFFFF00FF, 0xFF000000 },
  3654. { 0xFFFFFF66, 0xFF00FF33 }, // { 0xFFFFFF00, 0xFF000000 },
  3655. { 0xFFFFFF66, 0xFF00FF33 } // { 0xFF00FFFF, 0xFF000000 }
  3656. };
  3657. YCMD:sindex(playerid, arg[], help)
  3658. {
  3659. if(help)
  3660. {
  3661. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3662. SendClientMessage(playerid, STEALTH_GREEN, "Display texture slots of current object.");
  3663. return 1;
  3664. }
  3665. MapOpenCheck();
  3666. EditCheck(playerid);
  3667. // NoEditingMode(playerid);
  3668. new size;
  3669. if(isnull(arg)) size = 20;
  3670. else size = strval(arg);
  3671. if(size < 0 || size > 200) size = 20;
  3672. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3673. SendClientMessage(playerid, STEALTH_GREEN, "Labelling your objects with text corresponding to index (/rindex to turn off label)");
  3674. new line[8];
  3675. for(new i = 0; i < MAX_MATERIALS; i++)
  3676. {
  3677. format(line, sizeof(line), "%i", i);
  3678. SetDynamicObjectMaterialText(ObjectData[CurrObject[playerid]][oID],
  3679. i,
  3680. line,
  3681. 10,
  3682. "Arial",
  3683. size,
  3684. 1,
  3685. ShowIndexColors[i][FaceColor],
  3686. ShowIndexColors[i][BackColor],
  3687. 1);
  3688. }
  3689. return 1;
  3690. }
  3691. // Restores an object to it's original form
  3692. YCMD:rindex(playerid, arg[], help)
  3693. {
  3694. if(help)
  3695. {
  3696. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3697. SendClientMessage(playerid, STEALTH_GREEN, "Restore objects textures after displaying texture slots.");
  3698. return 1;
  3699. }
  3700. MapOpenCheck();
  3701. EditCheck(playerid);
  3702. // NoEditingMode(playerid);
  3703. new index = CurrObject[playerid];
  3704. // Destroy the object
  3705. DestroyDynamicObject(ObjectData[index][oID]);
  3706. // Re-create object
  3707. ObjectData[index][oID] = CreateDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  3708. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  3709. // Update the streamer
  3710. foreach(new i : Player)
  3711. {
  3712. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  3713. }
  3714. // Update the materials
  3715. UpdateMaterial(index);
  3716. // Update object text
  3717. UpdateObjectText(index);
  3718. if(ObjectData[index][oAttachedVehicle] > -1) UpdateAttachedVehicleObject(ObjectData[index][oAttachedVehicle], index, VEHICLE_REATTACH_UPDATE);
  3719. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3720. SendClientMessage(playerid, STEALTH_GREEN, "Reset current objects labels");
  3721. return 1;
  3722. }
  3723. // Get information on a model
  3724. YCMD:minfo(playerid, arg[], help)
  3725. {
  3726. if(help)
  3727. {
  3728. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3729. SendClientMessage(playerid, STEALTH_GREEN, "See information on the provided model ID.");
  3730. return 1;
  3731. }
  3732. new model = strval(arg);
  3733. if(isnull(arg) || !(0 <= model <= 19999)) {
  3734. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3735. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /minfo <ID [0-19999]>");
  3736. return 1;
  3737. }
  3738. new Float:r = Float:GetColSphereRadius(model),
  3739. Float:rOff[3], Float:Min[3], Float:Max[3];
  3740. GetColSphereOffset(model, rOff[0], rOff[1], rOff[2]);
  3741. GetModelBoundingBox(model, Min[0], Min[1], Min[2], Max[0], Max[1], Max[2]);
  3742. new buffer[1024];
  3743. strcat(buffer, sprintf("Bounding Sphere\n\tRadius: %f\n\tRadius Offset: %f, %f, %f\n\n",
  3744. r, rOff[0], rOff[1], rOff[2]));
  3745. strcat(buffer, sprintf("Axis Alligned Bounding Box\n\tMinimum: %f, %f, %f\n\t",
  3746. Min[0], Min[1], Min[2]));
  3747. strcat(buffer, sprintf("Maximun: %f, %f, %f\n\t",
  3748. Max[0], Max[1], Max[2]));
  3749. strcat(buffer, sprintf("Dimensions: %f, %f, %f",
  3750. floatabs(Min[0] - Max[0]), floatabs(Min[1] - Max[1]), floatabs(Min[2] - Max[2])));
  3751. Dialog_Show(
  3752. playerid, DIALOG_STYLE_MSGBOX,
  3753. sprintf("Model Information: %i", model),
  3754. buffer,
  3755. "Okay"
  3756. );
  3757. return 1;
  3758. }
  3759. // Set a pivot point
  3760. YCMD:pivot(playerid, arg[], help)
  3761. {
  3762. if(help)
  3763. {
  3764. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3765. SendClientMessage(playerid, STEALTH_GREEN, "Set the desired pivot to rotate around.");
  3766. return 1;
  3767. }
  3768. MapOpenCheck();
  3769. NoEditingMode(playerid);
  3770. new Float:x, Float:y, Float:z, Float:fa;
  3771. GetPosFaInFrontOfPlayer(playerid, 2.0, x, y, z, fa);
  3772. PivotObject[playerid] = CreateDynamicObject(1974, x, y, z, 0.0, 0.0, 0.0, -1, -1, playerid);
  3773. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, PivotObject[playerid], E_STREAMER_DRAW_DISTANCE, 3000.0);
  3774. SetDynamicObjectMaterial(PivotObject[playerid], 0, 10765, "airportgnd_sfse", "white", -256);
  3775. Streamer_Update(playerid);
  3776. EditingMode[playerid] = true;
  3777. SetEditMode(playerid, EDIT_MODE_PIVOT);
  3778. EditDynamicObject(playerid, PivotObject[playerid]);
  3779. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3780. SendClientMessage(playerid, STEALTH_GREEN, "Editing your pivot point");
  3781. return 1;
  3782. }
  3783. YCMD:togpivot(playerid, arg[], help)
  3784. {
  3785. if(help)
  3786. {
  3787. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3788. SendClientMessage(playerid, STEALTH_GREEN, "Toggle pivot rotation.");
  3789. return 1;
  3790. }
  3791. MapOpenCheck();
  3792. if(PivotPointOn[playerid])
  3793. {
  3794. PivotPointOn[playerid] = false;
  3795. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3796. SendClientMessage(playerid, STEALTH_GREEN, "Pivot point turned off");
  3797. }
  3798. else
  3799. {
  3800. PivotPointOn[playerid] = true;
  3801. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3802. SendClientMessage(playerid, STEALTH_GREEN, "Pivot point turned on");
  3803. }
  3804. return 1;
  3805. }
  3806. // Move object on X axis
  3807. YCMD:ox(playerid, arg[], help)
  3808. {
  3809. if(help)
  3810. {
  3811. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3812. SendClientMessage(playerid, STEALTH_GREEN, "Move current object along the X axis.");
  3813. return 1;
  3814. }
  3815. MapOpenCheck();
  3816. EditCheck(playerid);
  3817. NoEditingMode(playerid);
  3818. new Float:dist;
  3819. dist = floatstr(arg);
  3820. if(dist == 0) dist = 1.0;
  3821. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  3822. ObjectData[CurrObject[playerid]][oX] += dist;
  3823. SetDynamicObjectPos(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oX], ObjectData[CurrObject[playerid]][oY], ObjectData[CurrObject[playerid]][oZ]);
  3824. UpdateObject3DText(CurrObject[playerid]);
  3825. sqlite_UpdateObjectPos(CurrObject[playerid]);
  3826. return 1;
  3827. }
  3828. // Move object on Y axis
  3829. YCMD:oy(playerid, arg[], help)
  3830. {
  3831. if(help)
  3832. {
  3833. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3834. SendClientMessage(playerid, STEALTH_GREEN, "Move current object along the Y axis.");
  3835. return 1;
  3836. }
  3837. MapOpenCheck();
  3838. EditCheck(playerid);
  3839. NoEditingMode(playerid);
  3840. new Float:dist;
  3841. dist = floatstr(arg);
  3842. if(dist == 0) dist = 1.0;
  3843. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  3844. ObjectData[CurrObject[playerid]][oY] += dist;
  3845. SetDynamicObjectPos(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oX], ObjectData[CurrObject[playerid]][oY], ObjectData[CurrObject[playerid]][oZ]);
  3846. UpdateObject3DText(CurrObject[playerid]);
  3847. sqlite_UpdateObjectPos(CurrObject[playerid]);
  3848. return 1;
  3849. }
  3850. // Move object on Z axis
  3851. YCMD:oz(playerid, arg[], help)
  3852. {
  3853. if(help)
  3854. {
  3855. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3856. SendClientMessage(playerid, STEALTH_GREEN, "Move current object along the Z axis.");
  3857. return 1;
  3858. }
  3859. MapOpenCheck();
  3860. EditCheck(playerid);
  3861. NoEditingMode(playerid);
  3862. new Float:dist;
  3863. dist = floatstr(arg);
  3864. if(dist == 0) dist = 1.0;
  3865. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  3866. ObjectData[CurrObject[playerid]][oZ] += dist;
  3867. SetDynamicObjectPos(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oX], ObjectData[CurrObject[playerid]][oY], ObjectData[CurrObject[playerid]][oZ]);
  3868. UpdateObject3DText(CurrObject[playerid]);
  3869. sqlite_UpdateObjectPos(CurrObject[playerid]);
  3870. return 1;
  3871. }
  3872. // Move object on RX rot
  3873. YCMD:rx(playerid, arg[], help)
  3874. {
  3875. if(help)
  3876. {
  3877. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3878. SendClientMessage(playerid, STEALTH_GREEN, "Rotate currently object around the X axis.");
  3879. return 1;
  3880. }
  3881. MapOpenCheck();
  3882. EditCheck(playerid);
  3883. NoEditingMode(playerid);
  3884. new Float:rot;
  3885. rot = floatstr(arg);
  3886. if(rot == 0) rot = 5.0;
  3887. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  3888. if(PivotPointOn[playerid])
  3889. {
  3890. new i = CurrObject[playerid];
  3891. AttachObjectToPoint(i, PivotPoint[playerid][xPos], PivotPoint[playerid][yPos], PivotPoint[playerid][zPos], rot, 0.0, 0.0, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  3892. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  3893. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  3894. UpdateObject3DText(CurrObject[playerid]);
  3895. }
  3896. else
  3897. {
  3898. ObjectData[CurrObject[playerid]][oRX] += rot;
  3899. SetDynamicObjectRot(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oRX], ObjectData[CurrObject[playerid]][oRY], ObjectData[CurrObject[playerid]][oRZ]);
  3900. }
  3901. sqlite_UpdateObjectPos(CurrObject[playerid]);
  3902. return 1;
  3903. }
  3904. // Move object on RX rot
  3905. YCMD:ry(playerid, arg[], help)
  3906. {
  3907. if(help)
  3908. {
  3909. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3910. SendClientMessage(playerid, STEALTH_GREEN, "Rotate currently object around the Y axis.");
  3911. return 1;
  3912. }
  3913. MapOpenCheck();
  3914. EditCheck(playerid);
  3915. NoEditingMode(playerid);
  3916. new Float:rot;
  3917. rot = floatstr(arg);
  3918. if(rot == 0) rot = 5.0;
  3919. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  3920. if(PivotPointOn[playerid])
  3921. {
  3922. new i = CurrObject[playerid];
  3923. AttachObjectToPoint(i, PivotPoint[playerid][xPos], PivotPoint[playerid][yPos], PivotPoint[playerid][zPos], 0.0, rot, 0.0, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  3924. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  3925. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  3926. UpdateObject3DText(CurrObject[playerid]);
  3927. }
  3928. else
  3929. {
  3930. ObjectData[CurrObject[playerid]][oRY] += rot;
  3931. SetDynamicObjectRot(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oRX], ObjectData[CurrObject[playerid]][oRY], ObjectData[CurrObject[playerid]][oRZ]);
  3932. }
  3933. sqlite_UpdateObjectPos(CurrObject[playerid]);
  3934. return 1;
  3935. }
  3936. // Move object on RX rot
  3937. YCMD:rz(playerid, arg[], help)
  3938. {
  3939. if(help)
  3940. {
  3941. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3942. SendClientMessage(playerid, STEALTH_GREEN, "Rotate currently object around the Z axis.");
  3943. return 1;
  3944. }
  3945. MapOpenCheck();
  3946. EditCheck(playerid);
  3947. NoEditingMode(playerid);
  3948. new Float:rot;
  3949. rot = floatstr(arg);
  3950. if(rot == 0) rot = 5.0;
  3951. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  3952. if(PivotPointOn[playerid])
  3953. {
  3954. new i = CurrObject[playerid];
  3955. AttachObjectToPoint(i, PivotPoint[playerid][xPos], PivotPoint[playerid][yPos], PivotPoint[playerid][zPos], 0.0, 0.0, rot, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  3956. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  3957. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  3958. UpdateObject3DText(CurrObject[playerid]);
  3959. }
  3960. else
  3961. {
  3962. ObjectData[CurrObject[playerid]][oRZ] += rot;
  3963. SetDynamicObjectRot(ObjectData[CurrObject[playerid]][oID], ObjectData[CurrObject[playerid]][oRX], ObjectData[CurrObject[playerid]][oRY], ObjectData[CurrObject[playerid]][oRZ]);
  3964. }
  3965. sqlite_UpdateObjectPos(CurrObject[playerid]);
  3966. return 1;
  3967. }
  3968. // Move all objects on X axis
  3969. YCMD:dox(playerid, arg[], help)
  3970. {
  3971. if(help)
  3972. {
  3973. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  3974. SendClientMessage(playerid, STEALTH_GREEN, "Move all loaded objects along the X axis.");
  3975. return 1;
  3976. }
  3977. MapOpenCheck();
  3978. NoEditingMode(playerid);
  3979. new Float:dist, time;
  3980. time = GetTickCount();
  3981. dist = floatstr(arg);
  3982. if(dist == 0) dist = 1.0;
  3983. db_begin_transaction(EditMap);
  3984. foreach(new i : Objects)
  3985. {
  3986. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  3987. ObjectData[i][oX] += dist;
  3988. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  3989. UpdateObject3DText(i);
  3990. sqlite_UpdateObjectPos(i);
  3991. }
  3992. db_end_transaction(EditMap);
  3993. return 1;
  3994. }
  3995. // Move all objects on Y axis
  3996. YCMD:doy(playerid, arg[], help)
  3997. {
  3998. if(help)
  3999. {
  4000. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4001. SendClientMessage(playerid, STEALTH_GREEN, "Move all loaded objects along the Y axis.");
  4002. return 1;
  4003. }
  4004. MapOpenCheck();
  4005. NoEditingMode(playerid);
  4006. new Float:dist, time;
  4007. time = GetTickCount();
  4008. dist = floatstr(arg);
  4009. if(dist == 0) dist = 1.0;
  4010. db_begin_transaction(EditMap);
  4011. foreach(new i : Objects)
  4012. {
  4013. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  4014. ObjectData[i][oY] += dist;
  4015. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  4016. UpdateObject3DText(i);
  4017. sqlite_UpdateObjectPos(i);
  4018. }
  4019. db_end_transaction(EditMap);
  4020. return 1;
  4021. }
  4022. // Move all objects on Z axis
  4023. YCMD:doz(playerid, arg[], help)
  4024. {
  4025. if(help)
  4026. {
  4027. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4028. SendClientMessage(playerid, STEALTH_GREEN, "Move all loaded objects along the Z axis.");
  4029. return 1;
  4030. }
  4031. MapOpenCheck();
  4032. NoEditingMode(playerid);
  4033. new Float:dist, time;
  4034. time = GetTickCount();
  4035. dist = floatstr(arg);
  4036. if(dist == 0) dist = 1.0;
  4037. db_begin_transaction(EditMap);
  4038. foreach(new i : Objects)
  4039. {
  4040. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  4041. ObjectData[i][oZ] += dist;
  4042. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  4043. UpdateObject3DText(i);
  4044. sqlite_UpdateObjectPos(i);
  4045. }
  4046. db_end_transaction(EditMap);
  4047. return 1;
  4048. }
  4049. // Rotate map on RX
  4050. YCMD:drx(playerid, arg[], help)
  4051. {
  4052. if(help)
  4053. {
  4054. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4055. SendClientMessage(playerid, STEALTH_GREEN, "Rotate all loaded objects around the X axis.");
  4056. return 1;
  4057. }
  4058. MapOpenCheck();
  4059. new Float:Delta, time;
  4060. time = GetTickCount();
  4061. if(isnull(arg)) Delta = 1.0;
  4062. else if(sscanf(arg, "f", Delta))
  4063. {
  4064. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4065. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /drx <rotation> ");
  4066. return 1;
  4067. }
  4068. // We need to get the map center as the rotation node
  4069. new Float:mCenterX, Float:mCenterY, Float:mCenterZ;
  4070. if(GetMapCenter(mCenterX, mCenterY, mCenterZ))
  4071. {
  4072. // Loop through all objects and perform rotation calculations
  4073. db_begin_transaction(EditMap);
  4074. foreach(new i : Objects)
  4075. {
  4076. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  4077. AttachObjectToPoint(i, mCenterX, mCenterY, mCenterZ, Delta, 0.0, 0.0, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  4078. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  4079. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  4080. UpdateObject3DText(i);
  4081. sqlite_UpdateObjectPos(i);
  4082. }
  4083. db_end_transaction(EditMap);
  4084. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4085. SendClientMessage(playerid, STEALTH_GREEN, "Map RX rotation complete ");
  4086. }
  4087. else
  4088. {
  4089. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4090. SendClientMessage(playerid, STEALTH_YELLOW, "There is not enough objects for this command to work");
  4091. }
  4092. return 1;
  4093. }
  4094. // Rotate map on RY
  4095. YCMD:dry(playerid, arg[], help)
  4096. {
  4097. if(help)
  4098. {
  4099. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4100. SendClientMessage(playerid, STEALTH_GREEN, "Rotate all loaded objects around the Y axis.");
  4101. return 1;
  4102. }
  4103. MapOpenCheck();
  4104. new Float:Delta, time;
  4105. time = GetTickCount();
  4106. if(isnull(arg)) Delta = 1.0;
  4107. else if(sscanf(arg, "f", Delta))
  4108. {
  4109. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4110. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /dry <rotation> ");
  4111. return 1;
  4112. }
  4113. // We need to get the map center as the rotation node
  4114. new Float:mCenterX, Float:mCenterY, Float:mCenterZ;
  4115. if(GetMapCenter(mCenterX, mCenterY, mCenterZ))
  4116. {
  4117. // Loop through all objects and perform rotation calculations
  4118. db_begin_transaction(EditMap);
  4119. foreach(new i : Objects)
  4120. {
  4121. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  4122. AttachObjectToPoint(i, mCenterX, mCenterY, mCenterZ, 0.0, Delta, 0.0, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  4123. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  4124. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  4125. UpdateObject3DText(i);
  4126. sqlite_UpdateObjectPos(i);
  4127. }
  4128. db_end_transaction(EditMap);
  4129. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4130. SendClientMessage(playerid, STEALTH_GREEN, "Map RY rotation complete ");
  4131. }
  4132. else
  4133. {
  4134. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4135. SendClientMessage(playerid, STEALTH_YELLOW, "There is not enough objects for this command to work");
  4136. }
  4137. return 1;
  4138. }
  4139. // Rotate map on RZ
  4140. YCMD:drz(playerid, arg[], help)
  4141. {
  4142. if(help)
  4143. {
  4144. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4145. SendClientMessage(playerid, STEALTH_GREEN, "Rotate all loaded objects around the Z axis.");
  4146. return 1;
  4147. }
  4148. MapOpenCheck();
  4149. new Float:Delta, time;
  4150. time = GetTickCount();
  4151. if(isnull(arg)) Delta = 1.0;
  4152. else if(sscanf(arg, "f", Delta))
  4153. {
  4154. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4155. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /drz <rotation> ");
  4156. return 1;
  4157. }
  4158. // We need to get the map center as the rotation node
  4159. new Float:mCenterX, Float:mCenterY, Float:mCenterZ;
  4160. if(GetMapCenter(mCenterX, mCenterY, mCenterZ))
  4161. {
  4162. // Loop through all objects and perform rotation calculations
  4163. db_begin_transaction(EditMap);
  4164. foreach(new i : Objects)
  4165. {
  4166. SaveUndoInfo(i, UNDO_TYPE_EDIT, time);
  4167. AttachObjectToPoint(i, mCenterX, mCenterY, mCenterZ, 0.0, 0.0, Delta, ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  4168. SetDynamicObjectPos(ObjectData[i][oID], ObjectData[i][oX], ObjectData[i][oY], ObjectData[i][oZ]);
  4169. SetDynamicObjectRot(ObjectData[i][oID], ObjectData[i][oRX], ObjectData[i][oRY], ObjectData[i][oRZ]);
  4170. UpdateObject3DText(i);
  4171. sqlite_UpdateObjectPos(i);
  4172. }
  4173. db_end_transaction(EditMap);
  4174. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4175. SendClientMessage(playerid, STEALTH_GREEN, "Map RZ rotation complete ");
  4176. }
  4177. else
  4178. {
  4179. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4180. SendClientMessage(playerid, STEALTH_YELLOW, "There is not enough objects for this command to work");
  4181. }
  4182. return 1;
  4183. }
  4184. YCMD:odd(playerid, arg[], help)
  4185. {
  4186. if(help)
  4187. {
  4188. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4189. SendClientMessage(playerid, STEALTH_GREEN, "Set a specific object's draw distance.");
  4190. return 1;
  4191. }
  4192. MapOpenCheck();
  4193. EditCheck(playerid);
  4194. NoEditingMode(playerid);
  4195. new Float:dd;
  4196. dd = floatstr(arg);
  4197. if(dd == 0.0) dd = 300.0;
  4198. SaveUndoInfo(CurrObject[playerid], UNDO_TYPE_EDIT);
  4199. ObjectData[CurrObject[playerid]][oDD] = dd;
  4200. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[CurrObject[playerid]][oID], E_STREAMER_DRAW_DISTANCE, dd);
  4201. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[CurrObject[playerid]][oID], E_STREAMER_STREAM_DISTANCE, dd);
  4202. sqlite_UpdateObjectDD(CurrObject[playerid]);
  4203. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4204. SendClientMessage(playerid, STEALTH_GREEN, sprintf("Objects draw distance set to %.2f", dd));
  4205. return 1;
  4206. }
  4207. // Extras
  4208. YCMD:hidetext3d(playerid, arg[], help)
  4209. {
  4210. if(help)
  4211. {
  4212. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4213. SendClientMessage(playerid, STEALTH_GREEN, "Hide all 3D text labels.");
  4214. return 1;
  4215. }
  4216. TextOption[tShowText] = false;
  4217. HideGroupLabels(playerid);
  4218. HideObjectText();
  4219. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4220. SendClientMessage(playerid, STEALTH_GREEN, "All 3D Text labels hidden");
  4221. return 1;
  4222. }
  4223. YCMD:showtext3d(playerid, arg[], help)
  4224. {
  4225. if(help)
  4226. {
  4227. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4228. SendClientMessage(playerid, STEALTH_GREEN, "Show all 3D text labels.");
  4229. return 1;
  4230. }
  4231. /*/Experimental Multiplier
  4232. new Float:mult = floatstr(arg);
  4233. if(0.0 < mult <= 1.0)
  4234. Streamer_SetRadiusMultiplier(STREAMER_TYPE_3D_TEXT_LABEL, mult, playerid);
  4235. else if(mult) {
  4236. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4237. SendClientMessage(playerid, STEALTH_GREEN, "Invalid multiplier specified, must be between 0.0 and 1.0");
  4238. return 1;
  4239. }
  4240. else
  4241. Streamer_SetRadiusMultiplier(STREAMER_TYPE_3D_TEXT_LABEL, 1.0, playerid);*/
  4242. TextOption[tShowText] = true;
  4243. ShowGroupLabels(playerid);
  4244. ShowObjectText();
  4245. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4246. SendClientMessage(playerid, STEALTH_GREEN, "All 3D Text labels shown");
  4247. return 1;
  4248. }
  4249. YCMD:edittext3d(playerid, arg[], help)
  4250. {
  4251. if(help)
  4252. {
  4253. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4254. SendClientMessage(playerid, STEALTH_GREEN, "Shows you a dialog with 3D text options.");
  4255. return 1;
  4256. }
  4257. new optline[256];
  4258. // Init the text menu
  4259. inline SelectOption(spid, sdialogid, sresponse, slistitem, string:stext[])
  4260. {
  4261. #pragma unused slistitem, sdialogid, spid, stext
  4262. if(sresponse)
  4263. {
  4264. // Toggle the selected option
  4265. TextOption[TEXTOPTIONS:slistitem] = !TextOption[TEXTOPTIONS:slistitem];
  4266. // Toggled text?
  4267. if(slistitem == 0)
  4268. {
  4269. if(TextOption[tShowText])
  4270. {
  4271. ShowGroupLabels(playerid);
  4272. ShowObjectText();
  4273. }
  4274. else
  4275. {
  4276. HideGroupLabels(playerid);
  4277. HideObjectText();
  4278. }
  4279. }
  4280. // Show it again
  4281. format(optline, sizeof(optline), "{FFFF00}Text: %s\n{FFFF00}Object Note: %s\n{FFFF00}Model Info: %s\n{FFFF00}Group ID: %s\n{FFFF00}Grouped Text: %s\n{FFFF00}Always Show New Objects: %s\n",
  4282. (TextOption[tShowText] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4283. (TextOption[tShowNote] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4284. (TextOption[tShowModel] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4285. (TextOption[tShowGroup] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4286. (TextOption[tShowGrouped] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4287. (TextOption[tAlwaysShowNew] ? ("{00AA00}Enabled") : ("{FF3000}Disabled"))
  4288. );
  4289. Dialog_ShowCallback(playerid, using inline SelectOption, DIALOG_STYLE_LIST, "Texture Studio - 3D Text Editor", optline, "Ok", "Cancel");
  4290. }
  4291. }
  4292. // Show the dialog
  4293. format(optline, sizeof(optline), "{FFFF00}Text: %s\n{FFFF00}Object Note: %s\n{FFFF00}Model Info: %s\n{FFFF00}Group ID: %s\n{FFFF00}Grouped Text: %s\n{FFFF00}Always Show New Objects: %s\n",
  4294. (TextOption[tShowText] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4295. (TextOption[tShowNote] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4296. (TextOption[tShowModel] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4297. (TextOption[tShowGroup] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4298. (TextOption[tShowGrouped] ? ("{00AA00}Enabled") : ("{FF3000}Disabled")),
  4299. (TextOption[tAlwaysShowNew] ? ("{00AA00}Enabled") : ("{FF3000}Disabled"))
  4300. );
  4301. Dialog_ShowCallback(playerid, using inline SelectOption, DIALOG_STYLE_LIST, "Texture Studio - 3D Text Editor", optline, "Ok", "Cancel");
  4302. return 1;
  4303. }
  4304. YCMD:note(playerid, arg[], help)
  4305. {
  4306. if(help)
  4307. {
  4308. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4309. SendClientMessage(playerid, STEALTH_GREEN, "Show or change an object's note.");
  4310. return 1;
  4311. }
  4312. MapOpenCheck();
  4313. new index, note[64];
  4314. if(sscanf(arg, "iS()[64]", index, note))
  4315. {
  4316. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4317. SendClientMessage(playerid, STEALTH_YELLOW, "Usage: /note <Index> <Optional: New Note>");
  4318. return 1;
  4319. }
  4320. if(isnull(note) || !strlen(note))
  4321. {
  4322. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4323. SendClientMessage(playerid, STEALTH_GREEN, sprintf("Object's note: %s", ObjectData[index][oNote]));
  4324. }
  4325. else
  4326. {
  4327. SaveUndoInfo(index, UNDO_TYPE_EDIT);
  4328. format(ObjectData[index][oNote], 64, "%s", note);
  4329. sqlite_ObjNote(index);
  4330. UpdateObject3DText(index);
  4331. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4332. SendClientMessage(playerid, STEALTH_YELLOW, "Note changed");
  4333. }
  4334. return 1;
  4335. }
  4336. YCMD:setspawn(playerid, arg[], help)
  4337. {
  4338. if(help)
  4339. {
  4340. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4341. SendClientMessage(playerid, STEALTH_GREEN, "Set this map's spawn position to your current position.");
  4342. return 1;
  4343. }
  4344. MapOpenCheck();
  4345. GetPlayerPos(playerid, MapSetting[mSpawn][xPos], MapSetting[mSpawn][yPos], MapSetting[mSpawn][zPos]);
  4346. sqlite_UpdateSettings();
  4347. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4348. SendClientMessage(playerid, STEALTH_YELLOW, sprintf("You have set the map's spawn position to (%0.2f, %0.2f, %0.2f)", MapSetting[mSpawn][xPos], MapSetting[mSpawn][yPos], MapSetting[mSpawn][zPos]));
  4349. return 1;
  4350. }
  4351. YCMD:gotomap(playerid, arg[], help)
  4352. {
  4353. if(help)
  4354. {
  4355. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4356. SendClientMessage(playerid, STEALTH_GREEN, "Sends you to this map's spawn position.");
  4357. return 1;
  4358. }
  4359. if(MapSetting[mSpawn][xPos] == 0.0)
  4360. return SendClientMessage(playerid, STEALTH_YELLOW, "This map doesn't have a spawn position, set one with \"/setspawn\"");
  4361. SetPlayerPos(playerid, MapSetting[mSpawn][xPos], MapSetting[mSpawn][yPos], MapSetting[mSpawn][zPos]);
  4362. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4363. SendClientMessage(playerid, STEALTH_YELLOW, "You've been teleported to the map's spawn position");
  4364. return 1;
  4365. }
  4366. HideObjectText()
  4367. {
  4368. foreach(new i : Objects)
  4369. {
  4370. UpdateDynamic3DTextLabelText(ObjectData[i][oTextID], 0, "");
  4371. }
  4372. return 1;
  4373. }
  4374. ShowObjectText()
  4375. {
  4376. foreach(new i : Objects)
  4377. {
  4378. UpdateObject3DText(i, false);
  4379. }
  4380. return 1;
  4381. }
  4382. YCMD:stopedit(playerid, arg[], help)
  4383. {
  4384. if(help)
  4385. {
  4386. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4387. SendClientMessage(playerid, STEALTH_GREEN, "Reset editing mode.");
  4388. return 1;
  4389. }
  4390. MapOpenCheck();
  4391. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  4392. if(EditingMode[playerid])
  4393. {
  4394. EditingMode[playerid] = false;
  4395. CancelEdit(playerid);
  4396. SendClientMessage(playerid, STEALTH_GREEN, "Editing mode reset.");
  4397. }
  4398. else SendClientMessage(playerid, STEALTH_YELLOW, "You're not editing.");
  4399. return 1;
  4400. }