1
0

RPFW.pwn 201 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576
  1. // Developers notes
  2. /* # Coding guideline
  3. * Add +1 at the end of array declarations to visually account for null bit.
  4. * Always log first.
  5. * Always notify discord last.
  6. * Always wait for other queries to finish before initiating one: "sql_wait(sqlHandle); // Wait for other queries to finish"
  7. * Delete GVar strings as soon as possible, but at least before the player quits or the gamemode exits, as per: https://forum.sa-mp.com/showthread.php?t=151076
  8. * Read all the functions before the OnGameModeInit(), to be able to follow the DRY principle. Repeating code will NOT BE ACCEPTED!
  9. */
  10. /* # Style guide
  11. * GLOBAL_CONSTANT
  12. * someFunction
  13. * SomeClass
  14. * playerid // Variable storing in-game player ID (local without underscores)
  15. * player_id // Variable storing database player ID (remote with underscores)
  16. */
  17. /* # Adding a discord bot to your guild.
  18. https://discordapp.com/oauth2/authorize?client_id=%CLIENT_ID%&scope=bot&permissions=3072
  19. Where %CLEINT_ID% is the client id.
  20. */
  21. /* # Todo:
  22. * Add geoiplib, to make connect messages fancier, and add a locate command.
  23. * Show underscores as spaces and convert spaces in changename input to undescores before regex check.
  24. * Vip limit on characters.
  25. * See why sql_insert_id wont work. (Try it via a callback)
  26. * Check if timestamps work (implemented on temp ban), before implementing it more.
  27. * Normalise database column names.
  28. * Some SMALLINT fields are using SQL_INTERGER_LEGNTH for size and could be smaller.
  29. */
  30. /// Global definitions
  31. // Colours
  32. /*
  33. #define COLOR_GREEN 0x33AA33AA
  34. #define COLOR_YELLOW 0xFFFF00AA
  35. #define COLOR_WHITE 0xFFFFFFAA
  36. #define COLOR_BLUE 0x0000BBAA
  37. #define COLOR_LIGHTBLUE 0x33CCFFAA
  38. #define COLOR_ORANGE 0xFF9900AA
  39. #define COLOR_RED 0xAA3333AA
  40. #define COLOR_LIME 0x10F441AA
  41. #define COLOR_NAVY 0x000080AA
  42. #define COLOR_AQUA 0xF0F8FFAA
  43. #define COLOR_CRIMSON 0xDC143CAA
  44. #define COLOR_BISQUE 0xFFE4C4AA
  45. #define COLOR_BLACK 0x000000AA
  46. #define COLOR_CHARTREUSE 0x7FFF00AA
  47. #define COLOR_BROWN 0XA52A2AAA
  48. #define COLOR_CORAL 0xFF7F50AA
  49. #define COLOR_GOLD 0xB8860BAA
  50. #define COLOR_GREENYELLOW 0xADFF2FAA
  51. #define COLOR_INDIGO 0x4B00B0AA
  52. #define COLOR_IVORY 0xFFFF82AA
  53. #define COLOR_LAWNGREEN 0x7CFC00AA
  54. #define COLOR_SEAGREEN 0x20B2AAAA
  55. #define COLOR_SEAGREEN 0x2E8B57AA
  56. #define COLOR_LIMEGREEN 0x32CD32AA //<--- Dark lime
  57. #define COLOR_MIDNIGHTBLUE 0X191970AA
  58. #define COLOR_MAROON 0x800000AA
  59. #define COLOR_OLIVE 0x808000AA
  60. #define COLOR_ORANGERED 0xFF4500AA
  61. #define COLOR_PINK 0xFFC0CBAA // - Light light pink
  62. #define COLOR_SPRINGGREEN 0x00FF7FAA
  63. #define COLOR_TOMATO 0xFF6347AA // - Tomato >:/ sounds wrong lol... well... :P
  64. #define COLOR_YELLOWGREEN 0x9ACD32AA //- like military green
  65. #define COLOR_MEDIUMAQUA 0x83BFBFAA
  66. #define COLOR_MEDIUMMAGENTA 0x8B008BAA // dark magenta ^^
  67. */
  68. #define COLOR_ACTIVEBORDER 0xB4B4B4FF
  69. #define COLOR_ACTIVECAPTION 0x99B4D1FF
  70. #define COLOR_ACTIVECAPTIONTEXT 0x000000FF
  71. #define COLOR_ALICEBLUE 0xF0F8FFFF
  72. #define COLOR_ANTIQUEWHITE 0xFAEBD7FF
  73. #define COLOR_APPWORKSPACE 0xABABABFF
  74. #define COLOR_AQUA 0x00FFFFFF
  75. #define COLOR_AQUAMARINE 0x7FFFD4FF
  76. #define COLOR_AZURE 0xF0FFFFFF
  77. #define COLOR_BEIGE 0xF5F5DCFF
  78. #define COLOR_BISQUE 0xFFE4C4FF
  79. #define COLOR_BLACK 0x000000FF
  80. #define COLOR_BLANCHEDALMOND 0xFFEBCDFF
  81. #define COLOR_BLUE 0x0000FFFF
  82. #define COLOR_BLUEVIOLET 0x8A2BE2FF
  83. #define COLOR_BROWN 0xA52A2AFF
  84. #define COLOR_BURLYWOOD 0xDEB887FF
  85. #define COLOR_BUTTONFACE 0xF0F0F0FF
  86. #define COLOR_BUTTONHIGHLIGHT 0xFFFFFFFF
  87. #define COLOR_BUTTONSHADOW 0xA0A0A0FF
  88. #define COLOR_CADETBLUE 0x5F9EA0FF
  89. #define COLOR_CHARTREUSE 0x7FFF00FF
  90. #define COLOR_CHOCOLATE 0xD2691EFF
  91. #define COLOR_CONTROL 0xF0F0F0FF
  92. #define COLOR_CONTROLDARK 0xA0A0A0FF
  93. #define COLOR_CONTROLDARKDARK 0x696969FF
  94. #define COLOR_CONTROLLIGHT 0xE3E3E3FF
  95. #define COLOR_CONTROLLIGHTLIGHT 0xFFFFFFFF
  96. #define COLOR_CONTROLTEXT 0x000000FF
  97. #define COLOR_CORAL 0xFF7F50FF
  98. #define COLOR_CORNFLOWERBLUE 0x6495EDFF
  99. #define COLOR_CORNSILK 0xFFF8DCFF
  100. #define COLOR_CRIMSON 0xDC143CFF
  101. #define COLOR_CYAN 0x00FFFFFF
  102. #define COLOR_DARKBLUE 0x00008BFF
  103. #define COLOR_DARKCYAN 0x008B8BFF
  104. #define COLOR_DARKGOLDENROD 0xB8860BFF
  105. #define COLOR_DARKGRAY 0xA9A9A9FF
  106. #define COLOR_DARKGREEN 0x006400FF
  107. #define COLOR_DARKKHAKI 0xBDB76BFF
  108. #define COLOR_DARKMAGENTA 0x8B008BFF
  109. #define COLOR_DARKOLIVEGREEN 0x556B2FFF
  110. #define COLOR_DARKORANGE 0xFF8C00FF
  111. #define COLOR_DARKORCHID 0x9932CCFF
  112. #define COLOR_DARKRED 0x8B0000FF
  113. #define COLOR_DARKSALMON 0xE9967AFF
  114. #define COLOR_DARKSEAGREEN 0x8FBC8BFF
  115. #define COLOR_DARKSLATEBLUE 0x483D8BFF
  116. #define COLOR_DARKSLATEGRAY 0x2F4F4FFF
  117. #define COLOR_DARKTURQUOISE 0x00CED1FF
  118. #define COLOR_DARKVIOLET 0x9400D3FF
  119. #define COLOR_DEEPPINK 0xFF1493FF
  120. #define COLOR_DEEPSKYBLUE 0x00BFFFFF
  121. #define COLOR_DEFAULT_CHAT 0xFFFFFFFF
  122. #define COLOR_DESKTOP 0x000000FF
  123. #define COLOR_DIMGRAY 0x696969FF
  124. #define COLOR_DODGERBLUE 0x1E90FFFF
  125. #define COLOR_FIREBRICK 0xB22222FF
  126. #define COLOR_FLBLUE 0x6495EDAA
  127. #define COLOR_FLORALWHITE 0xFFFAF0FF
  128. #define COLOR_FORESTGREEN 0x228B22FF
  129. #define COLOR_GAINSBORO 0xDCDCDCFF
  130. #define COLOR_GHOSTWHITE 0xF8F8FFFF
  131. #define COLOR_GOLD 0xFFD700FF
  132. #define COLOR_GOLDENROD 0xDAA520FF
  133. #define COLOR_GRADIENTACTIVECAPTION 0xB9D1EAFF
  134. #define COLOR_GRADIENTINACTIVECAPTION 0xD7E4F2FF
  135. #define COLOR_GRAY 0x808080FF
  136. #define COLOR_GRAYTEXT 0x808080FF
  137. #define COLOR_GREEN 0x008000FF
  138. #define COLOR_GREENYELLOW 0xADFF2FFF
  139. #define COLOR_GREY 0xAFAFAFAA
  140. #define COLOR_HIGHLIGHT 0x3399FFFF
  141. #define COLOR_HIGHLIGHTTEXT 0xFFFFFFFF
  142. #define COLOR_HONEYDEW 0xF0FFF0FF
  143. #define COLOR_HOTPINK 0xFF69B4FF
  144. #define COLOR_HOTTRACK 0x0066CCFF
  145. #define COLOR_INACTIVEBORDER 0xF4F7FCFF
  146. #define COLOR_INACTIVECAPTION 0xBFCDDBFF
  147. #define COLOR_INACTIVECAPTIONTEXT 0x434E54FF
  148. #define COLOR_INDIANRED 0xCD5C5CFF
  149. #define COLOR_INDIGO 0x4B0082FF
  150. #define COLOR_INFO 0xFFFFE1FF
  151. #define COLOR_INFOTEXT 0x000000FF
  152. #define COLOR_IVORY 0xFFFFF0FF
  153. #define COLOR_KHAKI 0xF0E68CFF
  154. #define COLOR_LAVENDER 0xE6E6FAFF
  155. #define COLOR_LAVENDERBLUSH 0xFFF0F5FF
  156. #define COLOR_LAWNGREEN 0x7CFC00FF
  157. #define COLOR_LEMONCHIFFON 0xFFFACDFF
  158. #define COLOR_LIGHTBLUE 0xADD8E6FF
  159. #define COLOR_LIGHTCORAL 0xF08080FF
  160. #define COLOR_LIGHTCYAN 0xE0FFFFFF
  161. #define COLOR_LIGHTGOLDENRODYELLOW 0xFAFAD2FF
  162. #define COLOR_LIGHTGRAY 0xD3D3D3FF
  163. #define COLOR_LIGHTGREEN 0x90EE90FF
  164. #define COLOR_LIGHTPINK 0xFFB6C1FF
  165. #define COLOR_LIGHTSALMON 0xFFA07AFF
  166. #define COLOR_LIGHTSEAGREEN 0x20B2AAFF
  167. #define COLOR_LIGHTSKYBLUE 0x87CEFAFF
  168. #define COLOR_LIGHTSLATEGRAY 0x778899FF
  169. #define COLOR_LIGHTSTEELBLUE 0xB0C4DEFF
  170. #define COLOR_LIGHTYELLOW 0xFFFFE0FF
  171. #define COLOR_LIME 0x00FF00FF
  172. #define COLOR_LIMEGREEN 0x32CD32FF
  173. #define COLOR_LINEN 0xFAF0E6FF
  174. #define COLOR_MAGENTA 0xFF00FFFF
  175. #define COLOR_MAROON 0x800000FF
  176. #define COLOR_MEDIUMAQUAMARINE 0x66CDAAFF
  177. #define COLOR_MEDIUMBLUE 0x0000CDFF
  178. #define COLOR_MEDIUMORCHID 0xBA55D3FF
  179. #define COLOR_MEDIUMPURPLE 0x9370DBFF
  180. #define COLOR_MEDIUMSEAGREEN 0x3CB371FF
  181. #define COLOR_MEDIUMSLATEBLUE 0x7B68EEFF
  182. #define COLOR_MEDIUMSPRINGGREEN 0x00FA9AFF
  183. #define COLOR_MEDIUMTURQUOISE 0x48D1CCFF
  184. #define COLOR_MEDIUMVIOLETRED 0xC71585FF
  185. #define COLOR_MENU 0xF0F0F0FF
  186. #define COLOR_MENUBAR 0xF0F0F0FF
  187. #define COLOR_MENUHIGHLIGHT 0x3399FFFF
  188. #define COLOR_MENUTEXT 0x000000FF
  189. #define COLOR_MIDNIGHTBLUE 0x191970FF
  190. #define COLOR_MINTCREAM 0xF5FFFAFF
  191. #define COLOR_MISTYROSE 0xFFE4E1FF
  192. #define COLOR_MOCCASIN 0xFFE4B5FF
  193. #define COLOR_NAVAJOWHITE 0xFFDEADFF
  194. #define COLOR_NAVY 0x000080FF
  195. #define COLOR_OLDLACE 0xFDF5E6FF
  196. #define COLOR_OLIVE 0x808000FF
  197. #define COLOR_OLIVEDRAB 0x6B8E23FF
  198. #define COLOR_ORANGE 0xFFA500FF
  199. #define COLOR_ORANGERED 0xFF4500FF
  200. #define COLOR_ORCHID 0xDA70D6FF
  201. #define COLOR_PALEGOLDENROD 0xEEE8AAFF
  202. #define COLOR_PALEGREEN 0x98FB98FF
  203. #define COLOR_PALETURQUOISE 0xAFEEEEFF
  204. #define COLOR_PALEVIOLETRED 0xDB7093FF
  205. #define COLOR_PAPAYAWHIP 0xFFEFD5FF
  206. #define COLOR_PEACHPUFF 0xFFDAB9FF
  207. #define COLOR_PERU 0xCD853FFF
  208. #define COLOR_PINK 0xFFC0CBFF
  209. #define COLOR_PLUM 0xDDA0DDFF
  210. #define COLOR_POWDERBLUE 0xB0E0E6FF
  211. #define COLOR_PURPLE 0x800080FF
  212. #define COLOR_RED 0xFF0000FF
  213. #define COLOR_ROSYBROWN 0xBC8F8FFF
  214. #define COLOR_ROYALBLUE 0x4169E1FF
  215. #define COLOR_SADDLEBROWN 0x8B4513FF
  216. #define COLOR_SALMON 0xFA8072FF
  217. #define COLOR_SANDYBROWN 0xF4A460FF
  218. #define COLOR_SCROLLBAR 0xC8C8C8FF
  219. #define COLOR_SEAGREEN 0x2E8B57FF
  220. #define COLOR_SEASHELL 0xFFF5EEFF
  221. #define COLOR_SIENNA 0xA0522DFF
  222. #define COLOR_SILVER 0xC0C0C0FF
  223. #define COLOR_SKYBLUE 0x87CEEBFF
  224. #define COLOR_SLATEBLUE 0x6A5ACDFF
  225. #define COLOR_SLATEGRAY 0x708090FF
  226. #define COLOR_SNOW 0xFFFAFAFF
  227. #define COLOR_SPRINGGREEN 0x00FF7FFF
  228. #define COLOR_STEELBLUE 0x4682B4FF
  229. #define COLOR_TAN 0xD2B48CFF
  230. #define COLOR_TEAL 0x008080FF
  231. #define COLOR_THISTLE 0xD8BFD8FF
  232. #define COLOR_TOMATO 0xFF6347FF
  233. #define COLOR_TRANSPARENT 0xFFFFFF00
  234. #define COLOR_TURQUOISE 0x40E0D0FF
  235. #define COLOR_VIOLET 0xEE82EEFF
  236. #define COLOR_WHEAT 0xF5DEB3FF
  237. #define COLOR_WHITE 0xFFFFFFFF
  238. #define COLOR_WHITESMOKE 0xF5F5F5FF
  239. #define COLOR_WINDOW 0xFFFFFFFF
  240. #define COLOR_WINDOWFRAME 0x646464FF
  241. #define COLOR_WINDOWTEXT 0x000000FF
  242. #define COLOR_YELLOW 0xFFFF00FF
  243. #define COLOR_YELLOWGREEN 0x9ACD32FF
  244. #define COLOR_STEALTH_ORANGE 0xFF880000
  245. #define COLOR_STEALTH_OLIVE 0x66660000
  246. #define COLOR_STEALTH_GREEN 0x33DD1100
  247. #define COLOR_STEALTH_PINK 0xFF22EE00
  248. #define COLOR_STEALTH_BLUE 0x0077BB00
  249. // Color groups
  250. #define COLOR_COMMAND_OUTPUT 0xFFFFFFFF // White
  251. #define COLOR_NOTICE 0xAFAFAFAA // Grey
  252. #define COLOR_WARNING 0xFFA500FF // Orange? (Looks more yellow to me)
  253. #define COLOR_ERROR 0xFF0000FF // Red
  254. #define COLOR_GLOBAL_CHAT 0xFFFFFFFF // White
  255. #define COLOR_PM_CHAT 0xFFFF00FF // Yellow
  256. #define COLOR_VIP_CHAT 0x800080FF // Purple
  257. #define COLOR_CREW_CHAT 0xFF9900AA // Orange
  258. #define COLOR_ADMIN_CHAT 0xB8860BAA // Gold
  259. #define COLOR_POLICE 0x00008BFF //
  260. #define COLOR_MEDIC 0xFFC0CBAA // Light pink
  261. #define COLOR_FIRE 0xAA3333AA // Red
  262. #define COLOR_SHERIFF 0xF5F5DCFF // Beige
  263. #define COLOR_FBI 0x000080AA // Navy
  264. #define COLOR_DMV 0xF0F8FFAA // Aqua
  265. #define COLOR_NEWS 0x808000FF // Olive
  266. #define EMBED_COLOR_GREY "{838383}"
  267. #define EMBED_COLOR_RED "{FF0000}"
  268. #define EMBED_COLOR_WHITE "{FFFFFF}"
  269. // SQL datatypes
  270. #define MAX_SQL_INTEGER 10
  271. #define MAX_SQL_TIMESTAMP 19 // 1999-01-08 04:05:06 [5 + 4 + 2 + 2 +2 + 2 + 2]
  272. #define MAX_SQL_FLOAT 16
  273. #define MAX_SQL_HASH 128
  274. #define MAX_SQL_IP 45
  275. #define MAX_SQL_REASON 121
  276. // Log levels
  277. #define LOGLEVEL_CHAT -2
  278. #define LOGLEVEL_COMMAND -1
  279. #define LOGLEVEL_DEBUG 0
  280. #define LOGLEVEL_INFO 1
  281. #define LOGLEVEL_NOTICE 2
  282. #define LOGLEVEL_WARNING 3
  283. #define LOGLEVEL_ERROR 4
  284. #define LOGLEVEL_CRITICAL 5
  285. #define LOGLEVEL_PANIC 6
  286. // Userlevels
  287. enum{ // Noted values as comments, for database reference.
  288. UNREGISTERED_PLAYER, // 0
  289. REGISTERED_PLAYER, // 1
  290. REGULAR_PLAYER, // 2 Spent many hours in and around the comunity.
  291. VIP_PLAYER, // 3 Donated.
  292. MODERATOR_CREW, // 4
  293. VETERAN_CREW, // 5 Inactive admins and management that are allowed to keep their rights.
  294. ADMIN_CREW, // 6
  295. UNDERCOVER_ADMIN_CREW, // 7
  296. MANAGEMENT_CREW, // 8
  297. UNDRECOVER_MANAGEMENT_CREW, // 9
  298. FOUNDER_PLAYER, // 10
  299. UNDERCOVER_FOUNDER_PLAYER, // 11
  300. }
  301. // Discord channels
  302. enum{
  303. ECHO_CHANNEL,
  304. MAIN_CHANNEL,
  305. ADMIN_ECHO_CHANNEL,
  306. ADMIN_CHANNEL,
  307. MANAGEMENT_CHANNEL,
  308. }
  309. // Chats
  310. enum{
  311. CHAT_LOCAL, // Has to be 0, else a gVar would have to be created OnJoin, this conserves memory when no chatmode is set (which will be the case most likely)
  312. CHAT_WHISPER,
  313. CHAT_LOW,
  314. CHAT_ACTION,
  315. CHAT_SHOUT,
  316. CHAT_OC,
  317. CHAT_GLOBAL,
  318. CHAT_CALL,
  319. CHAT_SMS,
  320. CHAT_RADIO,
  321. CHAT_PM,
  322. CHAT_GANG,
  323. CHAT_GANG_OC,
  324. CHAT_FACTION,
  325. CHAT_FACTION_OC,
  326. CHAT_VIP,
  327. CHAT_CREW,
  328. CHAT_ADMIN,
  329. CHAT_MANAGEMENT,
  330. CHAT_UNDERCOVER,
  331. }
  332. // Dialogs
  333. enum{
  334. DIALOG_CHANGENAME,
  335. DIALOG_REGISTER,
  336. DIALOG_ACCOUNT_CREATED,
  337. DIALOG_LOGIN,
  338. DIALOG_CHANGE_USERNAME,
  339. DIALOG_CHARACTERS,
  340. DIALOG_LOGIN_FAILED,
  341. DIALOG_DELETE_CHARACTER,
  342. DIALOG_GOTO,
  343. DIALOG_GOTO_INTERIOR,
  344. DIALOG_GOTO_PLAYER,
  345. DIALOG_GOTO_247,
  346. DIALOG_GOTO_AVIATION,
  347. DIALOG_GOTO_AMMUNATION,
  348. DIALOG_GOTO_BURGLARYHOUSE,
  349. DIALOG_GOTO_CASINO,
  350. DIALOG_GOTO_MISSION,
  351. DIALOG_GOTO_MISSIONEXT,
  352. DIALOG_GOTO_MISSIONHOUSE,
  353. DIALOG_GOTO_MODDING,
  354. DIALOG_GOTO_POLICE,
  355. DIALOG_GOTO_HOUSES,
  356. DIALOG_GOTO_SAFEHOUSE,
  357. DIALOG_GOTO_SEXWORK,
  358. DIALOG_GOTO_SHOPS,
  359. DIALOG_GOTO_SHOP,
  360. DIALOG_GOTO_STADIA,
  361. DIALOG_GOTO_UHOUSE,
  362. DIALOG_GOTO_UNCATAGORIZED,
  363. DIALOG_GOTO_WAREHOUSE,
  364. DIALOG_GOTO_BARBER,
  365. DIALOG_GOTO_FOOD,
  366. DIALOG_GOTO_GIRLHOUSE,
  367. DIALOG_GOTO_GARAGE,
  368. DIALOG_CREATE_PICKUP,
  369. DIALOG_CREATE_FACTION_PICKUP,
  370. DIALOG_DUTY_PD,
  371. DIALOG_POLICE_SKIN,
  372. DIALOG_DUTY_MD,
  373. DIALOG_MEDIC_SKIN,
  374. DIALOG_DUTY_FD,
  375. DIALOG_FIRE_SKIN,
  376. DIALOG_DUTY_SD,
  377. DIALOG_SHERIFF_SKIN,
  378. DIALOG_DUTY_FBI,
  379. DIALOG_FBI_SKIN,
  380. DIALOG_DUTY_DMV,
  381. DIALOG_DMV_SKIN,
  382. DIALOG_DUTY_NEWS,
  383. DIALOG_NEWS_SKIN,
  384. }
  385. // Pickups
  386. enum{
  387. PICKUP_FACTION_PD,
  388. PICKUP_FACTION_MD,
  389. PICKUP_FACTION_FD,
  390. PICKUP_FACTION_SD,
  391. PICKUP_FACTION_FBI,
  392. PICKUP_FACTION_DMV,
  393. PICKUP_FACTION_NEWS,
  394. PICKUP_PORTAL, // MUST be last as it's not in the pickup create dialog
  395. }
  396. // Location categories
  397. enum{
  398. GOTO_CATEGORY_INTERIOR,
  399. }
  400. enum{
  401. INTERIOR_CATEGORY_AVIATION,
  402. INTERIOR_CATEGORY_HOUSES,
  403. INTERIOR_CATEGORY_MISSION,
  404. INTERIOR_CATEGORY_MISSIONEXT,
  405. INTERIOR_CATEGORY_POLICE,
  406. INTERIOR_CATEGORY_SEXWORK,
  407. INTERIOR_CATEGORY_SHOPS,
  408. INTERIOR_CATEGORY_STADIA,
  409. }
  410. enum{
  411. INTERIOR_HOUSE_CAT_BURGLARY,
  412. INTERIOR_HOUSE_CAT_MISSION,
  413. INTERIOR_HOUSE_CAT_SAFE,
  414. INTERIOR_HOUSE_CAT_U,
  415. }
  416. enum{
  417. INTERIOR_SHOP_CAT_247,
  418. INTERIOR_SHOP_CAT_AMMUNATION,
  419. INTERIOR_SHOP_CAT_CASINO,
  420. INTERIOR_SHOP_CAT_MODSHOP,
  421. INTERIOR_SHOP_CAT_SHOP,
  422. }
  423. enum{INTERIOR_247_LSHAPED, INTERIOR_247_OBLONG, INTERIOR_247_MEDIUM, INTERIOR_247_MEDIUM_NOEXIT, INTERIOR_247_LONG, INTERIOR_247_SQAURE}
  424. enum{
  425. INTERIOR_AVIATION_TICKET,
  426. INTERIOR_AVIATION_BAGGAGE,
  427. INTERIOR_AVIATION_SHAMAL,
  428. INTERIOR_AVIATION_ANDROMADA,
  429. INTERIOR_AVIATION_LSAIRPORT
  430. }
  431. enum{INTERIOR_AMMU_OCEAN, INTERIOR_AMMU_PALOMINO, INTERIOR_AMMU_ANGEL, INTERIOR_AMMU_QUEBRADOS, INTERIOR_AMMU_2STORIES, INTERIOR_AMMU_BOOTH, INTERIOR_AMMU_RANGE}
  432. enum{
  433. INTERIOR_BURGLARY_LARGE,
  434. INTERIOR_BURGLARY_MEDIUM,
  435. INTERIOR_BURGLARY_SMALL,
  436. INTERIOR_BURGLARY_VERYLARGE,
  437. INTERIOR_BURGLARY_5,
  438. INTERIOR_BURGLARY_6,
  439. INTERIOR_BURGLARY_NOBATH,
  440. INTERIOR_BURGLARY_4,
  441. }
  442. enum{
  443. INTERIOR_CASINO_CALIGULAS,
  444. INTERIOR_CASINO_REDLAND,
  445. INTERIOR_CASINO_4DRAGONS,
  446. INTERIOR_CASINO_4DRAGONSUITE,
  447. }
  448. enum{
  449. INTERIOR_MISSION_ATRIUM,
  450. INTERIOR_MISSION_BIGSMOKE,
  451. INTERIOR_MISSION_JEFFERSON,
  452. INTERIOR_MISSION_JIZZY,
  453. INTERIOR_MISSION_RC,
  454. INTERIOR_MISSION_WUZI,
  455. }
  456. enum{
  457. INTERIOR_MISSIONEXT_GAS,
  458. INTERIOR_MISSIONEXT_LIBERTY,
  459. INTERIOR_MISSIONEXT_SFGARAGE,
  460. }
  461. enum{
  462. INTERIOR_MISSIONHOUSE_DESIRE,
  463. INTERIOR_MISSIONHOUSE_COLONEL,
  464. INTERIOR_MISSIONHOUSE_RYDER,
  465. INTERIOR_MISSIONHOUSE_SWEET,
  466. INTERIOR_MISSIONHOUSE_CRACK,
  467. }
  468. enum{
  469. INTERIOR_GARAGE_LOCO,
  470. INTERIOR_GARAGE_WHEEL,
  471. INTERIOR_GARAGE_TRANSFENDER,
  472. INTERIOR_GARAGE_SF,
  473. }
  474. enum{INTERIOR_PD_LV, INTERIOR_PD_LS, INTERIOR_PD_SF, INTERIOR_PD_BARBARA}
  475. enum{
  476. INTERIOR_HOUSE_GOLDEN,
  477. INTERIOR_HOUSE_HASHBURY,
  478. INTERIOR_HOUSE_JOHNSON,
  479. INTERIOR_HOUSE_MADDDOGG,
  480. INTERIOR_HOUSE_RED,
  481. INTERIOR_HOUSE_VERDANT,
  482. INTERIOR_HOUSE_UNUSED,
  483. INTERIOR_HOUSE_1,
  484. INTERIOR_HOUSE_2,
  485. INTERIOR_HOUSE_3,
  486. INTERIOR_HOUSE_4,
  487. }
  488. enum{
  489. INTERIOR_SEXWORK_BROTHEL,
  490. INTERIOR_SEXWORK_BROTHEL2,
  491. INTERIOR_SEXWORK_BIGSPREAD,
  492. INTERIOR_SEXWORK_STIPCLUB,
  493. }
  494. enum{
  495. INTERIOR_SHOP_TATTOO,
  496. INTERIOR_SHOP_BURGER,
  497. INTERIOR_SHOP_PIZZA,
  498. INTERIOR_SHOP_CLUCKIN,
  499. INTERIOR_SHOP_CALIGULAS,
  500. INTERIOR_SHOP_CASINO,
  501. INTERIOR_SHOP_4DRAGONS,
  502. INTERIOR_SHOP_4DRAGONSUITE,
  503. INTERIOR_SHOP_DONUTS,
  504. INTERIOR_SHOP_RC,
  505. INTERIOR_SHOP_PUMP,
  506. INTERIOR_SHOP_GANTONGYM,
  507. INTERIOR_SHOP_BETTING,
  508. INTERIOR_SHOP_RECORDS,
  509. INTERIOR_SHOP_PROLAPS,
  510. INTERIOR_SHOP_SEX,
  511. INTERIOR_SHOP_LVTATTOO,
  512. INTERIOR_SHOP_SFTATTOO,
  513. INTERIOR_SHOP_VICTIM,
  514. INTERIOR_SHOP_BELTGYM,
  515. INTERIOR_SHOP_URBAN,
  516. INTERIOR_SHOP_ZIP,
  517. INTERIOR_SHOP_LSTATTOO,
  518. INTERIOR_SHOP_BINCO,
  519. INTERIOR_SHOP_COBRAGYM,
  520. INTERIOR_SHOP_DIDIER,
  521. }
  522. enum{
  523. INTERIOR_STADIUM_BLOODBOWL,
  524. INTERIOR_STADIUM_KICKSTART,
  525. INTERIOR_STADIUM_8TRACK,
  526. INTERIOR_STADIUM_DIRTBIKE,
  527. }
  528. enum{
  529. INTERIOR_WAREHOUSE_1,
  530. INTERIOR_WAREHOUSE_2,
  531. }
  532. enum{
  533. INTERIOR_BARBER_1,
  534. INTERIOR_BARBER_2,
  535. INTERIOR_BARBER_3,
  536. }
  537. enum{
  538. INTERIOR_FOOD_DINER1,
  539. INTERIOR_FOOD_PIZZA,
  540. INTERIOR_FOOD_DONUT,
  541. INTERIOR_FOOD_BURGER,
  542. INTERIOR_FOOD_CLUCKIN,
  543. INTERIOR_FOOD_DONUTS,
  544. INTERIOR_FOOD_PUMP,
  545. INTERIOR_FOOD_PALIMO,
  546. INTERIOR_FOOD_COQ,
  547. }
  548. enum{
  549. INTERIOR_GIRL_DENISE,
  550. INTERIOR_GIRL_HELENA,
  551. INTERIOR_GIRL_KATIE,
  552. }
  553. // Factions
  554. enum{
  555. FACTION_NONE,
  556. FACTION_POLICE,
  557. FACTION_MEDIC,
  558. FACTION_FIRE,
  559. FACTION_SHERIFF,
  560. FACTION_FBI,
  561. FACTION_DMV,
  562. FACTION_NEWS,
  563. }
  564. // Jobs
  565. enum{
  566. JOB_NONE,
  567. JOB_POLICE,
  568. JOB_MEDIC,
  569. JOB_FIRE,
  570. JOB_SHERIFF,
  571. JOB_FBI,
  572. JOB_DMV,
  573. JOB_NEWS,
  574. }
  575. // Vehicles
  576. enum{
  577. EDITVEHICLE_PARK,
  578. EDITVEHICLE_COLOR,
  579. EDITVEHICLE_RESPAWN,
  580. EDITVEHICLE_SIREN,
  581. EDITVEHICLE_FACTION,
  582. EDITVEHICLE_DELETE,
  583. }
  584. new vehicleNameArray[212][] = {
  585. {"Landstalker"},
  586. {"Bravura"},
  587. {"Buffalo"},
  588. {"Linerunner"},
  589. {"Perrenial"},
  590. {"Sentinel"},
  591. {"Dumper"},
  592. {"Firetruck"},
  593. {"Trashmaster"},
  594. {"Stretch"},
  595. {"Manana"},
  596. {"Infernus"},
  597. {"Voodoo"},
  598. {"Pony"},
  599. {"Mule"},
  600. {"Cheetah"},
  601. {"Ambulance"},
  602. {"Leviathan"},
  603. {"Moonbeam"},
  604. {"Esperanto"},
  605. {"Taxi"},
  606. {"Washington"},
  607. {"Bobcat"},
  608. {"Mr Whoopee"},
  609. {"BF Injection"},
  610. {"Hunter"},
  611. {"Premier"},
  612. {"Enforcer"},
  613. {"Securicar"},
  614. {"Banshee"},
  615. {"Predator"},
  616. {"Bus"},
  617. {"Rhino"},
  618. {"Barracks"},
  619. {"Hotknife"},
  620. {"Trailer 1"},
  621. {"Previon"},
  622. {"Coach"},
  623. {"Cabbie"},
  624. {"Stallion"},
  625. {"Rumpo"},
  626. {"RC Bandit"},
  627. {"Romero"},
  628. {"Packer"},
  629. {"Monster"},
  630. {"Admiral"},
  631. {"Squalo"},
  632. {"Seasparrow"},
  633. {"Pizzaboy"},
  634. {"Tram"},
  635. {"Trailer 2"},
  636. {"Turismo"},
  637. {"Speeder"},
  638. {"Reefer"},
  639. {"Tropic"},
  640. {"Flatbed"},
  641. {"Yankee"},
  642. {"Caddy"},
  643. {"Solair"},
  644. {"Berkley's RC Van"},
  645. {"Skimmer"},
  646. {"PCJ-600"},
  647. {"Faggio"},
  648. {"Freeway"},
  649. {"RC Baron"},
  650. {"RC Raider"},
  651. {"Glendale"},
  652. {"Oceanic"},
  653. {"Sanchez"},
  654. {"Sparrow"},
  655. {"Patriot"},
  656. {"Quad"},
  657. {"Coastguard"},
  658. {"Dinghy"},
  659. {"Hermes"},
  660. {"Sabre"},
  661. {"Rustler"},
  662. {"ZR-350"},
  663. {"Walton"},
  664. {"Regina"},
  665. {"Comet"},
  666. {"BMX"},
  667. {"Burrito"},
  668. {"Camper"},
  669. {"Marquis"},
  670. {"Baggage"},
  671. {"Dozer"},
  672. {"Maverick"},
  673. {"News Chopper"},
  674. {"Rancher"},
  675. {"FBI Rancher"},
  676. {"Virgo"},
  677. {"Greenwood"},
  678. {"Jetmax"},
  679. {"Hotring"},
  680. {"Sandking"},
  681. {"Blista Compact"},
  682. {"Police Maverick"},
  683. {"Boxville"},
  684. {"Benson"},
  685. {"Mesa"},
  686. {"RC Goblin"},
  687. {"Hotring Racer A"},
  688. {"Hotring Racer B"},
  689. {"Bloodring Banger"},
  690. {"Rancher"},
  691. {"Super GT"},
  692. {"Elegant"},
  693. {"Journey"},
  694. {"Bike"},
  695. {"Mountain Bike"},
  696. {"Beagle"},
  697. {"Cropdust"},
  698. {"Stunt"},
  699. {"Tanker"},
  700. {"Roadtrain"},
  701. {"Nebula"},
  702. {"Majestic"},
  703. {"Buccaneer"},
  704. {"Shamal"},
  705. {"Hydra"},
  706. {"FCR-900"},
  707. {"NRG-500"},
  708. {"HPV1000"},
  709. {"Cement Truck"},
  710. {"Tow Truck"},
  711. {"Fortune"},
  712. {"Cadrona"},
  713. {"FBI Truck"},
  714. {"Willard"},
  715. {"Forklift"},
  716. {"Tractor"},
  717. {"Combine"},
  718. {"Feltzer"},
  719. {"Remington"},
  720. {"Slamvan"},
  721. {"Blade"},
  722. {"Freight"},
  723. {"Streak"},
  724. {"Vortex"},
  725. {"Vincent"},
  726. {"Bullet"},
  727. {"Clover"},
  728. {"Sadler"},
  729. {"Firetruck LA"},
  730. {"Hustler"},
  731. {"Intruder"},
  732. {"Primo"},
  733. {"Cargobob"},
  734. {"Tampa"},
  735. {"Sunrise"},
  736. {"Merit"},
  737. {"Utility"},
  738. {"Nevada"},
  739. {"Yosemite"},
  740. {"Windsor"},
  741. {"Monster A"},
  742. {"Monster B"},
  743. {"Uranus"},
  744. {"Jester"},
  745. {"Sultan"},
  746. {"Stratum"},
  747. {"Elegy"},
  748. {"Raindance"},
  749. {"RC Tiger"},
  750. {"Flash"},
  751. {"Tahoma"},
  752. {"Savanna"},
  753. {"Bandito"},
  754. {"Freight Flat"},
  755. {"Streak Carriage"},
  756. {"Kart"},
  757. {"Mower"},
  758. {"Duneride"},
  759. {"Sweeper"},
  760. {"Broadway"},
  761. {"Tornado"},
  762. {"AT-400"},
  763. {"DFT-30"},
  764. {"Huntley"},
  765. {"Stafford"},
  766. {"BF-400"},
  767. {"Newsvan"},
  768. {"Tug"},
  769. {"Trailer 3"},
  770. {"Emperor"},
  771. {"Wayfarer"},
  772. {"Euros"},
  773. {"Hotdog"},
  774. {"Club"},
  775. {"Freight Carriage"},
  776. {"Trailer 3"},
  777. {"Andromada"},
  778. {"Dodo"},
  779. {"RC Cam"},
  780. {"Launch"},
  781. {"Police Car (LSPD)"},
  782. {"Police Car (SFPD)"},
  783. {"Police Car (LVPD)"},
  784. {"Police Ranger"},
  785. {"Picador"},
  786. {"S.W.A.T. Van"},
  787. {"Alpha"},
  788. {"Phoenix"},
  789. {"Glendale"},
  790. {"Sadler"},
  791. {"Luggage Trailer A"},
  792. {"Luggage Trailer B"},
  793. {"Stair Trailer"},
  794. {"Boxville"},
  795. {"Farm Plow"},
  796. {"Utility Trailer"}
  797. };
  798. // Environment settings TODO: THESE SHOULD ALL BE READ FROM A CONFIG FILE!
  799. static bool:scriptDebug = true; // Debug setting
  800. #define MODE_NAME "0.0a Build 11"
  801. #define SERVER_NAME "Bone County RPG"
  802. #define PG_HOST "127.0.0.1"
  803. #define PG_ROLE "rpfw-dev"
  804. #define PG_PASS "nJd&1k$0fs"
  805. #define PG_DB "rpfw-dev"
  806. #define PG_PORT 5432
  807. #define DISCORD_HOME_GUILD_ID "666077037470941184" // Emerald City Roleplay
  808. #define DISCORD_ECHO_CHANNEL_ID "677855051166777344" // #bcrp-echo
  809. //#define DISCORD_ECHO_CHANNEL_ID "666078187079598080" // #ecrp-echo
  810. #define DISCORD_MAIN_CHANNEL_ID "677855315898793984" // #bcrp
  811. //#define DISCORD_MAIN_CHANNEL_ID "667396220402270228" // #development
  812. #define DISCORD_ADMIN_ECHO_CHANNEL_ID "672841892169383936" // #admin-echo
  813. #define DISCORD_ADMIN_CHANNEL_ID "667396026058932236" // #admins
  814. #define DISCORD_MANAGEMENT_CHANNEL_ID "666091376240361492" // #management
  815. // Game-mode limits
  816. #define MAX_CHARACTERS_PER_USER 20 // Maximum of MAX_CHARACTERS_PER_USER_DIGITS digits (Due to SQL query string length)
  817. #define MAX_CHARACTERS_PER_USER_DIGITS 3
  818. // SQL plugin
  819. new SQL:sqlHandle;
  820. // discord-connector
  821. //static DCC_Guild:homeGuild; // Discord guild controlled by game community.
  822. static DCC_Channel:echoChannel; // Public echo channel.
  823. static DCC_Channel:mainChannel; // Channel for communirty notifications.
  824. static DCC_Channel:adminEchoChannel; // Admin echo channel.
  825. static DCC_Channel:adminChannel; // Channel for admin notifications.
  826. static DCC_Channel:managementChannel; // Channel for management notifications.
  827. DiscordEcho(const message[], messageLevel){ // Write to echo channels.
  828. switch(messageLevel) // Output facilities.
  829. {
  830. case ECHO_CHANNEL: { // Public echo message
  831. DiscordSendChannelMessage(echoChannel, message);
  832. DiscordSendChannelMessage(adminEchoChannel, message); // Also send to admin echo channel, so admin can see everything in one channel without needing to constantly switch. Also handy as log on conflicts/complaints.
  833. }
  834. case MAIN_CHANNEL: {DiscordSendChannelMessage(mainChannel, message);} // Public notification
  835. case ADMIN_ECHO_CHANNEL: {DiscordSendChannelMessage(adminEchoChannel, message);} // Admin echo message
  836. case ADMIN_CHANNEL: {DiscordSendChannelMessage(adminChannel, message);} // Admin notification
  837. case MANAGEMENT_CHANNEL: {DiscordSendChannelMessage(managementChannel, message);} // Management notification
  838. }
  839. return 0;
  840. }
  841. // Natives
  842. native WP_Hash(buffer[], len, const str[]); // https://forum.sa-mp.com/showthread.php?t=570945
  843. //native Float:loadavg(); // https://forum.sa-mp.com/showthread.php?t=260206 LINUX ONLY
  844. // Includes
  845. #include <a_samp> // https://sa-mp.com
  846. #include <sql> // https://github.com/udan11/samp-plugin-sql (Fastest player in town and only one supporting postgreSQL) | Examples: https://pastebin.com/67y2nq2n https://github.com/udan11/samp-plugin-sql/issues/10
  847. #include <sscanf2> // Newest version: https://github.com/maddinat0r/sscanf/releases | Better readme: https://github.com/Y-Less/sscanf
  848. #include <strlib> // https://github.com/oscar-broman/strlib
  849. #include <Pawn.Regex> // https://github.com/urShadow/Pawn.Regex
  850. #include <Pawn.CMD> // https://github.com/urShadow/Pawn.CMD (Fastest player in town)
  851. #include <gvar> // https://github.com/samp-incognito/samp-gvar-plugin
  852. #include <discord-connector> // https://github.com/maddinat0r/samp-discord-connector (Only player in town)
  853. #include <streamer> // https://github.com/samp-incognisto/samp-streamer-plugin
  854. /// Middle-ware
  855. // Logging
  856. logger(const log_level, const message[]){ // Write to logging facility
  857. // Do not log commands or debug when script debugging is turned off.
  858. if(scriptDebug == false){ // Debug is off
  859. if(log_level == LOGLEVEL_COMMAND || log_level == LOGLEVEL_DEBUG){ // Command or debug message
  860. return 0; // Stop and do not log
  861. }
  862. }
  863. // Messagelevel tag
  864. new human_readable_log_level[8 + 1];
  865. switch(log_level){ // Assign log level.
  866. case LOGLEVEL_CHAT: human_readable_log_level = "chat";
  867. case LOGLEVEL_COMMAND: human_readable_log_level = "command";
  868. case LOGLEVEL_DEBUG: human_readable_log_level = "debug";
  869. case LOGLEVEL_INFO: human_readable_log_level = "info";
  870. case LOGLEVEL_NOTICE: human_readable_log_level = "notice";
  871. case LOGLEVEL_WARNING: human_readable_log_level = "warning";
  872. case LOGLEVEL_ERROR: human_readable_log_level = "error";
  873. case LOGLEVEL_CRITICAL: human_readable_log_level = "critical";
  874. case LOGLEVEL_PANIC: human_readable_log_level = "panic";
  875. }
  876. printf("[%s] %s", human_readable_log_level, message); // Print to STDOUT.
  877. return 0;
  878. }
  879. /*// SQL plugin (BROKEN, look at it again after I have more then a week of experience)
  880. //forward sqlQuery(SQL:handle, query[]);
  881. //public sqlQuery(SQL:handle, query[]){
  882. sqlQuery(SQL:handle, query[]){
  883. //sql_wait(handle); // Wait for all queries to finish.
  884. new Result:result = sql_query(handle, query);
  885. if(sql_error(result)){printf("SQL error");} // Did not work during a test with a faulty statement.
  886. return result;
  887. }*/
  888. // discord-connector
  889. DiscordSendChannelMessage(DCC_Channel:channel, const message[]){
  890. if(scriptDebug){ // Log middle-ware event in debugging mode only
  891. new channel_name[100 + 1]; // Default value from tutorial
  892. DCC_GetChannelName(channel, channel_name);
  893. new logMessage[26 + 100 + 2000 + 1]; // Discord max message length = 2000
  894. format(logMessage, sizeof(logMessage), "Send to discord channel %s: %s", channel_name, message);
  895. logger(LOGLEVEL_DEBUG, logMessage); // Actually log the message
  896. }
  897. //DCC_SendChannelMessage(channel, message); // Call discord-connector DISABLE THIS TO STOP ALL OUTGOING DISCORD MESSAGES
  898. }
  899. /// Game-mode
  900. // Account functions
  901. forward changeName(playerid, const name[]);
  902. public changeName(playerid, const name[]){ // Check if name is valid and force change if needed.
  903. // Prevent regex error when comparing against null
  904. if(isempty(name)){ // No name entered
  905. ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "You must enter a name.\n\nExamples:\n Jo_Bo\n Dingle_P._J._Berry\n Jackson_DeForest_Kelley\n MaryJo_Ann_LaFluer", "Change", ""); // Force RP name.
  906. return 0;
  907. }
  908. // Check name
  909. new Regex:r = Regex_New("^[A-Z][a-z]{1,}([A-Z][a-z]{1,})?(_([A-Z][a-z]{1,}([A-Z][a-z]{1,})?|[A-Z]\\.(_[A-Z]\\.)?))?_[A-Z][a-z]{1,}([A-Z][a-z]{1,})?$"); // Regex name filter
  910. new isValidName = Regex_Check(name, r); // Validate name to filter
  911. Regex_Delete(r);
  912. if(!isValidName){ // Invalid role-play name
  913. ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "Please pick a realistic name, separate first and last name with an underscore.\n\nExamples:\n Jo_Bo\n Dingle_P._J._Berry\n Jackson_DeForest_Kelley\n MaryJo_Ann_LaFluer", "Change", ""); // Force RP name.
  914. }
  915. else { // Valid role-play name
  916. print("Valid name");
  917. // Check for name in use
  918. /*new escaped_name[MAX_PLAYER_NAME + 1]; // TODO should be more, to account for escape characters.
  919. sql_escape_string(sqlHandle, name, escaped_name, sizeof(escaped_name)); // Escape player name BROKEN argument type mismatch on argument 2, but name is a sting...*/
  920. new character_query[40 + MAX_PLAYER_NAME + 1], Result:character_result = sql_query(sqlHandle, character_query);
  921. format(character_query, sizeof(character_query), "SELECT id FROM character WHERE name = '%s'", name);
  922. if(sql_num_rows(character_result) > 0){ // Name taken
  923. ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "Name already taken. Please pick an original name.", "Change", ""); // Force RP name.
  924. }
  925. else{ // Name free
  926. // Notify all players
  927. new message[11 + 4 + MAX_PLAYER_NAME + 1];
  928. format(message, sizeof(message), "* [%i] %s joined.", playerid, getCharacterName(playerid));
  929. SendClientMessageToAll(COLOR_NOTICE, message); // Notify all players
  930. DiscordEcho(message, ECHO_CHANNEL); // Notify discord public echo
  931. new client_connect_username[MAX_PLAYER_NAME + 1], admin_message[38 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
  932. GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
  933. if(GetPlayerState(playerid) == PLAYER_STATE_NONE){ // Not spawned: character creation (Creating a character without registering)
  934. // Notify admins
  935. format(admin_message, sizeof(admin_message), "* [%i] %s temporary charcter, created by: %s", playerid, getCharacterName(playerid), client_connect_username);
  936. sendToAdmins(COLOR_NOTICE, admin_message);
  937. // Do nothing let continue to spawn, after spawn character will be saved to database.
  938. }
  939. else{ // Spawnedplayer: Creating permanent or renaming an existing permanent character
  940. // Notify admins
  941. format(admin_message, sizeof(admin_message), "* [%i] %s created by: %s", playerid, getCharacterName(playerid), client_connect_username);
  942. sendToAdmins(COLOR_NOTICE, admin_message);
  943. // Send to skin selection
  944. ForceClassSelection(playerid);
  945. TogglePlayerSpectating(playerid, true);
  946. TogglePlayerSpectating(playerid, false);
  947. }
  948. // Change name (No way yet to change name ingame)
  949. /*if(GetGVarInt("userlevel", playerid) > 1){ // Registered player.
  950. // Get username
  951. new username[MAX_PLAYER_NAME + 1], message[75 + MAX_PLAYER_NAME + 1];
  952. GetGVarString("username", username, sizeof(username), playerid);
  953. // Update or create character name in database
  954. new callback[1];
  955. new Result:result;
  956. new query[51 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
  957. format(query, sizeof(query), "UPDATE \"user\"(name) VALUES('%s') WHERE username == '%s'", name, username);
  958. sql_wait(sqlHandle); // Wait for other queries to finish
  959. result = sql_query(sqlHandle, query, callback = "", "r");
  960. // Inform user
  961. format(message, sizeof(message), "SERVER: Your username remains unchanged, next time connect as: %s", client_connect_username);
  962. SendClientMessage(playerid, COLOR_WHITE, message);
  963. }*/
  964. SetPlayerName(playerid, name); // Change name in-game
  965. }
  966. }
  967. return 0;
  968. }
  969. forward register(playerid);
  970. public register(playerid){ // Register player in database
  971. if(GetPlayerState(playerid) == PLAYER_STATE_NONE){ // Not spawned
  972. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "ERROR: You need to have spawned to register.");
  973. }
  974. else{ // Spawned player
  975. if(GetGVarInt("userlevel", playerid) != UNREGISTERED_PLAYER){ // Registered player.
  976. new message[35 + MAX_PLAYER_NAME + 1];
  977. format(message, sizeof(message), "ERROR: You are already registered"); //, %s.",
  978. SendClientMessage(playerid, COLOR_WHITE, message);
  979. }
  980. else{ // Unregistered player.
  981. ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Password", "Please pick a strong and safe password, that you are able to remember.", "Continue", "Cancel"); // Password prompt
  982. }
  983. }
  984. }
  985. forward createCharacterRecord(playerid, id);
  986. public createCharacterRecord(playerid, id){
  987. new character_query[94 + MAX_SQL_INTEGER + MAX_PLAYER_NAME + 3 + 1];
  988. format(character_query, sizeof(character_query), "INSERT INTO character(user_id, name, skin_id) VALUES(%i, '%s', %i)", id, getPlayerName(playerid), GetPlayerSkin(playerid));
  989. sql_query(sqlHandle, character_query);
  990. }
  991. forward authenticate(playerid);
  992. public authenticate(playerid){
  993. ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Sign in", "Enter your password to log on", "Log in", "Cancel"); // Show password confirmation dialog
  994. }
  995. forward characterSelection(playerid);
  996. public characterSelection(playerid){
  997. if(GetGVarInt("userlevel", playerid) < REGISTERED_PLAYER){ // Unregistered player (Or worse?)
  998. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Register first with: /my account register");
  999. }
  1000. else{ // Registered player
  1001. // If spawned, save current character
  1002. if(GetPlayerState(playerid) != PLAYER_STATE_NONE){
  1003. savePlayerState(playerid);
  1004. }
  1005. new id = getUserID(playerid);
  1006. new character_query[75 + MAX_SQL_INTEGER + MAX_CHARACTERS_PER_USER_DIGITS + 1];
  1007. format(character_query, sizeof(character_query), "SELECT id, name FROM character WHERE user_id = %i LIMIT %i", id, MAX_CHARACTERS_PER_USER);
  1008. new Result:character_result = sql_query(sqlHandle, character_query);
  1009. new character_string[(MAX_PLAYER_NAME * MAX_CHARACTERS_PER_USER) + 1], character_array[MAX_CHARACTERS_PER_USER + 1];
  1010. for(new i = 0; i < sql_num_rows(character_result); i++){
  1011. new name[MAX_PLAYER_NAME + 1];
  1012. sql_get_field_assoc_ex(character_result, i, "name", name, sizeof(name));
  1013. format(character_string, sizeof(character_string), "%s%s\n", character_string, name);
  1014. character_array[i] = sql_get_field_assoc_int_ex(character_result, i, "id");
  1015. }
  1016. new character_array_string[MAX_CHARACTERS_PER_USER * MAX_SQL_INTEGER + 1];
  1017. strfrombin(character_array_string, character_array); // Convert array to string for use with GVar
  1018. SetGVarString("character_array_string", character_array_string, playerid);
  1019. ShowPlayerDialog(playerid, DIALOG_CHARACTERS, DIALOG_STYLE_LIST, "Characters", character_string, "Spawn", "New");
  1020. }
  1021. }
  1022. forward savePlayerState(playerid);
  1023. public savePlayerState(playerid){
  1024. new escaped_playername[MAX_PLAYER_NAME + 1], character_query[156 + MAX_SQL_INTEGER + (MAX_SQL_FLOAT * 3) + MAX_SQL_INTEGER + (MAX_SQL_FLOAT * 4) + (MAX_SQL_INTEGER * 2) + 1]; // Should be longer to allow for escaped characters
  1025. sql_escape_string(sqlHandle, getPlayerName(playerid), escaped_playername, sizeof(escaped_playername)); // Escape player name
  1026. new Float:health, Float:armour, Float:x, Float:y, Float:z, Float:angle;
  1027. // Unrealiable TODO change to gvars
  1028. GetPlayerHealth(playerid, health);
  1029. GetPlayerArmour(playerid, armour);
  1030. new world_id, interior_id;
  1031. getPlayerLocation(playerid, x, y, z, angle, world_id, interior_id);
  1032. format(character_query, sizeof(character_query), "UPDATE character SET (cash, health, armour, jailed, pos_x, pos_y, pos_z, rotation, world_id, interior_id) = (%i, '%f', '%f', %i, '%f', '%f', '%f', '%f', %i, %i) WHERE name = '%s'", GetPlayerMoney(playerid), health, armour, 0, x, y, z, angle, world_id, interior_id, escaped_playername);
  1033. sql_query(sqlHandle, character_query);
  1034. }
  1035. forward kickPlayerDelay(playerid);
  1036. public kickPlayerDelay(playerid){
  1037. Kick(playerid);
  1038. }
  1039. forward kickPlayer(playerid, kickerid, const reason[], banned);
  1040. public kickPlayer(playerid, kickerid, const reason[], banned){ // Kick a player
  1041. // Issuer of kick
  1042. new kickername[MAX_PLAYER_NAME + 1], kicker_id[MAX_SQL_INTEGER + 1];
  1043. if(kickerid == -1){ // Not kicked by in-game player
  1044. kickername = "SERVER";
  1045. kicker_id = "NULL";
  1046. }
  1047. else{ // Kicked by in-game player
  1048. kickername = getPlayerName(playerid);
  1049. kicker_id = "%s", getUserID(kickerid);
  1050. }
  1051. strreplace(kickername, "_", " ");
  1052. // Action
  1053. new action[16 + MAX_SQL_INTEGER + 1];
  1054. if(banned){
  1055. if(banned < 1){ // Permanent ban
  1056. action = "banned permanently";
  1057. }
  1058. else{ // Temporary ban
  1059. format(action, sizeof(action), "banned for %i days", banned);
  1060. }
  1061. }
  1062. else{
  1063. action = "kicked";
  1064. }
  1065. // Notify all players
  1066. new playername[MAX_PLAYER_NAME + 1], message[16 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 16 + MAX_SQL_REASON + 1], admin_message[23 + 4 + MAX_PLAYER_NAME + 16 + MAX_PLAYER_NAME + MAX_SQL_REASON + 1]; // Max samp chat message length 128 - 8 for "/kick ? ".
  1067. GetPlayerName(playerid, playername, sizeof(playername));
  1068. format(message, sizeof(message), "* [%i] %s %s, reason: %s", playerid, getCharacterName(playerid), action, reason);
  1069. format(admin_message, sizeof(admin_message), "* [%i] %s kicked %s, reason: %s", kickerid, kickername, getCharacterName(playerid), action, reason);
  1070. logger(LOGLEVEL_INFO, message); // Log event
  1071. SendClientMessageToAll(COLOR_NOTICE, message);
  1072. DiscordEcho(message, ECHO_CHANNEL);
  1073. sendToAdmins(COLOR_NOTICE, admin_message);
  1074. // Inform player (Redundant, but some people are blind or stupid)
  1075. new player_message[30 + 6 + MAX_PLAYER_NAME + MAX_SQL_REASON + 1]; // Max samp chat message length 128 - 8 for "/kick ? ".
  1076. format(player_message, sizeof(player_message), "SERVER: You have been %s, reason: %s", action, reason);
  1077. SendClientMessage(playerid, COLOR_ERROR, player_message); // Notify player
  1078. if(banned){
  1079. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "You may appeal this ban via the forum or Discord.");
  1080. }
  1081. new ip_id = getIPID(playerid);
  1082. // Crearte IP kick record
  1083. new ip_query[61 + 4 + MAX_SQL_REASON + 4 + 1];
  1084. format(ip_query, sizeof(ip_query), "INSERT INTO ip_kick(ip_id, reason, kicker_id) VALUES(%i, '%s', %s)", ip_id, reason, kicker_id);
  1085. sql_query(sqlHandle, ip_query);
  1086. // Get IP kick record
  1087. new ip_id_query[64 + 4 + MAX_SQL_REASON + 4 + 1];
  1088. format(ip_id_query, sizeof(ip_id_query), "SELECT id FROM ip_kick WHERE ip_id = %i ORDER BY id DESC LIMIT 1", ip_id);
  1089. new Result:ip_id_result = sql_query(sqlHandle, ip_id_query);
  1090. new ip_kick_id = sql_get_field_assoc_int(Result:ip_id_result, "id");
  1091. // User kick record
  1092. printf("Userlevel: %i", GetGVarInt("userlevel", playerid));
  1093. if(GetGVarInt("userlevel", playerid) > UNREGISTERED_PLAYER){ // Not logged in to a user account
  1094. new user_query[79 + 4 + MAX_SQL_REASON + 4 + 1];
  1095. format(user_query, sizeof(user_query), "INSERT INTO user_kick(user_id, reason, kicker_id, ip_kick_id) VALUES(%i, '%s', %s, %i)", getUserID(playerid), reason, kicker_id, ip_kick_id);
  1096. sql_query(sqlHandle, user_query);
  1097. }
  1098. SetTimerEx("kickPlayerDelay", 50, false, "i", playerid); // Give the message 50 milliseconds to reach the player before kicking.
  1099. }
  1100. banExpiration(days);
  1101. banExpiration(days){
  1102. if(days < 1){ // Permanent ban
  1103. new foo[MAX_SQL_TIMESTAMP + 1] = "0";
  1104. return foo;
  1105. }
  1106. else{ // Temporary ban
  1107. new year, month, day, hour, minute, second, expires[MAX_SQL_TIMESTAMP + 1];
  1108. getdate(year, month, day);
  1109. gettime(hour, minute, second);
  1110. day = day + days;
  1111. format(expires, sizeof(expires), "%i-%i-%i %i:%i:%i", year, month, day, hour, minute, second);
  1112. return expires;
  1113. //return year, month, day, hour, minute, second;
  1114. //return 0;
  1115. }
  1116. }
  1117. forward banPlayer(playerid, bannerid, const reason[], days);
  1118. public banPlayer(playerid, bannerid, const reason[], days){ // Ban & kick a player
  1119. new ip_id = getIPID(playerid);
  1120. // Create IP ban record
  1121. new banner_id, ip_query[72 + MAX_SQL_INTEGER + MAX_SQL_TIMESTAMP + MAX_SQL_REASON + MAX_SQL_INTEGER + 1];
  1122. if(bannerid < 0){ // Not banned by in-game player
  1123. format(ip_query, sizeof(ip_query), "INSERT INTO ip_ban(ip_id, expires, reason) VALUES(%i, '%s', '%s')", ip_id, banExpiration(days), reason);
  1124. }
  1125. else{ // Banned by in-game player
  1126. banner_id = getUserID(bannerid);
  1127. format(ip_query, sizeof(ip_query), "INSERT INTO ip_ban(ip_id, expires, reason, banner_id) VALUES(%i, '%s', '%s', %i)", ip_id, banExpiration(days), reason, banner_id);
  1128. }
  1129. sql_query(sqlHandle, ip_query);
  1130. // Get IP ban record ID
  1131. new ban_id_query[61 + MAX_PLAYER_NAME + 1];
  1132. format(ban_id_query, sizeof(ban_id_query), "SELECT id FROM ip_ban WHERE ip_id = %i ORDER BY id DESC LIMIT 1", ip_id);
  1133. new Result:ban_id_result = sql_query(sqlHandle, ban_id_query);
  1134. new ip_ban_id = sql_get_field_assoc_int(ban_id_result, "id");
  1135. // User ban record (As banned players get only kicked, noneed to check for active ban)
  1136. if(GetGVarInt("userlevel", playerid) > 1){ // Registered player
  1137. new user_query[97 + MAX_SQL_INTEGER + MAX_SQL_TIMESTAMP + MAX_SQL_REASON + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  1138. format(user_query, sizeof(user_query), "INSERT INTO user_ban(user_id, expires, reason, banner_id, ip_ban_id) VALUES(%i, %s, %s, %i, %i) WHERE id = %i", ip_id, banExpiration(days), reason, banner_id, ip_ban_id);
  1139. sql_query(sqlHandle, user_query);
  1140. }
  1141. // Kick player
  1142. kickPlayer(playerid, bannerid, reason, days);
  1143. }
  1144. // Database functions
  1145. forward getIPID(playerid);
  1146. public getIPID(playerid){
  1147. new player_ip[MAX_SQL_IP + 1], query[37 + MAX_SQL_IP + 1]; // Create varaibles
  1148. GetPlayerIp(playerid, player_ip, sizeof(player_ip)); // Polulate player_ip variable
  1149. format(query, sizeof(query), "SELECT id FROM ip WHERE address = '%s'", player_ip); // Format query string
  1150. new Result:result = sql_query(sqlHandle, query); // Execute query
  1151. return sql_get_field_assoc_int(result, "id"); // Get id from result
  1152. }
  1153. forward getUserID(playerid);
  1154. public getUserID(playerid){
  1155. // SQL escape username
  1156. new client_connect_username[MAX_PLAYER_NAME + 1], escaped_username[MAX_PLAYER_NAME + 1]; // TODO escaped_username should be longer to account for escape characters (Also increate database column size!)
  1157. GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
  1158. sql_escape_string(sqlHandle, client_connect_username, escaped_username, sizeof(escaped_username)); // Escape player name
  1159. // Get user ID
  1160. new userid_query[47 + MAX_PLAYER_NAME + 1];
  1161. format(userid_query, sizeof(userid_query), "SELECT id FROM \"user\" WHERE name = '%s'", escaped_username);
  1162. new Result:result = sql_query(sqlHandle, userid_query);
  1163. return sql_get_field_assoc_int(result, "id");
  1164. }
  1165. // Player functions
  1166. forward deleteAllGVars(playerid);
  1167. public deleteAllGVars(playerid){ // Delete GVars as per https://forum.sa-mp.com/showthread.php?t=151076
  1168. DeleteGVar("client_connect_username", playerid); // From OnPlayerConnect()
  1169. DeleteGVar("userlevel", playerid); // From OnPlayerConnect()
  1170. DeleteGVar("hash", playerid); // From DIALOG_REGISTER
  1171. DeleteGVar("character_array_string", playerid); // From OnDialogResponse()
  1172. DeleteGVar("authentication_count", playerid); // From DIALOG_LOGIN
  1173. DeleteGVar("character_id", playerid); // From DIALOG_CHARACTERS
  1174. DeleteGVar("chatmode", playerid); // From cmd:my()
  1175. DeleteGVar("disable_pickups", playerid); // From OnPlayerPickUpDynamicPickup()
  1176. DeleteGVar("goto_target", playerid); // From cmd:my() & cmd:p()
  1177. DeleteGVar("job", playerid); // From OnDialogResponse()
  1178. }
  1179. //getPlayerName(playerid);
  1180. getPlayerName(playerid){
  1181. // new playername[MAX_PLAYER_NAME + 1];
  1182. new const playername[MAX_PLAYER_NAME + 1];
  1183. GetPlayerName(playerid, playername, sizeof(playername));
  1184. // new output[MAX_PLAYER_NAME + 1];
  1185. // strfromliteral(output, playername);
  1186. return playername;
  1187. }
  1188. forward gotoCallback(Float:x, Float:y, Float:z, world, interior, Float:angle, const name[], playerid = -1);
  1189. stock gotoCallback(Float:x, Float:y, Float:z, world, interior, Float:angle, const name[], playerid = -1){
  1190. if(playerid== -1){
  1191. playerid = GetGVarInt("goto_target", playerid);
  1192. DeleteGVar("goto_target", playerid);
  1193. }
  1194. teleportPlayer(playerid, x, y, z, angle, world, interior);
  1195. // Inform admins
  1196. new admin_message[21 + 4 + MAX_PLAYER_NAME + 5 + 4 + MAX_PLAYER_NAME + 1 + 1]; // 5 + 4 + MAX_PLAYER_NAME + 1 = name
  1197. format(admin_message, sizeof(admin_message), "* [%i] %s teleported to: %s", playerid, getCharacterName(playerid), name);
  1198. sendToAdmins(COLOR_NOTICE, admin_message);
  1199. }
  1200. forward setPlayerSkin(playerid, skinid);
  1201. public setPlayerSkin(playerid, skinid){
  1202. new
  1203. Float:tmpPos[4],
  1204. vehicleid = GetPlayerVehicleID(playerid),
  1205. seatid = GetPlayerVehicleSeat(playerid);
  1206. GetPlayerPos(playerid, tmpPos[0], tmpPos[1], tmpPos[2]);
  1207. GetPlayerFacingAngle(playerid, tmpPos[3]);
  1208. if(skinid < 0 || skinid > 299) return 0;
  1209. if(GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_DUCK)
  1210. {
  1211. SetPlayerPos(playerid, tmpPos[0], tmpPos[1], tmpPos[2]);
  1212. SetPlayerFacingAngle(playerid, tmpPos[3]);
  1213. TogglePlayerControllable(playerid, 1); // preventing any freeze - optional
  1214. return SetPlayerSkin(playerid, skinid);
  1215. }
  1216. else if(IsPlayerInAnyVehicle(playerid))
  1217. {
  1218. new
  1219. tmp;
  1220. RemovePlayerFromVehicle(playerid);
  1221. SetPlayerPos(playerid, tmpPos[0], tmpPos[1], tmpPos[2]);
  1222. SetPlayerFacingAngle(playerid, tmpPos[3]);
  1223. TogglePlayerControllable(playerid, 1); // preventing any freeze - important - because of doing animations of exiting vehicle
  1224. tmp = SetPlayerSkin(playerid, skinid);
  1225. PutPlayerInVehicle(playerid, vehicleid, (seatid == 128) ? 0 : seatid);
  1226. return tmp;
  1227. }
  1228. else
  1229. {
  1230. return SetPlayerSkin(playerid, skinid);
  1231. }
  1232. }
  1233. forward getPlayerLocation(playerid, &Float:x, &Float:y, &Float:z, &Float:angle, &world, &interior);
  1234. public getPlayerLocation(playerid, &Float:x, &Float:y, &Float:z, &Float:angle, &world, &interior){
  1235. GetPlayerPos(playerid, x, y, z);
  1236. GetPlayerFacingAngle(playerid, angle);
  1237. world = GetPlayerVirtualWorld(playerid);
  1238. interior = GetPlayerInterior(playerid);
  1239. printf("Angle: %f", angle);
  1240. }
  1241. forward teleportPlayer(playerid, Float:x, Float:y, Float:z, Float:angle, world, interior);
  1242. public teleportPlayer(playerid, Float:x, Float:y, Float:z, Float:angle, world, interior){
  1243. if(world == -1){
  1244. world = GetPlayerVirtualWorld(playerid);
  1245. }
  1246. SetPlayerPos(playerid, x, y, z);
  1247. SetPlayerVirtualWorld(playerid, world);
  1248. SetPlayerInterior(playerid, interior);
  1249. SetPlayerFacingAngle(playerid, angle);
  1250. }
  1251. //forward setPlayerJob(playerid, job, skin_id = 0, color = COLOR_WHITE);
  1252. stock setPlayerJob(playerid, job, skin_id = 0, color = COLOR_WHITE){
  1253. switch(job){
  1254. case JOB_NONE:{
  1255. // Get skin from character record
  1256. new character_query[42 + MAX_SQL_INTEGER + 1];
  1257. format(character_query, sizeof(character_query), "SELECT skin_id FROM character WHERE id = %i", GetGVarInt("character_id", playerid));
  1258. new Result:id_result = sql_query(sqlHandle, character_query);
  1259. skin_id = sql_get_field_assoc_int(id_result, "skin_id");
  1260. color = COLOR_WHITE;
  1261. ResetPlayerWeapons(playerid);
  1262. // TODO: get weaponskill fromddatabase and set it to player.
  1263. // TODO: Set player weapons from database
  1264. }
  1265. case JOB_POLICE:{
  1266. SetPlayerSkillLevel(playerid, WEAPONSKILL_PISTOL, 1);
  1267. GivePlayerWeapon(playerid, 3, 1); // Baton
  1268. GivePlayerWeapon(playerid, 17, 10); // Teargas
  1269. GivePlayerWeapon(playerid, 22, 170); // 10 clips and a 9mm
  1270. }
  1271. // case JOB_MEDIC:
  1272. case JOB_FIRE:{
  1273. GivePlayerWeapon(playerid, 42, 1); // Fire extinguisher
  1274. }
  1275. case JOB_SHERIFF:{
  1276. SetPlayerSkillLevel(playerid, WEAPONSKILL_PISTOL, 1);
  1277. GivePlayerWeapon(playerid, 3, 1); // Baton
  1278. GivePlayerWeapon(playerid, 17, 10); // Teargas
  1279. GivePlayerWeapon(playerid, 22, 170); // 10 clips and a 9mm
  1280. }
  1281. case JOB_FBI:{
  1282. GivePlayerWeapon(playerid, 42, 1); // Fire extinguisher
  1283. }
  1284. case JOB_DMV:{
  1285. GivePlayerWeapon(playerid, 17, 10); // Teargas
  1286. }
  1287. case JOB_NEWS:{
  1288. GivePlayerWeapon(playerid, 43, 1); // Camera
  1289. }
  1290. }
  1291. printf("setPlayerSkin(%i, %i);", playerid, skin_id);
  1292. setPlayerSkin(playerid, skin_id);
  1293. SetGVarInt("job", job, playerid);
  1294. SetPlayerColor(playerid, color);
  1295. }
  1296. // Chat functions
  1297. //forward getCharacterName(playerid);
  1298. stock getCharacterName(playerid){ // Convert name from player name
  1299. new playername[MAX_PLAYER_NAME + 1];
  1300. GetPlayerName(playerid, playername, sizeof(playername));
  1301. strreplace(playername, "_", " ");
  1302. return playername;
  1303. }
  1304. forward sendToChat(playerid, target, text[128 + 1], receiver_id, DCC_User:author);
  1305. public sendToChat(playerid, target, text[128 + 1], receiver_id, DCC_User:author){
  1306. strtrim(text); // Trim edge whitespaces
  1307. if(isempty(text)){
  1308. return 0; // Fail if text is empty
  1309. }
  1310. new playername[MAX_PLAYER_NAME + 1];
  1311. if(playerid < 0){
  1312. DCC_GetUserName(author, playername, sizeof(playername));
  1313. } // Discord messagge
  1314. else{playername = getCharacterName(playerid);}
  1315. new chat_format, chat_color, chat_range, chat_userlevel, chat_character[1 + 1], chat_name[13 + 1], discord_channel;
  1316. switch(target){
  1317. case CHAT_WHISPER:{
  1318. chat_format = 2;
  1319. chat_range = 3;
  1320. chat_name = "whispers";
  1321. chat_color = COLOR_COMMAND_OUTPUT;
  1322. discord_channel = ADMIN_ECHO_CHANNEL;
  1323. }
  1324. case CHAT_LOW:{
  1325. chat_format = 2;
  1326. chat_range = 10;
  1327. chat_name = "speaks softly";
  1328. chat_color = COLOR_COMMAND_OUTPUT;
  1329. discord_channel = ADMIN_ECHO_CHANNEL;
  1330. }
  1331. case CHAT_LOCAL:{
  1332. chat_format = 1;
  1333. chat_range = 20;
  1334. chat_color = COLOR_COMMAND_OUTPUT;
  1335. discord_channel = ADMIN_ECHO_CHANNEL;
  1336. }
  1337. case CHAT_SHOUT:{
  1338. chat_format = 2;
  1339. chat_range = 50;
  1340. chat_name = "shouts";
  1341. chat_color = COLOR_COMMAND_OUTPUT;
  1342. discord_channel = ADMIN_ECHO_CHANNEL;
  1343. }
  1344. case CHAT_ACTION:{
  1345. chat_format = 0;
  1346. chat_range = 20;
  1347. chat_color = COLOR_COMMAND_OUTPUT;
  1348. discord_channel = ADMIN_ECHO_CHANNEL;
  1349. }
  1350. case CHAT_OC:{
  1351. chat_format = 3;
  1352. chat_range = 20;
  1353. chat_character = "'";
  1354. chat_name = "OOC";
  1355. chat_color = COLOR_COMMAND_OUTPUT;
  1356. discord_channel = ADMIN_ECHO_CHANNEL;
  1357. }
  1358. case CHAT_GLOBAL:{
  1359. chat_format = 3;
  1360. chat_character = "`";
  1361. chat_name = "Global";
  1362. chat_color = COLOR_COMMAND_OUTPUT;
  1363. discord_channel = ECHO_CHANNEL;
  1364. }
  1365. case CHAT_GANG:{
  1366. chat_format = 3;
  1367. chat_character = "~";
  1368. chat_name = "Gang";
  1369. chat_color = COLOR_CREW_CHAT;
  1370. // TODO: Output to gang Discord channel
  1371. discord_channel = ADMIN_ECHO_CHANNEL;
  1372. }
  1373. case CHAT_GANG_OC:{
  1374. chat_format = 3;
  1375. chat_character = "#";
  1376. chat_name = "Gang OC";
  1377. chat_color = COLOR_CREW_CHAT;
  1378. // TODO: Output to gang Discord channel
  1379. discord_channel = ADMIN_ECHO_CHANNEL;
  1380. }
  1381. case CHAT_FACTION:{
  1382. chat_format = 3;
  1383. chat_character = "!";
  1384. chat_name = "Faction";
  1385. chat_color = COLOR_CREW_CHAT;
  1386. // TODO: Output to faction Discord channel
  1387. discord_channel = ADMIN_ECHO_CHANNEL;
  1388. }
  1389. case CHAT_FACTION_OC:{
  1390. chat_format = 3;
  1391. chat_character = "$";
  1392. chat_name = "Faction OC";
  1393. chat_color = COLOR_CREW_CHAT;
  1394. // TODO: Output to faction Discord channel
  1395. discord_channel = ADMIN_ECHO_CHANNEL;
  1396. }
  1397. case CHAT_CREW:{
  1398. chat_format = 3;
  1399. chat_character = "@";
  1400. chat_name = "Crew";
  1401. chat_color = COLOR_CREW_CHAT;
  1402. chat_userlevel = MODERATOR_CREW;
  1403. discord_channel = ADMIN_ECHO_CHANNEL;
  1404. }
  1405. case CHAT_ADMIN:{
  1406. chat_format = 3;
  1407. chat_character = "%";
  1408. chat_name = "Admin";
  1409. chat_color = COLOR_ADMIN_CHAT;
  1410. chat_userlevel = ADMIN_CREW;
  1411. discord_channel = ADMIN_ECHO_CHANNEL;
  1412. }
  1413. case CHAT_MANAGEMENT:{
  1414. chat_format = 3;
  1415. chat_character = "&";
  1416. chat_name = "Management";
  1417. chat_color = COLOR_ADMIN_CHAT;
  1418. chat_userlevel = MANAGEMENT_CREW;
  1419. discord_channel = MANAGEMENT_CHANNEL;
  1420. }
  1421. case CHAT_VIP:{
  1422. chat_format = 3;
  1423. chat_character = "^";
  1424. chat_name = "VIP";
  1425. chat_color = COLOR_VIP_CHAT;
  1426. chat_userlevel = VIP_PLAYER;
  1427. discord_channel = ADMIN_ECHO_CHANNEL;
  1428. //TODO: Add VIP discord channel.
  1429. }
  1430. case CHAT_UNDERCOVER:{
  1431. chat_format = -1;
  1432. chat_character = "*";
  1433. chat_color = COLOR_COMMAND_OUTPUT;
  1434. chat_userlevel = ADMIN_CREW;
  1435. discord_channel = ECHO_CHANNEL;
  1436. }
  1437. case CHAT_PM:{
  1438. chat_format = 3;
  1439. chat_character = ">";
  1440. chat_name = "PM";
  1441. chat_color = COLOR_PM_CHAT;
  1442. discord_channel = ADMIN_ECHO_CHANNEL;
  1443. }
  1444. case CHAT_CALL:{
  1445. chat_format = 3;
  1446. chat_character = "+";
  1447. chat_name = "Call";
  1448. chat_color = COLOR_PM_CHAT;
  1449. discord_channel = ADMIN_ECHO_CHANNEL;
  1450. }
  1451. case CHAT_SMS:{
  1452. chat_format = 3;
  1453. chat_character = "-";
  1454. chat_name = "SMS";
  1455. chat_color = COLOR_PM_CHAT;
  1456. discord_channel = ADMIN_ECHO_CHANNEL;
  1457. }
  1458. case CHAT_RADIO:{
  1459. chat_format = 3;
  1460. chat_character = "=";
  1461. chat_name = "Radio";
  1462. chat_color = COLOR_PM_CHAT;
  1463. discord_channel = ADMIN_ECHO_CHANNEL;
  1464. }
  1465. }
  1466. // Format chat message
  1467. new message[9 + sizeof(chat_character) + (6 * 8) + sizeof(chat_name) + 4 + MAX_PLAYER_NAME + 128 + 1];
  1468. new discord_message[23 + sizeof(chat_character) + sizeof(chat_name) + sizeof(playerid) + MAX_PLAYER_NAME + 128 + 1];
  1469. switch(chat_format){
  1470. case -1:{
  1471. format(message, sizeof(message), "%s %s", chat_character, text);
  1472. format(discord_message, sizeof(discord_message), "```css\n%s %s\n```", chat_character, text);
  1473. }
  1474. case 0:{
  1475. format(message, sizeof(message), EMBED_COLOR_GREY"[{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s{%06x} %s", GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_color >>> 8, text);
  1476. format(discord_message, sizeof(discord_message), "```css\n[%i] %s %s\n```", playerid, playername, text);
  1477. }
  1478. case 1:{
  1479. format(message, sizeof(message), EMBED_COLOR_GREY"[{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s"EMBED_COLOR_GREY":{%06x} %s", GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_color >>> 8, text);
  1480. format(discord_message, sizeof(discord_message), "```css\n[%i] %s: %s\n```", playerid, playername, text);
  1481. }
  1482. case 2:{
  1483. format(message, sizeof(message), EMBED_COLOR_GREY"[{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s %s"EMBED_COLOR_GREY":{%06x} %s", GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_name, chat_color >>> 8, text);
  1484. format(discord_message, sizeof(discord_message), "```css\n[%i] %s %s: %s\n```", playerid, playername, chat_name, text);
  1485. }
  1486. case 3:{
  1487. format(message, sizeof(message), "%s "EMBED_COLOR_GREY"({%06x}%s"EMBED_COLOR_GREY") [{%06x}%i"EMBED_COLOR_GREY"] {%06x}%s"EMBED_COLOR_GREY":{%06x} %s", chat_character, chat_color >>> 8, chat_name, GetPlayerColor(playerid) >>> 8, playerid, GetPlayerColor(playerid) >>> 8, playername, chat_color >>> 8, text);
  1488. format(discord_message, sizeof(discord_message), "```css\n%s (%s) [%i] %s: %s\n```", chat_character, chat_name, playerid, playername, text);
  1489. }// Good discord tag options for color effects: yaml, css, moon, elixir, haxe, groovy, brainfuck, accesslog,inform7, c,
  1490. }
  1491. // Authorisation
  1492. if(chat_userlevel && chat_userlevel > GetGVarInt("userlevel", playerid)){ // User not privilged to read chat
  1493. if(target == CHAT_CREW){ // Show the user the message was sent to crew chat.
  1494. SendClientMessage(playerid, chat_color, message);
  1495. }
  1496. else{
  1497. SendClientMessage(playerid, COLOR_CREW_CHAT, "ERROR: You are not authorized to speak in this chat.");
  1498. return 0; // Fail to send the message
  1499. }
  1500. }
  1501. // Send TODO: Add checks for muted.
  1502. if(chat_range){ // Ranged chats
  1503. logger(LOGLEVEL_CHAT, message); // Log event
  1504. // Show message to players in range
  1505. new Float:x, Float:y, Float:z;
  1506. GetPlayerPos(playerid, x, y, z);
  1507. for(new recipient_id, a = GetPlayerPoolSize(); recipient_id < a; recipient_id++){
  1508. if(IsPlayerConnected(receiver_id)){
  1509. new Float:distance = GetPlayerDistanceFromPoint(recipient_id, x, y, z);
  1510. if(distance <= chat_range){ // Player nearby
  1511. sendClientMultiMessage(recipient_id, chat_color, message, Bool:false);
  1512. }
  1513. }
  1514. }
  1515. DiscordEcho(discord_message, discord_channel);
  1516. }
  1517. else{ // Global chats
  1518. if(target == CHAT_GLOBAL){ // Public chat
  1519. logger(LOGLEVEL_CHAT, message); // Log event
  1520. sendClientMultiMessage(0, chat_color, message, Bool:true);
  1521. DiscordEcho(discord_message, discord_channel);
  1522. }
  1523. else if(target == CHAT_GANG || target == CHAT_GANG_OC || target == CHAT_FACTION || target == CHAT_FACTION_OC || target == CHAT_CALL || target == CHAT_SMS || target == CHAT_RADIO ){ // Entity chat
  1524. // TODO
  1525. // TODO sendToAdmins();
  1526. // TODO send to specific discord channel
  1527. SendClientMessage(playerid, chat_color, "You are not a member of the required entity.");
  1528. }
  1529. else if(target == CHAT_PM){
  1530. new output[sizeof(message)];
  1531. strdel(message, 0, 1);
  1532. format(output, sizeof(output), "<%s", message);
  1533. sendClientMultiMessage(receiver_id, chat_color, output, Bool:false);
  1534. new receipt[12 + 1 + sizeof(chat_name) + 4 + MAX_PLAYER_NAME + 128 + 1];
  1535. format(receipt, sizeof(receipt), "%s (%s) to [%i] %s: %s", chat_character, chat_name, receiver_id, playername, text);
  1536. sendClientMultiMessage(playerid, chat_color, receipt, Bool:false);
  1537. new admin_message[15 + 1 + sizeof(chat_name) + 4 + MAX_PLAYER_NAME + 4 + 128 + 1];
  1538. format(admin_message, sizeof(admin_message), "%s (%s) [%i] %s to [%i]: %s", chat_character, chat_name, playerid, playername, receiver_id, text);
  1539. logger(LOGLEVEL_CHAT, admin_message); // Log event
  1540. sendToAdmins(chat_color, admin_message);
  1541. }
  1542. else{ // Chat with privileged users
  1543. for(new recipient_id, a = GetPlayerPoolSize(); recipient_id < a; recipient_id++){
  1544. if(IsPlayerConnected(recipient_id)){
  1545. if(GetGVarInt("userlevel", recipient_id) >= chat_userlevel){ // Privileged
  1546. logger(LOGLEVEL_CHAT, message); // Log event
  1547. sendClientMultiMessage(recipient_id, chat_color, message, Bool:false);
  1548. DiscordEcho(discord_message, discord_channel);
  1549. }
  1550. }
  1551. }
  1552. }
  1553. }
  1554. return 1;
  1555. }
  1556. forward sendToAdmins(chat_color, const message[]);
  1557. public sendToAdmins(chat_color, const message[]){
  1558. for(new recipient_id, a = GetPlayerPoolSize(); recipient_id < a; recipient_id++){
  1559. if(IsPlayerConnected(recipient_id)){
  1560. if(GetGVarInt("userlevel", recipient_id) >= ADMIN_CREW){ // Privileged
  1561. SendClientMessage(recipient_id, chat_color, message);
  1562. }
  1563. }
  1564. }
  1565. DiscordEcho(message, ADMIN_ECHO_CHANNEL);
  1566. }
  1567. forward sendPM(playerid, text[128 + 1], recipient_id);
  1568. public sendPM(playerid, text[128 + 1], recipient_id){
  1569. if (recipient_id == INVALID_PLAYER_ID){
  1570. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "ERROR: Player not found.");
  1571. }
  1572. else{
  1573. sendToChat(playerid, CHAT_PM, text, recipient_id, DCC_INVALID_USER);
  1574. }
  1575. }
  1576. forward sendClientMultiMessage(recipient_id, chat_color, const message[], Bool:toall);
  1577. public sendClientMultiMessage(recipient_id, chat_color, const message[], Bool:toall){
  1578. if(strlen(message) > 144){ // SAMP does not send messages longer than 144 characters
  1579. new part_1[144 + 1], part_2[144 + 1];
  1580. strmid(part_1, message, 0, 143); // TODO see if this can be moved 1 bit
  1581. strmid(part_2, message, 143, 286);
  1582. if(toall){
  1583. SendClientMessageToAll(chat_color, part_1);
  1584. SendClientMessageToAll(chat_color, part_2);
  1585. }
  1586. else{
  1587. SendClientMessage(recipient_id, chat_color, part_1);
  1588. SendClientMessage(recipient_id, chat_color, part_2);
  1589. }
  1590. }
  1591. else{
  1592. if(toall){SendClientMessageToAll(chat_color, message);}
  1593. else{SendClientMessage(recipient_id, chat_color, message);}
  1594. }
  1595. }
  1596. // Pickup functions
  1597. forward createDynamicPickup(object, Float:x, Float:y, Float:z, world, interior, pickup_type);
  1598. public createDynamicPickup(object, Float:x, Float:y, Float:z, world, interior, pickup_type){
  1599. // Object position corrections
  1600. if(object == 19902){
  1601. z = z - 0.5;
  1602. }
  1603. else if(object == 19607){
  1604. z = z - 0.5;
  1605. }
  1606. // Pickup types
  1607. new type;
  1608. switch(pickup_type){
  1609. case 99999: type = 2;
  1610. default: type = 1;
  1611. }
  1612. new pickupid = CreateDynamicPickup(object, type, x, y, z, world, interior);
  1613. SetGVarInt("pickup_type", pickup_type, pickupid);
  1614. printf("new pickupid = CreateDynamicPickup(%i, %i, %f, %f, %f, %i, %i);", pickupid, object, type, x, y, z, world, interior);
  1615. return pickupid;
  1616. }
  1617. forward spawnPortal(id, object, Float:pos_x, Float:pos_y, Float:pos_z, world, interior, exit_object, Float:exit_pos_x, Float:exit_pos_y, Float:exit_pos_z, exit_world, exit_interior);
  1618. public spawnPortal(id, object, Float:pos_x, Float:pos_y, Float:pos_z, world, interior, exit_object, Float:exit_pos_x, Float:exit_pos_y, Float:exit_pos_z, exit_world, exit_interior){
  1619. new pickup_id = createDynamicPickup(object, pos_x, pos_y, pos_z, world, interior, PICKUP_PORTAL);
  1620. SetGVarFloat("pickup_x", exit_pos_x, pickup_id);
  1621. SetGVarFloat("pickup_y", exit_pos_y, pickup_id);
  1622. SetGVarFloat("pickup_z", exit_pos_z, pickup_id);
  1623. SetGVarInt("pickup_world", exit_world, pickup_id);
  1624. SetGVarInt("pickup_interior", exit_interior, pickup_id);
  1625. new exit_pickup_id = createDynamicPickup(exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior, PICKUP_PORTAL);
  1626. SetGVarFloat("pickup_x", pos_x, exit_pickup_id);
  1627. SetGVarFloat("pickup_y", pos_y, exit_pickup_id);
  1628. SetGVarFloat("pickup_z", pos_z, exit_pickup_id);
  1629. SetGVarInt("pickup_world", world, exit_pickup_id);
  1630. SetGVarInt("pickup_interior", interior, exit_pickup_id);
  1631. new portal_query[64 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  1632. format(portal_query, sizeof(portal_query), "UPDATE portal SET (pickup_id, exit_pickup_id) = (%i, %i) WHERE id = %i", pickup_id, exit_pickup_id, id);
  1633. sql_query(sqlHandle, portal_query);
  1634. }
  1635. forward destroyPortal(id);
  1636. public destroyPortal(id){
  1637. DestroyDynamicPickup(id);
  1638. DeleteGVar("pickup_type", id);
  1639. DeleteGVar("pickup_x", id);
  1640. DeleteGVar("pickup_y", id);
  1641. DeleteGVar("pickup_z", id);
  1642. DeleteGVar("pickup_world", id);
  1643. DeleteGVar("pickup_interior", id);
  1644. }
  1645. // Vehicle functions
  1646. getVehicleModelFromName(name[])
  1647. {
  1648. for(new i = 0; i < 211; i++)
  1649. {
  1650. if(strfind(vehicleNameArray[i], name, true) != -1)
  1651. return i + 400;
  1652. }
  1653. return -1;
  1654. }
  1655. stock editVehicle(playerid, target, option, color1 = -1, color2 = -1, respawn = -1, faction_id = -1){
  1656. new vehicleid = GetPlayerVehicleID(target);
  1657. if(vehicleid == 0){
  1658. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Target player does not occupy a vehicle.");
  1659. }
  1660. // Get vehicle record
  1661. new vehicle_query[54 + sizeof(vehicleid) + 1], admin_message[23 + (4 * 2) + (MAX_PLAYER_NAME * 2) + 1];
  1662. format(vehicle_query, sizeof(vehicle_query), "SELECT id, addsiren FROM vehicle WHERE vehicle_id = %i", vehicleid);
  1663. new Result:vehicle_result = sql_query(sqlHandle, vehicle_query), record_id;
  1664. if(sql_num_rows(vehicle_result) > 0){ // Record exists
  1665. record_id = sql_get_field_assoc_int(vehicle_result, "id");
  1666. }
  1667. new save_query[88 + (MAX_SQL_INTEGER *2) + (MAX_SQL_FLOAT * 4) + 1];
  1668. switch(option){
  1669. case EDITVEHICLE_PARK:{
  1670. new Float:x, Float:y, Float:z, Float:angle;
  1671. GetVehiclePos(vehicleid, x, y, z);
  1672. GetVehicleZAngle(vehicleid, angle);
  1673. if(sql_num_rows(vehicle_result) < 1){ // New vehicle
  1674. format(save_query, sizeof(save_query), "INSERT INTO vehicle(model_id, pos_x, pos_y, pos_z, angle, vehicle_id) VALUES(%i, %f, %f, %f, %f, %i)", GetVehicleModel(vehicleid), x, y, z, angle, vehicleid);
  1675. format(admin_message, sizeof(admin_message), "* [%i] %s has saved a vehicle for [%i] %s", playerid, getPlayerName(playerid), target, getPlayerName(target));
  1676. }
  1677. else{ // Existing vehicle
  1678. format(save_query, sizeof(save_query), "UPDATE vehicle(pos_x, pos_y, pos_z, angle) VALUES(%f, %f, %f, %f) WHERE id = %i", x, y, z, angle, record_id);
  1679. format(admin_message, sizeof(admin_message), "* [%i] %s has parked vehicle %i, for [%i] %s", record_id, getPlayerName(playerid), record_id, target, getPlayerName(target));
  1680. }
  1681. sql_query(sqlHandle, save_query);
  1682. sendToAdmins(COLOR_NOTICE, admin_message);
  1683. }
  1684. case EDITVEHICLE_COLOR:{
  1685. if(sql_num_rows(vehicle_result) < 1){
  1686. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "To be able to permanently save colours, the vehicle needs to be parked first.");
  1687. }
  1688. else{
  1689. format(save_query, sizeof(save_query), "UPDATE vehicle(color1, color2) VALUES(%i, %i) WHERE id = %i", color1, color2, record_id);
  1690. format(admin_message, sizeof(admin_message), "* [%i] %s has updated the colours of vehicle %i, for [%i] %s", playerid, getPlayerName(playerid), record_id, target, getPlayerName(target));
  1691. sql_query(sqlHandle, save_query);
  1692. }
  1693. ChangeVehicleColor(vehicleid, color1, color2);
  1694. }
  1695. case EDITVEHICLE_RESPAWN:{
  1696. if(sql_num_rows(vehicle_result) < 1){
  1697. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "To be able to save the respawn delay, the vehicle needs to be parked first.");
  1698. }
  1699. else{
  1700. format(save_query, sizeof(save_query), "UPDATE vehicle SET respawn_delay = %i WHERE id = %i", respawn, record_id);
  1701. format(admin_message, sizeof(admin_message), "* [%i] %s has updated the respawn delay of vehicle %i, for [%i] %s", playerid, getPlayerName(playerid), record_id, target, getPlayerName(target));
  1702. sql_query(sqlHandle, save_query);
  1703. DestroyVehicle(vehicleid);
  1704. vehicleid = addvehicle(record_id);
  1705. PutPlayerInVehicle(target, vehicleid, 0);
  1706. }
  1707. }
  1708. case EDITVEHICLE_SIREN:{
  1709. if(sql_num_rows(vehicle_result) < 1){
  1710. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "To be able to save the siren, the vehicle needs to be parked first.");
  1711. }
  1712. else{
  1713. new siren = sql_get_field_assoc_int(vehicle_result, "addsiren");
  1714. if(siren){
  1715. format(save_query, sizeof(save_query), "UPDATE vehicle(siren) VALUES(0) WHERE id = %i", record_id);
  1716. format(admin_message, sizeof(admin_message), "* [%i] %s has removed the siren of vehicle %i, for [%i] %s", playerid, getPlayerName(playerid), record_id, target, getPlayerName(target));
  1717. }
  1718. else{
  1719. format(save_query, sizeof(save_query), "UPDATE vehicle(siren) VALUES(1) WHERE id = %i", record_id);
  1720. format(admin_message, sizeof(admin_message), "* [%i] %s has added a siren to vehicle %i, for [%i] %s", playerid, getPlayerName(playerid), record_id, target, getPlayerName(target));
  1721. }
  1722. sql_query(sqlHandle, save_query);
  1723. DestroyVehicle(vehicleid);
  1724. vehicleid = addvehicle(record_id);
  1725. PutPlayerInVehicle(target, vehicleid, 0);
  1726. }
  1727. }
  1728. case EDITVEHICLE_FACTION:{
  1729. if(sql_num_rows(vehicle_result) < 1){
  1730. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "To be able to save faction ownership, the vehicle needs to be parked first.");
  1731. }
  1732. else{
  1733. format(save_query, sizeof(save_query), "UPDATE vehicle(faction_id) VALUES(%i) WHERE id = %i", faction_id, record_id);
  1734. format(admin_message, sizeof(admin_message), "* [%i] %s has set faction ownership to vehicle %i, for [%i] %s", playerid, getPlayerName(playerid), record_id, target, getPlayerName(target));
  1735. }
  1736. }
  1737. case EDITVEHICLE_DELETE:{
  1738. DestroyVehicle(vehicleid);
  1739. format(save_query, sizeof(save_query), "DELETE FROM vehicle WHERE id = %i", record_id);
  1740. }
  1741. }
  1742. return 0;
  1743. }
  1744. addvehicle(vehicle_id){
  1745. // Get vehicle record
  1746. new vehicle_query[121 + (MAX_SQL_INTEGER * 6) + (MAX_SQL_FLOAT * 4) + 1];
  1747. format(vehicle_query, sizeof(vehicle_query), "SELECT model_id, pos_x, pos_y, pos_z, angle, color1, color2, respawn_delay, addsiren, faction_id FROM vehicle WHERE id = %i", vehicle_id);
  1748. new Result:vehicle_result = sql_query(sqlHandle, vehicle_query);
  1749. if(sql_num_rows(vehicle_result) > 0){ // Record exists
  1750. new model_id = sql_get_field_assoc_int(vehicle_result, "model_id"); // Work around for next line will be deemed to long with this included.
  1751. new vehicleid = AddStaticVehicleEx(model_id, sql_get_field_assoc_float(vehicle_result, "pos_x"), sql_get_field_assoc_float(vehicle_result, "pos_y"), sql_get_field_assoc_float(vehicle_result, "pos_z"), sql_get_field_assoc_float(vehicle_result, "angle"), sql_get_field_assoc_int(vehicle_result, "color1"), sql_get_field_assoc_int(vehicle_result, "color2"), sql_get_field_assoc_int(vehicle_result, "respawn_delay"), sql_get_field_assoc_int(vehicle_result, "addsiren"));
  1752. SetVehicleParamsEx(vehicleid, 0, 0, 0, 1, 0, 0, 0); // Lock the doors for all players
  1753. new faction_id = sql_get_field_assoc_int(vehicle_result, "faction_id");
  1754. if(faction_id > 0){
  1755. SetGVarInt("car_faction_id", faction_id, vehicleid);
  1756. }
  1757. new update_query[44 + (MAX_SQL_INTEGER * 2) + 1];
  1758. format(update_query, sizeof(update_query), "UPDATE vehicle SET vehicle_id = %i WHERE id = %i", vehicleid, vehicle_id);
  1759. sql_query(sqlHandle, update_query);
  1760. return vehicleid;
  1761. }
  1762. return 0;
  1763. }
  1764. // Command functions
  1765. public OnPlayerCommandPerformed(playerid, cmd[], params[], result, flags){
  1766. if(result == -1){
  1767. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Unknown command.");
  1768. return 0;
  1769. }
  1770. return 1;
  1771. }
  1772. public OnPlayerCommandReceived(playerid, cmd[], params[], flags){
  1773. new userlevel = GetGVarInt("userlevel", playerid);
  1774. if(flags){
  1775. if(flags > userlevel){
  1776. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Access denied.");
  1777. printf("player %d doesn�t have access to command '%s'", playerid, cmd); // TODO make a list of unique commands we dont have but people try to use
  1778. return 0;
  1779. }
  1780. }
  1781. return 1;
  1782. }
  1783. public PC_OnInit(){ // TODO
  1784. return 1; // Remove this once stuff is in place.
  1785. }
  1786. flags:test(ADMIN_CREW);
  1787. cmd:test(playerid, params[]){
  1788. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Executed");
  1789. return 1;
  1790. }
  1791. // Command commands
  1792. cmd:help(playerid, params[]){
  1793. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Ask questions in the chat, on Discord or the forum.\nTo list all commands: /cmds");
  1794. return 1;
  1795. }
  1796. alias:help("h");
  1797. cmd:cmds(playerid, params[]){
  1798. SendClientMessage(playerid, COLOR_NOTICE, "Command help syntax: \"/\" = start of cmd, \"()\" = group, \"|\" = or, \"<>\" = required parameter, \"[]\" = optional parameter, \",\" = next item.");
  1799. SendClientMessage(playerid, COLOR_NOTICE, "Command help syntax example: /command <parameter> [optional_parameter], /next_command (option | option | option <parameter> <parameter>)");
  1800. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "General commands: (/help, /h), (/cmds, /cmd, /commands), (/my, /myself, /mine), /lock");
  1801. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Chat commands: (/me, /emote, /action) <msg>, (/w, /whisper) <msg>, (/low, /soft) <msg>, (/l, /local) <msg>, (/s, /shout, /scream) <msg>, (/o, ', /oc, /ooc) <msg>");
  1802. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Chat commands: (/g, `, /global, /public) <msg>, (/gc, ~) <msg>, (/fc, !) <msg>, (/vc, &) <msg>, (/cc, @) <msg>, /my chatmode <chat_name>");
  1803. if(GetGVarInt("userlevel", playerid) >= ADMIN_CREW){
  1804. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Admin commands: /property (pickup | portal), (/v, /vehivle, /veh), (/p, /player)");
  1805. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Admin commands extend the options for commands like /my");
  1806. }
  1807. return 0;
  1808. }
  1809. alias:cmds("commands", "cmd");
  1810. // User commands
  1811. cmd:register(playerid, params[]){
  1812. register(playerid);
  1813. }
  1814. cmd:my(playerid, params[]){
  1815. // No option specified
  1816. if(strlen(params) < 1){
  1817. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /my <option> <value>");
  1818. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Options: account, chatmode");
  1819. if(GetGVarInt("userlevel", playerid) >= ADMIN_CREW){
  1820. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Admin options: goto");
  1821. }
  1822. return 0;
  1823. }
  1824. // Options
  1825. if(!strcmp(params, "account", true, 7)){ // /my account
  1826. strdel(params, 0, 8); // Remove first 8 characters, "account ", from the string.
  1827. // Values
  1828. if (isequal(params, "register", .ignorecase = true)){ // /my account register
  1829. register(playerid); // Call public register function
  1830. }
  1831. else if (isequal(params, "characters", .ignorecase = true)){ // /my account characters
  1832. characterSelection(playerid);
  1833. }
  1834. else if (isequal(params, "deletecharacter", .ignorecase = true)){ // /my account characters
  1835. ShowPlayerDialog(playerid, DIALOG_DELETE_CHARACTER, DIALOG_STYLE_MSGBOX, "Charater deletion", "You are about to permanently delete this charater and all it's assets.\n This can NOT be undone.", "Destroy", "Abort");
  1836. }
  1837. else{ // Invalid value
  1838. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /my account ( register | characters | deletecharacter)");
  1839. }
  1840. }
  1841. else if(!strcmp(params, "chatmode", true, 8)){ // /my chatmode
  1842. strdel(params, 0, 9); // Remove first 9 characters, "account ", from the string.
  1843. // Values
  1844. if (isequal(params, "whisper", .ignorecase = true)){
  1845. SetGVarInt("chatmode", CHAT_WHISPER, playerid);
  1846. }
  1847. else if (isequal(params, "low", .ignorecase = true)){
  1848. SetGVarInt("chatmode", CHAT_LOW, playerid);
  1849. }
  1850. else if (isequal(params, "local", .ignorecase = true)){
  1851. SetGVarInt("chatmode", CHAT_LOCAL, playerid);
  1852. }
  1853. else if (isequal(params, "shout", .ignorecase = true)){
  1854. SetGVarInt("chatmode", CHAT_SHOUT, playerid);
  1855. }
  1856. else if (isequal(params, "oc", .ignorecase = true)){
  1857. SetGVarInt("chatmode", CHAT_OC, playerid);
  1858. }
  1859. else if (isequal(params, "global", .ignorecase = true)){
  1860. SetGVarInt("chatmode", CHAT_GLOBAL, playerid);
  1861. }
  1862. else if (isequal(params, "gang", .ignorecase = true)){
  1863. SetGVarInt("chatmode", CHAT_GANG, playerid);
  1864. }
  1865. else if (isequal(params, "faction", .ignorecase = true)){
  1866. SetGVarInt("chatmode", CHAT_FACTION, playerid);
  1867. }
  1868. else if (isequal(params, "vip", .ignorecase = true)){
  1869. SetGVarInt("chatmode", CHAT_VIP, playerid);
  1870. }
  1871. else if (isequal(params, "crew", .ignorecase = true)){
  1872. SetGVarInt("chatmode", CHAT_CREW, playerid);
  1873. }
  1874. else if (isequal(params, "admin", .ignorecase = true)){
  1875. SetGVarInt("chatmode", CHAT_ADMIN, playerid);
  1876. }
  1877. else if (isequal(params, "management", .ignorecase = true)){
  1878. SetGVarInt("chatmode", CHAT_MANAGEMENT, playerid);
  1879. }
  1880. else{ // Invalid value
  1881. printf("else isequals register");
  1882. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /my chatmode <value>");
  1883. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Values: whisper low local shout oc global gang faction vip crew admin management");
  1884. }
  1885. }
  1886. else if(!strcmp(params, "goto", true, 4) || !strcmp(params, "sendto", true, 6) || !strcmp(params, "teleport", true, 8)){
  1887. if(GetGVarInt("userlevel", playerid) < ADMIN_CREW){
  1888. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Access denied.");
  1889. }
  1890. SetGVarInt("goto_target", playerid, playerid);
  1891. ShowPlayerDialog(playerid, DIALOG_GOTO, DIALOG_STYLE_LIST, "Categories", "Interiors\nPlayers", "Select", "Cancel");
  1892. }
  1893. else{ // Invalid option
  1894. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/my options: account chatmode");
  1895. if(GetGVarInt("userlevel", playerid) >= ADMIN_CREW){
  1896. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Admin options: goto");
  1897. }
  1898. }
  1899. return 0;
  1900. }
  1901. alias:my("myself", "mine");
  1902. // Chat commands
  1903. cmd:w(playerid, params[128 + 1]){
  1904. sendToChat(playerid, CHAT_WHISPER, params, 0, DCC_INVALID_USER);
  1905. return 1;
  1906. }
  1907. alias:w("whisper");
  1908. cmd:low(playerid, params[128 + 1]){
  1909. sendToChat(playerid, CHAT_LOW, params, 0, DCC_INVALID_USER);
  1910. return 1;
  1911. }
  1912. alias:low("soft");
  1913. cmd:l(playerid, params[128 + 1]){
  1914. sendToChat(playerid, CHAT_LOCAL, params, 0, DCC_INVALID_USER);
  1915. return 1;
  1916. }
  1917. alias:l("local");
  1918. cmd:me(playerid, params[128 + 1]){
  1919. sendToChat(playerid, CHAT_ACTION, params, 0, DCC_INVALID_USER);
  1920. return 1;
  1921. }
  1922. alias:me("emote", "action");
  1923. cmd:s(playerid, params[128 + 1]){
  1924. sendToChat(playerid, CHAT_SHOUT, params, 0, DCC_INVALID_USER);
  1925. return 1;
  1926. }
  1927. alias:s("shout", "scream");
  1928. cmd:o(playerid, params[128 + 1]){
  1929. sendToChat(playerid, CHAT_OC, params, 0, DCC_INVALID_USER);
  1930. return 1;
  1931. }
  1932. alias:o("oc", "ooc");
  1933. cmd:g(playerid, params[128 + 1]){
  1934. sendToChat(playerid, CHAT_GLOBAL, params, 0, DCC_INVALID_USER);
  1935. return 1;
  1936. }
  1937. alias:g("global", "public");
  1938. cmd:gc(playerid, params[128 + 1]){
  1939. sendToChat(playerid, CHAT_GANG, params, 0, DCC_INVALID_USER);
  1940. return 1;
  1941. }
  1942. cmd:fc(playerid, params[128 + 1]){
  1943. sendToChat(playerid, CHAT_FACTION, params, 0, DCC_INVALID_USER);
  1944. return 1;
  1945. }
  1946. cmd:vc(playerid, params[128 + 1]){
  1947. sendToChat(playerid, CHAT_VIP, params, 0, DCC_INVALID_USER);
  1948. return 1;
  1949. }
  1950. cmd:cc(playerid, params[128 + 1]){
  1951. sendToChat(playerid, CHAT_CREW, params, 0, DCC_INVALID_USER);
  1952. return 1;
  1953. }
  1954. cmd:pm(playerid, params[128 + 1]){
  1955. new recipient_id, message[128 + 1];
  1956. if (sscanf(params, "u s", recipient_id, message)){
  1957. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /pm <playerid> <message>");
  1958. }
  1959. else{
  1960. sendPM(playerid, message, recipient_id);
  1961. }
  1962. return 1;
  1963. }
  1964. alias:pm("msg", "dm");
  1965. // Vehicle commands
  1966. flags:v(ADMIN_CREW);
  1967. cmd:v(playerid, params[]){
  1968. //new vehicle_id;
  1969. if(strlen(params) < 1){
  1970. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /v [player ID] <model> | park | respawn <seconds> | siren | faction <id> | delete");
  1971. }
  1972. if(!sscanf(params, "i s", target, params)){
  1973. if(!IsPlayerConnected(target)){
  1974. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "That player is not ingame.");
  1975. }
  1976. }
  1977. else{
  1978. target = playerid;
  1979. }
  1980. if(!strcmp(params, "park", true, 4)){
  1981. editVehicle(playerid, target, EDITVEHICLE_PARK);
  1982. }
  1983. else if(!strcmp(params, "respawn", true, 7)){
  1984. strdel(params, 0, 8); // Remove first 8 characters from the string.
  1985. new respawn;
  1986. if(!sscanf(params, "i", respawn)){
  1987. editVehicle(playerid, target, EDITVEHICLE_RESPAWN, -1, -1, respawn);
  1988. }
  1989. else{
  1990. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/v [ID] respawn usage: <seconds>");
  1991. }
  1992. }
  1993. else if(!strcmp(params, "siren", true, 5)){
  1994. editVehicle(playerid, target, EDITVEHICLE_SIREN);
  1995. }
  1996. else if(!strcmp(params, "faction", true, 7)){
  1997. strdel(params, 0, 8); // Remove first 8 characters from the string.
  1998. new faction_id;
  1999. if(!sscanf(params, "i", faction_id)){
  2000. new faction_query[35 + MAX_SQL_INTEGER + 1];
  2001. format(faction_query, sizeof(faction_query), "SELECT id FROM faction WHERE id = %i", faction_id);
  2002. new Result:faction_result = sql_query(sqlHandle, faction_query);
  2003. if(sql_num_rows(faction_result) < 1 && faction_id > 0){
  2004. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid faction ID.");
  2005. }
  2006. else{
  2007. editVehicle(playerid, target, EDITVEHICLE_FACTION, -1, -1, -1, faction_id);
  2008. }
  2009. }
  2010. else{
  2011. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/v [ID] faction usage: <faction ID>");
  2012. }
  2013. }
  2014. else if(!strcmp(params, "delete", true, 6)){
  2015. editVehicle(playerid, target, EDITVEHICLE_DELETE);
  2016. }
  2017. else if(!sscanf(params, "s")){
  2018. // Get model ID
  2019. new modelid = getVehicleModelFromName(params);
  2020. if(modelid == -1){
  2021. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Unkown parameter or model name.");
  2022. }
  2023. new Float:x, Float:y, Float:z, Float:angle, worldid, interiorid;
  2024. getPlayerLocation(target, x, y, z, angle, worldid, interiorid);
  2025. // To prevent crashses in certain situations.
  2026. if(IsPlayerInAnyVehicle(target)){
  2027. GetVehicleZAngle(GetPlayerVehicleID(target), angle);
  2028. RemovePlayerFromVehicle(target);
  2029. }
  2030. new vehicleid = AddStaticVehicleEx(modelid, x, y, z, angle, -1, -1, -1);
  2031. SetVehicleVirtualWorld(vehicleid, worldid);
  2032. PutPlayerInVehicle(target, vehicleid, 0);
  2033. new admin_message[33 + 4 + MAX_PLAYER_NAME + 1];
  2034. format(admin_message, sizeof(admin_message), "[%i] %s has created a temporary vehicle.", playerid, getPlayerName(playerid));
  2035. sendToAdmins(COLOR_NOTICE, admin_message);
  2036. }
  2037. else{
  2038. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /v [player ID] <model> | park | respawn <seconds> | siren | delete");
  2039. }
  2040. return 1;
  2041. }
  2042. alias:v("vehicle", "veh");
  2043. // Player commands
  2044. cmd:p(playerid, params[]){
  2045. // No parameters
  2046. if(strlen(params) < 1){
  2047. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /p <ID> option");
  2048. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p options: admin, goto");
  2049. }
  2050. // Syntax
  2051. new player_id, option[123 + 1];
  2052. if(sscanf(params, "i s", player_id, option)){
  2053. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /p <ID> <option>");
  2054. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p options: admin, goto");
  2055. }
  2056. if(!strcmp(option, "admin", true, 5)){
  2057. SetGVarInt("userlevel", ADMIN_CREW, player_id);
  2058. // TODO take admin if already admin
  2059. // TODO notify admins
  2060. }
  2061. else if(!strcmp(option, "goto", true, 4) && !strcmp(option, "sendto", true, 6 && !strcmp(option, "teleport", true, 8)) ){
  2062. if(GetGVarInt("userlevel", playerid) < ADMIN_CREW){
  2063. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Access denied.");
  2064. SetGVarInt("goto_target", player_id);
  2065. }
  2066. }
  2067. else if(!strcmp(option, "info", true, 4){
  2068. new area_id = GetGVarInt("disable_pickups", player_id);
  2069. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: Access denied.");
  2070. }
  2071. else{
  2072. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p <ID> options: admin, goto, info");
  2073. }
  2074. return 1;
  2075. }
  2076. alias:p("player");
  2077. // Admin commands
  2078. flags:property(ADMIN_CREW);
  2079. cmd:property(playerid, params[]){
  2080. // No option specified
  2081. if(strlen(params) < 1){
  2082. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property options: pickup, portal");
  2083. }
  2084. // Options
  2085. if(!strcmp(params, "pickup", true, 6)){ // /property pickup
  2086. strdel(params, 0, 7); // Remove first 7 characters, "pickup ", from the string.
  2087. // No parameters
  2088. if(strlen(params) < 1){
  2089. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /property pickup <create | ID <goto | move | delete>>");
  2090. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/p options: admin, goto");
  2091. }
  2092. // Values
  2093. new pickup_id, option[110 + 1];
  2094. if(!strcmp(params, "create", true)){ // /property pickup create
  2095. ShowPlayerDialog(playerid, DIALOG_CREATE_PICKUP, DIALOG_STYLE_LIST, "Pickup caterogy", "Faction", "Select", "Cancel");
  2096. }
  2097. else if (!sscanf(params, "i s", pickup_id, option)){
  2098. new pickup_query[69 + MAX_SQL_INTEGER + 1];
  2099. format(pickup_query, sizeof(pickup_query), "SELECT object_id, type_id, pickup_id, pos_x, pos_y, pos_z, world_id, pickup_id, angle FROM pickup WHERE id = %i", pickup_id);
  2100. new Result:pickup_result = sql_query(sqlHandle, pickup_query);
  2101. if(sql_num_rows(pickup_result) < 1){ // Invalid pickup ID
  2102. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid pickup ID");
  2103. }
  2104. new pickupid = sql_get_field_assoc_int(pickup_result, "pickup_id");
  2105. if(!strcmp(option, "move", true)){
  2106. // Destroy old pickup
  2107. DestroyDynamicPickup(pickupid);
  2108. // Create new pickup
  2109. new Float:x, Float:y, Float:z;
  2110. GetPlayerPos(playerid, x, y, z);
  2111. new interior = GetPlayerInterior(playerid);
  2112. new world = GetPlayerVirtualWorld(playerid);
  2113. new Float:angle;
  2114. new object_id = sql_get_field_assoc_int(pickup_result, "object_id");
  2115. new type_id = sql_get_field_assoc_int(pickup_result, "type_id");
  2116. new new_pickupid = createDynamicPickup(object_id, x, y, z, world, interior, type_id);
  2117. angle = GetPlayerFacingAngle(playerid, angle);
  2118. // Update pickup record
  2119. new update_query[118 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  2120. format(update_query, sizeof(update_query), "UPDATE pickup SET pos_x = '%f', pos_y = '%f', pos_z = '%f', world_id = %i, interior_id = %i, pickup_id = %i, angle = %f WHERE id = %i", x, y, z, world, interior, new_pickupid, pickup_id, angle);
  2121. sql_query(sqlHandle, update_query);
  2122. // Inform admins
  2123. new admin_message[39 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
  2124. format(admin_message, sizeof(admin_message), "* [%i] %s modified the location of pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  2125. sendToAdmins(COLOR_NOTICE, admin_message);
  2126. }
  2127. else if(!strcmp(option, "delete", true)){
  2128. // Destroy pickup
  2129. DestroyDynamicPickup(pickupid);
  2130. // Delete pickup record
  2131. new update_query[95 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  2132. format(update_query, sizeof(update_query), "DELETE FROM pickup WHERE id = %i", pickup_id);
  2133. sql_query(sqlHandle, update_query);
  2134. // Inform admins
  2135. new admin_message[39 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
  2136. format(admin_message, sizeof(admin_message), "* [%i] %s deleted pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  2137. sendToAdmins(COLOR_NOTICE, admin_message);
  2138. }
  2139. else if(!strcmp(option, "goto", true)){
  2140. new name[7 + MAX_SQL_INTEGER];
  2141. format(name, sizeof(name), "pickup %i", pickupid);
  2142. gotoCallback(sql_get_field_assoc_float(pickup_result, "pos_x"), sql_get_field_assoc_float(pickup_result, "pos_y"), sql_get_field_assoc_float(pickup_result, "pos_z"), sql_get_field_assoc_int(pickup_result, "world_id"), sql_get_field_assoc_int(pickup_result, "interior_id"), sql_get_field_assoc_float(pickup_result, "angle"), name, playerid); // TODO check if this informs admins
  2143. }
  2144. else{ // Invalid option.
  2145. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property pickup <ID> usage: goto, move, delete");
  2146. }
  2147. }
  2148. else{ // Invalid value
  2149. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property pickup usage: create, <ID> <goto | move | delete>");
  2150. }
  2151. }
  2152. else if(!strcmp(params, "portal", true, 6)){ // /property portal
  2153. strdel(params, 0, 7); // Remove first 7 characters, "portal ", from the string.
  2154. // No parameters
  2155. if(strlen(params) < 1){
  2156. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /property portal <create | ID <goto | exit | entrance | object | delete>>");
  2157. }
  2158. // Values
  2159. new portal_id, option[116 + 1];
  2160. if (!strcmp(params, "create", true, 6)){ // /property portal create
  2161. strdel(params, 0, 7); // Remove first 7 characters, "create ", from the string.
  2162. // Worlds
  2163. new value[105 + 1], world_id;
  2164. if (sscanf(params, "s", value)){
  2165. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "For a portal that works in all worlds use: /property portal create all");
  2166. }
  2167. if(!strcmp(value, "all", true)){
  2168. world_id = -1;
  2169. }
  2170. else{
  2171. world_id = GetPlayerVirtualWorld(playerid);
  2172. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid world option, creating default portal.");
  2173. }
  2174. new Float:x, Float:y, Float:z, Float:angle, world, interior;
  2175. getPlayerLocation(playerid, x, y, z, angle, world, interior);
  2176. new pickup_id = createDynamicPickup(19902, x, y, z, world_id, interior, PICKUP_PORTAL);
  2177. // Create portal database record
  2178. new portal_query[120 + (MAX_SQL_FLOAT * 3) + (MAX_SQL_INTEGER * 3) + MAX_SQL_FLOAT + 1];
  2179. format(portal_query, sizeof(portal_query), "INSERT INTO portal(object, pos_x, pos_y, pos_z, world, pickup_id, interior_id, angle) VALUES (19902, '%f', '%f', '%f', %i, %i, %i, %f)", x, y, z, world_id, pickup_id, interior, 360 - angle);
  2180. sql_query(sqlHandle, portal_query);
  2181. // Inform user(s)
  2182. new portal_id_query[91 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + 1];
  2183. format(portal_id_query, sizeof(portal_id_query), "SELECT id FROM portal WHERE pos_x = '%f' AND pos_y = '%f' AND pos_z = '%f' AND world = %i AND interior_id = %i", x, y, z, world_id, interior);
  2184. new Result:portal_id_result = sql_query(sqlHandle, portal_id_query);
  2185. portal_id = sql_get_field_assoc_int(Result:portal_id_result, "id");
  2186. new message[69 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1], admin_message[21 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
  2187. format(message, sizeof(message), "Portal %i created. Create the other side with: /property portal %i exit", portal_id, portal_id);
  2188. format(admin_message, sizeof(admin_message), "* [%i] %s created portal: %i", playerid, getPlayerName(playerid), portal_id);
  2189. sendToAdmins(COLOR_NOTICE , admin_message);
  2190. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, message);
  2191. }
  2192. else if (!sscanf(params, "i s", portal_id, option)){
  2193. // Get portal record
  2194. new portal_query[189 + MAX_SQL_INTEGER + 1];
  2195. format(portal_query, sizeof(portal_query), "SELECT object, pos_x, pos_y, pos_z, world, interior_id, pickup_id, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior_id, exit_pickup_id, angle, exit_angle FROM portal WHERE id = %i", portal_id);
  2196. new Result:portal_result = sql_query(sqlHandle, portal_query);
  2197. // Invalid portal ID
  2198. if(sql_num_rows(portal_result) < 1){ // Invalid portal ID
  2199. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid portal ID");
  2200. }
  2201. if (!strcmp(option, "exit", true, 4)){
  2202. new Float:pos_x = sql_get_field_assoc_float(portal_result, "pos_x");
  2203. new Float:pos_y = sql_get_field_assoc_float(portal_result, "pos_y");
  2204. new Float:pos_z = sql_get_field_assoc_float(portal_result, "pos_z");
  2205. new world_id = sql_get_field_assoc_int(portal_result, "world");
  2206. new interior_id = sql_get_field_assoc_int(portal_result, "interior_id");
  2207. new session_id = sql_get_field_assoc_int(portal_result, "pickup_id");
  2208. new exit_pickup_id = sql_get_field_assoc_int(portal_result, "exit_pickup_id");
  2209. new Float:angle = sql_get_field_assoc_float(portal_result, "angle");
  2210. // Location
  2211. new Float:x, Float:y, Float:z, Float:player_angle, world, interior;
  2212. getPlayerLocation(playerid, x, y, z, player_angle, world, interior);
  2213. // World
  2214. if(world_id != -1){ // Not an all-world portal
  2215. world = GetPlayerVirtualWorld(playerid);
  2216. }
  2217. else{
  2218. world = world_id;
  2219. }
  2220. // Delete old exit if exists
  2221. if(exit_pickup_id){
  2222. destroyPortal(exit_pickup_id);
  2223. }
  2224. new pickup_id = createDynamicPickup(19607, x, y, z, world, interior, PICKUP_PORTAL);
  2225. SetGVarFloat("pickup_x", pos_x, pickup_id);
  2226. SetGVarFloat("pickup_y", pos_y, pickup_id);
  2227. SetGVarFloat("pickup_z", pos_z, pickup_id);
  2228. SetGVarInt("pickup_world", world_id, pickup_id);
  2229. SetGVarFloat("pickup_angle", angle, pickup_id);
  2230. SetGVarInt("pickup_interior", interior_id, pickup_id);
  2231. SetGVarFloat("pickup_x", x, session_id);
  2232. SetGVarFloat("pickup_y", y, session_id);
  2233. SetGVarFloat("pickup_z", z, session_id);
  2234. SetGVarInt("pickup_world", world, session_id);
  2235. SetGVarFloat("pickup_angle", player_angle, session_id);
  2236. SetGVarInt("pickup_interior", interior, session_id);
  2237. // Update portal record
  2238. new update_query[172 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  2239. format(update_query, sizeof(update_query), "UPDATE portal SET exit_object = 19607, exit_pos_x = '%f', exit_pos_y = '%f', exit_pos_z = '%f', exit_world = %i, exit_interior_id = %i, exit_pickup_id = %i, exit_angle = %i WHERE id = %i", x, y, z, world, interior, pickup_id, 360 - player_angle, portal_id);
  2240. sql_query(sqlHandle, update_query);
  2241. // Inform admins and Discord
  2242. new admin_message[61 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
  2243. format(admin_message, sizeof(admin_message), "* [%i] %s modified the exit location of portal: %i", playerid, getPlayerName(playerid), portal_id);
  2244. sendToAdmins(COLOR_NOTICE , admin_message);
  2245. }
  2246. else if(!strcmp(option, "object", true, 6)){
  2247. strdel(option, 0, 7); // Remove first 7 characters, from the string.
  2248. new object, exit_object;
  2249. print(option);
  2250. if (sscanf(option, "i i", object, exit_object)){
  2251. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid syntax, specify two object ID's: /property portal <ID> object <ID> <ID>");
  2252. }
  2253. new Float:pos_x = sql_get_field_assoc_float(portal_result, "pos_x");
  2254. new Float:pos_y = sql_get_field_assoc_float(portal_result, "pos_y");
  2255. new Float:pos_z = sql_get_field_assoc_float(portal_result, "pos_z");
  2256. new world_id = sql_get_field_assoc_int(portal_result, "world");
  2257. new interior_id = sql_get_field_assoc_int(portal_result, "interior_id");
  2258. new pickup_id = sql_get_field_assoc_int(portal_result, "pickup_id");
  2259. new Float:exit_pos_x = sql_get_field_assoc_float(portal_result, "exit_pos_x");
  2260. new Float:exit_pos_y = sql_get_field_assoc_float(portal_result, "exit_pos_y");
  2261. new Float:exit_pos_z = sql_get_field_assoc_float(portal_result, "exit_pos_z");
  2262. new exit_world_id = sql_get_field_assoc_int(portal_result, "exit_world");
  2263. new exit_interior_id = sql_get_field_assoc_int(portal_result, "exit_interior_id");
  2264. new exit_pickup_id = sql_get_field_assoc_int(portal_result, "exit_pickup_id");
  2265. destroyPortal(exit_pickup_id);
  2266. destroyPortal(pickup_id);
  2267. spawnPortal(portal_id, object, pos_x, pos_y, pos_z, world_id, interior_id, exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world_id, exit_interior_id);
  2268. new update_query[57 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  2269. format(update_query, sizeof(update_query), "UPDATE portal SET (object, exit_object) = (%i, %i) WHERE id = %i", object, exit_object, portal_id);
  2270. sql_query(sqlHandle, update_query);
  2271. }
  2272. else if(!strcmp(option, "delete", true, 6)){
  2273. new pickup_id = sql_get_field_assoc_int(portal_result, "pickup_id");
  2274. new exit_pickup_id = sql_get_field_assoc_int(portal_result, "exit_pickup_id");
  2275. // TODO: Confirmation, by spectating the pickup or having to be near.
  2276. destroyPortal(exit_pickup_id);
  2277. destroyPortal(pickup_id);
  2278. // Delete portal record
  2279. new delete_query[31 + MAX_SQL_INTEGER + 1];
  2280. format(delete_query, sizeof(delete_query), "DELETE FROM portal WHERE id = %i", portal_id);
  2281. sql_query(sqlHandle, delete_query);
  2282. }
  2283. else if(!strcmp(option, "entrance", true, 8)){
  2284. new object = sql_get_field_assoc_int(portal_result, "object");
  2285. //new Float:x = sql_get_field_assoc_float(portal_result, "pos_x");
  2286. //new Float:y = sql_get_field_assoc_float(portal_result, "pos_y");
  2287. //new Float:z = sql_get_field_assoc_float(portal_result, "pos_z"); todo shorten qeury
  2288. new world = sql_get_field_assoc_int(portal_result, "world");
  2289. new pickup_id = sql_get_field_assoc_int(portal_result, "pickup_id");
  2290. new Float:pos_x = sql_get_field_assoc_float(portal_result, "exit_pos_x");
  2291. new Float:pos_y = sql_get_field_assoc_float(portal_result, "exit_pos_y");
  2292. new Float:pos_z = sql_get_field_assoc_float(portal_result, "exit_pos_z");
  2293. new world_id = sql_get_field_assoc_int(portal_result, "exit_world");
  2294. new interior_id = sql_get_field_assoc_int(portal_result, "exit_interior");
  2295. new Float:angle = sql_get_field_assoc_float(portal_result, "exit_angle");
  2296. if(sql_num_rows(portal_result) < 1){ // Invalid portal ID
  2297. return SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Invalid portal ID");
  2298. }
  2299. // Location
  2300. new Float:x, Float:y, Float:z, Float:player_angle, player_world, interior;
  2301. getPlayerLocation(playerid, x, y, z, player_angle, player_world, interior);
  2302. // World
  2303. if(world_id == -1){ // All-world portal
  2304. world = world_id;
  2305. }
  2306. destroyPortal(pickup_id); // Despawn old pickups and remove GVars
  2307. new pickupid = createDynamicPickup(object, x, y, z, world, interior, PICKUP_PORTAL);
  2308. SetGVarFloat("pickup_x", pos_x, pickupid);
  2309. SetGVarFloat("pickup_y", pos_y, pickupid);
  2310. SetGVarFloat("pickup_z", pos_z, pickupid);
  2311. SetGVarInt("pickup_world", world_id, pickupid);
  2312. SetGVarInt("pickup_interior", interior_id, pickupid);
  2313. SetGVarFloat("pickup_angle", angle, pickupid);
  2314. // Inform admins and Discord
  2315. new admin_message[65 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
  2316. format(admin_message, sizeof(admin_message), "* [%i] %s modified the entrance location of portal: %i", playerid, getPlayerName(playerid), portal_id);
  2317. sendToAdmins(COLOR_NOTICE, admin_message);
  2318. }
  2319. else if(!strcmp(option, "goto", true)){
  2320. teleportPlayer(playerid, sql_get_field_assoc_float(Result:portal_result, "exit_pos_x"), sql_get_field_assoc_float(Result:portal_result, "exit_pos_y"), sql_get_field_assoc_float(Result:portal_result, "exit_pos_z"), sql_get_field_assoc_float(Result:portal_result, "angle"), sql_get_field_assoc_int(Result:portal_result, "exit_world_id"), sql_get_field_assoc_int(Result:portal_result, "exit_interior_id"));
  2321. }
  2322. else{ // Invalid option
  2323. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property portal <ID> options: goto, exit, entrance, object, delete");
  2324. }
  2325. }
  2326. else{ // Invalid value
  2327. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: /property portal <create | ID <goto | exit | entrance | object | delete>>");
  2328. }
  2329. }
  2330. else{ // Invalid option
  2331. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "/property options: pickup, portal");
  2332. }
  2333. return 1;
  2334. }
  2335. cmd:lock(playerid, params[]){
  2336. new vehicleid = GetPlayerVehicleID(playerid);
  2337. if(vehicleid){ // Player in vehicle
  2338. new engine, lights, alarm, doors, bonnet, boot, objective;
  2339. GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective);
  2340. new faction_id = GetGVarInt("vehicle_faction_id", vehicleid);
  2341. new job_id = GetGVarInt("faction_job_id", faction_id);
  2342. if(faction_id){ // Faction vehicle
  2343. if(job_id == GetGVarInt("job_id", playerid) || faction_id == GetGVarInt("faction_id", playerid)){ // Faction member or on faction job
  2344. if(doors){ // Doors are locked
  2345. SetVehicleParamsEx(vehicleid, engine, lights, alarm, 0, bonnet, boot, objective); // Unlock doors
  2346. }
  2347. else{
  2348. SetVehicleParamsEx(vehicleid, engine, lights, alarm, 1, bonnet, boot, objective);
  2349. }
  2350. }
  2351. else{
  2352. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "You are not a member of, or on a job for the faction that owns this vehicle.");
  2353. }
  2354. }
  2355. // TODO if player owned vehicle
  2356. }
  2357. else{ // Plare not in a vehicle
  2358. // Inside portal pickup
  2359. new area_id = GetGVarInt("disable_pickups", playerid);
  2360. if(area_id){ // Player is in a pickup
  2361. // TODO lockable doors
  2362. }
  2363. else{ // Not in a pickup
  2364. // Nearest vehicle
  2365. new Float:x, Float:y, Float:z, Float:nearest_distance, nearest_vehicleid;
  2366. GetPlayerPos(vehicleid, x, y, z);
  2367. for(new a = GetVehiclePoolSize(); vehicleid < a; vehicleid++){
  2368. new Float:vehicle_distance = GetVehicleDistanceFromPoint(vehicleid, x, y, z);
  2369. if(!nearest_distance || nearest_distance > vehicle_distance){
  2370. nearest_distance = vehicle_distance;
  2371. nearest_vehicleid = vehicleid;
  2372. }
  2373. }
  2374. new engine, lights, alarm, doors, bonnet, boot, objective;
  2375. GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective);
  2376. new faction_id = GetGVarInt("vehicle_faction_id", nearest_vehicleid);
  2377. if(faction_id){ // Faction vehicle
  2378. if(faction_id == GetGVarInt("job_id", playerid) || faction_id == GetGVarInt("faction_id", playerid)){ // Faction member or on faction job
  2379. if(doors){ // Doors are locked
  2380. SetVehicleParamsEx(nearest_vehicleid, engine, lights, alarm, 0, bonnet, boot, objective); // Unlock doors
  2381. }
  2382. else{
  2383. SetVehicleParamsEx(nearest_vehicleid, engine, lights, alarm, 1, bonnet, boot, objective);
  2384. }
  2385. }
  2386. else{
  2387. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "You are not a member of, or on a job for the faction that owns this vehicle.");
  2388. }
  2389. }
  2390. }
  2391. }
  2392. }
  2393. // Dialog functions
  2394. forward dialogGotoInterior(playerid);
  2395. public dialogGotoInterior(playerid){
  2396. ShowPlayerDialog(playerid, DIALOG_GOTO_INTERIOR, DIALOG_STYLE_LIST, "Categories", "Avaition\nHouses\nMissions\nMission exteriors\nPolice departments\nSex work\nShops\nStadia", "Select", "Back");
  2397. }
  2398. forward dialogGotoPlayer(playerid);
  2399. public dialogGotoPlayer(playerid){
  2400. for(new targetid, a = GetPlayerPoolSize(); targetid < a; targetid++){
  2401. if(IsPlayerConnected(targetid)){
  2402. // TODO: Decide to use this or TABplayer list.
  2403. }
  2404. }
  2405. ShowPlayerDialog(playerid, DIALOG_GOTO_PLAYER, DIALOG_STYLE_LIST, "Players", "", "Goto", "Back");
  2406. }
  2407. dialogGotoHouses(playerid){
  2408. ShowPlayerDialog(playerid, DIALOG_GOTO_HOUSES, DIALOG_STYLE_TABLIST, "Houses", "Burglary houses\nMission houses\nSafe houses\nUncategorized", "Select", "Cancel");
  2409. }
  2410. dialogGotoShops(playerid){
  2411. ShowPlayerDialog(playerid, DIALOG_GOTO_SHOPS, DIALOG_STYLE_TABLIST, "Shops", "24/7's\nAmmunation's\nCasino's\nModding shops\nUncatagorized", "Select", "Cancel");
  2412. }
  2413. // a_samp events
  2414. public OnGameModeInit(){
  2415. new message[36 + 22 + 1];
  2416. format(message, sizeof(message), "* Global game-mode initialization: v%s", MODE_NAME);
  2417. logger(LOGLEVEL_NOTICE, "* Global game-mode initialization."); // Log event.
  2418. // Player radar blip markers only visible to nearby players.
  2419. ShowPlayerMarkers(PLAYER_MARKERS_MODE_STREAMED);
  2420. LimitPlayerMarkerRadius(15);
  2421. // Set mode name
  2422. SetGameModeText(MODE_NAME);
  2423. // SQL log level
  2424. if(scriptDebug){
  2425. sql_debug(LOG_ALL, LOG_ALL); // Log everything everywhere.
  2426. }
  2427. else{
  2428. sql_debug(LOG_INFO, LOG_WARNING); // Loglevel info for file and worning for console.
  2429. }
  2430. // Connect to database
  2431. sqlHandle = SQL:sql_connect(SQL_HANDLER_POSTGRESQL, PG_HOST, PG_ROLE, PG_PASS, PG_DB, PG_PORT);
  2432. printf("sqlconnection = %d", _:sqlHandle);
  2433. if(!sql_ping(sqlHandle)){
  2434. print( " + Database connection" );
  2435. }
  2436. else{
  2437. print( "Database connection failed" );
  2438. }
  2439. // Initialize Discord
  2440. //homeGuild = DCC_GetGuildId(DISCORD_HOME_GUILD_ID); // Set home guild ID. NOT NEEDED FOR NOW AND BROKEN
  2441. echoChannel = DCC_FindChannelById(DISCORD_ECHO_CHANNEL_ID); // Set main echo channel ID.
  2442. mainChannel = DCC_FindChannelById(DISCORD_MAIN_CHANNEL_ID); // Set main notification channel ID.
  2443. adminEchoChannel = DCC_FindChannelById(DISCORD_ADMIN_ECHO_CHANNEL_ID); // Set admin echo channel ID.
  2444. adminChannel = DCC_FindChannelById(DISCORD_ADMIN_CHANNEL_ID); // Set admin notification channel ID.
  2445. managementChannel = DCC_FindChannelById(DISCORD_MANAGEMENT_CHANNEL_ID); // Set management notification channel ID.
  2446. DiscordEcho(message, ECHO_CHANNEL); // Notify Discord
  2447. //DiscordEcho(message, MAIN_CHANNEL); // TODO Enable after we are stable
  2448. // Factions
  2449. new Result:faction_result = sql_query(sqlHandle, "SELECT job_id FROM faction");
  2450. for(new i = 0; i < sql_num_rows(faction_result); i++){
  2451. SetGVarInt("faction_job_id", sql_get_field_assoc_int_ex(faction_result, i, "job_id"));
  2452. }
  2453. // Portals
  2454. new Result:portal_result = sql_query(sqlHandle, "SELECT id, object, pos_x, pos_y, pos_z, world, interior_id, exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior_id FROM portal");
  2455. for(new i = 0; i < sql_num_rows(portal_result); i++){
  2456. new id = sql_get_field_assoc_int_ex(portal_result, i, "id");
  2457. new object = sql_get_field_assoc_int_ex(portal_result, i, "object");
  2458. new Float:pos_x = sql_get_field_assoc_float_ex(portal_result, i, "pos_x");
  2459. new Float:pos_y = sql_get_field_assoc_float_ex(portal_result, i, "pos_y");
  2460. new Float:pos_z = sql_get_field_assoc_float_ex(portal_result, i, "pos_z");
  2461. new world = sql_get_field_assoc_int_ex(portal_result, i, "world");
  2462. new interior = sql_get_field_assoc_int_ex(portal_result, i, "interior_id");
  2463. new exit_object = sql_get_field_assoc_int_ex(portal_result, i, "exit_object");
  2464. new Float:exit_pos_x = sql_get_field_assoc_float_ex(portal_result, i, "exit_pos_x");
  2465. new Float:exit_pos_y = sql_get_field_assoc_float_ex(portal_result, i, "exit_pos_y");
  2466. new Float:exit_pos_z = sql_get_field_assoc_float_ex(portal_result, i, "exit_pos_z");
  2467. new exit_world = sql_get_field_assoc_int_ex(portal_result, i, "exit_world");
  2468. new exit_interior = sql_get_field_assoc_int_ex(portal_result, i, "exit_interior_id");
  2469. spawnPortal(id, object, pos_x, pos_y, pos_z, world, interior, exit_object, exit_pos_x, exit_pos_y, exit_pos_z, exit_world, exit_interior);
  2470. }
  2471. // Pickups
  2472. new Result:pickup_result = sql_query(sqlHandle, "SELECT id, object_id, pos_x, pos_y, pos_z, world_id, interior_id, type_id FROM pickup");
  2473. for(new i = 0; i < sql_num_rows(pickup_result); i++){
  2474. new id = sql_get_field_assoc_int_ex(pickup_result, i, "id");
  2475. new object_id = sql_get_field_assoc_int_ex(pickup_result, i, "object_id");
  2476. new Float:pos_x = sql_get_field_assoc_float_ex(pickup_result, i, "pos_x");
  2477. new Float:pos_y = sql_get_field_assoc_float_ex(pickup_result, i, "pos_y");
  2478. new Float:pos_z = sql_get_field_assoc_float_ex(pickup_result, i, "pos_z");
  2479. new world_id = sql_get_field_assoc_int_ex(pickup_result, i, "world_id");
  2480. new interior_id = sql_get_field_assoc_int_ex(pickup_result, i, "interior_id");
  2481. new type_id = sql_get_field_assoc_int_ex(pickup_result, i, "type_id");
  2482. new pickupid = createDynamicPickup(object_id, pos_x, pos_y, pos_z, world_id, interior_id, type_id);
  2483. // Update pickup record
  2484. new pickup_query[44 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  2485. format(pickup_query, sizeof(pickup_query), "UPDATE pickup SET pickup_id = %i WHERE id = %i", pickupid, id);
  2486. sql_query(sqlHandle, pickup_query);
  2487. }
  2488. // Vehicles
  2489. new Result:vehicle_result = sql_query(sqlHandle, "SELECT id FROM vehicle");
  2490. for(new i = 0; i < sql_num_rows(vehicle_result); i++){
  2491. printf("Add: %i | vehicle_id: %i", i, sql_get_field_assoc_int_ex(vehicle_result, i, "id"));
  2492. addvehicle(sql_get_field_assoc_int_ex(vehicle_result, i, "id"));
  2493. }
  2494. // Hobo's with a cane (0 ammo value makes them lose the cane as soon as they switch weapon)
  2495. // Only homeless skins, as players should slowly class up in society.
  2496. AddPlayerClass(134, -184.7607, 950.5010, 16.7740, 358.3032, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard right curb.
  2497. AddPlayerClass(10, -184.7607, 950.5010, 16.7740, 358.3032, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard right curb.
  2498. AddPlayerClass(78, 111.0115, 1189.2029, 18.1627, 89.0095, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard left curb.
  2499. AddPlayerClass(129, 111.0115, 1189.2029, 18.1627, 89.0095, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard left curb.
  2500. AddPlayerClass(162, -109.4227, 1242.4860, 16.8223, 183.5798, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard left curb.
  2501. AddPlayerClass(77, -109.4227, 1242.4860, 16.8223, 183.5798, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard left curb.
  2502. AddPlayerClass(79, -201.5379, 948.1683, 15.9131, 359.9720, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard left curb.
  2503. AddPlayerClass(196, -201.5379, 948.1683, 15.9131, 359.9720, 15, 0, 0, 0, 0, false); // Fort Carson West boulevard left curb.
  2504. AddPlayerClass(239, 62.4694, 1205.0531, 18.8153, 89.9380, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard right curb.
  2505. AddPlayerClass(89, 62.4694, 1205.0531, 18.8153, 89.9380, 15, 0, 0, 0, 0, false); // Fort Carson South boulevard right curb.
  2506. AddPlayerClass(135, -126.0831, 1242.5745, 18.6138, 183.2986, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard right curb.
  2507. AddPlayerClass(197, -126.0831, 1242.5745, 18.6138, 183.2986, 15, 0, 0, 0, 0, false); // Fort Carson East boulevard right curb.
  2508. return 1;
  2509. }
  2510. public OnGameModeExit(){
  2511. // Cycle every player
  2512. for(new playerid, a = GetPlayerPoolSize(); playerid < a; playerid++){
  2513. if(IsPlayerConnected(playerid)){
  2514. // Set name back to username
  2515. //new client_connect_username[MAX_PLAYER_NAME + 1];
  2516. //GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid);
  2517. //SetPlayerName(playerid, client_connect_username); // Change name in-game back to username, for login after restart PROBLEM: Crashses the server on GMX.
  2518. deleteAllGVars(playerid); // Delete GVars as per https://forum.sa-mp.com/showthread.php?t=151076
  2519. // TODO think of somthing for the usernames, kickign every player, or accapting character names as usersnames.
  2520. }
  2521. }
  2522. // Cycle every vehicle
  2523. for(new vehicleid, a = GetVehiclePoolSize(); vehicleid < a; vehicleid++){
  2524. if(GetVehicleModel(vehicleid)){DeleteGVar("car_faction", vehicleid);} // Delete GVars as per https://forum.sa-mp.com/showthread.php?t=151076
  2525. }
  2526. logger(LOGLEVEL_NOTICE, "* Global game-mode termination."); // Log event
  2527. sql_wait(sqlHandle); // Wait for queries to finish.
  2528. sql_disconnect(sqlHandle); // Disconnect from database.
  2529. DiscordEcho("* Global game-mode termination.", ECHO_CHANNEL); // Notify discord
  2530. //DiscordEcho("* Global game-mode termination.", MAIN_CHANNEL); // Enable when stable
  2531. return 1;
  2532. }
  2533. public OnPlayerRequestClass(playerid, classid){ // Skin selection before spawn.
  2534. if(scriptDebug){
  2535. new message[23 + 4 + MAX_PLAYER_NAME + 1];
  2536. format(message, sizeof(message), "* [%i] %s Class selection.", playerid, getCharacterName(playerid));
  2537. logger(LOGLEVEL_DEBUG, message); // Log event.
  2538. }
  2539. SetPlayerPos(playerid, -185.5514, 944.2042, 15.9337); // In front of Fort Carson city limits sign.
  2540. SetPlayerFacingAngle(playerid, 182.7345); // Charater looks toward the camera.
  2541. SetPlayerCameraPos(playerid, -185.5514, 939.0957, 15.6594); // Further in front of the Fort Carson city limits sign.
  2542. SetPlayerCameraLookAt(playerid, -185.5514, 944.2042, 15.9337); // In front of Fort Carson city limits sign.
  2543. return 1; // Must return one, or skin selection breaks
  2544. }
  2545. public OnPlayerConnect(playerid){
  2546. SetPlayerColor(playerid, COLOR_BLACK);
  2547. // Create & populate variables
  2548. new playername[MAX_PLAYER_NAME + 1], playerip[MAX_SQL_IP + 1];
  2549. playername = getPlayerName(playerid);
  2550. GetPlayerIp(playerid, playerip, sizeof(playerip));
  2551. // Global connection notification
  2552. new admin_message[23 + MAX_PLAYER_NAME + MAX_SQL_IP + 1];
  2553. format(admin_message, sizeof(admin_message), "* [%d] %s (IP: %s) connected.", playerid, getCharacterName(playerid), playerip);
  2554. logger(LOGLEVEL_INFO, admin_message); // Log event
  2555. sendToAdmins(COLOR_NOTICE, admin_message); // Notify all admins.
  2556. // Create IP record or update connection attempts
  2557. new ip_query[109 + MAX_SQL_IP + 1];
  2558. format(ip_query, sizeof(ip_query), "INSERT INTO ip(address) VALUES('%s') ON CONFLICT (address) DO UPDATE SET connections = ip.connections+1", playerip);
  2559. sql_query(sqlHandle, ip_query);
  2560. // Check if IP is banned
  2561. new ip_id = getIPID(playerid);
  2562. new ban_query[75 + MAX_SQL_INTEGER + 1];
  2563. format(ban_query, sizeof(ban_query), "SELECT id, reason FROM ip_ban WHERE ip_id = %i AND expires > NOW()::timestamp", ip_id);
  2564. new Result:ban_result = sql_query(sqlHandle, ban_query);
  2565. if(sql_num_rows(ban_result) > 0){ // Banned
  2566. new kick_message[8 + MAX_SQL_REASON + 1];
  2567. format(kick_message, sizeof(kick_message), "Banned: %s", sql_get_field_assoc_int(ban_result, "reason"));
  2568. kickPlayer(playerid, -1, kick_message, 1);
  2569. }
  2570. // Get user record
  2571. new escaped_username[MAX_PLAYER_NAME + 1], user_query[47 + MAX_PLAYER_NAME + 1]; // Should be longer to allow for escaped characters
  2572. sql_escape_string(sqlHandle, playername, escaped_username, sizeof(escaped_username)); // Escape player name
  2573. format(user_query, sizeof(user_query), "SELECT id FROM \"user\" WHERE name = '%s'", escaped_username);
  2574. //new Result:result = sqlQuery(sqlHandle, user_query); // Middleware broken.
  2575. new Result:result = sql_query(sqlHandle, user_query);
  2576. SetGVarString("client_connect_username", playername, playerid); // Used by register, DIALOG_LOGIN, getUserID & OnGameModeExit
  2577. if(sql_num_rows(result) == 0){ // Unkown user
  2578. SetGVarInt("userlevel", UNREGISTERED_PLAYER, playerid); // Set userlevel unregistered
  2579. print("UNkown user sending to changeName()");
  2580. changeName(playerid, playername); // Check, force and set role-play name
  2581. }
  2582. else{ // Known user
  2583. ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Sign in", "Enter your password to log on", "Log in", "Cancel"); // Show password confirmation dialog
  2584. }
  2585. //return 1;
  2586. }
  2587. public OnPlayerDisconnect(playerid, reason){
  2588. if(GetPlayerState(playerid) != PLAYER_STATE_NONE){ // Only save character if spawned
  2589. savePlayerState(playerid); // Save character
  2590. }
  2591. deleteAllGVars(playerid); // Delete GVars as per https://forum.sa-mp.com/showthread.php?t=151076
  2592. new playername[MAX_PLAYER_NAME + 1], message[40 + 4 + MAX_PLAYER_NAME + 1];
  2593. playername = getPlayerName(playerid);
  2594. switch(reason){
  2595. case 0: format(message, sizeof(message), "* [%i] %s disconnected. (Lost Connection)", playerid, getCharacterName(playerid));
  2596. case 1: format(message, sizeof(message), "* [%i] %s disconnected. (Leaving)", playerid, getCharacterName(playerid));
  2597. case 2: format(message, sizeof(message), "* [%i] %s disconnected. (Kicked)", playerid, getCharacterName(playerid)); // Leave this in place for RCON kicks.
  2598. }
  2599. logger(LOGLEVEL_INFO, message); // Log event
  2600. SendClientMessageToAll(COLOR_NOTICE, message); // Notify all players.
  2601. DiscordEcho(message, ECHO_CHANNEL); // Notify discord.
  2602. return 1;
  2603. }
  2604. public OnPlayerSpawn(playerid){
  2605. if(scriptDebug){ // Log event in case of debugging.
  2606. new message[MAX_PLAYER_NAME + 14 + 1];
  2607. format(message, sizeof(message), "* [%i] %s spawned.", playerid, getCharacterName(playerid));
  2608. logger(LOGLEVEL_DEBUG, message); // Log event.
  2609. }
  2610. if(GetGVarInt("userlevel", playerid) == UNREGISTERED_PLAYER){ // Unregistered player.
  2611. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "SERVER: To reserve your name, save your character, statistics and money, type: /register");
  2612. }
  2613. return 1;
  2614. }
  2615. public OnPlayerDeath(playerid, killerid, reason){
  2616. new message[15 + MAX_PLAYER_NAME + 1];
  2617. format(message, sizeof(message), "* [%d] %s died.", playerid, getCharacterName(playerid)); // TODO Add killerid & reason.
  2618. logger(LOGLEVEL_DEBUG, message); // Log event
  2619. DiscordEcho(message, ADMIN_ECHO_CHANNEL); // Notify Discord admin echo.
  2620. //ResetPlayerMoney(playerid); TODO test if required
  2621. //SpawnPlayer(playerid);
  2622. return 1;
  2623. }
  2624. public OnVehicleSpawn(vehicleid)
  2625. {
  2626. return 1;
  2627. }
  2628. public OnVehicleDeath(vehicleid, killerid)
  2629. {
  2630. return 1;
  2631. }
  2632. public OnPlayerText(playerid, text[]){
  2633. new shortcut_message[128 + 1];
  2634. strfromliteral(shortcut_message, text);
  2635. strdel(shortcut_message, 0, 1); // Remove chat character from text
  2636. switch(strgetfirstc(text)){
  2637. case '`': {
  2638. if(GetGVarInt("chatmode", playerid) == CHAT_LOCAL){
  2639. sendToChat(playerid, CHAT_GLOBAL, shortcut_message, 0, DCC_INVALID_USER);
  2640. }
  2641. else if (GetGVarInt("chatmode", playerid) == CHAT_GLOBAL){
  2642. sendToChat(playerid, CHAT_LOCAL, shortcut_message, 0, DCC_INVALID_USER);
  2643. }
  2644. else{
  2645. sendToChat(playerid, CHAT_GLOBAL, shortcut_message, 0, DCC_INVALID_USER);
  2646. }
  2647. }
  2648. case '~': {sendToChat(playerid, CHAT_GANG, shortcut_message, 0, DCC_INVALID_USER);}
  2649. case '#': {sendToChat(playerid, CHAT_GANG_OC, shortcut_message, 0, DCC_INVALID_USER);}
  2650. case '!': {sendToChat(playerid, CHAT_FACTION, shortcut_message, 0, DCC_INVALID_USER);}
  2651. case '$': {sendToChat(playerid, CHAT_FACTION_OC, shortcut_message, 0, DCC_INVALID_USER);}
  2652. case '^': {sendToChat(playerid, CHAT_VIP, shortcut_message, 0, DCC_INVALID_USER);}
  2653. case '@': {sendToChat(playerid, CHAT_CREW, shortcut_message, 0, DCC_INVALID_USER);}
  2654. case '%': {sendToChat(playerid, CHAT_ADMIN, shortcut_message, 0, DCC_INVALID_USER);}
  2655. case '&': {sendToChat(playerid, CHAT_MANAGEMENT, shortcut_message, 0, DCC_INVALID_USER);}
  2656. case '*': {sendToChat(playerid, CHAT_UNDERCOVER, shortcut_message, 0, DCC_INVALID_USER);}
  2657. case '+': {sendToChat(playerid, CHAT_CALL, shortcut_message, 0, DCC_INVALID_USER);}
  2658. case '-': {sendToChat(playerid, CHAT_SMS, shortcut_message, 0, DCC_INVALID_USER);}
  2659. case '=': {sendToChat(playerid, CHAT_RADIO, shortcut_message, 0, DCC_INVALID_USER);}
  2660. case '>': {
  2661. new recipient_id, message[128 + 1];
  2662. if (sscanf(shortcut_message, "u s", recipient_id, message)){
  2663. SendClientMessage(playerid, COLOR_COMMAND_OUTPUT, "Usage: > <playerid> <message>");
  2664. }
  2665. else{
  2666. sendPM(playerid, message, recipient_id);
  2667. }
  2668. }
  2669. default:{
  2670. new chatmode = GetGVarInt("chatmode", playerid), message[128 + 1];
  2671. strmid(message, text, 0, 128);
  2672. // message = text;
  2673. if(!chatmode){ // Default is local chat
  2674. sendToChat(playerid, CHAT_LOCAL, message, 0, DCC_INVALID_USER);
  2675. }
  2676. else{ // Send to preferred chat
  2677. printf("chatmode: %i", chatmode);
  2678. sendToChat(playerid, chatmode, message, 0, DCC_INVALID_USER);
  2679. }
  2680. }
  2681. }
  2682. return 0; // Return 1 for default behavior, return 0 to disable default output.
  2683. }
  2684. public OnPlayerCommandText(playerid, cmdtext[]){
  2685. if(scriptDebug){ // Log event in case of debugging.
  2686. new message[5 + 4 + MAX_PLAYER_NAME + 128 + 1]; // 128 = samp text input limit.
  2687. format(message, sizeof(message), "[%d] %s: %s", playerid, getCharacterName(playerid), cmdtext);
  2688. logger(LOGLEVEL_COMMAND, message); // Log event
  2689. }
  2690. return 0;
  2691. }
  2692. public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
  2693. {
  2694. return 1;
  2695. }
  2696. public OnPlayerExitVehicle(playerid, vehicleid)
  2697. {
  2698. return 1;
  2699. }
  2700. public OnPlayerStateChange(playerid, newstate, oldstate)
  2701. {
  2702. return 1;
  2703. }
  2704. public OnPlayerEnterCheckpoint(playerid)
  2705. {
  2706. return 1;
  2707. }
  2708. public OnPlayerLeaveCheckpoint(playerid)
  2709. {
  2710. return 1;
  2711. }
  2712. public OnPlayerEnterRaceCheckpoint(playerid)
  2713. {
  2714. return 1;
  2715. }
  2716. public OnPlayerLeaveRaceCheckpoint(playerid)
  2717. {
  2718. return 1;
  2719. }
  2720. public OnRconCommand(cmd[]){ // The website and some cronjobs do RCON commands. TODO create filter not to show some commands to preven spam
  2721. new message[8 + 128 + 1]; // Max samp message legnth = 128.
  2722. format(message, sizeof(message), "* RCON: %s", cmd);
  2723. logger(LOGLEVEL_NOTICE, message); // Log event
  2724. DiscordEcho(message, MANAGEMENT_CHANNEL);
  2725. return 1;
  2726. }
  2727. public OnPlayerRequestSpawn(playerid){ // After picking a skin in class selection.
  2728. SetPlayerColor(playerid, COLOR_WHITE);
  2729. new playername[MAX_PLAYER_NAME + 1], message[14 + MAX_PLAYER_NAME + 1];
  2730. playername = getPlayerName(playerid);
  2731. if(scriptDebug){ // Only log spawns when debuggins script.
  2732. format(message, sizeof(message), "* [%d] %s Chose a character.", playerid, getCharacterName(playerid));
  2733. logger(LOGLEVEL_DEBUG, message); // Log event
  2734. }
  2735. if(GetGVarInt("userlevel", playerid) > UNREGISTERED_PLAYER){ // Registered player
  2736. createCharacterRecord(playerid, getUserID(playerid)); // Save character
  2737. new client_connect_username[MAX_PLAYER_NAME + 1], admin_message[25 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
  2738. GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
  2739. format(admin_message, sizeof(admin_message), "[%i] %s has been created by %s.", playerid, getCharacterName(playerid), client_connect_username);
  2740. DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
  2741. }
  2742. return 1;
  2743. }
  2744. public OnObjectMoved(objectid)
  2745. {
  2746. return 1;
  2747. }
  2748. public OnPlayerObjectMoved(playerid, objectid)
  2749. {
  2750. return 1;
  2751. }
  2752. //public OnPlayerPickUpPickup(playerid, pickupid){} // Replaced byOnPlayerPickUpDynamicPickup() streamer.inc
  2753. public OnPlayerPickUpDynamicPickup(playerid, pickupid){ // Requires streamer
  2754. new type = GetGVarInt("pickup_type", pickupid);
  2755. // Special pickup types first, rugular in the else{} conditional statement
  2756. if(type == PICKUP_PORTAL){
  2757. // Do nothing if the player just used a pickup
  2758. if(GetGVarInt("disable_pickups", playerid)){
  2759. return 0;
  2760. }
  2761. new Float:x = GetGVarFloat("pickup_x", pickupid);
  2762. new Float:y = GetGVarFloat("pickup_y", pickupid);
  2763. new Float:z = GetGVarFloat("pickup_z", pickupid);
  2764. new world = GetGVarInt("pickup_world", pickupid);
  2765. // Don't releport when the exit is not set
  2766. if(x == 0 && y == 0 && z == 0){
  2767. return 0;
  2768. }
  2769. // Create dynamic area and temporarily disable pickups for player
  2770. new area = CreateDynamicCircle(x, y, 1.7, world, -1, playerid);
  2771. SetGVarInt("disable_pickups", area, playerid);
  2772. // Teleport player
  2773. teleportPlayer(playerid, x, y, z, GetGVarInt("pickup_angle", pickupid), world, GetGVarInt("pickup_interior", pickupid));
  2774. }
  2775. else{
  2776. // Do nothing if the player just used a pickup
  2777. if(GetGVarInt("disable_pickups", playerid)){
  2778. return 0;
  2779. }
  2780. // Create dynamic area and temporarily disable pickups for player
  2781. new Float:x, Float:y, Float:z;
  2782. GetPlayerPos(playerid, x, y, z);
  2783. new area = CreateDynamicCircle(x, y, 1, GetPlayerVirtualWorld(playerid), -1, playerid);
  2784. SetGVarInt("disable_pickups", area, playerid);
  2785. // Regular pickup types
  2786. switch(type){
  2787. case PICKUP_FACTION_PD: {
  2788. switch(GetGVarInt("job", playerid)){
  2789. case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_PD, DIALOG_STYLE_MSGBOX, "Active police duty", "Go on police duty as a rookie cop?", "Yes", "No");}
  2790. case JOB_POLICE:{ShowPlayerDialog(playerid, DIALOG_DUTY_PD, DIALOG_STYLE_MSGBOX, "Active police duty", "Go off police duty?", "Yes", "No");}
  2791. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  2792. }
  2793. }
  2794. case PICKUP_FACTION_MD:{
  2795. switch(GetGVarInt("job", playerid)){
  2796. case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_MD, DIALOG_STYLE_MSGBOX, "Active medic duty", "Go on medic duty as a rookie paramedic?", "Yes", "No");}
  2797. case JOB_MEDIC:{ShowPlayerDialog(playerid, DIALOG_DUTY_MD, DIALOG_STYLE_MSGBOX, "Active medic duty", "Go off paramedic duty?", "Yes", "No");}
  2798. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
  2799. }
  2800. }
  2801. case PICKUP_FACTION_FD:{
  2802. printf("jobid: %i", GetGVarInt("job", playerid));
  2803. switch(GetGVarInt("job", playerid)){
  2804. case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_FD, DIALOG_STYLE_MSGBOX, "Active fire duty", "Go on fire duty as a rookie firefighter?", "Yes", "No");}
  2805. case JOB_FIRE:{ShowPlayerDialog(playerid, DIALOG_DUTY_FD, DIALOG_STYLE_MSGBOX, "Active firefighter duty", "Go off firefighter duty?", "Yes", "No");}
  2806. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
  2807. }
  2808. }
  2809. case PICKUP_FACTION_FBI:{
  2810. switch(GetGVarInt("job", playerid)){
  2811. case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_FBI, DIALOG_STYLE_MSGBOX, "Active FBI duty", "Go on FBI duty as a rookie agent?", "Yes", "No");}
  2812. case JOB_FBI:{ShowPlayerDialog(playerid, DIALOG_DUTY_FBI, DIALOG_STYLE_MSGBOX, "Active medic duty", "Go off FBI duty?", "Yes", "No");}
  2813. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
  2814. }
  2815. }
  2816. case PICKUP_FACTION_DMV:{
  2817. switch(GetGVarInt("job", playerid)){
  2818. case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_DMV, DIALOG_STYLE_MSGBOX, "Active DMV duty", "Go on DMV duty as a rookie service officer?", "Yes", "No");}
  2819. case JOB_DMV:{ShowPlayerDialog(playerid, DIALOG_DUTY_DMV, DIALOG_STYLE_MSGBOX, "Active DMV duty", "Go off DMV duty?", "Yes", "No");}
  2820. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
  2821. }
  2822. }
  2823. case PICKUP_FACTION_NEWS:{
  2824. switch(GetGVarInt("job", playerid)){
  2825. case JOB_NONE:{ShowPlayerDialog(playerid, DIALOG_DUTY_NEWS, DIALOG_STYLE_MSGBOX, "Active broadcasting duty", "Go on network duty as a rookie reporter?", "Yes", "No");}
  2826. case JOB_NEWS:{ShowPlayerDialog(playerid, DIALOG_DUTY_NEWS, DIALOG_STYLE_MSGBOX, "Active broadcasting duty", "Go off network duty?", "Yes", "No");}
  2827. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you have another job.");}
  2828. }
  2829. }
  2830. }
  2831. }
  2832. return 1;
  2833. }
  2834. public OnPlayerLeaveDynamicArea(playerid, areaid){ // Requires streamer
  2835. // Reactivate pickup after player leaves it
  2836. new area = GetGVarInt("disable_pickups", playerid);
  2837. if(area == 0 && areaid != 0){ // Stop if player had not had this area disabled (With the exception of areaid 0 as GetVarInt() returns 0 on null)
  2838. return;
  2839. }
  2840. else if(area == 0){ // Player has not had picks disabled
  2841. return;
  2842. }
  2843. if(area == areaid){ // Player had this pickup disabled
  2844. DestroyDynamicArea(GetGVarInt("disable_pickups", playerid));
  2845. DeleteGVar("disable_pickups", playerid);
  2846. }
  2847. }
  2848. public OnVehicleMod(playerid, vehicleid, componentid)
  2849. {
  2850. return 1;
  2851. }
  2852. public OnVehiclePaintjob(playerid, vehicleid, paintjobid)
  2853. {
  2854. return 1;
  2855. }
  2856. public OnVehicleRespray(playerid, vehicleid, color1, color2)
  2857. {
  2858. return 1;
  2859. }
  2860. public OnPlayerSelectedMenuRow(playerid, row)
  2861. {
  2862. return 1;
  2863. }
  2864. public OnPlayerExitedMenu(playerid)
  2865. {
  2866. return 1;
  2867. }
  2868. public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
  2869. {
  2870. return 1;
  2871. }
  2872. public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
  2873. {
  2874. return 1;
  2875. }
  2876. public OnRconLoginAttempt(ip[], password[], success){
  2877. new message[30 + MAX_SQL_IP + 1];
  2878. if(success){
  2879. format(message, sizeof(message), "* [%s] authenticated via RCON.", ip);
  2880. }
  2881. else{
  2882. format(message, sizeof(message), "* [%s] invalid RCON authentication.", ip);
  2883. }
  2884. logger(LOGLEVEL_NOTICE, message); // Log event
  2885. DiscordEcho(message, MANAGEMENT_CHANNEL); // Notify Discord management.
  2886. return 1;
  2887. }
  2888. public OnPlayerUpdate(playerid) // Don't use for now.
  2889. {
  2890. return 1;
  2891. }
  2892. public OnPlayerStreamIn(playerid, forplayerid){
  2893. return 1;
  2894. }
  2895. public OnPlayerStreamOut(playerid, forplayerid)
  2896. {
  2897. return 1;
  2898. }
  2899. public OnVehicleStreamIn(vehicleid, forplayerid)
  2900. {
  2901. return 1;
  2902. }
  2903. public OnVehicleStreamOut(vehicleid, forplayerid)
  2904. {
  2905. return 1;
  2906. }
  2907. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]){
  2908. switch(dialogid){
  2909. case DIALOG_CHANGENAME:{
  2910. if(GetGVarInt("userlevel", playerid) > UNREGISTERED_PLAYER){ // Registered player
  2911. if(!response){ // User aborted
  2912. return 0; // Allow escaping dialogm without forcing to continue
  2913. }
  2914. }
  2915. changeName(playerid, inputtext); // Forced name check and change
  2916. }
  2917. case DIALOG_REGISTER:{
  2918. if(response){ // If they clicked 'Yes' or pressed enter
  2919. // Check password complexity
  2920. new Regex:r = Regex_New("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[0-9!@#\\$%\\^&\\*\\(\\)\\-\\_=+[{\\]}\\\\|;:'\",<.>\\/?]).{8,}$"); // Regex password filter
  2921. new isSecurePassword = Regex_Check(inputtext, r); // Validate name to filter
  2922. Regex_Delete(r);
  2923. if(!isSecurePassword){ // Insecure password
  2924. ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Insecure password", "Enter a secure password, containg at least:\n\n * A lowercase letter (a-z)\n * A capiral letter (A-Z)\n * A number (0-9).\n * A character that is not a letter (0-9!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?).\n * 8 characters.", "Register", "Cancel"); // Show password requirements.
  2925. }
  2926. else { // Secure password
  2927. // Hash password
  2928. new buffer[MAX_SQL_HASH + 1], hash[MAX_SQL_HASH + 1];
  2929. WP_Hash(buffer, sizeof(buffer), inputtext);
  2930. GetGVarString("hash", hash, sizeof(hash), playerid);
  2931. if(isempty(hash)){ // First password dialog
  2932. SetGVarString("hash", buffer, playerid); // Save password has a GVar
  2933. ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Password confirmation", "Repeat your password to confirm.", "Register", "Cancel"); // Show password confirmation dialog
  2934. }
  2935. else{ // Password confirmation
  2936. if(!isequal(hash, buffer)){ // Password does not match confirmation
  2937. DeleteGVar("hash", playerid);
  2938. SendClientMessage(playerid, COLOR_RED, "ERROR: Password does not match password confirmation.");
  2939. ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Password", "Enter the same password twice.", "Continue", "Cancel"); // Password prompt
  2940. }
  2941. else{ // Password matches confirmation
  2942. DeleteGVar("hash", playerid);
  2943. new client_connect_username[MAX_PLAYER_NAME + 1], playerIP[MAX_SQL_IP + 1], escaped_username[MAX_PLAYER_NAME + 1];
  2944. GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid);
  2945. GetPlayerIp(playerid, playerIP, sizeof(playerIP));
  2946. sql_escape_string(sqlHandle, client_connect_username, escaped_username, sizeof(escaped_username));
  2947. // Create user record
  2948. new user_query[61 + MAX_PLAYER_NAME + MAX_SQL_HASH + 1 + MAX_SQL_IP + 1];
  2949. format(user_query, sizeof(user_query), "INSERT INTO \"user\"(name, password) VALUES('%s', '%s')", escaped_username, hash);
  2950. /*new Result:user_result = sql_query(sqlHandle, user_query);
  2951. //new id = sql_insert_id(user_result); // Broken, always returns 0.
  2952. // sql_insert_id workaround*/
  2953. sql_query(sqlHandle, user_query);
  2954. new id = getUserID(playerid); // Get ID user user record
  2955. SetGVarInt("userlevel", REGISTERED_PLAYER, playerid);
  2956. // Create user_ip relation table record
  2957. new user_ip_query[50 + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1 ];
  2958. format(user_ip_query, sizeof(user_ip_query), "INSERT INTO user_ip(id, id) VALUES(%i, %i)", getIPID(playerid), id);
  2959. sql_query(sqlHandle, user_ip_query);
  2960. createCharacterRecord(playerid, id); // Save character
  2961. // Inform user
  2962. new dialogMessage[135 + MAX_PLAYER_NAME + 1], message[31 + MAX_PLAYER_NAME + 1];
  2963. format(dialogMessage, sizeof(dialogMessage), "To login as any of your characters, connect as: \nRemember your username carefully, as you have to use it to connect with SA-MP client!", client_connect_username);
  2964. ShowPlayerDialog(playerid, DIALOG_ACCOUNT_CREATED, DIALOG_STYLE_MSGBOX, "Account created", dialogMessage, "Play", "");
  2965. format(message, sizeof(message), "SERVER: Remember your username, %s!", client_connect_username);
  2966. SendClientMessage(playerid, COLOR_WARNING, message);
  2967. // send discord admin echo
  2968. new admin_message[30 + 4 + MAX_PLAYER_NAME + 1];
  2969. format(admin_message, sizeof(admin_message), "[%i] %s has registered an account.", playerid, client_connect_username);
  2970. DiscordEcho(admin_message, ADMIN_ECHO_CHANNEL);
  2971. }
  2972. }
  2973. }
  2974. }
  2975. else{ // Pressed ESC or clicked cancel
  2976. DeleteGVar("hash", playerid);
  2977. }
  2978. }
  2979. case DIALOG_LOGIN:{
  2980. if(response){ // If they clicked 'Yes' or pressed enter
  2981. // Escape username
  2982. new client_connect_username[MAX_PLAYER_NAME + 1], escaped_username[MAX_PLAYER_NAME + 1];
  2983. GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid);
  2984. sql_escape_string(sqlHandle, client_connect_username, escaped_username, sizeof(escaped_username));
  2985. // Get account
  2986. new user_query[82 + MAX_PLAYER_NAME + 1], hash[MAX_SQL_HASH + 1];
  2987. format(user_query, sizeof(user_query), "SELECT id, password, level FROM \"user\" WHERE name = '%s'", escaped_username);
  2988. new Result:user_result = sql_query(sqlHandle, user_query);
  2989. sql_get_field_assoc_ex(user_result, 0, "password", hash, sizeof(hash));
  2990. // Compare hashes
  2991. new buffer[MAX_SQL_HASH + 1];
  2992. WP_Hash(buffer, sizeof(buffer), inputtext);
  2993. if (!isequal(buffer, hash)){ // Hashes don't match
  2994. // Brute-force protection
  2995. new authentication_count = GetGVarInt("authentication_count", playerid);
  2996. authentication_count++;
  2997. SetGVarInt("authentication_count", authentication_count, playerid);
  2998. ShowPlayerDialog(playerid, DIALOG_LOGIN_FAILED, DIALOG_STYLE_MSGBOX, "Authenticaion failed", "Invalid password.", "Wait", "");
  2999. switch(authentication_count){
  3000. case 0: SetTimerEx("authenticate", 3000, false, "i", playerid); // Return to authentication workflow in 3 second.
  3001. case 1: SetTimerEx("authenticate", 5000, false, "i", playerid); // Return to authentication workflow in 5 seconds.
  3002. case 2: SetTimerEx("authenticate", 7000, false, "i", playerid); // Return to authentication workflow in 7 seconds.
  3003. default: ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", ""); // After 4 failed authentication attempts
  3004. }
  3005. }
  3006. else{ // Hashes match
  3007. // Set userlevel (This has to be done before banning, else the user ban record won't save)
  3008. new userlevel = sql_get_field_assoc_int(user_result, "level");
  3009. printf("Setting userlevel: %i", userlevel);
  3010. SetGVarInt("userlevel", userlevel, playerid);
  3011. // Check bans
  3012. new ban_query[76 + MAX_SQL_INTEGER + 1];
  3013. format(ban_query, sizeof(ban_query), "SELECT user_id FROM user_ban WHERE user_id = %i AND expires > NOW()::timestamp", getUserID(playerid));
  3014. new Result:ban_result = sql_query(sqlHandle, ban_query);
  3015. if(sql_num_rows(ban_result) > 0){ // Banned
  3016. new reason[121 + 1];
  3017. format(reason, sizeof(reason), "Logged in with banned account: %i", sql_get_field_assoc_int(ban_result, "user_id"));
  3018. banPlayer(playerid, -1, reason, 10);
  3019. }
  3020. // Get character names
  3021. characterSelection(playerid);
  3022. }
  3023. }
  3024. else{ // Pressed ESC or clicked cancel
  3025. ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", "");
  3026. }
  3027. }
  3028. case DIALOG_CHANGE_USERNAME:{
  3029. if(response){ // If they clicked 'Yes' or pressed enter
  3030. new Regex:r = Regex_New("^[0-9a-zA-Z\\[\\]\\(\\)\\$@._=]{1,}$"); // Regex name filter
  3031. new isValidName = Regex_Check(inputtext, r);
  3032. Regex_Delete(r);
  3033. if(isValidName){ // Valid name
  3034. // Get user record
  3035. new escaped_username[MAX_PLAYER_NAME + 1], user_query[36 + MAX_PLAYER_NAME + 1];
  3036. sql_escape_string(sqlHandle, inputtext, escaped_username, sizeof(escaped_username)); // Escape player name
  3037. format(user_query, sizeof(user_query), "SELECT id FROM \"user\" WHERE name = '%s'", escaped_username);
  3038. //new Result:result = sqlQuery(sqlHandle, user_query); // Middleware broken.
  3039. new Result:result = sql_query(sqlHandle, user_query);
  3040. if(sql_num_rows(result) > 0){ // Username taken
  3041. ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", "");
  3042. }
  3043. else{ // Username free
  3044. SetGVarString("client_connect_username", inputtext, playerid); // Used by register and DIALOG_LOGIN
  3045. SetPlayerName(playerid, inputtext); // Change name in-game
  3046. return 1; // Do nothing to let player continue class selection
  3047. }
  3048. }
  3049. else{ // Invalid name
  3050. ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Invalid name. Names may only contain numbers (0-9), letters (a-z) & (A-Z) and special characters ([]()$@._=)", "Change", "");
  3051. }
  3052. }
  3053. else{ // Pick another username
  3054. ShowPlayerDialog(playerid, DIALOG_CHANGE_USERNAME, DIALOG_STYLE_INPUT, "Username", "Pick an unregistered username.", "Change", "");
  3055. }
  3056. }
  3057. case DIALOG_CHARACTERS:{ // TODO set color & skin in case of job
  3058. if(response){ // Spawn as character
  3059. new character_array_string[MAX_CHARACTERS_PER_USER * MAX_SQL_INTEGER + 1], character_array[MAX_CHARACTERS_PER_USER + 1];
  3060. GetGVarString("character_array_string", character_array_string, sizeof(character_array_string), playerid);
  3061. DeleteGVar("character_array_string");
  3062. strtobin(character_array, character_array_string);
  3063. new character_query[132 + MAX_PLAYER_NAME + 1], name[24 + 1];
  3064. format(character_query, sizeof(character_query), "SELECT name, skin_id, cash, armour, health, pos_x, pos_y, pos_z, rotation, world_id, interior_id, job_id FROM character WHERE id = %i", character_array[listitem]);
  3065. new Result:character_result = sql_query(sqlHandle, character_query);
  3066. sql_get_field_assoc(character_result, "name", name, sizeof(name));
  3067. new skin_id = sql_get_field_assoc_int(character_result, "skin_id");
  3068. new cash = sql_get_field_assoc_int(character_result, "cash");
  3069. new Float:armour = sql_get_field_assoc_int(character_result, "armour");
  3070. new Float:health = sql_get_field_assoc_int(character_result, "health");
  3071. new Float:pos_x = sql_get_field_assoc_int(character_result, "pos_x");
  3072. new Float:pos_y = sql_get_field_assoc_int(character_result, "pos_y");
  3073. new Float:pos_z = sql_get_field_assoc_int(character_result, "pos_z");
  3074. new Float:rotation = sql_get_field_assoc_int(character_result, "rotation");
  3075. new world_id = sql_get_field_assoc_int(character_result, "world_id");
  3076. new interior_id = sql_get_field_assoc_int(character_result, "interior_id");
  3077. //new job_id = sql_get_field_assoc_int(character_result, "job_id");
  3078. // Temporary bug workaround TODO find cause
  3079. if(pos_x == 0 && pos_y == 0 && pos_z == 0){ // Sometimes this happens. Due to unreliable OnPlayerDisconnect() & OnGamemodeExit(), due to character creation, or due to (forgot the other possiblity, but had a strong hunch)?
  3080. pos_x = -144.0328;
  3081. pos_y = 1225.0564;
  3082. pos_z = 19.8992;
  3083. rotation = 175.5507;
  3084. }
  3085. SetSpawnInfo(playerid, 0, skin_id, pos_x, pos_y, pos_z, rotation, 0, 0, 0, 0, 0, 0);
  3086. SetGVarInt("character_id", character_array[listitem], playerid);
  3087. SetPlayerName(playerid, name); // Change name in-game
  3088. SetPlayerColor(playerid, COLOR_WHITE);
  3089. SpawnPlayer(playerid);
  3090. ResetPlayerMoney(playerid);
  3091. GivePlayerMoney(playerid, cash);
  3092. SetPlayerHealth(playerid, health);
  3093. SetPlayerArmour(playerid, armour);
  3094. SetPlayerVirtualWorld(playerid, world_id);
  3095. SetPlayerInterior(playerid, interior_id);
  3096. // TODO design a way to keep job on rejoin
  3097. // Notify all players
  3098. new message[16 + 4 + MAX_PLAYER_NAME + 1];
  3099. format(message, sizeof(message), "* [%i] %s joined.", playerid, getCharacterName(playerid));
  3100. SendClientMessageToAll(COLOR_NOTICE, message); // Notify all players.
  3101. DiscordEcho(message, ECHO_CHANNEL); // Notify discord public echo
  3102. }
  3103. else{ // New character
  3104. // character cap
  3105. new id = getUserID(playerid);
  3106. new character_query[60 + MAX_SQL_INTEGER + 1];
  3107. format(character_query, sizeof(character_query), "SELECT id FROM character WHERE character_id = %i", id);
  3108. new Result:character_result = sql_query(sqlHandle, character_query);
  3109. printf("%i", sql_num_rows(character_result));
  3110. if(sql_num_rows(character_result) >= MAX_CHARACTERS_PER_USER){ // At or over character limit
  3111. SendClientMessage(playerid, COLOR_WARNING, "SERVER: Maximum characters reached, can not create another.");
  3112. characterSelection(playerid);
  3113. }
  3114. else{
  3115. ShowPlayerDialog(playerid, DIALOG_CHANGENAME, DIALOG_STYLE_INPUT, "Character name", "Pick a name.\n\nExamples:\n Jo_Bo\n Dingle_P._J._Berry\n Jackson_DeForest_Kelley\n MaryJo_Ann_LaFluer", "Change", ""); // Force RP name.
  3116. // changeName(playerid, ""); // Pick name and save character ANNOYING this forces new character creation, no way out.
  3117. }
  3118. }
  3119. }
  3120. case DIALOG_LOGIN_FAILED:{
  3121. ShowPlayerDialog(playerid, DIALOG_LOGIN_FAILED, DIALOG_STYLE_MSGBOX, "Authenticaion failed", "Take some time to think about your password...", "Wait", "Longer");
  3122. }
  3123. case DIALOG_DELETE_CHARACTER:{
  3124. if(response){ // Delete character
  3125. new playername[MAX_PLAYER_NAME + 1];
  3126. playername = getPlayerName(playerid);
  3127. // Checkcharacter amount
  3128. new id = getUserID(playerid), character_query[75 + MAX_SQL_INTEGER + MAX_CHARACTERS_PER_USER_DIGITS + 1];
  3129. format(character_query, sizeof(character_query), "SELECT id, name FROM character WHERE user_id = %i LIMIT %i", id, MAX_CHARACTERS_PER_USER);
  3130. new Result:character_result = sql_query(sqlHandle, character_query);
  3131. if(sql_num_rows(character_result) < 2){ // 1 character or less
  3132. SendClientMessage(playerid, COLOR_WARNING, "SERVER: You can not have less then one character.\nCreate another character,before deleting this one.");
  3133. }
  3134. else{ // More then 1 character
  3135. // delete character record
  3136. new delete_query[50 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
  3137. format(delete_query, sizeof(delete_query), "DELETE FROM character WHERE name = '%s' AND user_id = %i", playername, getUserID(playerid));
  3138. sql_query(sqlHandle, delete_query);
  3139. // infordm admin echo
  3140. new client_connect_username[MAX_PLAYER_NAME + 1], message[28 + 4 + MAX_PLAYER_NAME + MAX_PLAYER_NAME + 1];
  3141. GetGVarString("client_connect_username", client_connect_username, sizeof(client_connect_username), playerid); // Get client connect name
  3142. format(message, sizeof(message), "* [%i] %s has been deleted by it's user: %s", playerid, getCharacterName(playerid), client_connect_username);
  3143. DiscordEcho(message, ADMIN_ECHO_CHANNEL);
  3144. sendToAdmins(COLOR_COMMAND_OUTPUT, message);
  3145. // Player must not be spawned or will be able to esacpe the character menu and continue with character without dartabase record
  3146. ForceClassSelection(playerid);
  3147. TogglePlayerSpectating(playerid, true);
  3148. TogglePlayerSpectating(playerid, false);
  3149. characterSelection(playerid);
  3150. }
  3151. }
  3152. }
  3153. case DIALOG_GOTO:{
  3154. if(response){
  3155. switch(listitem){
  3156. case GOTO_CATEGORY_INTERIOR:{
  3157. dialogGotoInterior(playerid);
  3158. }
  3159. /*case GOTO_CATEGORY_PLAYER:{
  3160. dialogGotoPlayer(playerid);
  3161. }*/
  3162. }
  3163. }
  3164. }
  3165. case DIALOG_GOTO_INTERIOR:{
  3166. if(response){
  3167. switch(listitem){
  3168. case INTERIOR_CATEGORY_AVIATION:{
  3169. ShowPlayerDialog(playerid, DIALOG_GOTO_AVIATION, DIALOG_STYLE_TABLIST, "Aviation interiors", "Francis Intn'l Airport - Ticket sales\tStarting Cutscene\nFrancis Intn'l Airport - Baggage claim\tStarting Cutscene\nShamal cabin\tMission \"Free Fall\"\nAndromada cargo hold\tMission \"Stowaway\"\nLS Airport, Baggage Reclaim\tCutscene in \"Opening Mission\"", "Goto", "Cancel");
  3170. }
  3171. case INTERIOR_CATEGORY_HOUSES:{
  3172. dialogGotoHouses(playerid);
  3173. }
  3174. case INTERIOR_CATEGORY_MISSION:{
  3175. ShowPlayerDialog(playerid, DIALOG_GOTO_MISSION, DIALOG_STYLE_TABLIST, "Mission interiors", "Atrium\tMission \"Just Business\"\tLS\nBig Smoke's Crack Palace\tMission \"End of the Line\"\nJefferson Motel\tMission \"Reuniting the Families\"\tLS\nPleasure Domes/Jizzy's\tMission \"Ice Cold Killa\"\tSF\nRC Battlefield\tMission \"New Model Army\"\nWoozies Apartment/Wu-Zi Mu's\t\tSF\n", "Goto", "Cancel");
  3176. }
  3177. case INTERIOR_CATEGORY_MISSIONEXT:{
  3178. ShowPlayerDialog(playerid, DIALOG_GOTO_MISSIONEXT, DIALOG_STYLE_TABLIST, "Mission exteriors", "Dillimore Gas Station\tMission \"Tanker Commander\"\nLiberty City\tMission \"Saint Marks Bistro\"\nSan Fierro Garage\tDoherty (Locked Camera Position}", "Goto", "Cancel");
  3179. }
  3180. case INTERIOR_CATEGORY_POLICE:{
  3181. ShowPlayerDialog(playerid, DIALOG_GOTO_POLICE, DIALOG_STYLE_LIST, "Police departments", "Las Venturas\nLos Santos\nSan Fierro\nBarbara's love nest", "Goto", "Cancel");
  3182. }
  3183. case INTERIOR_CATEGORY_SEXWORK:{
  3184. ShowPlayerDialog(playerid, DIALOG_GOTO_SEXWORK, DIALOG_STYLE_LIST, "Brothels & stip clubs", "Brother\nBrother2\nBig spread ranch\tBC\n", "Goto", "Cancel");
  3185. }
  3186. case INTERIOR_CATEGORY_SHOPS:{
  3187. dialogGotoShops(playerid);
  3188. }
  3189. case INTERIOR_CATEGORY_STADIA:{
  3190. ShowPlayerDialog(playerid, DIALOG_GOTO_STADIA, DIALOG_STYLE_TABLIST, "Stadia", "Bloodbowl stadium\nKickstart stadium\n8 Track stadium\nDirtbike stadium\n", "Goto", "Cancel");
  3191. }
  3192. }
  3193. }
  3194. else{
  3195. ShowPlayerDialog(playerid, DIALOG_GOTO, DIALOG_STYLE_LIST, "Categories", "Interiors\nPlayers", "Select", "Cancel");
  3196. }
  3197. }
  3198. case DIALOG_GOTO_HOUSES:{
  3199. if(response){
  3200. switch(listitem){
  3201. case INTERIOR_HOUSE_CAT_BURGLARY:{
  3202. ShowPlayerDialog(playerid, DIALOG_GOTO_BURGLARYHOUSE, DIALOG_STYLE_TABLIST, "Burglary houses", "Large\t2 story\t3 bedroom clone of house 9\t\nMedium\t1 story\t1 bedroom\tEast LS\nSmall\t1 story\t1 bedroom\tCalton Heights, SF\nVery large\t2 story\t4 bedrooms\nSmall\t1 story\t2 bedrooms\tJefferson LS\nSmall\t1 story\t2 bedrooms\tEast LS\nSmall\t1 story\t1 bedroom (NO BATHROOM!)", "Goto", "Cancel");
  3203. }
  3204. case INTERIOR_HOUSE_CAT_MISSION:{
  3205. ShowPlayerDialog(playerid, DIALOG_GOTO_MISSIONHOUSE, DIALOG_STYLE_TABLIST, "Mission houses", "Burning Desire house\t\tEast LS\nColonel Furhberger's\tMission \"Home Invasion\"\t Los Flores, LS\nRyder's house\nSweet's house\tCutscene in \"First Date\"\nCrack Den\tMission \"Cleaning The Hood\"", "Goto", "Cancel");
  3206. }
  3207. case INTERIOR_HOUSE_CAT_SAFE:{
  3208. ShowPlayerDialog(playerid, DIALOG_GOTO_SAFEHOUSE, DIALOG_STYLE_TABLIST, "Safe houses", "Golden Bed motel room\t\t\nHashbury house\tHashburry\tSF\nThe Johnson house\tGanton\tLS\nMadd Doggs mansion\tMulholland\tLS\nRed Bed motel Room\nVerdant Bluffs safehouse\tVerdant Bluffs\t LV\nUnused safehouse\tLarge modern safehouse", "Goto", "Cancel");
  3209. }
  3210. case INTERIOR_HOUSE_CAT_U:{
  3211. ShowPlayerDialog(playerid, DIALOG_GOTO_UHOUSE, DIALOG_STYLE_TABLIST, "To be categorized houses", "", "Goto", "Cancel");
  3212. }
  3213. }
  3214. }
  3215. else{
  3216. dialogGotoInterior(playerid);
  3217. }
  3218. }
  3219. case DIALOG_GOTO_SHOPS:{
  3220. if(response){
  3221. switch(listitem){
  3222. case INTERIOR_SHOP_CAT_247:{
  3223. ShowPlayerDialog(playerid, DIALOG_GOTO_247, DIALOG_STYLE_TABLIST, "24/7's", "L-shaped\tBig\tNO EXIT\nOblong\tBig\tNO EXIT\nSquare\tMedium\tCreek, LV\nSquare\tMedium\tNO EXIT\nLong\tSmall\tMulholland\nSquare\tSmall\tWhetstone", "Goto", "Cancel");
  3224. }
  3225. case INTERIOR_SHOP_CAT_AMMUNATION:{
  3226. ShowPlayerDialog(playerid, DIALOG_GOTO_AMMUNATION, DIALOG_STYLE_TABLIST, "Ammunation's", "Ocean Flats\tSF\nPalomino Creek\tLV\nAngel Pine\tSF\nEl Quebrados\tLV\n2 Stories/t with Booth and Range\n Booth\n Range", "Goto", "Cancel");
  3227. }
  3228. case INTERIOR_SHOP_CAT_CASINO:{
  3229. ShowPlayerDialog(playerid, DIALOG_GOTO_SHOP, DIALOG_STYLE_TABLIST, "Casino's", "Caligulas casino\tThe Strip\tLV\nCasino (Redsands West)\tThe Strip\tLV\n4 Dragons casino\tThe Strip\tLV\n Four Dragons' Managerial Suite", "Goto", "Cancel");
  3230. }
  3231. case INTERIOR_SHOP_CAT_MODSHOP:{
  3232. ShowPlayerDialog(playerid, DIALOG_GOTO_MODDING, DIALOG_STYLE_TABLIST, "Modding shops", "Loco Low Co\tLos Santos\nWheel Arch Angels\tSan Fierro\nTransfender", "Goto", "Cancel");
  3233. }
  3234. case INTERIOR_SHOP_CAT_SHOP:{
  3235. ShowPlayerDialog(playerid, DIALOG_GOTO_SHOP, DIALOG_STYLE_TABLIST, "Stores & parlors", "Tattoos\tIdlewood\tLS\nBurger Shot\tWhitewood Estates\nWell Stacked Pizza\tBlueberry\nCluckin' Bell\nRusty Brown's donuts\tMission \"Burning Desire\"\nZero's RC shop\tGarcia\tSF\nThe Welcome Pump\nGanton Gym\tGanton\tLS\nInside Track Betting\nBlastin' Fools Records", "Goto", "Cancel");
  3236. }
  3237. }
  3238. }
  3239. else{
  3240. dialogGotoInterior(playerid);
  3241. }
  3242. }
  3243. case DIALOG_GOTO_247:{
  3244. if(response){
  3245. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
  3246. world = GetPlayerVirtualWorld(playerid);
  3247. switch(listitem){
  3248. case INTERIOR_247_LSHAPED:{
  3249. x = -25.7220;
  3250. y = -187.8216;
  3251. z = 1003.5469;
  3252. interior = 17;
  3253. angle = 5.0760;
  3254. name = "L-shaped ammunation";
  3255. }
  3256. case INTERIOR_247_OBLONG:{
  3257. x = 6.0856;
  3258. y = -28.8966;
  3259. z = 1003.5494;
  3260. interior = 10;
  3261. angle = 5.0365;
  3262. name = "Oblong ammunation";
  3263. }
  3264. case INTERIOR_247_MEDIUM:{
  3265. x = -30.9875;
  3266. y = -89.6806;
  3267. z = 1003.5469;
  3268. interior = 18;
  3269. angle = 359.8401;
  3270. name = "Medium ammunation";
  3271. }
  3272. case INTERIOR_247_MEDIUM_NOEXIT:{
  3273. x = -26.1856;
  3274. y = -140.9164;
  3275. z = 1003.5469;
  3276. interior = 16;
  3277. angle = 2.9087;
  3278. name = "Medium no exit ammunation";
  3279. }
  3280. case INTERIOR_247_LONG:{
  3281. x = -27.844;
  3282. y = 26.6737;
  3283. z = 1003.5573;
  3284. interior = 4;
  3285. angle = 184.3118;
  3286. name = "Small long ammunation";
  3287. }
  3288. case INTERIOR_247_SQAURE:{
  3289. x = -26.8339,
  3290. y = -55.5846,
  3291. z = 1003.5469,
  3292. interior = 6,
  3293. angle = 3.9528;
  3294. name = "Small square ammunation";
  3295. }
  3296. }
  3297. gotoCallback(x, y, z, world, interior, angle, name);
  3298. }
  3299. else{dialogGotoShops(playerid);}
  3300. }
  3301. case DIALOG_GOTO_AVIATION:{
  3302. if(response){
  3303. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[39 + 1];
  3304. world = GetPlayerVirtualWorld(playerid);
  3305. switch(listitem){
  3306. case INTERIOR_AVIATION_TICKET:{
  3307. x = -1827.147338;
  3308. y = 7.207418;
  3309. z = 1061.143554;
  3310. interior = 14;
  3311. angle = 335.3199;
  3312. name = "Francis Intn'l Airport - Ticket sales";
  3313. }
  3314. case INTERIOR_AVIATION_BAGGAGE:{
  3315. x = -1855.568725;
  3316. y = 41.263156;
  3317. z = 1061.143554;
  3318. interior = 14;
  3319. angle = 335.3199;
  3320. name = "Francis Intn'l Airport - Baggage claim";
  3321. }
  3322. case INTERIOR_AVIATION_SHAMAL:{
  3323. x = 2.384830;
  3324. y = 33.103397;
  3325. z = 1199.849976 ;
  3326. interior = 1;
  3327. angle = 359.8401;
  3328. name = "Shamal cabin";
  3329. }
  3330. case INTERIOR_AVIATION_ANDROMADA:{
  3331. x = 315.856170;
  3332. y = 1024.496459;
  3333. z = 1949.797363;
  3334. interior = 9;
  3335. angle = 359.6368;
  3336. name = "Andromada cargo hold";
  3337. }
  3338. case INTERIOR_AVIATION_LSAIRPORT:{
  3339. x = -1870.80;
  3340. y = 59.81;
  3341. z = 1056.25;
  3342. interior = 14;
  3343. angle = 85.8541;
  3344. name = "LS Airport, Baggage Reclaim";
  3345. }
  3346. }
  3347. gotoCallback(x, y, z, world, interior, angle, name);
  3348. }
  3349. else{dialogGotoInterior(playerid);}
  3350. }
  3351. case DIALOG_GOTO_AMMUNATION:{ // TODO there are more ammunations that deserve a booth and range teleport
  3352. if(response){
  3353. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
  3354. world = GetPlayerVirtualWorld(playerid);
  3355. switch(listitem){
  3356. case INTERIOR_AMMU_OCEAN:{
  3357. x = 286.148987;
  3358. y = -40.644398 ;
  3359. z = 1001.569946;
  3360. interior = 1;
  3361. angle = 0.7529;
  3362. name = "Ocean Flats, SF";
  3363. }
  3364. case INTERIOR_AMMU_PALOMINO:{
  3365. x = 286.800995;
  3366. y = -82.547600;
  3367. z = 1001.539978;
  3368. interior = 4;
  3369. angle = 290.2195;
  3370. name = "Palomino Creek, LV";
  3371. }
  3372. case INTERIOR_AMMU_ANGEL:{
  3373. x = 296.919983;
  3374. y = -108.071999;
  3375. z = 1001.569946;
  3376. interior = 6;
  3377. angle = 290.2195;
  3378. name = "Angel Pine, SF";
  3379. }
  3380. case INTERIOR_AMMU_QUEBRADOS:{
  3381. x = 316.524994;
  3382. y = -167.706985;
  3383. z = 999.661987;
  3384. interior = 6;
  3385. angle = 10.3031;
  3386. name = "El Quebrados, LV";
  3387. }
  3388. case INTERIOR_AMMU_2STORIES:{
  3389. x = 314.820984;
  3390. y = -141.431992;
  3391. z = 999.661987;
  3392. interior = 7;
  3393. angle = 20.2254;
  3394. name = "2 Stories, with booth and range";
  3395. }
  3396. case INTERIOR_AMMU_BOOTH:{
  3397. x = 302.292877;
  3398. y = -143.139099;
  3399. z = 1004.062500;
  3400. interior = 7;
  3401. angle = 20.2254;
  3402. name = "Booth";
  3403. }
  3404. case INTERIOR_AMMU_RANGE:{
  3405. x = 280.795104;
  3406. y = -135.203353;
  3407. z = 1004.062500;
  3408. interior = 7;
  3409. angle = 20.2254;
  3410. name = "Range";
  3411. }
  3412. }
  3413. gotoCallback(x, y, z, world, interior, angle, name);
  3414. }
  3415. else{dialogGotoShops(playerid);}
  3416. }
  3417. case DIALOG_GOTO_BURGLARYHOUSE:{
  3418. if(response){
  3419. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[45 + 1];
  3420. world = GetPlayerVirtualWorld(playerid);
  3421. switch(listitem){
  3422. case INTERIOR_BURGLARY_LARGE:{
  3423. x = 235.508994;
  3424. y = 1189.169897;
  3425. z = 1080.339966;
  3426. interior = 3;
  3427. angle = 349.4844;
  3428. name = "Large: 2 story, 3 bedroom clone of house 9";
  3429. }
  3430. case INTERIOR_BURGLARY_MEDIUM:{
  3431. x = 225.756989;
  3432. y = 1240.000000;
  3433. z = 1082.149902;
  3434. interior = 2;
  3435. angle = 96.2852;
  3436. name = "Medium: 1 story, 1 bedroom";
  3437. }
  3438. case INTERIOR_BURGLARY_SMALL:{
  3439. x = 223.043991;
  3440. y = 1289.259888;
  3441. z = 1082.199951;
  3442. interior = 1;
  3443. angle = 359.868;
  3444. name = "Small: 1 story, 1 bedroom";
  3445. }
  3446. case INTERIOR_BURGLARY_VERYLARGE:{
  3447. x = 225.630997;
  3448. y = 1022.479980;
  3449. z = 1084.069946;
  3450. interior = 7;
  3451. angle = 270.2654;
  3452. name = "VERY Large: 2 story, 4 bedrooms";
  3453. }
  3454. case INTERIOR_BURGLARY_5:{
  3455. x = 295.138977;
  3456. y = 1474.469971;
  3457. z = 1080.519897;
  3458. interior = 15;
  3459. angle = 0;
  3460. name = "Small: 1 story, 2 bedrooms";
  3461. }
  3462. case INTERIOR_BURGLARY_6:{
  3463. x = 328.493988;
  3464. y = 1480.589966;
  3465. z = 1084.449951;
  3466. interior = 15;
  3467. angle = 0;
  3468. name = "Small: 1 story, 2 bedrooms";
  3469. }
  3470. case INTERIOR_BURGLARY_NOBATH:{
  3471. x = 385.803986;
  3472. y = 1471.769897;
  3473. z = 1080.209961;
  3474. interior = 15;
  3475. angle = 0;
  3476. name = "Small: 1 story, 1 bedroom (NO BATHROOM!)";
  3477. }
  3478. case INTERIOR_BURGLARY_4:{
  3479. x = 239.2819;
  3480. y = 1114.1991;
  3481. z = 1080.9922;
  3482. world = GetPlayerVirtualWorld(playerid);
  3483. interior = 5;
  3484. angle = 270.2654;
  3485. name = "Burglary House X4";
  3486. }
  3487. }
  3488. gotoCallback(x, y, z, world, interior, angle, name);
  3489. }
  3490. else{dialogGotoHouses(playerid);}
  3491. }
  3492. case DIALOG_GOTO_CASINO:{
  3493. if(response){
  3494. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
  3495. world = GetPlayerVirtualWorld(playerid);
  3496. switch(listitem){
  3497. case INTERIOR_CASINO_CALIGULAS:{
  3498. x = 2233.8032;
  3499. y = 1712.2303;
  3500. z = 1011.7632;
  3501. interior = 1;
  3502. angle = 184.3891;
  3503. name = "Caligulas Casino";
  3504. }
  3505. case INTERIOR_CASINO_REDLAND:{
  3506. x = 1118.8878;
  3507. y = -10.2737;
  3508. z = 1002.0859;
  3509. interior = 12;
  3510. angle = 165.8482;
  3511. name = "Casino (Redsands West)";
  3512. }
  3513. case INTERIOR_CASINO_4DRAGONS:{
  3514. x = 2016.2699;
  3515. y = 1017.7790;
  3516. z = 996.8750;
  3517. interior = 10;
  3518. angle = 88.0055;
  3519. name = "4 Dragons Casino";
  3520. }
  3521. case INTERIOR_CASINO_4DRAGONSUITE:{
  3522. x = 2003.1178;
  3523. y = 1015.1948;
  3524. z = 33.008;
  3525. world = GetPlayerVirtualWorld(playerid);
  3526. interior = 11;
  3527. angle = 351.5789;
  3528. name = "Four Dragons' Managerial Suite";
  3529. }
  3530. }
  3531. gotoCallback(x, y, z, world, interior, angle, name);
  3532. }
  3533. else{dialogGotoInterior(playerid);}
  3534. }
  3535. case DIALOG_GOTO_MISSION:{
  3536. if(response){
  3537. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
  3538. world = GetPlayerVirtualWorld(playerid);
  3539. switch(listitem){
  3540. case INTERIOR_MISSION_ATRIUM:{
  3541. x = 1726.18;
  3542. y = -1641.00;
  3543. z = 20.23;
  3544. interior = 18;
  3545. angle = 172.4193;
  3546. name = "Atrium";
  3547. }
  3548. case INTERIOR_MISSION_BIGSMOKE:{
  3549. x = 2567.52;
  3550. y = -1294.59;
  3551. z = 1063.25 ;
  3552. interior = 2;
  3553. angle = 254.9548;
  3554. name = "Big Smoke's Crack Palace";
  3555. }
  3556. case INTERIOR_MISSION_JEFFERSON:{
  3557. x = 2220.26;
  3558. y = -1148.01;
  3559. z = 1025.80;
  3560. interior = 15;
  3561. angle = 273.7328;
  3562. name = "Jefferson Motel";
  3563. }
  3564. case INTERIOR_MISSION_JIZZY:{
  3565. x = -2637.69;
  3566. y = 1404.24;
  3567. z = 906.46;
  3568. interior = 3;
  3569. angle = 94.6794;
  3570. name = "Pleasure Domes/Jizzy's";
  3571. }
  3572. case INTERIOR_MISSION_RC:{
  3573. x = -1079.99;
  3574. y = 1061.58;
  3575. z = 1343.04;
  3576. interior = 10;
  3577. angle = 274.5268;
  3578. name = "RC Battlefield";
  3579. }
  3580. case INTERIOR_MISSION_WUZI:{
  3581. x = -2158.72;
  3582. y = 641.29;
  3583. z = 1052.38;
  3584. interior = 1;
  3585. angle = 86.5402;
  3586. name = "Woozies Apartment/Wu-Zi Mu's";
  3587. }
  3588. }
  3589. gotoCallback(x, y, z, world, interior, angle, name);
  3590. }
  3591. else{dialogGotoInterior(playerid);}
  3592. }
  3593. case DIALOG_GOTO_MISSIONEXT:{
  3594. if(response){
  3595. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
  3596. world = GetPlayerVirtualWorld(playerid);
  3597. switch(listitem){
  3598. case INTERIOR_MISSIONEXT_GAS:{
  3599. x = 664.19;
  3600. y = -570.73;
  3601. z = 16.34;
  3602. interior = 0;
  3603. angle = 264.9829;
  3604. name = "Dillimore Gas Station";
  3605. }
  3606. case INTERIOR_MISSIONEXT_LIBERTY:{ // TODO Create extra interior inside the shop
  3607. x = -750.80;
  3608. y = 491.00;
  3609. z = 1371.70;
  3610. interior = 1;
  3611. angle = 71.7782;
  3612. name = "Liberty City";
  3613. }
  3614. case INTERIOR_MISSIONEXT_SFGARAGE:{ // TODO Create extra interior of area that does not capture the camera & see about the camera camera capturing (Use it for broadcast? & In other world or interior place more usable?)
  3615. x = -2042.42;
  3616. y = 178.59;
  3617. z = 28.84;
  3618. interior = 1;
  3619. angle = 156.2153;
  3620. name = "San Fierro Garage Interior";
  3621. }
  3622. }
  3623. gotoCallback(x, y, z, world, interior, angle, name);
  3624. }
  3625. else{dialogGotoInterior(playerid);}
  3626. }
  3627. case DIALOG_GOTO_MISSIONHOUSE:{
  3628. if(response){
  3629. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
  3630. world = GetPlayerVirtualWorld(playerid);
  3631. switch(listitem){
  3632. case INTERIOR_MISSIONHOUSE_DESIRE:{
  3633. x = 2338.32;
  3634. y = -1180.61;
  3635. z = 1027.98;
  3636. interior = 5;
  3637. angle = 99.1864;
  3638. name = "Burning Desire House";
  3639. }
  3640. case INTERIOR_MISSIONHOUSE_COLONEL:{
  3641. x = 2807.63;
  3642. y = -1170.15;
  3643. z = 1025.57;
  3644. interior = 8;
  3645. angle = 193.7117;
  3646. name = "Colonel Furhberger's";
  3647. }
  3648. case INTERIOR_MISSIONHOUSE_RYDER:{
  3649. x = 2451.77;
  3650. y = -1699.80;
  3651. z = 1013.51;
  3652. interior = 2;
  3653. angle = 314.5253;
  3654. name = "Ryder's House";
  3655. }
  3656. case INTERIOR_MISSIONHOUSE_SWEET:{
  3657. x = 2535.83;
  3658. y = -1674.32;
  3659. z = 1015.50;
  3660. interior = 1;
  3661. angle = 260.9709;
  3662. name = "Sweet's House";
  3663. }
  3664. case INTERIOR_MISSIONHOUSE_CRACK:{
  3665. x = 318.565;
  3666. y = 1115.210;
  3667. z = 1082.98;
  3668. interior = 5;
  3669. angle = 267.459;
  3670. name = "Crack den";
  3671. }
  3672. }
  3673. gotoCallback(x, y, z, world, interior, angle, name);
  3674. }
  3675. else{dialogGotoHouses(playerid);}
  3676. }
  3677. case DIALOG_GOTO_GARAGE:{
  3678. if(response){
  3679. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
  3680. world = GetPlayerVirtualWorld(playerid);
  3681. switch(listitem){
  3682. case INTERIOR_GARAGE_LOCO:{
  3683. x = 616.7820;
  3684. y = -74.8151;
  3685. z = 997.6350;
  3686. interior = 2;
  3687. angle = 320.9263;
  3688. name = "Loco Low Co";
  3689. }
  3690. case INTERIOR_GARAGE_WHEEL:{
  3691. x = 615.2851;
  3692. y = -124.2390;
  3693. z = 997.6350;
  3694. interior = 3;
  3695. angle = 266.5704;
  3696. name = "Wheel Arch Angels";
  3697. }
  3698. case INTERIOR_GARAGE_TRANSFENDER:{
  3699. x = 617.5380;
  3700. y = -1.9900;
  3701. z = 1000.6829;
  3702. interior = 1;
  3703. angle = 15.6789;
  3704. name = "Transfender";
  3705. }
  3706. case INTERIOR_GARAGE_SF:{
  3707. x = -2041.2334;
  3708. y = 178.3969;
  3709. z = 28.8465;
  3710. world = GetPlayerVirtualWorld(playerid);
  3711. interior = 1;
  3712. angle = 156.2153;
  3713. name = "San Fierro Garage";
  3714. }
  3715. }
  3716. gotoCallback(x, y, z, world, interior, angle, name);
  3717. }
  3718. else{dialogGotoShops(playerid);}
  3719. }
  3720. case DIALOG_GOTO_POLICE:{
  3721. if(response){
  3722. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[30 + 1];
  3723. world = GetPlayerVirtualWorld(playerid);
  3724. switch(listitem){
  3725. case INTERIOR_PD_LV:{
  3726. x = 288.4723;
  3727. y = 170.0647;
  3728. z = 1007.1794;
  3729. interior = 3;
  3730. angle = 22.0477;
  3731. name = "Las Venturas police deparment";
  3732. }
  3733. case INTERIOR_PD_LS:{
  3734. x = 246.6695;
  3735. y = 65.8039;
  3736. z = 1003.6406;
  3737. interior = 6;
  3738. angle = 7.9562;
  3739. name = "Los Santos police deparment";
  3740. }
  3741. case INTERIOR_PD_SF:{
  3742. x = 246.0688;
  3743. y = 108.9703;
  3744. z = 1003.2188;
  3745. interior = 10;
  3746. angle = 0.2922;
  3747. name = "San Fierro police deparment";
  3748. }
  3749. case INTERIOR_PD_BARBARA:{
  3750. x = 322.5014;
  3751. y = 303.6906;
  3752. z = 999.1484;
  3753. interior = 5;
  3754. angle = 8.1747;
  3755. name = "Barbara's Love nest";
  3756. }
  3757. }
  3758. gotoCallback(x, y, z, world, interior, angle, name);
  3759. }
  3760. else{dialogGotoInterior(playerid);}
  3761. }
  3762. case DIALOG_GOTO_SAFEHOUSE:{
  3763. if(response){
  3764. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
  3765. world = GetPlayerVirtualWorld(playerid);
  3766. switch(listitem){
  3767. case INTERIOR_HOUSE_GOLDEN:{
  3768. x = 2251.85;
  3769. y = -1138.16;
  3770. z = 1050.63;
  3771. interior = 9;
  3772. angle = 167.3959;
  3773. name = "Golden Bed motel room";
  3774. }
  3775. case INTERIOR_HOUSE_HASHBURY:{
  3776. x = 2260.76;
  3777. y = -1210.45;
  3778. z = 1049.02;
  3779. interior = 10;
  3780. angle = 266.88;
  3781. name = "Hashbury house";
  3782. }
  3783. case INTERIOR_HOUSE_JOHNSON:{
  3784. x = 2496.65;
  3785. y = -1696.55;
  3786. z = 1014.74;
  3787. interior = 3;
  3788. angle = 179.2174;
  3789. name = "The Johnson house";
  3790. }
  3791. case INTERIOR_HOUSE_MADDDOGG:{
  3792. x = 1299.14;
  3793. y = -794.77;
  3794. z = 1084.00;
  3795. interior = 5;
  3796. angle = 231.3418;
  3797. name = "Madd Doggs mansion";
  3798. }
  3799. case INTERIOR_HOUSE_RED:{
  3800. x = 2262.83;
  3801. y = -1137.71;
  3802. z = 1050.63;
  3803. interior = 10;
  3804. angle = 266.88;
  3805. name = "Red Bed motel room";
  3806. }
  3807. case INTERIOR_HOUSE_VERDANT:{
  3808. x = 2365.42;
  3809. y = -1131.85;
  3810. z = 1050.88;
  3811. interior = 8;
  3812. angle = 177.3947;
  3813. name = "Verdant Bluffs safehouse";
  3814. }
  3815. case INTERIOR_HOUSE_UNUSED:{
  3816. x = 2324.33;
  3817. y = -1144.79;
  3818. z = 1050.71;
  3819. interior = 12;
  3820. angle = 269.0954;
  3821. name = "Unused safe house";
  3822. }
  3823. case INTERIOR_HOUSE_1:{
  3824. x = 2233.6919;
  3825. y = -1112.8107;
  3826. z = 1050.8828;
  3827. world = GetPlayerVirtualWorld(playerid);
  3828. interior = 5;
  3829. angle = 8.6483;
  3830. name = "Safe House group 1";
  3831. }
  3832. case INTERIOR_HOUSE_2:{
  3833. x = 1211.2484;
  3834. y = 1049.0234;
  3835. z = 359.941;
  3836. world = GetPlayerVirtualWorld(playerid);
  3837. interior = 6;
  3838. angle = 170.9341;
  3839. name = "Safe House group 2";
  3840. }
  3841. case INTERIOR_HOUSE_3:{
  3842. x = 2319.1272;
  3843. y = -1023.9562;
  3844. z = 1050.2109;
  3845. world = GetPlayerVirtualWorld(playerid);
  3846. interior = 9;
  3847. angle = 167.3959;
  3848. name = "Safe House group 3";
  3849. }
  3850. case INTERIOR_HOUSE_4:{
  3851. x = 2261.0977;
  3852. y = -1137.8833;
  3853. z = 1050.6328;
  3854. world = GetPlayerVirtualWorld(playerid);
  3855. interior = 10;
  3856. angle = 266.88;
  3857. name = "Safe House group 4";
  3858. }
  3859. }
  3860. gotoCallback(x, y, z, world, interior, angle, name);
  3861. }
  3862. else{dialogGotoHouses(playerid);}
  3863. }
  3864. case DIALOG_GOTO_SHOP:{
  3865. if(response){
  3866. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[34 + 1];
  3867. world = GetPlayerVirtualWorld(playerid);
  3868. switch(listitem){
  3869. case INTERIOR_SHOP_TATTOO:{
  3870. x = -203.0764;
  3871. y = -24.1658;
  3872. z = 1002.2734;
  3873. interior = 16;
  3874. angle = 252.8154;
  3875. name = "Tattoos";
  3876. }
  3877. case INTERIOR_SHOP_RC:{
  3878. x = -2240.00;
  3879. y = 131.00;
  3880. z = 1035.40;
  3881. interior = 6;
  3882. angle = 269.0954;
  3883. name = "Zero's RC shop";
  3884. }
  3885. case INTERIOR_SHOP_GANTONGYM:{
  3886. x = 770.8033;
  3887. y = -0.7033;
  3888. z = 1000.7267;
  3889. world = GetPlayerVirtualWorld(playerid);
  3890. interior = 5;
  3891. angle = 22.8599;
  3892. name = "Ganton Gym";
  3893. }
  3894. case INTERIOR_SHOP_BETTING:{
  3895. x = 830.6016;
  3896. y = 5.9404;
  3897. z = 1004.1797;
  3898. world = GetPlayerVirtualWorld(playerid);
  3899. interior = 3;
  3900. angle = 125.8149;
  3901. name = "Inside Track Betting";
  3902. }
  3903. case INTERIOR_SHOP_RECORDS:{
  3904. x = 1037.8276;
  3905. y = 0.397;
  3906. z = 1001.2845;
  3907. world = GetPlayerVirtualWorld(playerid);
  3908. interior = 3;
  3909. angle = 353.9335;
  3910. name = "Blastin' Fools Records";
  3911. }
  3912. case INTERIOR_SHOP_PROLAPS:{
  3913. x = 206.4627;
  3914. y = -137.7076;
  3915. z = 1003.0938;
  3916. world = GetPlayerVirtualWorld(playerid);
  3917. interior = 3;
  3918. angle = 10.9347;
  3919. name = "Pro-Laps";
  3920. }
  3921. case INTERIOR_SHOP_SEX:{
  3922. x = -100.2674;
  3923. y = -22.9376;
  3924. z = 1000.7188;
  3925. world = GetPlayerVirtualWorld(playerid);
  3926. interior = 3;
  3927. angle = 17.285;
  3928. name = "Sex Shop";
  3929. }
  3930. case INTERIOR_SHOP_LVTATTOO:{
  3931. x = -201.2236;
  3932. y = -43.2465;
  3933. z = 1002.2734;
  3934. world = GetPlayerVirtualWorld(playerid);
  3935. interior = 3;
  3936. angle = 45.8613;
  3937. name = "Las Venturas Tattoo parlor";
  3938. }
  3939. case INTERIOR_SHOP_SFTATTOO:{
  3940. x = -202.9381;
  3941. y = -6.7006;
  3942. z = 1002.2734;
  3943. world = GetPlayerVirtualWorld(playerid);
  3944. interior = 17;
  3945. angle = 204.2693;
  3946. name = "Lost San Fierro Tattoo parlor";
  3947. }
  3948. case INTERIOR_SHOP_VICTIM:{
  3949. x = 225.0306;
  3950. y = -9.1838;
  3951. z = 1002.218;
  3952. world = GetPlayerVirtualWorld(playerid);
  3953. interior = 5;
  3954. angle = 85.5322;
  3955. name = "Victim";
  3956. }
  3957. case INTERIOR_SHOP_BELTGYM:{
  3958. x = 773.7318;
  3959. y = -74.6957;
  3960. z = 1000.6542;
  3961. world = GetPlayerVirtualWorld(playerid);
  3962. interior = 7;
  3963. angle = 5.2304;
  3964. name = "Below The Belt Gym (Las Venturas)";
  3965. }
  3966. case INTERIOR_SHOP_URBAN:{
  3967. x = 204.1174;
  3968. y = -46.8047;
  3969. z = 1001.8047;
  3970. world = GetPlayerVirtualWorld(playerid);
  3971. interior = 1;
  3972. angle = 357.5777;
  3973. name = "SubUrban";
  3974. }
  3975. case INTERIOR_SHOP_ZIP:{
  3976. x = 161.4048;
  3977. y = -94.2416;
  3978. z = 1001.8047;
  3979. world = GetPlayerVirtualWorld(playerid);
  3980. interior = 18;
  3981. angle = 0.7938;
  3982. name = "Zip";
  3983. }
  3984. case INTERIOR_SHOP_LSTATTOO:{
  3985. x = -202.842;
  3986. y = -24.0325;
  3987. z = 1002.2734;
  3988. world = GetPlayerVirtualWorld(playerid);
  3989. interior = 16;
  3990. angle = 252.8154;
  3991. name = "Los Santos Tattoo Parlor";
  3992. }
  3993. case INTERIOR_SHOP_BINCO:{
  3994. x = 207.5219;
  3995. y = -109.7448;
  3996. z = 1005.1328;
  3997. world = GetPlayerVirtualWorld(playerid);
  3998. interior = 15;
  3999. angle = 358.62;
  4000. name = "Binco";
  4001. }
  4002. case INTERIOR_SHOP_COBRAGYM:{
  4003. x = 773.8887;
  4004. y = -47.7698;
  4005. z = 1000.5859;
  4006. world = GetPlayerVirtualWorld(playerid);
  4007. interior = 6;
  4008. angle = 10.7161;
  4009. name = "Cobra Gym";
  4010. }
  4011. case INTERIOR_SHOP_DIDIER:{
  4012. x = 204.1658;
  4013. y = -165.7678;
  4014. z = 1000.5234;
  4015. world = GetPlayerVirtualWorld(playerid);
  4016. interior = 14;
  4017. angle = 181.7583;
  4018. name = "Didier Sachs";
  4019. }
  4020. }
  4021. gotoCallback(x, y, z, world, interior, angle, name);
  4022. }
  4023. else{dialogGotoShops(playerid);}
  4024. }
  4025. case DIALOG_GOTO_STADIA:{
  4026. if(response){
  4027. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[25 + 1];
  4028. world = GetPlayerVirtualWorld(playerid);
  4029. switch(listitem){
  4030. case INTERIOR_STADIUM_BLOODBOWL:{
  4031. x = -1394.20;
  4032. y = 987.62;
  4033. z = 1023.96;
  4034. interior = 15;
  4035. angle = 0.7013;
  4036. name = "Bloodbowl Stadium";
  4037. }
  4038. case INTERIOR_STADIUM_KICKSTART:{
  4039. x = -1410.72;
  4040. y = 1591.16;
  4041. z = 1052.53;
  4042. interior = 14;
  4043. angle = 159.1255;
  4044. name = "Kickstart Stadium";
  4045. }
  4046. case INTERIOR_STADIUM_8TRACK:{
  4047. x = -1395.958;
  4048. y = -208.197;
  4049. z = 1051.170;
  4050. interior = 7;
  4051. angle = 355.8576;
  4052. name = "8 Track Stadium";
  4053. }
  4054. case INTERIOR_STADIUM_DIRTBIKE:{
  4055. x = -1424.9319;
  4056. y = -664.5869;
  4057. z = 1059.8585;
  4058. interior = 4;
  4059. angle = 170.9341;
  4060. name = "Dirtbike Stadium";
  4061. }
  4062. }
  4063. gotoCallback(x, y, z, world, interior, angle, name);
  4064. }
  4065. else{dialogGotoInterior(playerid);}
  4066. }
  4067. case DIALOG_GOTO_SEXWORK:{
  4068. if(response){
  4069. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
  4070. world = GetPlayerVirtualWorld(playerid);
  4071. switch(listitem){
  4072. case INTERIOR_SEXWORK_BROTHEL:{
  4073. x = 974.0177;
  4074. y = -9.5937;
  4075. z = 1001.1484;
  4076. world = GetPlayerVirtualWorld(playerid);
  4077. interior = 3;
  4078. angle = 22.6045;
  4079. name = "Brothel";
  4080. }
  4081. case INTERIOR_SEXWORK_BROTHEL2:{
  4082. x = 961.9308;
  4083. y = -51.9071;
  4084. z = 1001.1172;
  4085. world = GetPlayerVirtualWorld(playerid);
  4086. interior = 3;
  4087. angle = 95.5381;
  4088. name = "Brothel2";
  4089. }
  4090. case INTERIOR_SEXWORK_BIGSPREAD:{
  4091. x = 1212.1489;
  4092. y = -28.5388;
  4093. z = 1000.9531;
  4094. world = GetPlayerVirtualWorld(playerid);
  4095. interior = 3;
  4096. angle = 170.5692;
  4097. name = "The Big Spread Ranch";
  4098. }
  4099. case INTERIOR_SEXWORK_STIPCLUB:{
  4100. x = 1204.6689;
  4101. y = -13.5429;
  4102. z = 1000.9219;
  4103. world = GetPlayerVirtualWorld(playerid);
  4104. interior = 2;
  4105. angle = 350.0204;
  4106. name = "The Pig Pen (strip club 2)";
  4107. }
  4108. }
  4109. gotoCallback(x, y, z, world, interior, angle, name);
  4110. }
  4111. else{dialogGotoInterior(playerid);}
  4112. }
  4113. case DIALOG_GOTO_WAREHOUSE:{
  4114. if(response){
  4115. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
  4116. world = GetPlayerVirtualWorld(playerid);
  4117. switch(listitem){
  4118. case INTERIOR_WAREHOUSE_1:{
  4119. x = 1290.4106;
  4120. y = 1.9512;
  4121. z = 1001.0201;
  4122. world = GetPlayerVirtualWorld(playerid);
  4123. interior = 18;
  4124. angle = 179.9419;
  4125. name =" Warehouse 1";
  4126. }
  4127. case INTERIOR_WAREHOUSE_2:{
  4128. x = 1412.1472;
  4129. y = -2.2836;
  4130. z = 1000.9241;
  4131. world = GetPlayerVirtualWorld(playerid);
  4132. interior = 1;
  4133. angle = 114.661;
  4134. name = "Warehouse 2";
  4135. }
  4136. }
  4137. gotoCallback(x, y, z, world, interior, angle, name);
  4138. }
  4139. else{dialogGotoInterior(playerid);}
  4140. }
  4141. case DIALOG_GOTO_BARBER:{
  4142. if(response){
  4143. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
  4144. world = GetPlayerVirtualWorld(playerid);
  4145. switch(listitem){
  4146. case INTERIOR_BARBER_1:{
  4147. x = 418.4666;
  4148. y = -80.4595;
  4149. z = 1001.8047;
  4150. world = GetPlayerVirtualWorld(playerid);
  4151. interior = 3;
  4152. angle = 343.2358;
  4153. name = "Barber Shop";
  4154. }
  4155. case INTERIOR_BARBER_2:{
  4156. x = 414.2987;
  4157. y = -18.8044;
  4158. z = 1001.8047;
  4159. world = GetPlayerVirtualWorld(playerid);
  4160. interior = 2;
  4161. angle = 41.4265;
  4162. name = "Barber Shop 2 (Reece's)";
  4163. }
  4164. case INTERIOR_BARBER_3:{
  4165. x = 411.9707;
  4166. y = -51.9217;
  4167. z = 1001.8984;
  4168. world = GetPlayerVirtualWorld(playerid);
  4169. interior = 12;
  4170. angle = 173.3449;
  4171. name = "Barber Shop 3";
  4172. }
  4173. }
  4174. gotoCallback(x, y, z, world, interior, angle, name);
  4175. }
  4176. else{dialogGotoInterior(playerid);}
  4177. }
  4178. case DIALOG_GOTO_FOOD:{
  4179. if(response){
  4180. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
  4181. world = GetPlayerVirtualWorld(playerid);
  4182. switch(listitem){
  4183. case INTERIOR_FOOD_BURGER:{
  4184. x = 366.0248;
  4185. y = -73.3478;
  4186. z = 1001.5078;
  4187. interior = 10;
  4188. angle = 292.0084;
  4189. name = "Burger Shot";
  4190. }
  4191. case INTERIOR_FOOD_PIZZA:{
  4192. x = 372.3520;
  4193. y = -131.6510;
  4194. z = 1001.4922;
  4195. interior = 5;
  4196. angle = 354.2285;
  4197. name = "Well Stacked Pizza";
  4198. }
  4199. case INTERIOR_FOOD_CLUCKIN:{
  4200. x = 365.7158;
  4201. y = -9.8873;
  4202. z = 1001.8516;
  4203. interior = 9;
  4204. angle = 160.528;
  4205. name = "Cluckin' Bell";
  4206. }
  4207. case INTERIOR_FOOD_DONUTS:{
  4208. x = 376.99;
  4209. y = -191.21;
  4210. z = 1000.63;
  4211. interior = 17;
  4212. angle = 141.0245;
  4213. name = "Rusty Brown's donuts";
  4214. }
  4215. case INTERIOR_FOOD_PUMP:{
  4216. x = 681.66;
  4217. y = -453.32;
  4218. z = -25.61;
  4219. interior = 1;
  4220. angle = 166.166;
  4221. name = "The Welcome Pump";
  4222. }
  4223. case INTERIOR_FOOD_DINER1:{
  4224. x = 454.9853;
  4225. y = -107.2548;
  4226. z = 999.4376;
  4227. world = GetPlayerVirtualWorld(playerid);
  4228. interior = 5;
  4229. angle = 309.0195;
  4230. name = "Diner 1";
  4231. }
  4232. case INTERIOR_FOOD_DONUT:{
  4233. x = 378.026;
  4234. y = -190.5155;
  4235. z = 1000.6328;
  4236. world = GetPlayerVirtualWorld(playerid);
  4237. interior = 17;
  4238. angle = 141.0245;
  4239. name = "Rusty Brown's Donuts";
  4240. }
  4241. case INTERIOR_FOOD_PALIMO:{
  4242. x = 2331.8984;
  4243. y = 6.7816;
  4244. z = 26.5032;
  4245. world = GetPlayerVirtualWorld(playerid);
  4246. interior = 0;
  4247. angle = 100.2357;
  4248. name = "Palamino Diner";
  4249. }
  4250. case INTERIOR_FOOD_COQ:{
  4251. x = 445.6003;
  4252. y = -6.9823;
  4253. z = 1000.7344;
  4254. world = GetPlayerVirtualWorld(playerid);
  4255. interior = 1;
  4256. angle = 172.2105;
  4257. name = "World of Coq";
  4258. }
  4259. }
  4260. gotoCallback(x, y, z, world, interior, angle, name);
  4261. }
  4262. else{dialogGotoInterior(playerid);}
  4263. }
  4264. case DIALOG_GOTO_GIRLHOUSE:{
  4265. if(response){
  4266. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
  4267. world = GetPlayerVirtualWorld(playerid);
  4268. switch(listitem){
  4269. case INTERIOR_GIRL_DENISE:{
  4270. x = 245.2307;
  4271. y = 304.7632;
  4272. z = 999.1484;
  4273. world = GetPlayerVirtualWorld(playerid);
  4274. interior = 1;
  4275. angle = 273.4364;
  4276. name = "Denise's Bedroom";
  4277. }
  4278. case INTERIOR_GIRL_HELENA:{
  4279. x = 290.623;
  4280. y = 309.0622;
  4281. z = 999.1484;
  4282. world = GetPlayerVirtualWorld(playerid);
  4283. interior = 3;
  4284. angle = 89.9164;
  4285. name = "Helena's Barn";
  4286. }
  4287. case INTERIOR_GIRL_KATIE:{
  4288. x = 269.6405;
  4289. y = 305.9512;
  4290. z = 999.1484;
  4291. world = GetPlayerVirtualWorld(playerid);
  4292. interior = 2;
  4293. angle = 215.6625;
  4294. name = "Katie's Lovenest";
  4295. }
  4296. }
  4297. gotoCallback(x, y, z, world, interior, angle, name);
  4298. }
  4299. else{dialogGotoInterior(playerid);}
  4300. }
  4301. /*case DIALOG_GOTO_UNCATAGORIZED:{
  4302. if(response){
  4303. new Float:x, Float:y, Float:z, world, interior, Float:angle, name[31 + 1];
  4304. world = GetPlayerVirtualWorld(playerid);
  4305. switch(listitem){
  4306. case INTERIOR_UNCATEGORIZED_BDUPAPPARTMENT:{
  4307. x = 1527.0468;
  4308. y = -12.0236;
  4309. z = 1002.0971;
  4310. world = GetPlayerVirtualWorld(playerid);
  4311. interior = 3;
  4312. angle = 350.0013;
  4313. name = "B Dup's Apartment";
  4314. }
  4315. case INTERIOR_UNCATEGORIZED_PALACE:{
  4316. x = 1523.5098;
  4317. y = -47.8211;
  4318. z = 1002.2699;
  4319. world = GetPlayerVirtualWorld(playerid);
  4320. interior = 2;
  4321. angle = 262.7038;
  4322. name = "B Dup's Crack Palace";
  4323. }
  4324. case INTERIOR_UNCATEGORIZED_OGLOC:{
  4325. x = 512.9291;
  4326. y = -11.6929;
  4327. z = 1001.5653;
  4328. world = GetPlayerVirtualWorld(playerid);
  4329. interior = 3;
  4330. angle = 198.7669;
  4331. name = "OG Loc's House";
  4332. }
  4333. case INTERIOR_:{
  4334. x = 1.1853;
  4335. y = -3.2387;
  4336. z = 999.4284;
  4337. world = GetPlayerVirtualWorld(playerid);
  4338. interior = 2;
  4339. angle = 87.5718;
  4340. name = "Angel Pine Trailer";
  4341. }
  4342. case INTERIOR_UNCATEGORIZED_PLANDEPT:{
  4343. x = 386.5259;
  4344. y = 173.6381;
  4345. z = 1008.3828;
  4346. world = GetPlayerVirtualWorld(playerid);
  4347. interior = 3;
  4348. angle = 63.7399;
  4349. name = "Planning Department";
  4350. }
  4351. case INTERIOR_:{
  4352. x = 419.8936;
  4353. y = 2537.1155;
  4354. z = 10;
  4355. world = GetPlayerVirtualWorld(playerid);
  4356. interior = 10;
  4357. angle = 67.6537;
  4358. name = "Abandoned AC tower";
  4359. }
  4360. case INTERIOR_:{
  4361. x = 256.9047;
  4362. y = -41.6537;
  4363. z = 1002.0234;
  4364. world = GetPlayerVirtualWorld(playerid);
  4365. interior = 14;
  4366. angle = 85.8774;
  4367. name = "Wardrobe/Changing room";
  4368. }
  4369. case INTERIOR_:{
  4370. x = 493.1443;
  4371. y = -24.2607;
  4372. z = 1000.6797;
  4373. world = GetPlayerVirtualWorld(playerid);
  4374. interior = 17;
  4375. angle = 356.9864;
  4376. name = "Club";
  4377. }
  4378. case INTERIOR_:{
  4379. x = -944.2402;
  4380. y = 1886.1536;
  4381. z = 5.0051;
  4382. world = GetPlayerVirtualWorld(playerid);
  4383. interior = 17;
  4384. angle = 179.8548;
  4385. name = "Sherman Dam";
  4386. }
  4387. case INTERIOR_:{
  4388. x = 2217.281;
  4389. y = -1150.5349;
  4390. z = 1025.7969;
  4391. world = GetPlayerVirtualWorld(playerid);
  4392. interior = 15;
  4393. angle = 273.7328;
  4394. name = "Jefferson Motel";
  4395. }
  4396. case INTERIOR_:{
  4397. x = 446.3247;
  4398. y = 509.9662;
  4399. z = 1001.4195;
  4400. world = GetPlayerVirtualWorld(playerid);
  4401. interior = 12;
  4402. angle = 330.5671;
  4403. name = "Budget Inn Motel Room";
  4404. }
  4405. case INTERIOR_:{
  4406. x = 2306.3826;
  4407. y = -15.2365;
  4408. z = 26.7496;
  4409. world = GetPlayerVirtualWorld(playerid);
  4410. interior = 0;
  4411. angle = 274.49;
  4412. name = "Palamino Bank";
  4413. }
  4414. case INTERIOR_:{
  4415. x = 663.0588;
  4416. y = -573.6274;
  4417. z = 16.3359;
  4418. world = GetPlayerVirtualWorld(playerid);
  4419. interior = 0;
  4420. angle = 264.9829;
  4421. name = "Dillimore Gas Station";
  4422. }
  4423. case INTERIOR_:{
  4424. x = -227.5703;
  4425. y = 1401.5544;
  4426. z = 27.7656;
  4427. world = GetPlayerVirtualWorld(playerid);
  4428. interior = 18;
  4429. angle = 269.2978;
  4430. name = "Lil' Probe Inn";
  4431. }
  4432. case INTERIOR_:{
  4433. x = -688.1496;
  4434. y = 942.0826;
  4435. z = 13.6328;
  4436. world = GetPlayerVirtualWorld(playerid);
  4437. interior = 0;
  4438. angle = 177.6574;
  4439. name = "Torreno's Ranch";
  4440. }
  4441. case INTERIOR_:{
  4442. x = -1916.1268;
  4443. y = 714.8617;
  4444. z = 46.5625;
  4445. world = GetPlayerVirtualWorld(playerid);
  4446. interior = 0;
  4447. angle = 152.2839;
  4448. name = "Zombotech - lobby area";
  4449. }
  4450. case INTERIOR_:{
  4451. x = 818.7714;
  4452. y = -1102.8689;
  4453. z = 25.794;
  4454. world = GetPlayerVirtualWorld(playerid);
  4455. interior = 0;
  4456. angle = 91.1439;
  4457. name = "Crypt in LS cemetery (temple)";
  4458. }
  4459. case INTERIOR_:{
  4460. x = 255.2083;
  4461. y = -59.6753;
  4462. z = 1.5703;
  4463. world = GetPlayerVirtualWorld(playerid);
  4464. interior = 0;
  4465. angle = 1.4645;
  4466. name = "Blueberry Liquor Store";
  4467. }
  4468. case INTERIOR_:{
  4469. x = 446.626;
  4470. y = 1397.738;
  4471. z = 1084.3047;
  4472. world = GetPlayerVirtualWorld(playerid);
  4473. interior = 2;
  4474. angle = 343.9647;
  4475. name = "Pair of Burglary Houses";
  4476. }
  4477. case INTERIOR_:{
  4478. x = 227.3922;
  4479. y = 1114.6572;
  4480. z = 1080.9985;
  4481. world = GetPlayerVirtualWorld(playerid);
  4482. interior = 5;
  4483. angle = 267.459;
  4484. name = "Crack Den";
  4485. }
  4486. case INTERIOR_:{
  4487. x = 227.7559;
  4488. y = 1114.3844;
  4489. z = 1080.9922;
  4490. world = GetPlayerVirtualWorld(playerid);
  4491. interior = 5;
  4492. angle = 266.2624;
  4493. name = "Burglary House X11";
  4494. }
  4495. case INTERIOR_:{
  4496. x = 261.1165;
  4497. y = 1287.2197;
  4498. world = GetPlayerVirtualWorld(playerid);
  4499. interior = 4;
  4500. z = 1080.2578;
  4501. angle = 178.9149;
  4502. name = "Burglary House X12";
  4503. }
  4504. case INTERIOR_:{
  4505. x = 449.0172;
  4506. y = -88.9894;
  4507. z = 999.5547;
  4508. world = GetPlayerVirtualWorld(playerid);
  4509. interior = 4;
  4510. angle = 89.6608;
  4511. name = "Jay's Diner";
  4512. }
  4513. case INTERIOR_GIRL_MICHELLE:{
  4514. x = 306.1966;
  4515. y = 307.819;
  4516. z = 1003.3047;
  4517. world = GetPlayerVirtualWorld(playerid);
  4518. interior = 4;
  4519. angle = 203.1354;
  4520. name = "Michelle's Love Nest*";
  4521. }
  4522. case INTERIOR_:{
  4523. x = 24.3769;
  4524. y = 1341.1829;
  4525. z = 1084.375;
  4526. world = GetPlayerVirtualWorld(playerid);
  4527. interior = 10;
  4528. angle = 8.3305;
  4529. name = "Burglary House X14";
  4530. }
  4531. case INTERIOR_:{
  4532. x = 963.0586;
  4533. y = 2159.7563;
  4534. z = 1011.0303;
  4535. world = GetPlayerVirtualWorld(playerid);
  4536. interior = 1;
  4537. angle = 175.313;
  4538. name = "Sindacco Abatoir";
  4539. }
  4540. case INTERIOR_:{
  4541. x = 2548.4807;
  4542. y = 2823.7429;
  4543. z = 10.8203;
  4544. world = GetPlayerVirtualWorld(playerid);
  4545. interior = 0;
  4546. angle = 270.6003;
  4547. name = "K.A.C.C. Military Fuels Depot";
  4548. }
  4549. case INTERIOR_:{
  4550. x = 215.1515;
  4551. y = 1874.0579;
  4552. z = 13.1406;
  4553. world = GetPlayerVirtualWorld(playerid);
  4554. interior = 0;
  4555. angle = 177.553;
  4556. name = "Area 69";
  4557. }
  4558. case INTERIOR_:{
  4559. x = 221.6766;
  4560. y = 1142.4962;
  4561. z = 1082.6094;
  4562. world = GetPlayerVirtualWorld(playerid);
  4563. interior = 4;
  4564. angle = 184.9618;
  4565. name = "Burglary House X13";
  4566. }
  4567. case INTERIOR_:{
  4568. x = 2323.7063;
  4569. y = -1147.6509;
  4570. z = 1050.7101;
  4571. world = GetPlayerVirtualWorld(playerid);
  4572. interior = 12;
  4573. angle = 206.5352;
  4574. name = "Unused Safe House";
  4575. }
  4576. case INTERIOR_GIRL_MILLIE:{
  4577. x = 344.9984;
  4578. y = 307.1824;
  4579. z = 999.1557;
  4580. world = GetPlayerVirtualWorld(playerid);
  4581. interior = 6;
  4582. angle = 193.643;
  4583. name = "Millie's Bedroom";
  4584. }
  4585. case INTERIOR_:{
  4586. x = -1864.9434;
  4587. y = 55.7325;
  4588. z = 1055.5276;
  4589. world = GetPlayerVirtualWorld(playerid);
  4590. interior = 14;
  4591. angle = 85.8541;
  4592. name = "Los Santos Airport";
  4593. }
  4594. case INTERIOR_:{
  4595. x = -262.1759;
  4596. y = 1456.6158;
  4597. z = 1084.3672;
  4598. world = GetPlayerVirtualWorld(playerid);
  4599. interior = 4;
  4600. angle = 82.459;
  4601. name = "Burglary House X15";
  4602. }
  4603. case INTERIOR_:{
  4604. x = 22.861;
  4605. y = 1404.9165;
  4606. z = 1084.4297;
  4607. world = GetPlayerVirtualWorld(playerid);
  4608. interior = 5;
  4609. angle = 349.6158;
  4610. name = "Burglary House X16";
  4611. }
  4612. case INTERIOR_:{
  4613. x = 140.3679;
  4614. y = 1367.8837;
  4615. z = 1083.8621;
  4616. world = GetPlayerVirtualWorld(playerid);
  4617. interior = 5;
  4618. angle = 349.2372;
  4619. name = "Burglary House X17";
  4620. }
  4621. case INTERIOR_:{
  4622. x = 1494.8589;
  4623. y = 1306.48;
  4624. z = 1093.2953;
  4625. world = GetPlayerVirtualWorld(playerid);
  4626. interior = 3;
  4627. angle = 196.065;
  4628. name = "Bike School";
  4629. }
  4630. case INTERIOR_:{
  4631. x = -1401.067;
  4632. y = 1265.3706;
  4633. z = 1039.8672;
  4634. world = GetPlayerVirtualWorld(playerid);
  4635. interior = 16;
  4636. angle = 178.6483;
  4637. name = "Vice Stadium";
  4638. }
  4639. case INTERIOR_:{
  4640. x = 234.2826;
  4641. y = 1065.229;
  4642. z = 1084.2101;
  4643. world = GetPlayerVirtualWorld(playerid);
  4644. interior = 6;
  4645. angle = 4.3864;
  4646. name = "Burglary House X18";
  4647. }
  4648. case INTERIOR_:{
  4649. x = -68.5145;
  4650. y = 1353.8485;
  4651. z = 1080.2109;
  4652. world = GetPlayerVirtualWorld(playerid);
  4653. interior = 6;
  4654. angle = 3.5742;
  4655. name = "Burglary House X19";
  4656. }
  4657. case INTERIOR_:{
  4658. x = -285.2511;
  4659. y = 1471.197;
  4660. z = 1084.375;
  4661. world = GetPlayerVirtualWorld(playerid);
  4662. interior = 15;
  4663. angle = 85.6547;
  4664. name = "Burglary House X20";
  4665. }
  4666. case INTERIOR_:{
  4667. x = 442.1295;
  4668. y = -52.4782;
  4669. z = 999.7167;
  4670. world = GetPlayerVirtualWorld(playerid);
  4671. interior = 6;
  4672. angle = 177.9394;
  4673. name = "Secret Valley Diner";
  4674. }
  4675. case INTERIOR_:{
  4676. x = 2182.2017;
  4677. y = 1628.5848;
  4678. z = 1043.8723;
  4679. world = GetPlayerVirtualWorld(playerid);
  4680. interior = 2;
  4681. angle = 224.8601;
  4682. name = "Rosenberg's Office in Caligulas";
  4683. }
  4684. case INTERIOR_:{
  4685. x = 748.4623;
  4686. y = 1438.2378;
  4687. z = 1102.9531;
  4688. world = GetPlayerVirtualWorld(playerid);
  4689. interior = 6;
  4690. angle = 0.6069;
  4691. name = "Fanny Batter's Whore House";
  4692. }
  4693. case INTERIOR_:{
  4694. x = 366.0002;
  4695. y = -9.4338;
  4696. z = 1001.8516;
  4697. world = GetPlayerVirtualWorld(playerid);
  4698. interior = 9;
  4699. angle = 160.528;
  4700. name = "Cluckin' Bell";
  4701. }
  4702. case INTERIOR_:{
  4703. x = 2216.1282;
  4704. y = -1076.3052;
  4705. z = 1050.4844;
  4706. world = GetPlayerVirtualWorld(playerid);
  4707. interior = 1;
  4708. angle = 86.428;
  4709. name = "The Camel's Toe Safehouse";
  4710. }
  4711. case INTERIOR_:{
  4712. x = 2268.5156;
  4713. y = 1647.7682;
  4714. z = 1084.2344;
  4715. world = GetPlayerVirtualWorld(playerid);
  4716. interior = 1;
  4717. angle = 99.7331;
  4718. name = "Caligula's Roof";
  4719. }
  4720. case INTERIOR_:{
  4721. x = 2236.6997;
  4722. y = -1078.9478;
  4723. z = 1049.0234;
  4724. world = GetPlayerVirtualWorld(playerid);
  4725. interior = 2;
  4726. angle = 2.5706;
  4727. name = "Old Venturas Strip Casino";
  4728. }
  4729. case INTERIOR_:{
  4730. x = -2031.1196;
  4731. y = -115.8287;
  4732. z = 1035.1719;
  4733. world = GetPlayerVirtualWorld(playerid);
  4734. interior = 3;
  4735. angle = 190.1877;
  4736. name = "Driving School";
  4737. }
  4738. case INTERIOR_:{
  4739. x = 2365.1089;
  4740. y = -1133.0795;
  4741. z = 1050.875;
  4742. world = GetPlayerVirtualWorld(playerid);
  4743. interior = 8;
  4744. angle = 177.3947;
  4745. name = "Verdant Bluffs Safehouse";
  4746. }
  4747. case INTERIOR_:{
  4748. x = 1168.512;
  4749. y = 1360.1145;
  4750. z = 10.9293;
  4751. world = GetPlayerVirtualWorld(playerid);
  4752. interior = 0;
  4753. angle = 196.5933;
  4754. name = "Bike School";
  4755. }
  4756. case INTERIOR_:{
  4757. x = 1893.0731;
  4758. y = 1017.8958;
  4759. z = 31.8828;
  4760. world = GetPlayerVirtualWorld(playerid);
  4761. interior = 10;
  4762. angle = 86.1044;
  4763. name = "Four Dragons' Janitor's Office";
  4764. }
  4765. case INTERIOR_:{
  4766. x = 501.9578;
  4767. y = -70.5648;
  4768. z = 998.7578;
  4769. world = GetPlayerVirtualWorld(playerid);
  4770. interior = 11;
  4771. angle = 171.5706;
  4772. name = "Bar";
  4773. }
  4774. case INTERIOR_:{
  4775. x = -42.5267;
  4776. y = 1408.23;
  4777. z = 1084.4297;
  4778. world = GetPlayerVirtualWorld(playerid);
  4779. interior = 8;
  4780. angle = 172.068;
  4781. name = "Burglary House X21";
  4782. }
  4783. case INTERIOR_:{
  4784. x = 2283.3118;
  4785. y = 1139.307;
  4786. z = 1050.8984;
  4787. world = GetPlayerVirtualWorld(playerid);
  4788. interior = 11;
  4789. angle = 19.7032;
  4790. name = "Willowfield Safehouse";
  4791. }
  4792. case INTERIOR_:{
  4793. x = 84.9244;
  4794. y = 1324.2983;
  4795. z = 1083.8594;
  4796. world = GetPlayerVirtualWorld(playerid);
  4797. interior = 9;
  4798. angle = 159.5582;
  4799. name = "Burglary House X22";
  4800. }
  4801. case INTERIOR_:{
  4802. x = 260.7421;
  4803. y = 1238.2261;
  4804. z = 1084.2578;
  4805. world = GetPlayerVirtualWorld(playerid);
  4806. interior = 9;
  4807. angle = 84.3084;
  4808. name = "Burglary House X23";
  4809. }
  4810. case INTERIOR_:{
  4811. x = -1658.1656;
  4812. y = 1215.0002;
  4813. z = 7.25;
  4814. world = GetPlayerVirtualWorld(playerid);
  4815. interior = 0;
  4816. angle = 103.9074;
  4817. name = "Otto's Autos";
  4818. }
  4819. case INTERIOR_:{
  4820. x = -1961.6281;
  4821. y = 295.2378;
  4822. z = 35.4688;
  4823. world = GetPlayerVirtualWorld(playerid);
  4824. interior = 0;
  4825. angle = 264.4891;
  4826. name = "Wang Cars";
  4827. }
  4828. }
  4829. gotoCallback(x, y, z, world, interior, angle, name);
  4830. }
  4831. else{dialogGotoUncatagorized(playerid);}
  4832. }*/
  4833. case DIALOG_CREATE_PICKUP:{
  4834. if(response){
  4835. switch(listitem){
  4836. case 0: ShowPlayerDialog(playerid, DIALOG_CREATE_FACTION_PICKUP, DIALOG_STYLE_LIST, "Faction types", "Police\nMedic\nFire fighter\nFederal Bureau of Investigation\nDepeartment of motorvehicles\nBroadcasting", "Select", "Cancel"); }
  4837. }
  4838. }
  4839. case DIALOG_CREATE_FACTION_PICKUP:{
  4840. if(response){
  4841. printf("Listitem: % i", listitem);
  4842. new Float:x, Float:y, Float:z;
  4843. GetPlayerPos(playerid, x, y, z);
  4844. new world = GetPlayerVirtualWorld(playerid);
  4845. new interior = GetPlayerInterior(playerid);
  4846. new pickupid = createDynamicPickup(1247, x, y, z, world, interior, listitem);
  4847. // Create pickup record
  4848. new pickup_query[127 + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_FLOAT + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + MAX_SQL_INTEGER + 1];
  4849. format(pickup_query, sizeof(pickup_query), "INSERT INTO pickup(object_id, pos_x, pos_y, pos_z, world_id, interior_id, type_id, pickup_id) VALUES (1247, '%f', '%f', '%f', %i, %i, %i, %i)", x, y, z, world, interior, listitem, pickupid);
  4850. sql_query(sqlHandle, pickup_query);
  4851. // Get pickup record ID
  4852. new id_query[44 + 1];
  4853. format(id_query, sizeof(id_query), "SELECT id FROM pickup WHERE pickup_id = %i", pickupid);
  4854. new Result:id_result = sql_query(sqlHandle, id_query);
  4855. new pickup_id = sql_get_field_assoc_int(id_result, "id");
  4856. new admin_message[21 + 4 + MAX_PLAYER_NAME + MAX_SQL_INTEGER + 1];
  4857. // Inform admins
  4858. listitem++; // To account for FACTION_NONE
  4859. printf("Listitem: % i", listitem);
  4860. switch(listitem){
  4861. case FACTION_POLICE: format(admin_message, sizeof(admin_message), "* [%i] %s created police faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  4862. case FACTION_MEDIC: format(admin_message, sizeof(admin_message), "* [%i] %s created medic faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  4863. case FACTION_FIRE: format(admin_message, sizeof(admin_message), "* [%i] %s created firefighter faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  4864. case FACTION_SHERIFF: format(admin_message, sizeof(admin_message), "* [%i] %s created shariff faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  4865. case FACTION_FBI: format(admin_message, sizeof(admin_message), "* [%i] %s created FBI faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  4866. case FACTION_DMV: format(admin_message, sizeof(admin_message), "* [%i] %s created DMV faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  4867. case FACTION_NEWS: format(admin_message, sizeof(admin_message), "* [%i] %s created broadcasting faction pickup: %i", playerid, getPlayerName(playerid), pickup_id);
  4868. default: return 0;
  4869. }
  4870. sendToAdmins(COLOR_NOTICE, admin_message);
  4871. }
  4872. }
  4873. case DIALOG_DUTY_PD:{
  4874. if(response){
  4875. // TODO: Check if has passport
  4876. switch(GetGVarInt("job", playerid)){
  4877. case JOB_NONE:{ // Is citizen
  4878. // TODO: Check for crimes, warrents, etc
  4879. ShowPlayerDialog(playerid, DIALOG_POLICE_SKIN, DIALOG_STYLE_TABLIST, "Police skins", "Police Officer\tMale\tLS\nPolice Officer\tMale\tSF\nMotorbike Cop\tMale\tLS\nPolice Officer (Without gun holster)\tMale\tLS\nPolice Officer (Without gun holster)\tMale\tSF\nPolice Officer\tFemale\tLS\nPolice Officer\tFemale\tSF", "Duty", "Cancel");
  4880. }
  4881. case JOB_POLICE:{ // Is on duty
  4882. setPlayerJob(playerid, JOB_NONE);
  4883. }
  4884. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  4885. }
  4886. }
  4887. }
  4888. case DIALOG_POLICE_SKIN:{
  4889. if(response){
  4890. new skin;
  4891. switch(listitem){
  4892. case 0:{skin = 280;}
  4893. case 1:{skin = 281;}
  4894. case 2:{skin = 284;}
  4895. case 3:{skin = 300;}
  4896. case 4:{skin = 301;}
  4897. case 5:{skin = 306;}
  4898. case 6:{skin = 307;}
  4899. }
  4900. setPlayerJob(playerid, JOB_POLICE, skin, COLOR_POLICE);
  4901. }
  4902. }
  4903. case DIALOG_DUTY_MD:{
  4904. if(response){
  4905. // TODO: Check if has passport
  4906. switch(GetGVarInt("job", playerid)){
  4907. case JOB_NONE:{
  4908. // TODO: Check for crimes, warrents, etc
  4909. ShowPlayerDialog(playerid, DIALOG_MEDIC_SKIN, DIALOG_STYLE_TABLIST, "Paramedic skins", "Los Santos white\tMale\nLas Venturas blue\tMale\nSan Fierro green\tMale\nSan Fierro green\tFemale", "Duty", "Cancel");
  4910. }
  4911. case JOB_MEDIC:{
  4912. setPlayerJob(playerid, JOB_NONE);
  4913. }
  4914. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  4915. }
  4916. }
  4917. }
  4918. case DIALOG_MEDIC_SKIN:{
  4919. if(response){
  4920. new skin;
  4921. switch(listitem){
  4922. case 0:{skin = 274;}
  4923. case 1:{skin = 275;}
  4924. case 2:{skin = 276;}
  4925. case 3:{skin = 308;} // TODO find out why this is broken.
  4926. }
  4927. setPlayerJob(playerid, JOB_MEDIC, skin, COLOR_MEDIC);
  4928. }
  4929. }
  4930. case DIALOG_DUTY_FD:{
  4931. if(response){
  4932. // TODO: Check if has passport
  4933. switch(GetGVarInt("job", playerid)){
  4934. case JOB_NONE:{
  4935. // TODO: Check for crimes, warrents, etc
  4936. ShowPlayerDialog(playerid, DIALOG_FIRE_SKIN, DIALOG_STYLE_TABLIST, "Firefighter skins", "Los Santos green\tMale\nLas Venturas yellow\tMale\nSan Fierro black\tMale", "Duty", "Cancel");
  4937. }
  4938. case JOB_FIRE:{
  4939. setPlayerJob(playerid, JOB_NONE);
  4940. }
  4941. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  4942. }
  4943. }
  4944. }
  4945. case DIALOG_FIRE_SKIN:{
  4946. if(response){
  4947. new skin;
  4948. switch(listitem){
  4949. case 0:{skin = 277;}
  4950. case 1:{skin = 278;}
  4951. case 2:{skin = 279;}
  4952. }
  4953. setPlayerJob(playerid, JOB_FIRE, skin, COLOR_FIRE);
  4954. }
  4955. }
  4956. case DIALOG_DUTY_SD:{
  4957. if(response){
  4958. // TODO: Check if has passport
  4959. switch(GetGVarInt("job", playerid)){
  4960. case JOB_NONE:{
  4961. // TODO: Check for crimes, warrents, etc
  4962. ShowPlayerDialog(playerid, DIALOG_SHERIFF_SKIN, DIALOG_STYLE_TABLIST, "Sheriff skins", "Officer\tMale\tLV\nCounty sheriff\tMale\tCountryside\nDesert sheriff\tMale\tDesert\nOfficer (Without gun holster)\tMale\nOfficer\tFemale\nCounty sheriff (Without hat)\tMale\nDesert sheriff\tMale", "Duty", "Cancel");
  4963. }
  4964. case JOB_SHERIFF:{
  4965. setPlayerJob(playerid, JOB_NONE);
  4966. }
  4967. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  4968. }
  4969. }
  4970. }
  4971. case DIALOG_SHERIFF_SKIN:{
  4972. if(response){
  4973. new skin;
  4974. switch(listitem){
  4975. case 0:{skin = 282;}
  4976. case 1:{skin = 283;}
  4977. case 2:{skin = 288;}
  4978. case 3:{skin = 302;}
  4979. case 4:{skin = 309;}
  4980. case 5:{skin = 310;}
  4981. case 6:{skin = 311;}
  4982. }
  4983. setPlayerJob(playerid, JOB_SHERIFF, skin, COLOR_SHERIFF);
  4984. }
  4985. }
  4986. case DIALOG_DUTY_FBI:{
  4987. if(response){
  4988. // TODO: Check if has passport
  4989. switch(GetGVarInt("job", playerid)){
  4990. case JOB_NONE:{
  4991. // TODO: Check for crimes, warrents, etc
  4992. ShowPlayerDialog(playerid, DIALOG_FBI_SKIN, DIALOG_STYLE_TABLIST, "Agent skins", "Caucasian MIB agent\tMale\nAfro-American MIB agent\tMale\nSWAT special forces\tMale\nFBI agent\tMale\nAfro-American bouncer\tMale\nCaucasian Bouncer\tMale\nOriental businesswoman\tFemale\nCaucasian businesswoman\tFemale", "Duty", "Cancel");
  4993. }
  4994. case JOB_FBI:{
  4995. setPlayerJob(playerid, JOB_NONE);
  4996. }
  4997. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  4998. }
  4999. }
  5000. }
  5001. case DIALOG_FBI_SKIN:{
  5002. if(response){
  5003. new skin;
  5004. switch(listitem){
  5005. case 0:{skin = 165;}
  5006. case 1:{skin = 166;}
  5007. case 2:{skin = 258;}
  5008. case 3:{skin = 286;}
  5009. case 4:{skin = 163;}
  5010. case 5:{skin = 164;}
  5011. case 7:{skin = 141;}
  5012. case 8:{skin = 150;}
  5013. }
  5014. setPlayerJob(playerid, JOB_FBI, skin, COLOR_FBI);
  5015. }
  5016. }
  5017. case DIALOG_DUTY_DMV:{
  5018. if(response){
  5019. // TODO: Check if has passport
  5020. switch(GetGVarInt("job", playerid)){
  5021. case JOB_NONE:{
  5022. // TODO: Check for crimes, warrents, etc
  5023. ShowPlayerDialog(playerid, DIALOG_DMV_SKIN, DIALOG_STYLE_TABLIST, "DMV skins", "Airport ground worker\tMale\nSecurity guard\tMale", "Duty", "Cancel");
  5024. }
  5025. case JOB_DMV:{
  5026. setPlayerJob(playerid, JOB_NONE);
  5027. }
  5028. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  5029. }
  5030. }
  5031. }
  5032. case DIALOG_DMV_SKIN:{
  5033. if(response){
  5034. new skin;
  5035. switch(listitem){
  5036. case 0:{skin = 16;}
  5037. case 1:{skin = 71;}
  5038. }
  5039. setPlayerJob(playerid, JOB_DMV, skin, COLOR_DMV);
  5040. }
  5041. }
  5042. case DIALOG_DUTY_NEWS:{
  5043. if(response){
  5044. // TODO: Check if has passport
  5045. switch(GetGVarInt("job", playerid)){
  5046. case JOB_NONE:{
  5047. // TODO: Check for crimes, warrents, etc
  5048. ShowPlayerDialog(playerid, DIALOG_DMV_SKIN, DIALOG_STYLE_TABLIST, "Network skins", "Hispanic businesswoman\nCaucasian Businesswoman\nBusinessman\nRich woman", "Duty", "Cancel");
  5049. }
  5050. case JOB_NEWS:{
  5051. setPlayerJob(playerid, JOB_NONE);
  5052. }
  5053. default:{SendClientMessage(playerid, COLOR_ERROR, "SERVER: You can not use this pickup as long as you are on another job.");}
  5054. }
  5055. }
  5056. }
  5057. case DIALOG_NEWS_SKIN:{
  5058. if(response){
  5059. new skin;
  5060. switch(listitem){
  5061. case 0:{skin = 148;}
  5062. case 1:{skin = 150;}
  5063. case 2:{skin = 187;}
  5064. case 3:{skin = 219;}
  5065. }
  5066. setPlayerJob(playerid, JOB_NEWS, skin, COLOR_NEWS);
  5067. }
  5068. }
  5069. }
  5070. return 0; // MUST return 0 here, just like OnPlayerCommandText.
  5071. }
  5072. public OnPlayerClickPlayer(playerid, clickedplayerid, source)
  5073. {
  5074. return 1;
  5075. }
  5076. public OnEnterExitModShop(playerid, enterexit, interiorid)
  5077. {
  5078. return 1;
  5079. }
  5080. public OnPlayerGiveDamage(playerid, damagedid, Float: amount, weaponid)
  5081. {
  5082. return 1;
  5083. }
  5084. public OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid)
  5085. {
  5086. return 1;
  5087. }
  5088. // discord-connector events
  5089. public DCC_OnMessageCreate(DCC_Message:message){
  5090. // Originating Discord channel
  5091. new DCC_Channel:channel;
  5092. DCC_GetMessageChannel(message, channel);
  5093. // Originating Discord user
  5094. new DCC_User:author;
  5095. DCC_GetMessageAuthor(message, author);
  5096. // Message content
  5097. new str[128 + 1]; // Orignal was 256
  5098. new command[32 + 1], params[128 + 1];
  5099. DCC_GetMessageContent(message, str);
  5100. sscanf(str, "s[32]s[128]", command, params); // This string is to small some times, and throws an error BROKEN TODO
  5101. // Ignore bots
  5102. new bool:isBot;
  5103. DCC_IsUserBot(author, isBot);
  5104. if(isBot){
  5105. return 1;
  5106. }
  5107. if(!strcmp(command, "!players")){
  5108. new players_string[14 + (2 * MAX_PLAYERS) + (MAX_PLAYER_NAME * MAX_PLAYERS) + 1] = "Online players:";
  5109. for(new playerid, a = GetPlayerPoolSize(); playerid < a; playerid++){
  5110. if(IsPlayerConnected(playerid)){
  5111. format(players_string, sizeof(players_string), "%s %s,", players_string, getPlayerName(playerid));
  5112. }
  5113. }
  5114. strdel(players_string, strlen(players_string), strlen(players_string)); // Delete trailing comma
  5115. DiscordSendChannelMessage(channel, players_string);
  5116. print("Should be sending players");
  5117. }
  5118. else if(!strcmp(command, "!ip")){
  5119. DiscordSendChannelMessage(channel, "ecrp.h0v1n8.nl:6666");
  5120. }
  5121. else{
  5122. if(channel == echoChannel){
  5123. sendToChat(-1, CHAT_GLOBAL, str, 0, author);
  5124. }
  5125. }
  5126. /*// Beyond this point, don't respond to commands on foreign guilds.
  5127. if(guild != homeGuild){
  5128. return 1;
  5129. }*/
  5130. // Beyond this point, only respond to privilaged channels.
  5131. if(channel != adminEchoChannel && channel != adminChannel && channel != managementChannel){
  5132. return 1;
  5133. }
  5134. // Test command.
  5135. if(!strcmp(command, "!test", true)){
  5136. DiscordSendChannelMessage(channel, "Works.");
  5137. print("Some said !test in the echo channel.");
  5138. }
  5139. return 1;
  5140. }
  5141. // Entrypoint
  5142. main(){
  5143. // Credits
  5144. print("\n*----------------------------------*");
  5145. print(" RPFW by tBKwtWS.");
  5146. new message[21 + 20 + 1];
  5147. format(message, sizeof(message), " Role-play framework v%s", MODE_NAME);
  5148. print(message);
  5149. //printf("System load average: %f",loadavg()); // Linux only TODO: test
  5150. print("*----------------------------------*\n");
  5151. }