1
0

old_weapon-config.inc 163 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330
  1. #if defined _INC_WEAPON_CONFIG
  2. #endinput
  3. #endif
  4. #define _INC_WEAPON_CONFIG
  5. #include <a_samp>
  6. // Print debug messages in the chat and server log
  7. #if !defined WC_DEBUG
  8. #define WC_DEBUG false
  9. #endif
  10. // Print debug messages to the console but not the chat
  11. #if !defined WC_DEBUG_SILENT
  12. #define WC_DEBUG_SILENT false
  13. #endif
  14. // Max number of rejected hits (GetRejectedHit)
  15. #if !defined WC_MAX_REJECTED_HITS
  16. #define WC_MAX_REJECTED_HITS 15
  17. #endif
  18. // Max ranges for DAMAGE_TYPE_RANGE(_MULTIPLIER)
  19. #if !defined WC_MAX_DAMAGE_RANGES
  20. #define WC_MAX_DAMAGE_RANGES 5
  21. #endif
  22. // The world a player has after the death animation finished until he respawns or enters class selection
  23. #if !defined WC_DEATH_WORLD
  24. #define WC_DEATH_WORLD 0x00DEAD00
  25. #endif
  26. // The max number of entries in the damage feeds
  27. #if !defined WC_FEED_HEIGHT
  28. #define WC_FEED_HEIGHT 5
  29. #endif
  30. // Use Incognito's streamer for custom vending machines
  31. #if !defined WC_USE_STREAMER
  32. #define WC_USE_STREAMER false
  33. #endif
  34. // For SetWeaponName
  35. #if !defined WC_MAX_WEAPON_NAME
  36. #define WC_MAX_WEAPON_NAME 21
  37. #endif
  38. // For modes that always have negative cash
  39. #if !defined WC_CUSTOM_VENDING_MACHINES
  40. #define WC_CUSTOM_VENDING_MACHINES true
  41. #endif
  42. #if WC_USE_STREAMER && !defined Streamer_IncludeFileVersion
  43. #error streamer.inc is required when WC_USE_STREAMER=true
  44. #endif
  45. // https://github.com/oscar-broman/SKY/blob/master/SKY.inc
  46. #if !defined _INC_SKY
  47. #tryinclude <SKY>
  48. #if !defined _INC_SKY
  49. #error The SKY plugin is required, get it here: github.com/oscar-broman/sky
  50. #endif
  51. #endif
  52. // Given in OnInvalidWeaponDamage
  53. enum {
  54. WC_NO_ERROR,
  55. WC_NO_ISSUER,
  56. WC_NO_DAMAGED,
  57. WC_INVALID_DAMAGE,
  58. WC_INVALID_DISTANCE
  59. }
  60. // Used in SetWeaponDamage
  61. enum {
  62. DAMAGE_TYPE_MULTIPLIER,
  63. DAMAGE_TYPE_STATIC,
  64. DAMAGE_TYPE_RANGE_MULTIPLIER,
  65. DAMAGE_TYPE_RANGE
  66. }
  67. // Hits displayed in the damage feeds
  68. enum E_DAMAGE_FEED_HIT {
  69. e_Issuer,
  70. e_Name[MAX_PLAYER_NAME],
  71. Float:e_Amount,
  72. e_Weapon,
  73. e_Tick
  74. }
  75. // Given in OnRejectedHit
  76. enum E_REJECTED_HIT {
  77. e_Time,
  78. e_Hour,
  79. e_Minute,
  80. e_Second,
  81. e_Weapon,
  82. e_Reason,
  83. e_Info1,
  84. e_Info2,
  85. e_Info3,
  86. e_Name[MAX_PLAYER_NAME]
  87. }
  88. // e_Reason in E_REJECTED_HIT
  89. enum {
  90. HIT_NO_DAMAGEDID,
  91. HIT_INVALID_WEAPON,
  92. HIT_LAST_SHOT_INVALID,
  93. HIT_MULTIPLE_PLAYERS,
  94. HIT_MULTIPLE_PLAYERS_SHOTGUN,
  95. HIT_DYING_PLAYER,
  96. HIT_SAME_TEAM,
  97. HIT_UNSTREAMED,
  98. HIT_INVALID_HITTYPE,
  99. HIT_BEING_RESYNCED,
  100. HIT_NOT_SPAWNED,
  101. HIT_OUT_OF_RANGE,
  102. HIT_TOO_FAR_FROM_SHOT,
  103. SHOOTING_RATE_TOO_FAST,
  104. SHOOTING_RATE_TOO_FAST_MULTIPLE,
  105. HIT_RATE_TOO_FAST,
  106. HIT_RATE_TOO_FAST_MULTIPLE,
  107. HIT_KNIFE_FAILED,
  108. HIT_TOO_FAR_FROM_ORIGIN,
  109. HIT_INVALID_DAMAGE,
  110. HIT_SAME_VEHICLE,
  111. HIT_OWN_VEHICLE,
  112. HIT_INVALID_VEHICLE,
  113. HIT_DISCONNECTED
  114. }
  115. // Must be in sync with the enum above
  116. // Used in debug messages and GetRejectedHit
  117. stock const g_HitRejectReasons[][] = {
  118. "None or invalid player shot",
  119. "Invalid weapon",
  120. "Last shot invalid",
  121. "One bullet hit %d players",
  122. "Hit too many players with shotgun: %d",
  123. "Hit a dying player",
  124. "Hit a teammate",
  125. "Hit someone that can't see you (not streamed in)",
  126. "Invalid hit type: %d",
  127. "Hit while being resynced",
  128. "Hit when not spawned or dying",
  129. "Hit out of range (%f > %f)",
  130. "Hit player too far from hit position (dist %f)",
  131. "Shooting rate too fast: %d (%d samples, max %d)",
  132. "Shooting rate too fast: %d (%d samples, multiple weapons)",
  133. "Hit rate too fast: %d (%d samples, max %d)",
  134. "Hit rate too fast: %d (%d samples, multiple weapons)",
  135. "The knife kill did not sync",
  136. "Damage inflicted too far from current position (dist %f)",
  137. "Invalid weapon damage (%.4f)",
  138. "Hit a player in the same vehicle",
  139. "Hit the vehicle you're in",
  140. "Hit invalid vehicle: %d",
  141. "Hit a disconnected player ID: %d"
  142. };
  143. // Used for SetCustomVendingMachines
  144. #if WC_CUSTOM_VENDING_MACHINES
  145. enum E_VENDING_MACHINE {
  146. e_Model,
  147. e_Interior,
  148. Float:e_PosX,
  149. Float:e_PosY,
  150. Float:e_PosZ,
  151. Float:e_RotX,
  152. Float:e_RotY,
  153. Float:e_RotZ,
  154. Float:e_FrontX,
  155. Float:e_FrontY
  156. }
  157. #endif
  158. // Used to resync players that got team-knifed in lagshot mode
  159. enum E_RESYNC_DATA {
  160. Float:e_Health,
  161. Float:e_Armour,
  162. e_Skin,
  163. e_Team,
  164. Float:e_PosX,
  165. Float:e_PosY,
  166. Float:e_PosZ,
  167. Float:e_PosA,
  168. e_Weapon,
  169. e_WeaponId[13],
  170. e_WeaponAmmo[13]
  171. }
  172. // From OnPlayerWeaponShot
  173. enum E_SHOT_INFO {
  174. e_Tick,
  175. e_Weapon,
  176. e_HitType,
  177. e_HitId,
  178. e_Hits,
  179. Float:e_X,
  180. Float:e_Y,
  181. Float:e_Z,
  182. Float:e_OX,
  183. Float:e_OY,
  184. Float:e_OZ,
  185. Float:e_HX,
  186. Float:e_HY,
  187. Float:e_HZ,
  188. Float:e_Length,
  189. bool:e_Valid
  190. }
  191. enum E_HIT_INFO {
  192. e_Tick,
  193. e_Issuer,
  194. e_Weapon,
  195. Float:e_Amount,
  196. Float:e_Health,
  197. Float:e_Armour,
  198. e_Bodypart
  199. }
  200. enum E_SPAWN_INFO {
  201. e_Skin,
  202. e_Team,
  203. Float:e_PosX,
  204. Float:e_PosY,
  205. Float:e_PosZ,
  206. Float:e_Rot,
  207. e_Weapon1,
  208. e_Ammo1,
  209. e_Weapon2,
  210. e_Ammo2,
  211. e_Weapon3,
  212. e_Ammo3
  213. }
  214. // When a player takes or gives invalid damage (WC_* errors above)
  215. forward OnInvalidWeaponDamage(playerid, damagedid, Float:amount, weaponid, bodypart, error, bool:given);
  216. // Before damage is inflicted
  217. forward OnPlayerDamage(&playerid, &Float:amount, &issuerid, &weapon, &bodypart);
  218. // After OnPlayerDamage
  219. forward OnPlayerDamageDone(playerid, Float:amount, issuerid, weapon, bodypart);
  220. // Before the death animation is applied
  221. forward OnPlayerPrepareDeath(playerid, animlib[32], animname[32], &anim_lock, &respawn_time);
  222. // When the death animation is finished and the player has been sent to respawn
  223. forward OnPlayerDeathFinished(playerid, bool:cancelable);
  224. // When a shot or damage given is rejected
  225. forward OnRejectedHit(playerid, hit[E_REJECTED_HIT]);
  226. #if WC_CUSTOM_VENDING_MACHINES
  227. // When a player is about to use a vending machine
  228. forward OnPlayerUseVendingMachine(playerid, &Float:health_given);
  229. #endif
  230. // If you have your own definitions, remove them and use these instead
  231. #define BODY_PART_UNKNOWN 0
  232. #define WEAPON_UNARMED 0
  233. #define WEAPON_VEHICLE_M4 19
  234. #define WEAPON_VEHICLE_MINIGUN 20
  235. #define WEAPON_PISTOLWHIP 48
  236. #define WEAPON_HELIBLADES 50
  237. #define WEAPON_EXPLOSION 51
  238. #define WEAPON_CARPARK 52
  239. #define WEAPON_UNKNOWN 55
  240. #if WC_DEBUG_SILENT
  241. static s_DebugMsgBuf[512];
  242. #define DebugMessage(%1,%2) \
  243. format(s_DebugMsgBuf,512,%2),printf("(wc:%d) %s",%1,s_DebugMsgBuf)
  244. #define DebugMessageRed(%1,%2) \
  245. format(s_DebugMsgBuf,512,%2),printf("(wc:%d) WARN: %s",%1,s_DebugMsgBuf)
  246. #define DebugMessageAll(%1) \
  247. printf(s_DebugMsgBuf,"(wc) " %1)
  248. #define DebugMessageRedAll(%1) \
  249. printf(s_DebugMsgBuf,"(wc) WARN: " %1)
  250. #elseif WC_DEBUG
  251. static s_DebugMsgBuf[512];
  252. #define DebugMessage(%1,%2) \
  253. format(s_DebugMsgBuf,512,"(wc) " %2),SendClientMessage(%1,-1,s_DebugMsgBuf), \
  254. format(s_DebugMsgBuf,512,%2),printf("(wc:%d) %s",%1,s_DebugMsgBuf)
  255. #define DebugMessageRed(%1,%2) \
  256. format(s_DebugMsgBuf,512,"(wc) " %2),SendClientMessage(%1,0xcc0000ff,s_DebugMsgBuf), \
  257. format(s_DebugMsgBuf,512,%2),printf("(wc:%d) WARN: %s",%1,s_DebugMsgBuf)
  258. #define DebugMessageAll(%1) \
  259. format(s_DebugMsgBuf,512,"(wc) " %1),SendClientMessageToAll(-1,s_DebugMsgBuf), \
  260. printf(s_DebugMsgBuf,"(wc) " %1)
  261. #define DebugMessageRedAll(%1) \
  262. format(s_DebugMsgBuf,512,"(wc) " %1),SendClientMessageToAll(0xcc0000ff,s_DebugMsgBuf), \
  263. printf(s_DebugMsgBuf,"(wc) WARN: " %1)
  264. #else
  265. #define DebugMessage(%1);
  266. #define DebugMessageRed(%1);
  267. #define DebugMessageAll(%1);
  268. #define DebugMessageRedAll(%1);
  269. #endif
  270. // Weapons allowed in OnPlayerGiveDamage
  271. static const s_ValidDamageGiven[] = {
  272. 1, // 0 - Fist
  273. 1, // 1 - Brass knuckles
  274. 1, // 2 - Golf club
  275. 1, // 3 - Nitestick
  276. 1, // 4 - Knife
  277. 1, // 5 - Bat
  278. 1, // 6 - Shovel
  279. 1, // 7 - Pool cue
  280. 1, // 8 - Katana
  281. 1, // 9 - Chainsaw
  282. 1, // 10 - Dildo
  283. 1, // 11 - Dildo 2
  284. 1, // 12 - Vibrator
  285. 1, // 13 - Vibrator 2
  286. 1, // 14 - Flowers
  287. 1, // 15 - Cane
  288. 0, // 16 - Grenade
  289. 0, // 17 - Teargas
  290. 0, // 18 - Molotov
  291. 0, // 19 - Vehicle M4 (custom)
  292. 0, // 20 - Vehicle minigun
  293. 0, // 21
  294. 1, // 22 - Colt 45
  295. 1, // 23 - Silenced
  296. 1, // 24 - Deagle
  297. 1, // 25 - Shotgun
  298. 1, // 26 - Sawed-off
  299. 1, // 27 - Spas
  300. 1, // 28 - UZI
  301. 1, // 29 - MP5
  302. 1, // 30 - AK47
  303. 1, // 31 - M4
  304. 1, // 32 - Tec9
  305. 1, // 33 - Cuntgun
  306. 1, // 34 - Sniper
  307. 0, // 35 - Rocket launcher
  308. 0, // 36 - Heatseeker
  309. 0, // 37 - Flamethrower
  310. 1, // 38 - Minigun
  311. 0, // 39 - Satchel
  312. 0, // 40 - Detonator
  313. 1, // 41 - Spraycan
  314. 1, // 42 - Fire extinguisher
  315. 0, // 43 - Camera
  316. 0, // 44 - Night vision
  317. 0, // 45 - Infrared
  318. 1 // 46 - Parachute
  319. };
  320. // Weapons allowed in OnPlayerTakeDamage
  321. // 2 = valid in both OnPlayerGiveDamage and OnPlayerTakeDamage
  322. static const s_ValidDamageTaken[] = {
  323. 1, // 0 - Fist
  324. 1, // 1 - Brass knuckles
  325. 1, // 2 - Golf club
  326. 1, // 3 - Nitestick
  327. 1, // 4 - Knife
  328. 1, // 5 - Bat
  329. 1, // 6 - Shovel
  330. 1, // 7 - Pool cue
  331. 1, // 8 - Katana
  332. 1, // 9 - Chainsaw
  333. 1, // 10 - Dildo
  334. 1, // 11 - Dildo 2
  335. 1, // 12 - Vibrator
  336. 1, // 13 - Vibrator 2
  337. 1, // 14 - Flowers
  338. 1, // 15 - Cane
  339. 0, // 16 - Grenade
  340. 0, // 17 - Teargas
  341. 0, // 18 - Molotov
  342. 0, // 19 - Vehicle M4 (custom)
  343. 0, // 20 - Vehicle minigun (custom)
  344. 0, // 21
  345. 1, // 22 - Colt 45
  346. 1, // 23 - Silenced
  347. 1, // 24 - Deagle
  348. 1, // 25 - Shotgun
  349. 1, // 26 - Sawed-off
  350. 1, // 27 - Spas
  351. 1, // 28 - UZI
  352. 1, // 29 - MP5
  353. 1, // 30 - AK47
  354. 1, // 31 - M4
  355. 1, // 32 - Tec9
  356. 1, // 33 - Cuntgun
  357. 1, // 34 - Sniper
  358. 0, // 35 - Rocket launcher
  359. 0, // 36 - Heatseeker
  360. 2, // 37 - Flamethrower
  361. 1, // 38 - Minigun
  362. 0, // 39 - Satchel
  363. 0, // 40 - Detonator
  364. 1, // 41 - Spraycan
  365. 1, // 42 - Fire extinguisher
  366. 0, // 43 - Camera
  367. 0, // 44 - Night vision
  368. 0, // 45 - Infrared
  369. 1, // 46 - Parachute
  370. 0, // 47 - Fake pistol
  371. 0, // 48 - Pistol whip (custom)
  372. 2, // 49 - Vehicle
  373. 2, // 50 - Helicopter blades
  374. 2, // 51 - Explosion
  375. 0, // 52 - Car park (custom)
  376. 2, // 53 - Drowning
  377. 2 // 54 - Splat
  378. };
  379. // Default weapon damage. Connected to s_DamageType.
  380. // Melee weapons are multipliers because the damage differs
  381. // depending on type of punch/kick and fight style.
  382. static Float:s_WeaponDamage[] = {
  383. 1.0, // 0 - Fist
  384. 1.0, // 1 - Brass knuckles
  385. 1.0, // 2 - Golf club
  386. 1.0, // 3 - Nitestick
  387. 1.0, // 4 - Knife
  388. 1.0, // 5 - Bat
  389. 1.0, // 6 - Shovel
  390. 1.0, // 7 - Pool cue
  391. 1.0, // 8 - Katana
  392. 1.0, // 9 - Chainsaw
  393. 1.0, // 10 - Dildo
  394. 1.0, // 11 - Dildo 2
  395. 1.0, // 12 - Vibrator
  396. 1.0, // 13 - Vibrator 2
  397. 1.0, // 14 - Flowers
  398. 1.0, // 15 - Cane
  399. 82.5, // 16 - Grenade
  400. 0.0, // 17 - Teargas
  401. 1.0, // 18 - Molotov
  402. 9.9, // 19 - Vehicle M4 (custom)
  403. 46.2, // 20 - Vehicle minigun (custom)
  404. 0.0, // 21
  405. 8.25, // 22 - Colt 45
  406. 13.2, // 23 - Silenced
  407. 46.2, // 24 - Deagle
  408. 3.3, // 25 - Shotgun
  409. 3.3, // 26 - Sawed-off
  410. 4.95, // 27 - Spas
  411. 6.6, // 28 - UZI
  412. 8.25, // 29 - MP5
  413. 9.9, // 30 - AK47
  414. 9.9, // 31 - M4
  415. 6.6, // 32 - Tec9
  416. 24.75, // 33 - Cuntgun
  417. 41.25, // 34 - Sniper
  418. 82.5, // 35 - Rocket launcher
  419. 82.5, // 36 - Heatseeker
  420. 1.0, // 37 - Flamethrower
  421. 46.2, // 38 - Minigun
  422. 82.5, // 39 - Satchel
  423. 0.0, // 40 - Detonator
  424. 0.33, // 41 - Spraycan
  425. 0.33, // 42 - Fire extinguisher
  426. 0.0, // 43 - Camera
  427. 0.0, // 44 - Night vision
  428. 0.0, // 45 - Infrared
  429. 0.0, // 46 - Parachute
  430. 0.0, // 47 - Fake pistol
  431. 2.64, // 48 - Pistol whip (custom)
  432. 9.9, // 49 - Vehicle
  433. 330.0, // 50 - Helicopter blades
  434. 82.5, // 51 - Explosion
  435. 1.0, // 52 - Car park (custom)
  436. 1.0, // 53 - Drowning
  437. 165.0 // 54 - Splat
  438. };
  439. #assert DAMAGE_TYPE_MULTIPLIER == 0
  440. #assert DAMAGE_TYPE_STATIC == 1
  441. // Whether the damage is multiplied by the given/taken value (0) or always the same value (1)
  442. static s_DamageType[] = {
  443. 0, // 0 - Fist
  444. 0, // 1 - Brass knuckles
  445. 0, // 2 - Golf club
  446. 0, // 3 - Nitestick
  447. 0, // 4 - Knife
  448. 0, // 5 - Bat
  449. 0, // 6 - Shovel
  450. 0, // 7 - Pool cue
  451. 0, // 8 - Katana
  452. 0, // 9 - Chainsaw
  453. 0, // 10 - Dildo
  454. 0, // 11 - Dildo 2
  455. 0, // 12 - Vibrator
  456. 0, // 13 - Vibrator 2
  457. 0, // 14 - Flowers
  458. 0, // 15 - Cane
  459. 0, // 16 - Grenade
  460. 1, // 17 - Teargas
  461. 0, // 18 - Molotov
  462. 1, // 19 - Vehicle M4 (custom)
  463. 1, // 20 - Vehicle minigun (custom)
  464. 0, // 21
  465. 1, // 22 - Colt 45
  466. 1, // 23 - Silenced
  467. 1, // 24 - Deagle
  468. 1, // 25 - Shotgun
  469. 1, // 26 - Sawed-off
  470. 1, // 27 - Spas
  471. 1, // 28 - UZI
  472. 1, // 29 - MP5
  473. 1, // 30 - AK47
  474. 1, // 31 - M4
  475. 1, // 32 - Tec9
  476. 1, // 33 - Cuntgun
  477. 1, // 34 - Sniper
  478. 0, // 35 - Rocket launcher
  479. 0, // 36 - Heatseeker
  480. 0, // 37 - Flamethrower
  481. 1, // 38 - Minigun
  482. 0, // 39 - Satchel
  483. 0, // 40 - Detonator
  484. 1, // 41 - Spraycan
  485. 1, // 42 - Fire extinguisher
  486. 0, // 43 - Camera
  487. 0, // 44 - Night vision
  488. 0, // 45 - Infrared
  489. 0, // 46 - Parachute
  490. 0, // 47 - Fake pistol
  491. 1, // 48 - Pistol whip (custom)
  492. 1, // 49 - Vehicle
  493. 1, // 50 - Helicopter blades
  494. 0, // 51 - Explosion
  495. 0, // 52 - Car park
  496. 0, // 53 - Drowning
  497. 0 // 54 - Splat
  498. };
  499. // The default weapon range (from weapon.dat)
  500. // Note that due to various bugs, these can be exceeded, but
  501. // this include blocks out-of-range values.
  502. static Float:s_WeaponRange[] = {
  503. 0.0, // 0 - Fist
  504. 0.0, // 1 - Brass knuckles
  505. 0.0, // 2 - Golf club
  506. 0.0, // 3 - Nitestick
  507. 0.0, // 4 - Knife
  508. 0.0, // 5 - Bat
  509. 0.0, // 6 - Shovel
  510. 0.0, // 7 - Pool cue
  511. 0.0, // 8 - Katana
  512. 0.0, // 9 - Chainsaw
  513. 0.0, // 10 - Dildo
  514. 0.0, // 11 - Dildo 2
  515. 0.0, // 12 - Vibrator
  516. 0.0, // 13 - Vibrator 2
  517. 0.0, // 14 - Flowers
  518. 0.0, // 15 - Cane
  519. 0.0, // 16 - Grenade
  520. 0.0, // 17 - Teargas
  521. 0.0, // 18 - Molotov
  522. 90.0, // 19 - Vehicle M4 (custom)
  523. 75.0, // 20 - Vehicle minigun (custom)
  524. 0.0, // 21
  525. 35.0, // 22 - Colt 45
  526. 35.0, // 23 - Silenced
  527. 35.0, // 24 - Deagle
  528. 40.0, // 25 - Shotgun
  529. 35.0, // 26 - Sawed-off
  530. 40.0, // 27 - Spas
  531. 35.0, // 28 - UZI
  532. 45.0, // 29 - MP5
  533. 70.0, // 30 - AK47
  534. 90.0, // 31 - M4
  535. 35.0, // 32 - Tec9
  536. 100.0, // 33 - Cuntgun
  537. 320.0, // 34 - Sniper
  538. 0.0, // 35 - Rocket launcher
  539. 0.0, // 36 - Heatseeker
  540. 0.0, // 37 - Flamethrower
  541. 75.0 // 38 - Minigun
  542. };
  543. // The fastest possible gap between weapon shots in milliseconds
  544. static s_MaxWeaponShootRate[] = {
  545. 250, // 0 - Fist
  546. 250, // 1 - Brass knuckles
  547. 250, // 2 - Golf club
  548. 250, // 3 - Nitestick
  549. 250, // 4 - Knife
  550. 250, // 5 - Bat
  551. 250, // 6 - Shovel
  552. 250, // 7 - Pool cue
  553. 250, // 8 - Katana
  554. 30, // 9 - Chainsaw
  555. 250, // 10 - Dildo
  556. 250, // 11 - Dildo 2
  557. 250, // 12 - Vibrator
  558. 250, // 13 - Vibrator 2
  559. 250, // 14 - Flowers
  560. 250, // 15 - Cane
  561. 0, // 16 - Grenade
  562. 0, // 17 - Teargas
  563. 0, // 18 - Molotov
  564. 20, // 19 - Vehicle M4 (custom)
  565. 20, // 20 - Vehicle minigun (custom)
  566. 0, // 21
  567. 160, // 22 - Colt 45
  568. 120, // 23 - Silenced
  569. 120, // 24 - Deagle
  570. 800, // 25 - Shotgun
  571. 120, // 26 - Sawed-off
  572. 120, // 27 - Spas
  573. 50, // 28 - UZI
  574. 90, // 29 - MP5
  575. 90, // 30 - AK47
  576. 90, // 31 - M4
  577. 70, // 32 - Tec9
  578. 800, // 33 - Cuntgun
  579. 900, // 34 - Sniper
  580. 0, // 35 - Rocket launcher
  581. 0, // 36 - Heatseeker
  582. 0, // 37 - Flamethrower
  583. 20, // 38 - Minigun
  584. 0, // 39 - Satchel
  585. 0, // 40 - Detonator
  586. 10, // 41 - Spraycan
  587. 10, // 42 - Fire extinguisher
  588. 0, // 43 - Camera
  589. 0, // 44 - Night vision
  590. 0, // 45 - Infrared
  591. 0, // 46 - Parachute
  592. 0, // 47 - Fake pistol
  593. 400 // 48 - Pistol whip (custom)
  594. };
  595. // Whether the damage is applied directly to health (1) or is distributed between health and armour (0), and whether this rule applies only to the torso (1) or not (0)
  596. static s_DamageArmour[][2] = {
  597. {0, 0}, // 0 - Fist
  598. {0, 0}, // 1 - Brass knuckles
  599. {0, 0}, // 2 - Golf club
  600. {0, 0}, // 3 - Nitestick
  601. {0, 0}, // 4 - Knife
  602. {0, 0}, // 5 - Bat
  603. {0, 0}, // 6 - Shovel
  604. {0, 0}, // 7 - Pool cue
  605. {0, 0}, // 8 - Katana
  606. {0, 0}, // 9 - Chainsaw
  607. {0, 0}, // 10 - Dildo
  608. {0, 0}, // 11 - Dildo 2
  609. {0, 0}, // 12 - Vibrator
  610. {0, 0}, // 13 - Vibrator 2
  611. {0, 0}, // 14 - Flowers
  612. {0, 0}, // 15 - Cane
  613. {0, 0}, // 16 - Grenade
  614. {0, 0}, // 17 - Teargas
  615. {0, 0}, // 18 - Molotov
  616. {1, 1}, // 19 - Vehicle M4 (custom)
  617. {1, 1}, // 20 - Vehicle minigun (custom)
  618. {1, 0}, // 21
  619. {1, 1}, // 22 - Colt 45
  620. {1, 1}, // 23 - Silenced
  621. {1, 1}, // 24 - Deagle
  622. {1, 1}, // 25 - Shotgun
  623. {1, 1}, // 26 - Sawed-off
  624. {1, 1}, // 27 - Spas
  625. {1, 1}, // 28 - UZI
  626. {1, 1}, // 29 - MP5
  627. {1, 1}, // 30 - AK47
  628. {1, 1}, // 31 - M4
  629. {1, 1}, // 32 - Tec9
  630. {1, 1}, // 33 - Cuntgun
  631. {1, 1}, // 34 - Sniper
  632. {0, 0}, // 35 - Rocket launcher
  633. {0, 0}, // 36 - Heatseeker
  634. {0, 0}, // 37 - Flamethrower
  635. {1, 1}, // 38 - Minigun
  636. {0, 0}, // 39 - Satchel
  637. {0, 0}, // 40 - Detonator
  638. {0, 0}, // 41 - Spraycan
  639. {0, 0}, // 42 - Fire extinguisher
  640. {1, 0}, // 43 - Camera
  641. {1, 0}, // 44 - Night vision
  642. {1, 0}, // 45 - Infrared
  643. {1, 0}, // 46 - Parachute
  644. {1, 0}, // 47 - Fake pistol
  645. {0, 0}, // 48 - Pistol whip (custom)
  646. {0, 0}, // 49 - Vehicle
  647. {0, 1}, // 50 - Helicopter blades
  648. {0, 0}, // 51 - Explosion
  649. {0, 0}, // 52 - Car park
  650. {0, 0}, // 53 - Drowning
  651. {0, 0} // 54 - Splat
  652. };
  653. // That's right, it's called cuntgun
  654. stock const g_WeaponName[57][WC_MAX_WEAPON_NAME] = {
  655. {"Fist" }, {"Brass knuckles"}, {"Golf club" },
  656. {"Nightstick" }, {"Knife" }, {"Bat" },
  657. {"Shovel" }, {"Pool cue" }, {"Katana" },
  658. {"Chainsaw" }, {"Purple dildo" }, {"Dildo" },
  659. {"Vibrator" }, {"Vibrator" }, {"Flowers" },
  660. {"Cane" }, {"Grenade" }, {"Tear gas" },
  661. {"Molotov" }, {"Vehicle gun" }, {"Vehicle gun" },
  662. {"" }, {"Colt 45" }, {"Silenced pistol" },
  663. {"Deagle" }, {"Shotgun" }, {"Sawn-off shotgun" },
  664. {"Combat shotgun" }, {"Mac-10" }, {"MP5" },
  665. {"AK-47" }, {"M4" }, {"Tec-9" },
  666. {"Cuntgun" }, {"Sniper" }, {"Rocket launcher" },
  667. {"Heat seeking RPG" }, {"Flamethrower" }, {"Minigun" },
  668. {"Satchel" }, {"Detonator" }, {"Spraycan" },
  669. {"Fire extinguisher"}, {"Camera" }, {"Night vision goggles"},
  670. {"Infrared goggles" }, {"Parachute" }, {"Fake pistol" },
  671. {"Pistol whip" }, {"Vehicle" }, {"Helicopter blades" },
  672. {"Explosion" }, {"Car parking" }, {"Drowning" },
  673. {"Collision" }, {"Splat" }, {"Unknown" }
  674. };
  675. // Yes - this is every single one of them
  676. #if WC_CUSTOM_VENDING_MACHINES
  677. static const Float:sc_VendingMachines[][E_VENDING_MACHINE] = {
  678. {955, 0, -862.82, 1536.60, 21.98, 0.00, 0.00, 180.00, -862.84, 1537.60},
  679. {956, 0, 2271.72, -76.46, 25.96, 0.00, 0.00, 0.00, 2271.72, -77.46},
  680. {955, 0, 1277.83, 372.51, 18.95, 0.00, 0.00, 64.00, 1278.73, 372.07},
  681. {956, 0, 662.42, -552.16, 15.71, 0.00, 0.00, 180.00, 662.41, -551.16},
  682. {955, 0, 201.01, -107.61, 0.89, 0.00, 0.00, 270.00, 200.01, -107.63},
  683. {955, 0, -253.74, 2597.95, 62.24, 0.00, 0.00, 90.00, -252.74, 2597.95},
  684. {956, 0, -253.74, 2599.75, 62.24, 0.00, 0.00, 90.00, -252.74, 2599.75},
  685. {956, 0, -76.03, 1227.99, 19.12, 0.00, 0.00, 90.00, -75.03, 1227.99},
  686. {955, 0, -14.70, 1175.35, 18.95, 0.00, 0.00, 180.00, -14.72, 1176.35},
  687. {1977, 7, 316.87, -140.35, 998.58, 0.00, 0.00, 270.00, 315.87, -140.36},
  688. {1775, 17, 373.82, -178.14, 1000.73, 0.00, 0.00, 0.00, 373.82, -179.14},
  689. {1776, 17, 379.03, -178.88, 1000.73, 0.00, 0.00, 270.00, 378.03, -178.90},
  690. {1775, 17, 495.96, -24.32, 1000.73, 0.00, 0.00, 180.00, 495.95, -23.32},
  691. {1776, 17, 500.56, -1.36, 1000.73, 0.00, 0.00, 0.00, 500.56, -2.36},
  692. {1775, 17, 501.82, -1.42, 1000.73, 0.00, 0.00, 0.00, 501.82, -2.42},
  693. {956, 0, -1455.11, 2591.66, 55.23, 0.00, 0.00, 180.00, -1455.13, 2592.66},
  694. {955, 0, 2352.17, -1357.15, 23.77, 0.00, 0.00, 90.00, 2353.17, -1357.15},
  695. {955, 0, 2325.97, -1645.13, 14.21, 0.00, 0.00, 0.00, 2325.97, -1646.13},
  696. {956, 0, 2139.51, -1161.48, 23.35, 0.00, 0.00, 87.00, 2140.51, -1161.53},
  697. {956, 0, 2153.23, -1016.14, 62.23, 0.00, 0.00, 127.00, 2154.03, -1015.54},
  698. {955, 0, 1928.73, -1772.44, 12.94, 0.00, 0.00, 90.00, 1929.73, -1772.44},
  699. {1776, 1, 2222.36, 1602.64, 1000.06, 0.00, 0.00, 90.00, 2223.36, 1602.64},
  700. {1775, 1, 2222.20, 1606.77, 1000.05, 0.00, 0.00, 90.00, 2223.20, 1606.77},
  701. {1775, 1, 2155.90, 1606.77, 1000.05, 0.00, 0.00, 90.00, 2156.90, 1606.77},
  702. {1775, 1, 2209.90, 1607.19, 1000.05, 0.00, 0.00, 270.00, 2208.90, 1607.17},
  703. {1776, 1, 2155.84, 1607.87, 1000.06, 0.00, 0.00, 90.00, 2156.84, 1607.87},
  704. {1776, 1, 2202.45, 1617.00, 1000.06, 0.00, 0.00, 180.00, 2202.43, 1618.00},
  705. {1776, 1, 2209.24, 1621.21, 1000.06, 0.00, 0.00, 0.00, 2209.24, 1620.21},
  706. {1776, 3, 330.67, 178.50, 1020.07, 0.00, 0.00, 0.00, 330.67, 177.50},
  707. {1776, 3, 331.92, 178.50, 1020.07, 0.00, 0.00, 0.00, 331.92, 177.50},
  708. {1776, 3, 350.90, 206.08, 1008.47, 0.00, 0.00, 90.00, 351.90, 206.08},
  709. {1776, 3, 361.56, 158.61, 1008.47, 0.00, 0.00, 180.00, 361.54, 159.61},
  710. {1776, 3, 371.59, 178.45, 1020.07, 0.00, 0.00, 0.00, 371.59, 177.45},
  711. {1776, 3, 374.89, 188.97, 1008.47, 0.00, 0.00, 0.00, 374.89, 187.97},
  712. {1775, 2, 2576.70, -1284.43, 1061.09, 0.00, 0.00, 270.00, 2575.70, -1284.44},
  713. {1775, 15, 2225.20, -1153.42, 1025.90, 0.00, 0.00, 270.00, 2224.20, -1153.43},
  714. {955, 0, 1154.72, -1460.89, 15.15, 0.00, 0.00, 270.00, 1153.72, -1460.90},
  715. {956, 0, 2480.85, -1959.27, 12.96, 0.00, 0.00, 180.00, 2480.84, -1958.27},
  716. {955, 0, 2060.11, -1897.64, 12.92, 0.00, 0.00, 0.00, 2060.11, -1898.64},
  717. {955, 0, 1729.78, -1943.04, 12.94, 0.00, 0.00, 0.00, 1729.78, -1944.04},
  718. {956, 0, 1634.10, -2237.53, 12.89, 0.00, 0.00, 0.00, 1634.10, -2238.53},
  719. {955, 0, 1789.21, -1369.26, 15.16, 0.00, 0.00, 270.00, 1788.21, -1369.28},
  720. {956, 0, -2229.18, 286.41, 34.70, 0.00, 0.00, 180.00, -2229.20, 287.41},
  721. {955, 256, -1980.78, 142.66, 27.07, 0.00, 0.00, 270.00, -1981.78, 142.64},
  722. {955, 256, -2118.96, -423.64, 34.72, 0.00, 0.00, 255.00, -2119.93, -423.40},
  723. {955, 256, -2118.61, -422.41, 34.72, 0.00, 0.00, 255.00, -2119.58, -422.17},
  724. {955, 256, -2097.27, -398.33, 34.72, 0.00, 0.00, 180.00, -2097.29, -397.33},
  725. {955, 256, -2092.08, -490.05, 34.72, 0.00, 0.00, 0.00, -2092.08, -491.05},
  726. {955, 256, -2063.27, -490.05, 34.72, 0.00, 0.00, 0.00, -2063.27, -491.05},
  727. {955, 256, -2005.64, -490.05, 34.72, 0.00, 0.00, 0.00, -2005.64, -491.05},
  728. {955, 256, -2034.46, -490.05, 34.72, 0.00, 0.00, 0.00, -2034.46, -491.05},
  729. {955, 256, -2068.56, -398.33, 34.72, 0.00, 0.00, 180.00, -2068.58, -397.33},
  730. {955, 256, -2039.85, -398.33, 34.72, 0.00, 0.00, 180.00, -2039.86, -397.33},
  731. {955, 256, -2011.14, -398.33, 34.72, 0.00, 0.00, 180.00, -2011.15, -397.33},
  732. {955, 2048, -1350.11, 492.28, 10.58, 0.00, 0.00, 90.00, -1349.11, 492.28},
  733. {956, 2048, -1350.11, 493.85, 10.58, 0.00, 0.00, 90.00, -1349.11, 493.85},
  734. {955, 0, 2319.99, 2532.85, 10.21, 0.00, 0.00, 0.00, 2319.99, 2531.85},
  735. {956, 0, 2845.72, 1295.04, 10.78, 0.00, 0.00, 0.00, 2845.72, 1294.04},
  736. {955, 0, 2503.14, 1243.69, 10.21, 0.00, 0.00, 180.00, 2503.12, 1244.69},
  737. {956, 0, 2647.69, 1129.66, 10.21, 0.00, 0.00, 0.00, 2647.69, 1128.66},
  738. {1209, 0, -2420.21, 984.57, 44.29, 0.00, 0.00, 90.00, -2419.21, 984.57},
  739. {1302, 0, -2420.17, 985.94, 44.29, 0.00, 0.00, 90.00, -2419.17, 985.94},
  740. {955, 0, 2085.77, 2071.35, 10.45, 0.00, 0.00, 90.00, 2086.77, 2071.35},
  741. {956, 0, 1398.84, 2222.60, 10.42, 0.00, 0.00, 180.00, 1398.82, 2223.60},
  742. {956, 0, 1659.46, 1722.85, 10.21, 0.00, 0.00, 0.00, 1659.46, 1721.85},
  743. {955, 0, 1520.14, 1055.26, 10.00, 0.00, 0.00, 270.00, 1519.14, 1055.24},
  744. {1775, 6, -19.03, -57.83, 1003.63, 0.00, 0.00, 180.00, -19.05, -56.83},
  745. {1775, 18, -16.11, -91.64, 1003.63, 0.00, 0.00, 180.00, -16.13, -90.64},
  746. {1775, 16, -15.10, -140.22, 1003.63, 0.00, 0.00, 180.00, -15.11, -139.22},
  747. {1775, 17, -32.44, -186.69, 1003.63, 0.00, 0.00, 180.00, -32.46, -185.69},
  748. {1775, 16, -35.72, -140.22, 1003.63, 0.00, 0.00, 180.00, -35.74, -139.22},
  749. {1776, 6, -36.14, -57.87, 1003.63, 0.00, 0.00, 180.00, -36.16, -56.87},
  750. {1776, 18, -17.54, -91.71, 1003.63, 0.00, 0.00, 180.00, -17.56, -90.71},
  751. {1776, 16, -16.53, -140.29, 1003.63, 0.00, 0.00, 180.00, -16.54, -139.29},
  752. {1776, 17, -33.87, -186.76, 1003.63, 0.00, 0.00, 180.00, -33.89, -185.76},
  753. {1775, 6, -19.03, -57.83, 1003.63, 0.00, 0.00, 180.00, -19.05, -56.83},
  754. {1776, 6, -36.14, -57.87, 1003.63, 0.00, 0.00, 180.00, -36.16, -56.87},
  755. {1775, 18, -16.11, -91.64, 1003.63, 0.00, 0.00, 180.00, -16.13, -90.64},
  756. {1776, 18, -17.54, -91.71, 1003.63, 0.00, 0.00, 180.00, -17.56, -90.71},
  757. {1776, 16, -16.53, -140.29, 1003.63, 0.00, 0.00, 180.00, -16.54, -139.29},
  758. {1775, 16, -15.10, -140.22, 1003.63, 0.00, 0.00, 180.00, -15.11, -139.22},
  759. {1776, 17, -33.87, -186.76, 1003.63, 0.00, 0.00, 180.00, -33.89, -185.76},
  760. {1775, 17, -32.44, -186.69, 1003.63, 0.00, 0.00, 180.00, -32.46, -185.69},
  761. {1775, 16, -35.72, -140.22, 1003.63, 0.00, 0.00, 180.00, -35.74, -139.22}
  762. };
  763. #endif
  764. // Sorry about the mess..
  765. static s_LagCompMode;
  766. static s_LastExplosive[MAX_PLAYERS];
  767. static s_LastShot[MAX_PLAYERS][E_SHOT_INFO];
  768. static s_LastShotTicks[MAX_PLAYERS][10];
  769. static s_LastShotWeapons[MAX_PLAYERS][10];
  770. static s_LastShotIdx[MAX_PLAYERS];
  771. static s_LastHitTicks[MAX_PLAYERS][10];
  772. static s_LastHitWeapons[MAX_PLAYERS][10];
  773. static s_LastHitIdx[MAX_PLAYERS];
  774. static s_ShotsFired[MAX_PLAYERS];
  775. static s_HitsIssued[MAX_PLAYERS];
  776. static s_MaxShootRateSamples = 5;
  777. static s_MaxHitRateSamples = 5;
  778. static Float:s_PlayerMaxHealth[MAX_PLAYERS] = {100.0, ...};
  779. static Float:s_PlayerHealth[MAX_PLAYERS] = {100.0, ...};
  780. static Float:s_PlayerMaxArmour[MAX_PLAYERS] = {100.0, ...};
  781. static Float:s_PlayerArmour[MAX_PLAYERS] = {0.0, ...};
  782. static s_LastSentHealth[MAX_PLAYERS];
  783. static s_LastSentArmour[MAX_PLAYERS];
  784. static bool:s_DamageArmourToggle[2] = {false, ...};
  785. static s_PlayerTeam[MAX_PLAYERS] = {NO_TEAM, ...};
  786. static s_IsDying[MAX_PLAYERS];
  787. static s_DeathTimer[MAX_PLAYERS] = {-1, ...};
  788. static bool:s_HealthBarVisible[MAX_PLAYERS];
  789. static bool:s_SpawnForStreamedIn[MAX_PLAYERS];
  790. static s_RespawnTime = 3000;
  791. static s_CustomFallDamage = false;
  792. static bool:s_CbugAllowed = true;
  793. static s_CbugFroze[MAX_PLAYERS];
  794. static s_DamageFeed = true;
  795. static s_DamageFeedPlayer[MAX_PLAYERS] = {-1, ...};
  796. static s_DamageFeedHideDelay = 3000;
  797. static s_DamageFeedMaxUpdateRate = 250;
  798. static s_VehiclePassengerDamage = false;
  799. static s_VehicleUnoccupiedDamage = false;
  800. static Float:s_FallDeathVelocity = -0.6;
  801. static s_DamageTakenSound = 1190;
  802. static s_DamageGivenSound = 17802;
  803. static s_RejectedHits[MAX_PLAYERS][WC_MAX_REJECTED_HITS][E_REJECTED_HIT];
  804. static s_RejectedHitsIdx[MAX_PLAYERS];
  805. static s_World[MAX_PLAYERS];
  806. static s_LastAnim[MAX_PLAYERS] = {-1, ...};
  807. static Float:s_LastZVelo[MAX_PLAYERS] = {0.0, ...};
  808. static Float:s_LastZ[MAX_PLAYERS] = {0.0, ...};
  809. static s_LastUpdate[MAX_PLAYERS] = {-1, ...};
  810. static PlayerText:s_DamageFeedTaken[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...};
  811. static PlayerText:s_DamageFeedGiven[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...};
  812. static s_DamageFeedHitsGiven[MAX_PLAYERS][WC_FEED_HEIGHT][E_DAMAGE_FEED_HIT];
  813. static s_DamageFeedHitsTaken[MAX_PLAYERS][WC_FEED_HEIGHT][E_DAMAGE_FEED_HIT];
  814. static s_DamageFeedTimer[MAX_PLAYERS] = {-1, ...};
  815. static s_DamageFeedLastUpdate[MAX_PLAYERS];
  816. static s_Spectating[MAX_PLAYERS] = {INVALID_PLAYER_ID, ...};
  817. static s_LastStop[MAX_PLAYERS];
  818. static bool:s_FirstSpawn[MAX_PLAYERS] = {true, ...};
  819. #if WC_CUSTOM_VENDING_MACHINES
  820. static bool:s_CustomVendingMachines = true;
  821. static s_VendingMachineObject[sizeof(sc_VendingMachines)] = {-1, ...};
  822. static s_VendingUseTimer[MAX_PLAYERS] = {-1, ...};
  823. #endif
  824. static s_BeingResynced[MAX_PLAYERS];
  825. static s_KnifeTimeout[MAX_PLAYERS] = {-1, ...};
  826. static s_SyncData[MAX_PLAYERS][E_RESYNC_DATA];
  827. static Text:s_HealthBarBorder = Text:INVALID_TEXT_DRAW;
  828. static Text:s_HealthBarBackground = Text:INVALID_TEXT_DRAW;
  829. static PlayerText:s_HealthBarForeground[MAX_PLAYERS] = {PlayerText:INVALID_TEXT_DRAW, ...};
  830. static s_DamageRangeSteps[55];
  831. static Float:s_DamageRangeRanges[55][WC_MAX_DAMAGE_RANGES];
  832. static Float:s_DamageRangeValues[55][WC_MAX_DAMAGE_RANGES];
  833. static s_LastVehicleShooter[MAX_VEHICLES + 1] = {INVALID_PLAYER_ID, ...};
  834. static bool:s_InternalTextDraw[Text:MAX_TEXT_DRAWS];
  835. static bool:s_InternalPlayerTextDraw[MAX_PLAYERS][PlayerText:MAX_PLAYER_TEXT_DRAWS];
  836. static s_LastVehicleEnterTime[MAX_PLAYERS];
  837. static s_TrueDeath[MAX_PLAYERS];
  838. static s_InClassSelection[MAX_PLAYERS];
  839. static s_ForceClassSelection[MAX_PLAYERS];
  840. static s_ClassSpawnInfo[320][E_SPAWN_INFO];
  841. static s_PlayerSpawnInfo[MAX_PLAYERS][E_SPAWN_INFO];
  842. static s_PlayerFallbackSpawnInfo[MAX_PLAYERS][E_SPAWN_INFO];
  843. static s_PlayerClass[MAX_PLAYERS] = {-2, ...};
  844. static bool:s_SpawnInfoModified[MAX_PLAYERS];
  845. static bool:s_AlreadyConnected[MAX_PLAYERS];
  846. static s_DeathSkip[MAX_PLAYERS];
  847. static s_DeathSkipTick[MAX_PLAYERS];
  848. static s_LastVehicleTick[MAX_PLAYERS];
  849. static s_PreviousHits[MAX_PLAYERS][10][E_HIT_INFO];
  850. static s_PreviousHitI[MAX_PLAYERS];
  851. static Float:s_DamageDoneHealth[MAX_PLAYERS];
  852. static Float:s_DamageDoneArmour[MAX_PLAYERS];
  853. static s_DelayedDeathTimer[MAX_PLAYERS] = {-1, ...};
  854. static bool:s_VehicleAlive[MAX_VEHICLES] = {false, ...};
  855. static s_VehicleRespawnTimer[MAX_VEHICLES] = {-1, ...};
  856. native WC_IsValidVehicle(vehicleid) = IsValidVehicle;
  857. /*
  858. * Public API
  859. */
  860. stock IsBulletWeapon(weaponid)
  861. {
  862. return (WEAPON_COLT45 <= weaponid <= WEAPON_SNIPER) || weaponid == WEAPON_MINIGUN;
  863. }
  864. stock IsHighRateWeapon(weaponid)
  865. {
  866. switch (weaponid) {
  867. case WEAPON_FLAMETHROWER, WEAPON_DROWN, WEAPON_CARPARK,
  868. WEAPON_SPRAYCAN, WEAPON_FIREEXTINGUISHER: {
  869. return true;
  870. }
  871. }
  872. return false;
  873. }
  874. stock IsMeleeWeapon(weaponid)
  875. {
  876. return (WEAPON_UNARMED <= weaponid <= WEAPON_KATANA) || (WEAPON_DILDO <= weaponid <= WEAPON_CANE) || weaponid == WEAPON_PISTOLWHIP;
  877. }
  878. stock IsPlayerSpawned(playerid)
  879. {
  880. if (s_IsDying[playerid] || s_BeingResynced[playerid]) {
  881. return false;
  882. }
  883. switch (GetPlayerState(playerid)) {
  884. case PLAYER_STATE_ONFOOT .. PLAYER_STATE_PASSENGER,
  885. PLAYER_STATE_SPAWNED: {
  886. return true;
  887. }
  888. }
  889. return false;
  890. }
  891. stock AverageShootRate(playerid, shots, &multiple_weapons = 0)
  892. {
  893. if (playerid == INVALID_PLAYER_ID || s_ShotsFired[playerid] < shots) {
  894. return -1;
  895. }
  896. new total = 0, idx = s_LastShotIdx[playerid];
  897. multiple_weapons = false;
  898. for (new i = shots - 2; i >= 0; i--) {
  899. new prev_idx = (idx - i - 1) % sizeof(s_LastShotTicks[]);
  900. // JIT plugin fix
  901. if (prev_idx < 0) {
  902. prev_idx += sizeof(s_LastShotTicks[]);
  903. }
  904. new prev = s_LastShotTicks[playerid][prev_idx];
  905. new prev_weap = s_LastShotWeapons[playerid][prev_idx];
  906. new this_idx = (idx - i) % sizeof(s_LastShotTicks[]);
  907. // JIT plugin fix
  908. if (this_idx < 0) {
  909. this_idx += sizeof(s_LastShotTicks[]);
  910. }
  911. if (prev_weap != s_LastShotWeapons[playerid][this_idx]) {
  912. multiple_weapons = true;
  913. }
  914. total += s_LastShotTicks[playerid][this_idx] - prev;
  915. }
  916. return total / (shots - 1);
  917. }
  918. stock AverageHitRate(playerid, hits, &multiple_weapons = 0)
  919. {
  920. if (playerid == INVALID_PLAYER_ID || s_HitsIssued[playerid] < hits) {
  921. return -1;
  922. }
  923. new total = 0, idx = s_LastHitIdx[playerid];
  924. multiple_weapons = false;
  925. for (new i = hits - 2; i >= 0; i--) {
  926. new prev_idx = (idx - i - 1) % sizeof(s_LastHitTicks[]);
  927. // JIT plugin fix
  928. if (prev_idx < 0) {
  929. prev_idx += sizeof(s_LastHitTicks[]);
  930. }
  931. new prev = s_LastHitTicks[playerid][prev_idx];
  932. new prev_weap = s_LastHitWeapons[playerid][prev_idx];
  933. new this_idx = (idx - i) % sizeof(s_LastHitTicks[]);
  934. // JIT plugin fix
  935. if (this_idx < 0) {
  936. this_idx += sizeof(s_LastHitTicks[]);
  937. }
  938. if (prev_weap != s_LastHitWeapons[playerid][this_idx]) {
  939. multiple_weapons = true;
  940. }
  941. total += s_LastHitTicks[playerid][this_idx] - prev;
  942. }
  943. return total / (hits - 1);
  944. }
  945. stock SetRespawnTime(ms)
  946. {
  947. s_RespawnTime = max(0, ms);
  948. }
  949. stock GetRespawnTime()
  950. {
  951. return s_RespawnTime;
  952. }
  953. stock ReturnWeaponName(weaponid)
  954. {
  955. new name[sizeof(g_WeaponName[])];
  956. WC_GetWeaponName(weaponid, name);
  957. return name;
  958. }
  959. stock SetWeaponDamage(weaponid, damage_type, Float:amount, Float:...)
  960. {
  961. if (weaponid < 0 || weaponid >= sizeof(s_WeaponDamage)) {
  962. return 0;
  963. }
  964. if (damage_type == DAMAGE_TYPE_RANGE || damage_type == DAMAGE_TYPE_RANGE_MULTIPLIER) {
  965. if (!IsBulletWeapon(weaponid)) {
  966. return 0;
  967. }
  968. new args = numargs();
  969. if (!(args & 0b1)) {
  970. return 0;
  971. }
  972. new steps = (args - 1) / 2;
  973. s_DamageType[weaponid] = damage_type;
  974. s_DamageRangeSteps[weaponid] = steps;
  975. for (new i = 0; i < steps; i++) {
  976. if (i) {
  977. s_DamageRangeRanges[weaponid][i] = Float:getarg(1 + i*2);
  978. s_DamageRangeValues[weaponid][i] = Float:getarg(2 + i*2);
  979. } else {
  980. s_DamageRangeValues[weaponid][i] = amount;
  981. }
  982. }
  983. return 1;
  984. } else if (damage_type == DAMAGE_TYPE_MULTIPLIER || damage_type == DAMAGE_TYPE_STATIC) {
  985. s_DamageType[weaponid] = damage_type;
  986. s_DamageRangeSteps[weaponid] = 0;
  987. s_WeaponDamage[weaponid] = amount;
  988. return 1;
  989. }
  990. return 0;
  991. }
  992. stock SetCustomArmourRules(bool:armour_rules, bool:torso_rules = false)
  993. {
  994. s_DamageArmourToggle[0] = armour_rules;
  995. s_DamageArmourToggle[1] = torso_rules;
  996. }
  997. stock SetWeaponArmourRule(weaponid, bool:affects_armour, bool:torso_only = false)
  998. {
  999. if (weaponid < 0 || weaponid >= sizeof(s_WeaponDamage)) {
  1000. return 0;
  1001. }
  1002. s_DamageArmour[weaponid][0] = affects_armour;
  1003. s_DamageArmour[weaponid][1] = torso_only;
  1004. return 1;
  1005. }
  1006. stock SetDamageSounds(taken, given)
  1007. {
  1008. s_DamageTakenSound = taken;
  1009. s_DamageGivenSound = given;
  1010. }
  1011. stock SetCbugAllowed(bool:enabled)
  1012. {
  1013. s_CbugAllowed = enabled;
  1014. }
  1015. stock bool:GetCbugAllowed()
  1016. {
  1017. return s_CbugAllowed;
  1018. }
  1019. stock SetCustomFallDamage(bool:toggle, Float:damage_multiplier = 25.0, Float:death_velocity = -0.6)
  1020. {
  1021. s_CustomFallDamage = toggle;
  1022. if (toggle) {
  1023. s_WeaponDamage[WEAPON_COLLISION] = damage_multiplier;
  1024. s_FallDeathVelocity = -floatabs(death_velocity);
  1025. }
  1026. }
  1027. #if WC_CUSTOM_VENDING_MACHINES
  1028. stock SetCustomVendingMachines(bool:toggle)
  1029. {
  1030. s_CustomVendingMachines = toggle;
  1031. if (toggle) {
  1032. CreateVendingMachines();
  1033. } else {
  1034. DestroyVendingMachines();
  1035. }
  1036. }
  1037. #endif
  1038. stock SetVehiclePassengerDamage(bool:toggle)
  1039. {
  1040. s_VehiclePassengerDamage = toggle;
  1041. }
  1042. stock SetVehicleUnoccupiedDamage(bool:toggle)
  1043. {
  1044. s_VehicleUnoccupiedDamage = toggle;
  1045. }
  1046. stock SetDamageFeedForPlayer(playerid, toggle = -1)
  1047. {
  1048. if (IsPlayerConnected(playerid))
  1049. {
  1050. s_DamageFeedPlayer[playerid] = toggle;
  1051. DamageFeedUpdate(playerid);
  1052. return 1;
  1053. }
  1054. return 0;
  1055. }
  1056. stock IsDamageFeedActive(playerid = -1)
  1057. {
  1058. if (playerid != -1) {
  1059. return s_DamageFeedPlayer[playerid] == 1 || s_DamageFeed && s_DamageFeedPlayer[playerid] != 0;
  1060. }
  1061. return s_DamageFeed;
  1062. }
  1063. stock SetDamageFeed(bool:toggle)
  1064. {
  1065. s_DamageFeed = toggle;
  1066. for (new i = 0; i < MAX_PLAYERS; i++) {
  1067. if (IsPlayerConnected(i)) {
  1068. DamageFeedUpdate(i);
  1069. }
  1070. }
  1071. }
  1072. stock SetWeaponShootRate(weaponid, max_rate)
  1073. {
  1074. if (0 <= weaponid < sizeof(s_MaxWeaponShootRate)) {
  1075. s_MaxWeaponShootRate[weaponid] = max_rate;
  1076. return 1;
  1077. }
  1078. return 0;
  1079. }
  1080. stock IsPlayerDying(playerid)
  1081. {
  1082. if (0 <= playerid < MAX_PLAYERS) {
  1083. return s_IsDying[playerid];
  1084. }
  1085. return false;
  1086. }
  1087. stock SetWeaponMaxRange(weaponid, Float:range)
  1088. {
  1089. if (!IsBulletWeapon(weaponid)) {
  1090. return 0;
  1091. }
  1092. s_WeaponRange[weaponid] = range;
  1093. return 1;
  1094. }
  1095. stock SetPlayerMaxHealth(playerid, Float:value)
  1096. {
  1097. if (0 <= playerid < MAX_PLAYERS) {
  1098. s_PlayerMaxHealth[playerid] = value;
  1099. }
  1100. }
  1101. stock SetPlayerMaxArmour(playerid, Float:value)
  1102. {
  1103. if (0 <= playerid < MAX_PLAYERS) {
  1104. s_PlayerMaxArmour[playerid] = value;
  1105. }
  1106. }
  1107. stock Float:GetPlayerMaxHealth(playerid)
  1108. {
  1109. if (0 <= playerid < MAX_PLAYERS) {
  1110. return s_PlayerMaxHealth[playerid];
  1111. }
  1112. return 0.0;
  1113. }
  1114. stock Float:GetPlayerMaxArmour(playerid)
  1115. {
  1116. if (0 <= playerid < MAX_PLAYERS) {
  1117. return s_PlayerMaxArmour[playerid];
  1118. }
  1119. return 0.0;
  1120. }
  1121. stock Float:GetLastDamageHealth(playerid)
  1122. {
  1123. if (0 <= playerid < MAX_PLAYERS) {
  1124. return s_DamageDoneHealth[playerid];
  1125. }
  1126. return 0.0;
  1127. }
  1128. stock Float:GetLastDamageArmour(playerid)
  1129. {
  1130. if (0 <= playerid < MAX_PLAYERS) {
  1131. return s_DamageDoneArmour[playerid];
  1132. }
  1133. return 0.0;
  1134. }
  1135. stock DamagePlayer(playerid, Float:amount, issuerid = INVALID_PLAYER_ID, weaponid = WEAPON_UNKNOWN, bodypart = BODY_PART_UNKNOWN, bool:ignore_armour = false)
  1136. {
  1137. if (playerid < 0 || playerid > MAX_PLAYERS || !IsPlayerConnected(playerid)) {
  1138. return 0;
  1139. }
  1140. if (amount < 0.0) {
  1141. return 0;
  1142. }
  1143. if (weaponid < 0 || weaponid > 55) {
  1144. weaponid = WEAPON_UNKNOWN;
  1145. }
  1146. if (issuerid < 0 || issuerid > MAX_PLAYERS || !IsPlayerConnected(issuerid)) {
  1147. issuerid = INVALID_PLAYER_ID;
  1148. }
  1149. InflictDamage(playerid, amount, issuerid, weaponid, bodypart, ignore_armour);
  1150. return 1;
  1151. }
  1152. stock GetRejectedHit(playerid, idx, output[], maxlength = sizeof(output))
  1153. {
  1154. if (idx >= WC_MAX_REJECTED_HITS) {
  1155. return 0;
  1156. }
  1157. new real_idx = (s_RejectedHitsIdx[playerid] - idx) % WC_MAX_REJECTED_HITS;
  1158. // JIT plugin fix
  1159. if (real_idx < 0) {
  1160. real_idx += WC_MAX_REJECTED_HITS;
  1161. }
  1162. if (!s_RejectedHits[playerid][real_idx][e_Time]) {
  1163. return 0;
  1164. }
  1165. new reason = s_RejectedHits[playerid][real_idx][e_Reason];
  1166. new hour = s_RejectedHits[playerid][real_idx][e_Hour];
  1167. new minute = s_RejectedHits[playerid][real_idx][e_Minute];
  1168. new second = s_RejectedHits[playerid][real_idx][e_Second];
  1169. new i1 = s_RejectedHits[playerid][real_idx][e_Info1];
  1170. new i2 = s_RejectedHits[playerid][real_idx][e_Info2];
  1171. new i3 = s_RejectedHits[playerid][real_idx][e_Info3];
  1172. new weapon = s_RejectedHits[playerid][real_idx][e_Weapon];
  1173. new weapon_name[32];
  1174. WC_GetWeaponName(weapon, weapon_name);
  1175. format(output, maxlength, "[%02d:%02d:%02d] (%s -> %s) %s", hour, minute, second, weapon_name, s_RejectedHits[playerid][real_idx][e_Name], g_HitRejectReasons[reason]);
  1176. format(output, maxlength, output, i1, i2, i3);
  1177. return 1;
  1178. }
  1179. stock ResyncPlayer(playerid)
  1180. {
  1181. SaveSyncData(playerid);
  1182. s_BeingResynced[playerid] = true;
  1183. SpawnPlayerInPlace(playerid);
  1184. }
  1185. /*
  1186. * Hooked natives
  1187. */
  1188. stock WC_SpawnPlayer(playerid)
  1189. {
  1190. if (playerid < 0 || playerid >= MAX_PLAYERS || s_IsDying[playerid]) {
  1191. return 0;
  1192. }
  1193. if (s_PlayerHealth[playerid] == 0.0) {
  1194. s_PlayerHealth[playerid] = s_PlayerMaxHealth[playerid];
  1195. }
  1196. SpawnPlayer(playerid);
  1197. return 1;
  1198. }
  1199. stock WC_GetPlayerState(playerid)
  1200. {
  1201. if (s_IsDying[playerid]) {
  1202. return PLAYER_STATE_WASTED;
  1203. }
  1204. return GetPlayerState(playerid);
  1205. }
  1206. stock Float:WC_GetPlayerHealth(playerid, &Float:health = 0.0)
  1207. {
  1208. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1209. health = 0.0;
  1210. return 0.0;
  1211. }
  1212. health = s_PlayerHealth[playerid];
  1213. return health;
  1214. }
  1215. stock WC_SetPlayerHealth(playerid, Float:health, Float:armour = -1.0)
  1216. {
  1217. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1218. return 0;
  1219. }
  1220. if (health <= 0.0) {
  1221. s_PlayerArmour[playerid] = 0.0;
  1222. s_PlayerHealth[playerid] = 0.0;
  1223. InflictDamage(playerid, 0.0);
  1224. } else {
  1225. if (armour != -1.0) {
  1226. if (armour > s_PlayerMaxArmour[playerid]) {
  1227. armour = s_PlayerMaxArmour[playerid];
  1228. }
  1229. s_PlayerArmour[playerid] = armour;
  1230. }
  1231. if (health > s_PlayerMaxHealth[playerid]) {
  1232. health = s_PlayerMaxHealth[playerid];
  1233. }
  1234. s_PlayerHealth[playerid] = health;
  1235. UpdateHealthBar(playerid, true);
  1236. }
  1237. return 1;
  1238. }
  1239. stock Float:WC_GetPlayerArmour(playerid, &Float:armour = 0.0)
  1240. {
  1241. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1242. armour = 0.0;
  1243. return 0.0;
  1244. }
  1245. armour = s_PlayerArmour[playerid];
  1246. return armour;
  1247. }
  1248. stock WC_SetPlayerArmour(playerid, Float:armour)
  1249. {
  1250. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1251. return 0;
  1252. }
  1253. if (armour > s_PlayerMaxArmour[playerid]) {
  1254. armour = s_PlayerMaxArmour[playerid];
  1255. }
  1256. s_PlayerArmour[playerid] = armour;
  1257. UpdateHealthBar(playerid, true);
  1258. return 1;
  1259. }
  1260. stock WC_GetPlayerTeam(playerid)
  1261. {
  1262. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1263. return NO_TEAM;
  1264. }
  1265. if (!IsPlayerConnected(playerid)) {
  1266. return NO_TEAM;
  1267. }
  1268. return s_PlayerTeam[playerid];
  1269. }
  1270. stock WC_SetPlayerTeam(playerid, team)
  1271. {
  1272. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1273. return 0;
  1274. }
  1275. s_PlayerTeam[playerid] = team;
  1276. return 1;
  1277. }
  1278. stock WC_SendDeathMessage(killer, killee, weapon)
  1279. {
  1280. if (weapon == WEAPON_CARPARK) {
  1281. weapon = WEAPON_VEHICLE;
  1282. } else if (weapon == WEAPON_PISTOLWHIP) {
  1283. weapon = WEAPON_UNARMED;
  1284. } else if (weapon == WEAPON_UNKNOWN) {
  1285. weapon = WEAPON_DROWN;
  1286. } else if (weapon == WEAPON_VEHICLE_M4) {
  1287. weapon = WEAPON_M4;
  1288. } if (weapon == WEAPON_VEHICLE_MINIGUN) {
  1289. weapon = WEAPON_MINIGUN;
  1290. }
  1291. SendDeathMessage(killer, killee, weapon);
  1292. return 1;
  1293. }
  1294. stock SetWeaponName(weaponid, const name[])
  1295. {
  1296. if (weaponid < 0 || weaponid >= sizeof(g_WeaponName)) {
  1297. return 0;
  1298. }
  1299. strunpack(g_WeaponName[weaponid], name, sizeof(g_WeaponName[]));
  1300. return 1;
  1301. }
  1302. stock WC_GetWeaponName(weaponid, weapon[], len = sizeof(weapon))
  1303. {
  1304. if (weaponid < 0 || weaponid >= sizeof(g_WeaponName)) {
  1305. format(weapon, len, "Weapon %d", weaponid);
  1306. } else {
  1307. strunpack(weapon, g_WeaponName[weaponid], len);
  1308. }
  1309. return 1;
  1310. }
  1311. stock WC_ApplyAnimation(playerid, animlib[], animname[], Float:fDelta, loop, lockx, locky, freeze, time, forcesync = 0)
  1312. {
  1313. if (playerid < 0 || playerid >= MAX_PLAYERS || s_IsDying[playerid]) {
  1314. return 0;
  1315. }
  1316. return ApplyAnimation(playerid, animlib, animname, fDelta, loop, lockx, locky, freeze, time, forcesync);
  1317. }
  1318. stock WC_ClearAnimations(playerid, forcesync = 1)
  1319. {
  1320. if (playerid < 0 || playerid >= MAX_PLAYERS || s_IsDying[playerid]) {
  1321. return 0;
  1322. }
  1323. s_LastStop[playerid] = GetTickCount();
  1324. return ClearAnimations(playerid, forcesync);
  1325. }
  1326. stock WC_AddPlayerClass(modelid, Float:spawn_x, Float:spawn_y, Float:spawn_z, Float:z_angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo)
  1327. {
  1328. new classid = AddPlayerClass(modelid, spawn_x, spawn_y, spawn_z, z_angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo);
  1329. s_ClassSpawnInfo[classid][e_Skin] = modelid;
  1330. s_ClassSpawnInfo[classid][e_Team] = 0x7FFFFFFF;
  1331. s_ClassSpawnInfo[classid][e_PosX] = spawn_x;
  1332. s_ClassSpawnInfo[classid][e_PosY] = spawn_y;
  1333. s_ClassSpawnInfo[classid][e_PosZ] = spawn_z;
  1334. s_ClassSpawnInfo[classid][e_Rot] = z_angle;
  1335. s_ClassSpawnInfo[classid][e_Weapon1] = weapon1;
  1336. s_ClassSpawnInfo[classid][e_Ammo1] = weapon1_ammo;
  1337. s_ClassSpawnInfo[classid][e_Weapon2] = weapon2;
  1338. s_ClassSpawnInfo[classid][e_Ammo2] = weapon2_ammo;
  1339. s_ClassSpawnInfo[classid][e_Weapon3] = weapon3;
  1340. s_ClassSpawnInfo[classid][e_Ammo3] = weapon3_ammo;
  1341. return classid;
  1342. }
  1343. stock WC_AddPlayerClassEx(teamid, modelid, Float:spawn_x, Float:spawn_y, Float:spawn_z, Float:z_angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo)
  1344. {
  1345. new classid = AddPlayerClassEx(teamid, modelid, spawn_x, spawn_y, spawn_z, z_angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo);
  1346. s_ClassSpawnInfo[classid][e_Skin] = modelid;
  1347. s_ClassSpawnInfo[classid][e_Team] = teamid;
  1348. s_ClassSpawnInfo[classid][e_PosX] = spawn_x;
  1349. s_ClassSpawnInfo[classid][e_PosY] = spawn_y;
  1350. s_ClassSpawnInfo[classid][e_PosZ] = spawn_z;
  1351. s_ClassSpawnInfo[classid][e_Rot] = z_angle;
  1352. s_ClassSpawnInfo[classid][e_Weapon1] = weapon1;
  1353. s_ClassSpawnInfo[classid][e_Ammo1] = weapon1_ammo;
  1354. s_ClassSpawnInfo[classid][e_Weapon2] = weapon2;
  1355. s_ClassSpawnInfo[classid][e_Ammo2] = weapon2_ammo;
  1356. s_ClassSpawnInfo[classid][e_Weapon3] = weapon3;
  1357. s_ClassSpawnInfo[classid][e_Ammo3] = weapon3_ammo;
  1358. return classid;
  1359. }
  1360. stock WC_SetSpawnInfo(playerid, team, skin, Float:x, Float:y, Float:z, Float:rotation, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo)
  1361. {
  1362. s_PlayerClass[playerid] = -1;
  1363. s_SpawnInfoModified[playerid] = false;
  1364. s_PlayerSpawnInfo[playerid][e_Skin] = skin;
  1365. s_PlayerSpawnInfo[playerid][e_Team] = team;
  1366. s_PlayerSpawnInfo[playerid][e_PosX] = x;
  1367. s_PlayerSpawnInfo[playerid][e_PosY] = y;
  1368. s_PlayerSpawnInfo[playerid][e_PosZ] = z;
  1369. s_PlayerSpawnInfo[playerid][e_Rot] = rotation;
  1370. s_PlayerSpawnInfo[playerid][e_Weapon1] = weapon1;
  1371. s_PlayerSpawnInfo[playerid][e_Ammo1] = weapon1_ammo;
  1372. s_PlayerSpawnInfo[playerid][e_Weapon2] = weapon2;
  1373. s_PlayerSpawnInfo[playerid][e_Ammo2] = weapon2_ammo;
  1374. s_PlayerSpawnInfo[playerid][e_Weapon3] = weapon3;
  1375. s_PlayerSpawnInfo[playerid][e_Ammo3] = weapon3_ammo;
  1376. return SetSpawnInfo(playerid, team, skin, x, y, z, rotation, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo);
  1377. }
  1378. stock WC_TogglePlayerSpectating(playerid, toggle)
  1379. {
  1380. if (toggle) {
  1381. if (s_DeathTimer[playerid] != -1) {
  1382. KillTimer(s_DeathTimer[playerid]);
  1383. s_DeathTimer[playerid] = -1;
  1384. }
  1385. #if WC_CUSTOM_VENDING_MACHINES
  1386. if (s_VendingUseTimer[playerid] != -1) {
  1387. KillTimer(s_VendingUseTimer[playerid]);
  1388. s_VendingUseTimer[playerid] = -1;
  1389. }
  1390. #endif
  1391. s_IsDying[playerid] = false;
  1392. }
  1393. return TogglePlayerSpectating(playerid, toggle);
  1394. }
  1395. stock WC_TogglePlayerControllable(playerid, toggle)
  1396. {
  1397. if (playerid < 0 || playerid >= MAX_PLAYERS || s_IsDying[playerid]) {
  1398. return 0;
  1399. }
  1400. s_LastStop[playerid] = GetTickCount();
  1401. return TogglePlayerControllable(playerid, toggle);
  1402. }
  1403. stock WC_SetPlayerPos(playerid, Float:x, Float:y, Float:z)
  1404. {
  1405. if (playerid < 0 || playerid >= MAX_PLAYERS || s_IsDying[playerid]) {
  1406. return 0;
  1407. }
  1408. s_LastStop[playerid] = GetTickCount();
  1409. return SetPlayerPos(playerid, x, y, z);
  1410. }
  1411. stock WC_SetPlayerPosFindZ(playerid, Float:x, Float:y, Float:z)
  1412. {
  1413. if (playerid < 0 || playerid >= MAX_PLAYERS || s_IsDying[playerid]) {
  1414. return 0;
  1415. }
  1416. s_LastStop[playerid] = GetTickCount();
  1417. return SetPlayerPosFindZ(playerid, x, y, z);
  1418. }
  1419. stock WC_SetPlayerVelocity(playerid, Float:X, Float:Y, Float:Z)
  1420. {
  1421. if (playerid < 0 || playerid >= MAX_PLAYERS || s_IsDying[playerid]) {
  1422. return 0;
  1423. }
  1424. if (X == 0.0 && Y == 0.0 && Z == 0.0) {
  1425. s_LastStop[playerid] = GetTickCount();
  1426. }
  1427. return SetPlayerVelocity(playerid, X, Y, Z);
  1428. }
  1429. stock wc_SetPlayerVirtualWorld(playerid, worldid)
  1430. {
  1431. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1432. return 0;
  1433. }
  1434. s_World[playerid] = worldid;
  1435. if (s_IsDying[playerid]) {
  1436. return 1;
  1437. }
  1438. return SetPlayerVirtualWorld(playerid, worldid);
  1439. }
  1440. stock WC_GetPlayerVirtualWorld(playerid)
  1441. {
  1442. if (playerid < 0 || playerid >= MAX_PLAYERS) {
  1443. return 0;
  1444. }
  1445. new worldid = GetPlayerVirtualWorld(playerid);
  1446. if (worldid == WC_DEATH_WORLD) {
  1447. return s_World[playerid];
  1448. }
  1449. return worldid;
  1450. }
  1451. stock WC_PlayerSpectatePlayer(playerid, targetplayerid, mode = SPECTATE_MODE_NORMAL)
  1452. {
  1453. if (playerid < 0 || playerid >= MAX_PLAYERS || targetplayerid < 0 || targetplayerid >= MAX_PLAYERS) {
  1454. return 0;
  1455. }
  1456. s_Spectating[playerid] = targetplayerid;
  1457. return PlayerSpectatePlayer(playerid, targetplayerid, mode);
  1458. }
  1459. stock WC_DestroyVehicle(vehicleid)
  1460. {
  1461. if (0 < vehicleid < MAX_VEHICLES) {
  1462. s_LastVehicleShooter[vehicleid] = INVALID_PLAYER_ID;
  1463. s_VehicleAlive[vehicleid] = false;
  1464. if (s_VehicleRespawnTimer[vehicleid] != -1) {
  1465. KillTimer(s_VehicleRespawnTimer[vehicleid]);
  1466. s_VehicleRespawnTimer[vehicleid] = -1;
  1467. }
  1468. }
  1469. return DestroyVehicle(vehicleid);
  1470. }
  1471. stock WC_CreateVehicle(modelid, Float:x, Float:y, Float:z, Float:angle, color1, color2, respawn_delay, addsiren = 0)
  1472. {
  1473. new id = CreateVehicle(modelid, x, y, z, angle, color1, color2, respawn_delay, addsiren);
  1474. if (id != INVALID_VEHICLE_ID) {
  1475. s_VehicleAlive[id] = true;
  1476. return id;
  1477. }
  1478. return INVALID_VEHICLE_ID;
  1479. }
  1480. stock WC_AddStaticVehicle(modelid, Float:x, Float:y, Float:z, Float:angle, color1, color2)
  1481. {
  1482. new id = AddStaticVehicle(modelid, x, y, z, angle, color1, color2);
  1483. if (id != INVALID_VEHICLE_ID) {
  1484. s_VehicleAlive[id] = true;
  1485. return id;
  1486. }
  1487. return INVALID_VEHICLE_ID;
  1488. }
  1489. stock WC_AddStaticVehicleEx(modelid, Float:x, Float:y, Float:z, Float:angle, color1, color2, respawn_delay, addsiren = 0)
  1490. {
  1491. new id = AddStaticVehicleEx(modelid, x, y, z, angle, color1, color2, respawn_delay, addsiren);
  1492. if (id != INVALID_VEHICLE_ID) {
  1493. s_VehicleAlive[id] = true;
  1494. return id;
  1495. }
  1496. return INVALID_VEHICLE_ID;
  1497. }
  1498. stock WC_IsPlayerInCheckpoint(playerid)
  1499. {
  1500. if (!IsPlayerSpawned(playerid)) {
  1501. return 0;
  1502. }
  1503. return IsPlayerInCheckpoint(playerid);
  1504. }
  1505. stock WC_SetPlayerSpecialAction(playerid, actionid)
  1506. {
  1507. if (!IsPlayerSpawned(playerid)) {
  1508. return 0;
  1509. }
  1510. return SetPlayerSpecialAction(playerid, actionid);
  1511. }
  1512. stock Text:WC_TextDrawCreate(Float:x, Float:y, text[])
  1513. {
  1514. new Text:td = TextDrawCreate(x, y, text);
  1515. if (td != Text:INVALID_TEXT_DRAW) {
  1516. s_InternalTextDraw[td] = false;
  1517. }
  1518. return td;
  1519. }
  1520. stock WC_TextDrawDestroy(Text:text)
  1521. {
  1522. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1523. return TextDrawDestroy(text);
  1524. }
  1525. stock WC_TextDrawLetterSize(Text:text, Float:x, Float:y)
  1526. {
  1527. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1528. return TextDrawLetterSize(text, x, y);
  1529. }
  1530. stock WC_TextDrawTextSize(Text:text, Float:x, Float:y)
  1531. {
  1532. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1533. return TextDrawTextSize(text, x, y);
  1534. }
  1535. stock WC_TextDrawAlignment(Text:text, alignment)
  1536. {
  1537. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1538. return TextDrawAlignment(text, alignment);
  1539. }
  1540. stock WC_TextDrawColor(Text:text, color)
  1541. {
  1542. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1543. return TextDrawColor(text, color);
  1544. }
  1545. stock WC_TextDrawUseBox(Text:text, use)
  1546. {
  1547. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1548. return TextDrawUseBox(text, use);
  1549. }
  1550. stock WC_TextDrawBoxColor(Text:text, color)
  1551. {
  1552. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1553. return TextDrawBoxColor(text, color);
  1554. }
  1555. stock WC_TextDrawSetShadow(Text:text, size)
  1556. {
  1557. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1558. return TextDrawSetShadow(text, size);
  1559. }
  1560. stock WC_TextDrawSetOutline(Text:text, size)
  1561. {
  1562. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1563. return TextDrawSetOutline(text, size);
  1564. }
  1565. stock WC_TextDrawBackgroundColor(Text:text, color)
  1566. {
  1567. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1568. return TextDrawBackgroundColor(text, color);
  1569. }
  1570. stock WC_TextDrawFont(Text:text, font)
  1571. {
  1572. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1573. return TextDrawFont(text, font);
  1574. }
  1575. stock WC_TextDrawSetProportional(Text:text, set)
  1576. {
  1577. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1578. return TextDrawSetProportional(text, set);
  1579. }
  1580. stock WC_TextDrawSetSelectable(Text:text, set)
  1581. {
  1582. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1583. return TextDrawSetSelectable(text, set);
  1584. }
  1585. stock WC_TextDrawShowForPlayer(playerid, Text:text)
  1586. {
  1587. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1588. return TextDrawShowForPlayer(playerid, text);
  1589. }
  1590. stock WC_TextDrawHideForPlayer(playerid, Text:text)
  1591. {
  1592. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1593. return TextDrawHideForPlayer(playerid, text);
  1594. }
  1595. stock WC_TextDrawShowForAll(Text:text)
  1596. {
  1597. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1598. return TextDrawShowForAll(text);
  1599. }
  1600. stock WC_TextDrawHideForAll(Text:text)
  1601. {
  1602. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1603. return TextDrawHideForAll(text);
  1604. }
  1605. stock WC_TextDrawSetString(Text:text, string[])
  1606. {
  1607. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1608. return TextDrawSetString(text, string);
  1609. }
  1610. stock WC_TextDrawSetPreviewModel(Text:text, modelindex)
  1611. {
  1612. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1613. return TextDrawSetPreviewModel(text, modelindex);
  1614. }
  1615. stock WC_TextDrawSetPreviewRot(Text:text, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fZoom = 1.0)
  1616. {
  1617. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1618. return TextDrawSetPreviewRot(text, fRotX, fRotY, fRotZ, fZoom);
  1619. }
  1620. stock WC_TextDrawSetPreviewVehCol(Text:text, color1, color2)
  1621. {
  1622. if (_:text < 0 || _:text >= MAX_TEXT_DRAWS || s_InternalTextDraw[text]) return 0;
  1623. return TextDrawSetPreviewVehCol(text, color1, color2);
  1624. }
  1625. stock PlayerText:WC_CreatePlayerTextDraw(playerid, Float:x, Float:y, text[])
  1626. {
  1627. if (playerid < 0 || playerid >= MAX_PLAYERS) return PlayerText:INVALID_TEXT_DRAW;
  1628. new PlayerText:td = CreatePlayerTextDraw(playerid, x, y, text);
  1629. if (td != PlayerText:INVALID_TEXT_DRAW) {
  1630. s_InternalPlayerTextDraw[playerid][td] = false;
  1631. }
  1632. return td;
  1633. }
  1634. stock WC_PlayerTextDrawDestroy(playerid, PlayerText:text)
  1635. {
  1636. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1637. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1638. return PlayerTextDrawDestroy(playerid, text);
  1639. }
  1640. stock WC_PlayerTextDrawLetterSize(playerid, PlayerText:text, Float:x, Float:y)
  1641. {
  1642. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1643. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1644. return PlayerTextDrawLetterSize(playerid, text, x, y);
  1645. }
  1646. stock WC_PlayerTextDrawTextSize(playerid, PlayerText:text, Float:x, Float:y)
  1647. {
  1648. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1649. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1650. return PlayerTextDrawTextSize(playerid, text, x, y);
  1651. }
  1652. stock WC_PlayerTextDrawAlignment(playerid, PlayerText:text, alignment)
  1653. {
  1654. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1655. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1656. return PlayerTextDrawAlignment(playerid, text, alignment);
  1657. }
  1658. stock WC_PlayerTextDrawColor(playerid, PlayerText:text, color)
  1659. {
  1660. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1661. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1662. return PlayerTextDrawColor(playerid, text, color);
  1663. }
  1664. stock WC_PlayerTextDrawUseBox(playerid, PlayerText:text, use)
  1665. {
  1666. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1667. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1668. return PlayerTextDrawUseBox(playerid, text, use);
  1669. }
  1670. stock WC_PlayerTextDrawBoxColor(playerid, PlayerText:text, color)
  1671. {
  1672. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1673. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1674. return PlayerTextDrawBoxColor(playerid, text, color);
  1675. }
  1676. stock WC_PlayerTextDrawSetShadow(playerid, PlayerText:text, size)
  1677. {
  1678. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1679. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1680. return PlayerTextDrawSetShadow(playerid, text, size);
  1681. }
  1682. stock WC_PlayerTextDrawSetOutline(playerid, PlayerText:text, size)
  1683. {
  1684. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1685. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1686. return PlayerTextDrawSetOutline(playerid, text, size);
  1687. }
  1688. stock WC_PlayerTextDrawBackgroundColo(playerid, PlayerText:text, color)
  1689. {
  1690. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1691. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1692. return PlayerTextDrawBackgroundColor(playerid, text, color);
  1693. }
  1694. stock WC_PlayerTextDrawFont(playerid, PlayerText:text, font)
  1695. {
  1696. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1697. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1698. return PlayerTextDrawFont(playerid, text, font);
  1699. }
  1700. stock WC_PlayerTextDrawSetProportiona(playerid, PlayerText:text, set)
  1701. {
  1702. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1703. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1704. return PlayerTextDrawSetProportional(playerid, text, set);
  1705. }
  1706. stock WC_PlayerTextDrawSetSelectable(playerid, PlayerText:text, set)
  1707. {
  1708. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1709. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1710. return PlayerTextDrawSetSelectable(playerid, text, set);
  1711. }
  1712. stock WC_PlayerTextDrawShow(playerid, PlayerText:text)
  1713. {
  1714. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1715. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1716. return PlayerTextDrawShow(playerid, text);
  1717. }
  1718. stock WC_PlayerTextDrawHide(playerid, PlayerText:text)
  1719. {
  1720. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1721. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1722. return PlayerTextDrawHide(playerid, text);
  1723. }
  1724. stock WC_PlayerTextDrawSetString(playerid, PlayerText:text, string[])
  1725. {
  1726. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1727. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1728. return PlayerTextDrawSetString(playerid, text, string);
  1729. }
  1730. stock WC_PlayerTextDrawSetPreviewMode(playerid, PlayerText:text, modelindex)
  1731. {
  1732. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1733. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1734. return PlayerTextDrawSetPreviewModel(playerid, text, modelindex);
  1735. }
  1736. stock WC_PlayerTextDrawSetPreviewRot(playerid, PlayerText:text, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fZoom = 1.0)
  1737. {
  1738. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1739. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1740. return PlayerTextDrawSetPreviewRot(playerid, text, fRotX, fRotY, fRotZ, fZoom);
  1741. }
  1742. stock WC_PlayerTextDrawSetPreviewVehC(playerid, PlayerText:text, color1, color2)
  1743. {
  1744. if (playerid < 0 || playerid >= MAX_PLAYERS) return 0;
  1745. if (_:text < 0 || _:text >= MAX_PLAYER_TEXT_DRAWS || s_InternalPlayerTextDraw[playerid][text]) return 0;
  1746. return PlayerTextDrawSetPreviewVehCol(playerid, text, color1, color2);
  1747. }
  1748. /*
  1749. * Hooked callbacks
  1750. */
  1751. public OnGameModeInit()
  1752. {
  1753. ScriptInit();
  1754. #if defined WC_OnGameModeInit
  1755. return WC_OnGameModeInit();
  1756. #else
  1757. return 1;
  1758. #endif
  1759. }
  1760. public OnGameModeExit()
  1761. {
  1762. ScriptExit();
  1763. #if defined WC_OnGameModeExit
  1764. return WC_OnGameModeExit();
  1765. #else
  1766. return 1;
  1767. #endif
  1768. }
  1769. public OnFilterScriptInit()
  1770. {
  1771. ScriptInit();
  1772. #if defined WC_OnFilterScriptInit
  1773. return WC_OnFilterScriptInit();
  1774. #else
  1775. return 1;
  1776. #endif
  1777. }
  1778. public OnFilterScriptExit()
  1779. {
  1780. ScriptExit();
  1781. #if defined WC_OnFilterScriptExit
  1782. return WC_OnFilterScriptExit();
  1783. #else
  1784. return 1;
  1785. #endif
  1786. }
  1787. public OnPlayerConnect(playerid)
  1788. {
  1789. new tick = GetTickCount();
  1790. s_PlayerMaxHealth[playerid] = 100.0;
  1791. s_PlayerHealth[playerid] = 100.0;
  1792. s_PlayerMaxArmour[playerid] = 100.0;
  1793. s_PlayerArmour[playerid] = 0.0;
  1794. s_LastExplosive[playerid] = 0;
  1795. s_LastShotIdx[playerid] = 0;
  1796. s_LastShot[playerid][e_Tick] = 0;
  1797. s_LastHitIdx[playerid] = 0;
  1798. s_RejectedHitsIdx[playerid] = 0;
  1799. s_ShotsFired[playerid] = 0;
  1800. s_HitsIssued[playerid] = 0;
  1801. s_PlayerTeam[playerid] = NO_TEAM;
  1802. s_IsDying[playerid] = false;
  1803. s_BeingResynced[playerid] = false;
  1804. s_SpawnForStreamedIn[playerid] = false;
  1805. s_World[playerid] = 0;
  1806. s_LastAnim[playerid] = -1;
  1807. s_LastZVelo[playerid] = 0.0;
  1808. s_LastZ[playerid] = 0.0;
  1809. s_LastUpdate[playerid] = tick;
  1810. s_DamageFeedTimer[playerid] = -1;
  1811. s_DamageFeedLastUpdate[playerid] = tick;
  1812. s_Spectating[playerid] = INVALID_PLAYER_ID;
  1813. s_HealthBarVisible[playerid] = false;
  1814. s_LastSentHealth[playerid] = 0;
  1815. s_LastSentArmour[playerid] = 0;
  1816. s_LastStop[playerid] = tick;
  1817. s_FirstSpawn[playerid] = true;
  1818. s_LastVehicleEnterTime[playerid] = 0;
  1819. s_TrueDeath[playerid] = true;
  1820. s_InClassSelection[playerid] = false;
  1821. s_ForceClassSelection[playerid] = false;
  1822. s_PlayerClass[playerid] = -2;
  1823. s_SpawnInfoModified[playerid] = false;
  1824. s_PlayerFallbackSpawnInfo[playerid][e_Skin] = -1;
  1825. s_DeathSkip[playerid] = 0;
  1826. s_LastVehicleTick[playerid] = 0;
  1827. s_PreviousHitI[playerid] = 0;
  1828. s_CbugFroze[playerid] = 0;
  1829. s_DeathTimer[playerid] = -1;
  1830. s_DelayedDeathTimer[playerid] = -1;
  1831. s_DamageFeedPlayer[playerid] = -1;
  1832. for (new i = 0; i < sizeof(s_PreviousHits[]); i++) {
  1833. s_PreviousHits[playerid][i][e_Tick] = 0;
  1834. }
  1835. for (new i = 0; i < sizeof(s_RejectedHits[]); i++) {
  1836. s_RejectedHits[playerid][i][e_Time] = 0;
  1837. }
  1838. for (new i = 0; i < sizeof(s_DamageFeedHitsGiven[]); i++) {
  1839. s_DamageFeedHitsGiven[playerid][i][e_Tick] = 0;
  1840. s_DamageFeedHitsTaken[playerid][i][e_Tick] = 0;
  1841. }
  1842. SetPlayerTeam(playerid, 0xFE);
  1843. FreezeSyncData(playerid, false);
  1844. SetFakeFacingAngle(playerid, _);
  1845. DamageFeedUpdate(playerid);
  1846. #if WC_CUSTOM_VENDING_MACHINES
  1847. if (!s_AlreadyConnected[playerid]) {
  1848. RemoveDefaultVendingMachines(playerid);
  1849. }
  1850. #endif
  1851. s_AlreadyConnected[playerid] = false;
  1852. #if defined WC_OnPlayerConnect
  1853. return WC_OnPlayerConnect(playerid);
  1854. #else
  1855. return 1;
  1856. #endif
  1857. }
  1858. public OnPlayerDisconnect(playerid, reason)
  1859. {
  1860. #if defined WC_OnPlayerDisconnect
  1861. WC_OnPlayerDisconnect(playerid, reason);
  1862. #endif
  1863. #if WC_CUSTOM_VENDING_MACHINES
  1864. if (s_VendingUseTimer[playerid] != -1) {
  1865. KillTimer(s_VendingUseTimer[playerid]);
  1866. s_VendingUseTimer[playerid] = -1;
  1867. }
  1868. #endif
  1869. if (s_DelayedDeathTimer[playerid] != -1) {
  1870. KillTimer(s_DelayedDeathTimer[playerid]);
  1871. s_DelayedDeathTimer[playerid] = -1;
  1872. }
  1873. if (s_DeathTimer[playerid] != -1) {
  1874. KillTimer(s_DeathTimer[playerid]);
  1875. s_DeathTimer[playerid] = -1;
  1876. }
  1877. if (s_KnifeTimeout[playerid] != -1) {
  1878. KillTimer(s_KnifeTimeout[playerid]);
  1879. s_KnifeTimeout[playerid] = -1;
  1880. }
  1881. if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  1882. PlayerTextDrawDestroy(playerid, s_HealthBarForeground[playerid]);
  1883. s_InternalPlayerTextDraw[playerid][s_HealthBarForeground[playerid]] = false;
  1884. s_HealthBarForeground[playerid] = PlayerText:INVALID_TEXT_DRAW;
  1885. }
  1886. if (s_DamageFeedGiven[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  1887. PlayerTextDrawDestroy(playerid, s_DamageFeedGiven[playerid]);
  1888. s_InternalPlayerTextDraw[playerid][s_DamageFeedGiven[playerid]] = false;
  1889. s_DamageFeedGiven[playerid] = PlayerText:INVALID_TEXT_DRAW;
  1890. }
  1891. if (s_DamageFeedTaken[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  1892. PlayerTextDrawDestroy(playerid, s_DamageFeedTaken[playerid]);
  1893. s_InternalPlayerTextDraw[playerid][s_DamageFeedTaken[playerid]] = false;
  1894. s_DamageFeedTaken[playerid] = PlayerText:INVALID_TEXT_DRAW;
  1895. }
  1896. if (s_DamageFeedTimer[playerid] != -1) {
  1897. KillTimer(s_DamageFeedTimer[playerid]);
  1898. s_DamageFeedTimer[playerid] = -1;
  1899. }
  1900. SetHealthBarVisible(playerid, false);
  1901. s_Spectating[playerid] = INVALID_PLAYER_ID;
  1902. for (new i = 0; i < sizeof(s_LastVehicleShooter); i++) {
  1903. if (s_LastVehicleShooter[i] == playerid) {
  1904. s_LastVehicleShooter[i] = INVALID_PLAYER_ID;
  1905. }
  1906. }
  1907. for (new i = 0; i < sizeof(s_InternalPlayerTextDraw[]); i++) {
  1908. s_InternalPlayerTextDraw[playerid][PlayerText:i] = false;
  1909. }
  1910. for (new i = 0; i < MAX_PLAYERS; i++) {
  1911. if (!IsPlayerConnected(i)) {
  1912. continue;
  1913. }
  1914. for (new j = 0; j < sizeof(s_PreviousHits[]); j++) {
  1915. if (s_PreviousHits[i][j][e_Issuer] == playerid) {
  1916. s_PreviousHits[i][j][e_Issuer] = INVALID_PLAYER_ID;
  1917. }
  1918. }
  1919. }
  1920. return 1;
  1921. }
  1922. public OnPlayerSpawn(playerid)
  1923. {
  1924. s_TrueDeath[playerid] = false;
  1925. s_InClassSelection[playerid] = false;
  1926. if (s_ForceClassSelection[playerid]) {
  1927. DebugMessage(playerid, "Being forced into class selection");
  1928. ForceClassSelection(playerid);
  1929. SetPlayerHealth(playerid, 0.0);
  1930. SetPlayerVirtualWorld(playerid, WC_DEATH_WORLD);
  1931. return 1;
  1932. }
  1933. s_LastUpdate[playerid] = GetTickCount();
  1934. s_LastStop[playerid] = GetTickCount();
  1935. if (s_BeingResynced[playerid]) {
  1936. s_BeingResynced[playerid] = false;
  1937. UpdateHealthBar(playerid);
  1938. SetPlayerPos(playerid, s_SyncData[playerid][e_PosX], s_SyncData[playerid][e_PosY], s_SyncData[playerid][e_PosZ]);
  1939. SetPlayerFacingAngle(playerid, s_SyncData[playerid][e_PosA]);
  1940. SetPlayerSkin(playerid, s_SyncData[playerid][e_Skin]);
  1941. SetPlayerTeam(playerid, s_SyncData[playerid][e_Team]);
  1942. for (new i = 0; i < 13; i++) {
  1943. if (s_SyncData[playerid][e_WeaponId][i]) {
  1944. GivePlayerWeapon(playerid, s_SyncData[playerid][e_WeaponId][i], s_SyncData[playerid][e_WeaponAmmo][i]);
  1945. }
  1946. }
  1947. GivePlayerWeapon(playerid, s_SyncData[playerid][e_Weapon], 0);
  1948. return 1;
  1949. }
  1950. if (s_SpawnInfoModified[playerid]) {
  1951. new spawn_info[E_SPAWN_INFO], classid = s_PlayerClass[playerid];
  1952. s_SpawnInfoModified[playerid] = false;
  1953. if (classid == -1) {
  1954. spawn_info = s_PlayerSpawnInfo[playerid];
  1955. } else if (classid == -2) {
  1956. spawn_info = s_PlayerFallbackSpawnInfo[playerid];
  1957. } else {
  1958. if (s_ClassSpawnInfo[classid][e_Skin] == -1 && s_PlayerFallbackSpawnInfo[playerid][e_Skin] != -1) {
  1959. spawn_info = s_PlayerFallbackSpawnInfo[playerid];
  1960. } else {
  1961. spawn_info = s_ClassSpawnInfo[classid];
  1962. }
  1963. }
  1964. if (spawn_info[e_Skin] != -1) {
  1965. SetSpawnInfo(
  1966. playerid,
  1967. spawn_info[e_Team],
  1968. spawn_info[e_Skin],
  1969. spawn_info[e_PosX],
  1970. spawn_info[e_PosY],
  1971. spawn_info[e_PosZ],
  1972. spawn_info[e_Rot],
  1973. spawn_info[e_Weapon1],
  1974. spawn_info[e_Ammo1],
  1975. spawn_info[e_Weapon2],
  1976. spawn_info[e_Ammo2],
  1977. spawn_info[e_Weapon3],
  1978. spawn_info[e_Ammo3]
  1979. );
  1980. }
  1981. } else {
  1982. s_PlayerFallbackSpawnInfo[playerid][e_Team] = s_PlayerTeam[playerid];
  1983. s_PlayerFallbackSpawnInfo[playerid][e_Skin] = GetPlayerSkin(playerid);
  1984. GetPlayerPos(
  1985. playerid,
  1986. s_PlayerFallbackSpawnInfo[playerid][e_PosX],
  1987. s_PlayerFallbackSpawnInfo[playerid][e_PosY],
  1988. s_PlayerFallbackSpawnInfo[playerid][e_PosZ]
  1989. );
  1990. GetPlayerFacingAngle(playerid, s_PlayerFallbackSpawnInfo[playerid][e_Rot]);
  1991. }
  1992. if (s_DeathTimer[playerid] != -1) {
  1993. KillTimer(s_DeathTimer[playerid]);
  1994. s_DeathTimer[playerid] = -1;
  1995. }
  1996. if (s_IsDying[playerid]) {
  1997. s_IsDying[playerid] = false;
  1998. }
  1999. if (s_PlayerHealth[playerid] == 0.0) {
  2000. s_PlayerHealth[playerid] = s_PlayerMaxHealth[playerid];
  2001. }
  2002. UpdatePlayerVirtualWorld(playerid);
  2003. UpdateHealthBar(playerid, true);
  2004. FreezeSyncData(playerid, false);
  2005. SetFakeFacingAngle(playerid, _);
  2006. DamageFeedUpdate(playerid);
  2007. if (GetPlayerTeam(playerid) != 0xFE) {
  2008. SetPlayerTeam(playerid, 0xFE);
  2009. }
  2010. if (s_DeathSkip[playerid] == 2) {
  2011. DebugMessage(playerid, "Death skipped");
  2012. SetPlayerSpecialAction(playerid, SPECIAL_ACTION_NONE);
  2013. GivePlayerWeapon(playerid, 0, 1);
  2014. SetPlayerArmedWeapon(playerid, 0);
  2015. ClearAnimations(playerid);
  2016. ApplyAnimation(playerid, "PED", "IDLE_stance", 4.1, 1, 0, 0, 0, 1, 1);
  2017. s_DeathSkip[playerid] = 1;
  2018. s_DeathSkipTick[playerid] = GetTickCount();
  2019. return 1;
  2020. }
  2021. if (s_FirstSpawn[playerid]) {
  2022. s_FirstSpawn[playerid] = false;
  2023. #if WC_CUSTOM_VENDING_MACHINES
  2024. if (s_CustomVendingMachines) {
  2025. ApplyAnimation(playerid, "VENDING", "null", 0, 0, 0, 0, 0, 0);
  2026. }
  2027. #endif
  2028. }
  2029. #if defined WC_OnPlayerSpawn
  2030. return WC_OnPlayerSpawn(playerid);
  2031. #else
  2032. return 1;
  2033. #endif
  2034. }
  2035. public OnPlayerRequestClass(playerid, classid)
  2036. {
  2037. DebugMessage(playerid, "Requested class: %d", classid);
  2038. if (s_DeathSkip[playerid]) {
  2039. DebugMessage(playerid, "Skipping death - class selection skipped");
  2040. SpawnPlayer(playerid);
  2041. return 0;
  2042. }
  2043. if (s_ForceClassSelection[playerid]) {
  2044. s_ForceClassSelection[playerid] = false;
  2045. }
  2046. if (s_BeingResynced[playerid]) {
  2047. s_TrueDeath[playerid] = false;
  2048. SpawnPlayerInPlace(playerid);
  2049. return 0;
  2050. }
  2051. if (s_DeathTimer[playerid] != -1) {
  2052. KillTimer(s_DeathTimer[playerid]);
  2053. s_DeathTimer[playerid] = -1;
  2054. }
  2055. if (s_IsDying[playerid]) {
  2056. OnPlayerDeathFinished(playerid, false);
  2057. s_IsDying[playerid] = false;
  2058. }
  2059. FreezeSyncData(playerid, false);
  2060. UpdatePlayerVirtualWorld(playerid);
  2061. if (s_TrueDeath[playerid]) {
  2062. if (!s_InClassSelection[playerid]) {
  2063. DebugMessage(playerid, "True death class selection");
  2064. new Float:x, Float:y, Float:z;
  2065. GetPlayerPos(playerid, x, y, z);
  2066. RemoveBuildingForPlayer(playerid, 1484, x, y, z, 350.0),
  2067. RemoveBuildingForPlayer(playerid, 1485, x, y, z, 350.0),
  2068. RemoveBuildingForPlayer(playerid, 1486, x, y, z, 350.0);
  2069. s_InClassSelection[playerid] = true;
  2070. }
  2071. #if defined WC_OnPlayerRequestClass
  2072. if (WC_OnPlayerRequestClass(playerid, classid)) {
  2073. s_PlayerClass[playerid] = classid;
  2074. return 1;
  2075. } else {
  2076. return 0;
  2077. }
  2078. #else
  2079. s_PlayerClass[playerid] = classid;
  2080. return 1;
  2081. #endif
  2082. } else {
  2083. DebugMessage(playerid, "Not true death - being respawned");
  2084. s_ForceClassSelection[playerid] = true;
  2085. SpawnPlayerInPlace(playerid);
  2086. return 0;
  2087. }
  2088. }
  2089. public OnPlayerDeath(playerid, killerid, reason)
  2090. {
  2091. s_TrueDeath[playerid] = true;
  2092. s_InClassSelection[playerid] = false;
  2093. #if WC_CUSTOM_VENDING_MACHINES
  2094. if (s_VendingUseTimer[playerid] != -1) {
  2095. KillTimer(s_VendingUseTimer[playerid]);
  2096. s_VendingUseTimer[playerid] = -1;
  2097. }
  2098. #endif
  2099. if (s_BeingResynced[playerid] || s_ForceClassSelection[playerid]) {
  2100. return 1;
  2101. }
  2102. // Probably fake death
  2103. if (killerid != INVALID_PLAYER_ID && !IsPlayerStreamedIn(killerid, playerid)) {
  2104. killerid = INVALID_PLAYER_ID;
  2105. }
  2106. DebugMessageRedAll("OnPlayerDeath(%d died by %d from %d)", playerid, reason, killerid);
  2107. if (s_DeathTimer[playerid] != -1) {
  2108. KillTimer(s_DeathTimer[playerid]);
  2109. }
  2110. if (s_IsDying[playerid]) {
  2111. DebugMessageRedAll("death while dying %d", playerid);
  2112. return 1;
  2113. }
  2114. // WEAPON_UNKNOWN
  2115. if (reason < 0 || reason > 55) {
  2116. reason = 55;
  2117. }
  2118. new vehicleid = GetPlayerVehicleID(playerid);
  2119. // Let's assume they died from an exploading vehicle
  2120. if (vehicleid) {
  2121. reason = WEAPON_EXPLOSION;
  2122. killerid = INVALID_PLAYER_ID;
  2123. if (!HasSameTeam(playerid, s_LastVehicleShooter[vehicleid])) {
  2124. killerid = s_LastVehicleShooter[vehicleid];
  2125. }
  2126. }
  2127. new Float:amount = 0.0;
  2128. new bodypart = BODY_PART_UNKNOWN;
  2129. if (reason == WEAPON_PARACHUTE) {
  2130. reason = WEAPON_COLLISION;
  2131. }
  2132. if (OnPlayerDamage(playerid, amount, killerid, reason, bodypart)) {
  2133. if (reason < 0 || reason > WEAPON_UNKNOWN) {
  2134. reason = WEAPON_UNKNOWN;
  2135. }
  2136. if (amount == 0.0) {
  2137. amount = s_PlayerHealth[playerid] + s_PlayerArmour[playerid];
  2138. }
  2139. if (reason == WEAPON_COLLISION || reason == WEAPON_DROWN || reason == WEAPON_CARPARK) {
  2140. if (amount <= 0.0) {
  2141. amount = s_PlayerHealth[playerid];
  2142. }
  2143. s_PlayerHealth[playerid] -= amount;
  2144. } else {
  2145. if (amount <= 0.0) {
  2146. amount = s_PlayerHealth[playerid] + s_PlayerArmour[playerid];
  2147. }
  2148. s_PlayerArmour[playerid] -= amount;
  2149. }
  2150. if (s_PlayerArmour[playerid] < 0.0) {
  2151. s_DamageDoneArmour[playerid] = amount + s_PlayerArmour[playerid];
  2152. s_DamageDoneHealth[playerid] = -s_PlayerArmour[playerid];
  2153. s_PlayerHealth[playerid] += s_PlayerArmour[playerid];
  2154. s_PlayerArmour[playerid] = 0.0;
  2155. } else {
  2156. s_DamageDoneArmour[playerid] = amount;
  2157. s_DamageDoneHealth[playerid] = 0.0;
  2158. }
  2159. if (s_PlayerHealth[playerid] <= 0.0) {
  2160. amount += s_PlayerHealth[playerid];
  2161. s_DamageDoneHealth[playerid] += s_PlayerHealth[playerid];
  2162. s_PlayerHealth[playerid] = 0.0;
  2163. }
  2164. OnPlayerDamageDone(playerid, amount, killerid, reason, bodypart);
  2165. }
  2166. if (s_PlayerHealth[playerid] <= 0.0005) {
  2167. s_PlayerHealth[playerid] = 0.0;
  2168. s_IsDying[playerid] = true;
  2169. new animlib[32], animname[32], anim_lock, respawn_time;
  2170. OnPlayerPrepareDeath(playerid, animlib, animname, anim_lock, respawn_time);
  2171. #if defined WC_OnPlayerDeath
  2172. WC_OnPlayerDeath(playerid, killerid, reason);
  2173. #endif
  2174. OnPlayerDeathFinished(playerid, false);
  2175. } else {
  2176. if (vehicleid || WasPlayerInVehicle(playerid, 10000)) {
  2177. new Float:x, Float:y, Float:z, Float:r;
  2178. GetPlayerPos(playerid, x, y, z);
  2179. SetPlayerPos(playerid, x, y, z);
  2180. SaveSyncData(playerid);
  2181. if (vehicleid) {
  2182. GetVehicleZAngle(vehicleid, r);
  2183. } else {
  2184. GetPlayerFacingAngle(playerid, r);
  2185. }
  2186. s_DeathSkip[playerid] = 2;
  2187. ForceClassSelection(playerid);
  2188. SetSpawnInfo(playerid, 0xFE, GetPlayerSkin(playerid), x, y, z, r, 0, 0, 0, 0, 0, 0);
  2189. TogglePlayerSpectating(playerid, true);
  2190. TogglePlayerSpectating(playerid, false);
  2191. SetSpawnInfo(playerid, 0xFE, GetPlayerSkin(playerid), x, y, z, r, 0, 0, 0, 0, 0, 0);
  2192. TogglePlayerControllable(playerid, true);
  2193. GivePlayerWeapon(playerid, 1, 1);
  2194. } else {
  2195. SpawnPlayerInPlace(playerid);
  2196. }
  2197. }
  2198. UpdateHealthBar(playerid);
  2199. return 1;
  2200. }
  2201. static Float:AngleBetweenPoints(Float:x1, Float:y1, Float:x2, Float:y2);
  2202. forward WC_CbugPunishment(playerid, weapon);
  2203. public WC_CbugPunishment(playerid, weapon) {
  2204. FreezeSyncData(playerid, false);
  2205. ClearAnimations(playerid, 1);
  2206. GivePlayerWeapon(playerid, weapon, 0);
  2207. }
  2208. public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
  2209. {
  2210. if (!s_CbugAllowed && !IsPlayerDying(playerid) && GetPlayerState(playerid) == PLAYER_STATE_ONFOOT) {
  2211. if (newkeys & KEY_CROUCH) {
  2212. new tick = GetTickCount();
  2213. new diff = tick - s_LastShot[playerid][e_Tick];
  2214. if (s_LastShot[playerid][e_Tick] && diff < 1200 && !s_CbugFroze[playerid]) {
  2215. PlayerPlaySound(playerid, 1055, 0.0, 0.0, 0.0);
  2216. if (s_LastShot[playerid][e_Valid] && floatabs(s_LastShot[playerid][e_HX]) > 1.0 && floatabs(s_LastShot[playerid][e_HY]) > 1.0) {
  2217. SetPlayerFacingAngle(playerid, AngleBetweenPoints(
  2218. s_LastShot[playerid][e_HX],
  2219. s_LastShot[playerid][e_HY],
  2220. s_LastShot[playerid][e_OX],
  2221. s_LastShot[playerid][e_OY]
  2222. ));
  2223. }
  2224. new w, a;
  2225. GetPlayerWeaponData(playerid, 0, w, a);
  2226. ClearAnimations(playerid, 1);
  2227. ApplyAnimation(playerid, "PED", "IDLE_stance", 4.1, 1, 0, 0, 0, 0, 1);
  2228. FreezeSyncData(playerid, true);
  2229. GivePlayerWeapon(playerid, w, 0);
  2230. SetTimerEx("WC_CbugPunishment", 600, false, "ii", playerid, GetPlayerWeapon(playerid));
  2231. s_CbugFroze[playerid] = tick;
  2232. for (new i = 0; i < MAX_PLAYERS; i++) {
  2233. if (!IsPlayerConnected(i) && !IsPlayerDying(i)) {
  2234. continue;
  2235. }
  2236. for (new j = 0; j < sizeof(s_PreviousHits[]); j++) {
  2237. if (s_PreviousHits[i][j][e_Issuer] == playerid && tick - s_PreviousHits[i][j][e_Tick] <= 1200) {
  2238. s_PreviousHits[i][j][e_Issuer] = INVALID_PLAYER_ID;
  2239. new Float:health = WC_GetPlayerHealth(i);
  2240. new Float:armour = WC_GetPlayerArmour(i);
  2241. if (s_IsDying[i]) {
  2242. if (s_DelayedDeathTimer[i] == -1) {
  2243. continue;
  2244. }
  2245. KillTimer(s_DelayedDeathTimer[i]);
  2246. s_DelayedDeathTimer[i] = -1;
  2247. ClearAnimations(i, 1);
  2248. SetFakeFacingAngle(i, _);
  2249. FreezeSyncData(i, false);
  2250. s_IsDying[i] = false;
  2251. if (s_DeathTimer[i] != -1) {
  2252. KillTimer(s_DeathTimer[i]);
  2253. s_DeathTimer[i] = -1;
  2254. }
  2255. }
  2256. health += s_PreviousHits[i][j][e_Health];
  2257. armour += s_PreviousHits[i][j][e_Armour];
  2258. WC_SetPlayerHealth(i, health, armour);
  2259. }
  2260. }
  2261. }
  2262. }
  2263. }
  2264. }
  2265. if (GetPlayerState(playerid) == PLAYER_STATE_ONFOOT) {
  2266. #if WC_CUSTOM_VENDING_MACHINES
  2267. if (s_CustomVendingMachines
  2268. && newkeys == KEY_SECONDARY_ATTACK
  2269. && !oldkeys
  2270. && s_VendingUseTimer[playerid] == -1
  2271. && GetPlayerAnimationIndex(playerid) != 1660) {
  2272. new bool:failed = false;
  2273. if (GetPlayerMoney(playerid) <= 0 || s_PlayerHealth[playerid] >= s_PlayerMaxHealth[playerid]) {
  2274. failed = true;
  2275. }
  2276. new Float:z;
  2277. GetPlayerPos(playerid, z, z, z);
  2278. for (new i = 0; i < sizeof(sc_VendingMachines); i++) {
  2279. if (floatabs(z - sc_VendingMachines[i][e_PosZ]) > 1.5) {
  2280. continue;
  2281. }
  2282. if (IsPlayerInRangeOfPoint(playerid, 0.5, sc_VendingMachines[i][e_FrontX], sc_VendingMachines[i][e_FrontY], z)) {
  2283. if (failed) {
  2284. PlayerPlaySound(playerid, 1055, 0.0, 0.0, 0.0);
  2285. break;
  2286. }
  2287. new Float:health_given = 35.0;
  2288. if (OnPlayerUseVendingMachine(playerid, health_given)) {
  2289. s_VendingUseTimer[playerid] = SetTimerEx("WC_VendingMachineUsed", 2500, false, "if", playerid, health_given);
  2290. SetPlayerFacingAngle(playerid, sc_VendingMachines[i][e_RotZ]);
  2291. SetPlayerPos(playerid, sc_VendingMachines[i][e_FrontX], sc_VendingMachines[i][e_FrontY], z);
  2292. ApplyAnimation(playerid, "VENDING", "VEND_USE", 4.1, 0, 0, 1, 0, 0, 1);
  2293. PlayerPlaySound(playerid, 42600, 0.0, 0.0, 0.0);
  2294. } else {
  2295. PlayerPlaySound(playerid, 1055, 0.0, 0.0, 0.0);
  2296. }
  2297. break;
  2298. }
  2299. }
  2300. }
  2301. #endif
  2302. if (newkeys & KEY_FIRE) {
  2303. new weap = GetPlayerWeapon(playerid);
  2304. switch (weap) {
  2305. case WEAPON_BOMB, WEAPON_SATCHEL: {
  2306. s_LastExplosive[playerid] = WEAPON_SATCHEL;
  2307. }
  2308. case WEAPON_ROCKETLAUNCHER, WEAPON_HEATSEEKER, WEAPON_GRENADE: {
  2309. s_LastExplosive[playerid] = weap;
  2310. }
  2311. }
  2312. }
  2313. }
  2314. #if defined WC_OnPlayerKeyStateChange
  2315. return WC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys);
  2316. #else
  2317. return 1;
  2318. #endif
  2319. }
  2320. public OnPlayerStreamIn(playerid, forplayerid)
  2321. {
  2322. // Send ped floor_hit_f
  2323. if (s_IsDying[playerid]) {
  2324. SendLastSyncData(playerid, forplayerid, 0x2e040000 + 1150);
  2325. }
  2326. #if defined WC_OnPlayerStreamIn
  2327. return WC_OnPlayerStreamIn(playerid, forplayerid);
  2328. #else
  2329. return 1;
  2330. #endif
  2331. }
  2332. public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
  2333. {
  2334. #if WC_CUSTOM_VENDING_MACHINES
  2335. if (s_VendingUseTimer[playerid] != -1) {
  2336. KillTimer(s_VendingUseTimer[playerid]);
  2337. s_VendingUseTimer[playerid] = -1;
  2338. }
  2339. #endif
  2340. s_LastVehicleEnterTime[playerid] = gettime();
  2341. s_LastVehicleTick[playerid] = GetTickCount();
  2342. #if defined WC_OnPlayerEnterVehicle
  2343. return WC_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
  2344. #else
  2345. return 1;
  2346. #endif
  2347. }
  2348. public OnPlayerExitVehicle(playerid, vehicleid)
  2349. {
  2350. s_LastVehicleTick[playerid] = GetTickCount();
  2351. #if defined WC_OnPlayerExitVehicle
  2352. return WC_OnPlayerExitVehicle(playerid, vehicleid);
  2353. #else
  2354. return 1;
  2355. #endif
  2356. }
  2357. public OnPlayerStateChange(playerid, newstate, oldstate)
  2358. {
  2359. if (s_Spectating[playerid] != INVALID_PLAYER_ID && newstate != PLAYER_STATE_SPECTATING) {
  2360. s_Spectating[playerid] = INVALID_PLAYER_ID;
  2361. }
  2362. #if WC_CUSTOM_VENDING_MACHINES
  2363. if (s_VendingUseTimer[playerid] != -1) {
  2364. KillTimer(s_VendingUseTimer[playerid]);
  2365. s_VendingUseTimer[playerid] = -1;
  2366. }
  2367. #endif
  2368. if (s_IsDying[playerid] && (newstate == PLAYER_STATE_DRIVER || newstate == PLAYER_STATE_PASSENGER)) {
  2369. TogglePlayerControllable(playerid, false);
  2370. }
  2371. if (oldstate == PLAYER_STATE_DRIVER || oldstate == PLAYER_STATE_PASSENGER) {
  2372. s_LastVehicleTick[playerid] = GetTickCount();
  2373. if (newstate == PLAYER_STATE_ONFOOT) {
  2374. new Float:vx, Float:vy, Float:vz;
  2375. GetPlayerVelocity(playerid, vx, vy, vz);
  2376. if (vx*vx + vy*vy + vz*vz <= 0.05) {
  2377. for (new i = 0; i < MAX_PLAYERS; i++) {
  2378. if (i != playerid && IsPlayerConnected(i) && IsPlayerStreamedIn(playerid, i)) {
  2379. SendLastSyncData(playerid, i);
  2380. ClearAnimationsForPlayer(playerid, i);
  2381. }
  2382. }
  2383. }
  2384. }
  2385. }
  2386. switch (newstate) {
  2387. case PLAYER_STATE_ONFOOT,
  2388. PLAYER_STATE_DRIVER,
  2389. PLAYER_STATE_PASSENGER: {
  2390. SetHealthBarVisible(playerid, true);
  2391. }
  2392. default: {
  2393. SetHealthBarVisible(playerid, false);
  2394. }
  2395. }
  2396. #if defined WC_OnPlayerStateChange
  2397. return WC_OnPlayerStateChange(playerid, newstate, oldstate);
  2398. #else
  2399. return 1;
  2400. #endif
  2401. }
  2402. public OnPlayerPickUpPickup(playerid, pickupid)
  2403. {
  2404. if (!IsPlayerSpawned(playerid)) {
  2405. return 0;
  2406. }
  2407. #if defined WC_OnPlayerPickUpPickup
  2408. return WC_OnPlayerPickUpPickup(playerid, pickupid);
  2409. #else
  2410. return 1;
  2411. #endif
  2412. }
  2413. public OnPlayerUpdate(playerid)
  2414. {
  2415. if (s_IsDying[playerid]) {
  2416. return 1;
  2417. }
  2418. if (s_DeathSkip[playerid] == 1) {
  2419. if (s_DeathSkipTick[playerid]) {
  2420. if (GetTickCount() - s_DeathSkipTick[playerid] > 1000) {
  2421. new Float:x, Float:y, Float:z, Float:r;
  2422. GetPlayerPos(playerid, x, y, z);
  2423. GetPlayerFacingAngle(playerid, r);
  2424. SetSpawnInfo(playerid, 0xFE, GetPlayerSkin(playerid), x, y, z, r, 0, 0, 0, 0, 0, 0);
  2425. s_DeathSkipTick[playerid] = 0;
  2426. ApplyAnimation(playerid, "PED", "IDLE_stance", 4.1, 1, 0, 0, 0, 1, 1);
  2427. }
  2428. } else {
  2429. if (GetPlayerAnimationIndex(playerid) != 1189) {
  2430. s_DeathSkip[playerid] = 0;
  2431. WC_DeathSkipEnd(playerid);
  2432. DebugMessage(playerid, "Death skip end");
  2433. }
  2434. }
  2435. }
  2436. if (s_SpawnForStreamedIn[playerid]) {
  2437. WC_SpawnForStreamedIn(playerid);
  2438. s_SpawnForStreamedIn[playerid] = false;
  2439. }
  2440. new tick = GetTickCount();
  2441. s_LastUpdate[playerid] = tick;
  2442. // Detect fall damage based on velocity and animation
  2443. if (s_CustomFallDamage) {
  2444. new Float:vz, Float:z;
  2445. GetPlayerVelocity(playerid, vz, vz, vz);
  2446. GetPlayerPos(playerid, z, z, z);
  2447. new surfing = GetPlayerSurfingVehicleID(playerid);
  2448. if (surfing && surfing == INVALID_VEHICLE_ID) {
  2449. surfing = GetPlayerSurfingObjectID(playerid) != INVALID_OBJECT_ID;
  2450. } else {
  2451. surfing = 1;
  2452. }
  2453. if (surfing || tick - s_LastStop[playerid] < 2000) {
  2454. vz = 0.0;
  2455. s_LastZVelo[playerid] = 0.0;
  2456. } else {
  2457. if (vz != 0.0) {
  2458. s_LastZVelo[playerid] = vz;
  2459. }
  2460. if (z - s_LastZ[playerid] > 1.0) {
  2461. s_LastZVelo[playerid] = 0.1;
  2462. vz = 0.1;
  2463. }
  2464. }
  2465. s_LastZ[playerid] = z;
  2466. new anim = GetPlayerAnimationIndex(playerid);
  2467. if (anim != s_LastAnim[playerid]) {
  2468. new prev = s_LastAnim[playerid];
  2469. s_LastAnim[playerid] = anim;
  2470. if (((prev == 1130 && vz == 0.0) || 1128 <= anim <= 1134 || anim == 1208)) {
  2471. new Float:amount = -1.0;
  2472. DebugMessage(playerid, "vz: %f anim: %d prev: %d", vz, anim, prev);
  2473. vz = s_LastZVelo[playerid];
  2474. if (vz <= s_FallDeathVelocity) {
  2475. amount = 0.0;
  2476. } else if (vz <= -0.2) {
  2477. if (vz == -0.2) {
  2478. amount = s_WeaponDamage[WEAPON_COLLISION] * 0.2;
  2479. } else {
  2480. amount = (vz + 0.2) / (s_FallDeathVelocity + 0.2);
  2481. amount *= s_WeaponDamage[WEAPON_COLLISION];
  2482. }
  2483. }
  2484. if (GetPlayerWeapon(playerid) == WEAPON_PARACHUTE && anim == 1134) {
  2485. amount = -1.0;
  2486. }
  2487. if (amount >= 0.0) {
  2488. DebugMessage(playerid, "fall dmg: %.5f (vz: %f, anim: %d, prev: %d)", amount, vz, anim, prev);
  2489. InflictDamage(playerid, amount, INVALID_PLAYER_ID, WEAPON_COLLISION, 3);
  2490. if (amount == 0.0) {
  2491. amount = s_PlayerHealth[playerid];
  2492. }
  2493. }
  2494. }
  2495. }
  2496. }
  2497. #if defined WC_OnPlayerUpdate
  2498. return WC_OnPlayerUpdate(playerid);
  2499. #else
  2500. return 1;
  2501. #endif
  2502. }
  2503. public OnPlayerGiveDamage(playerid, damagedid, Float:amount, weaponid, bodypart)
  2504. {
  2505. if (!IsHighRateWeapon(weaponid)) {
  2506. DebugMessage(playerid, "OnPlayerGiveDamage(%d gave %f to %d using %d on bodypart %d)", playerid, amount, damagedid, weaponid, bodypart);
  2507. }
  2508. // Nobody got damaged
  2509. if (damagedid == INVALID_PLAYER_ID) {
  2510. #if defined OnInvalidWeaponDamage
  2511. OnInvalidWeaponDamage(playerid, damagedid, amount, weaponid, bodypart, WC_NO_DAMAGED, true);
  2512. #endif
  2513. AddRejectedHit(playerid, damagedid, HIT_NO_DAMAGEDID, weaponid);
  2514. return 0;
  2515. }
  2516. if (s_IsDying[damagedid]) {
  2517. AddRejectedHit(playerid, damagedid, HIT_DYING_PLAYER, weaponid);
  2518. return 0;
  2519. }
  2520. if (!s_LagCompMode) {
  2521. new npc = IsPlayerNPC(damagedid);
  2522. if (weaponid == WEAPON_KNIFE && _:amount == _:0.0) {
  2523. if (s_KnifeTimeout[damagedid] != -1) {
  2524. KillTimer(s_KnifeTimeout[damagedid]);
  2525. }
  2526. s_KnifeTimeout[damagedid] = SetTimerEx("WC_SetSpawnForStreamedIn", 2500, false, "i", damagedid);
  2527. }
  2528. if (!npc) {
  2529. return 0;
  2530. }
  2531. }
  2532. // Ignore unreliable and invalid damage
  2533. if (weaponid < 0 || weaponid >= sizeof(s_ValidDamageGiven) || !s_ValidDamageGiven[weaponid]) {
  2534. // Fire is synced as taken damage (because it's not reliable as given), so no need to show a rejected hit.
  2535. // Vehicle damage is also synced as taken, so no need to show that either.
  2536. if (weaponid != WEAPON_FLAMETHROWER && weaponid != WEAPON_VEHICLE) {
  2537. AddRejectedHit(playerid, damagedid, HIT_INVALID_WEAPON, weaponid);
  2538. }
  2539. return 0;
  2540. }
  2541. if (!IsPlayerSpawned(playerid)) {
  2542. // Make sure the rejected hit wasn't added in OnPlayerWeaponShot
  2543. if (!IsBulletWeapon(weaponid) || s_LastShot[playerid][e_Valid]) {
  2544. AddRejectedHit(playerid, damagedid, HIT_NOT_SPAWNED, weaponid);
  2545. }
  2546. return 0;
  2547. }
  2548. new npc = IsPlayerNPC(damagedid);
  2549. // From stealth knife, can be any weapon
  2550. if (_:amount == _:1833.33154296875) {
  2551. return 0;
  2552. }
  2553. if (weaponid == WEAPON_KNIFE) {
  2554. if (_:amount == _:0.0) {
  2555. // Resync without bothering the player being knifed
  2556. if (npc || HasSameTeam(playerid, damagedid)) {
  2557. if (s_KnifeTimeout[damagedid] != -1) {
  2558. KillTimer(s_KnifeTimeout[damagedid]);
  2559. }
  2560. s_KnifeTimeout[damagedid] = SetTimerEx("WC_SpawnForStreamedIn", 150, false, "i", damagedid);
  2561. ClearAnimations(playerid, 1);
  2562. SetPlayerArmedWeapon(playerid, 0);
  2563. return 0;
  2564. }
  2565. if (!OnPlayerDamage(damagedid, amount, playerid, weaponid, bodypart)) {
  2566. if (s_KnifeTimeout[damagedid] != -1) {
  2567. KillTimer(s_KnifeTimeout[damagedid]);
  2568. }
  2569. s_KnifeTimeout[damagedid] = SetTimerEx("WC_SpawnForStreamedIn", 150, false, "i", damagedid);
  2570. ClearAnimations(playerid, 1);
  2571. SetPlayerArmedWeapon(playerid, 0);
  2572. return 0;
  2573. }
  2574. s_DamageDoneHealth[playerid] = s_PlayerHealth[playerid];
  2575. s_DamageDoneArmour[playerid] = s_PlayerArmour[playerid];
  2576. OnPlayerDamageDone(damagedid, s_PlayerHealth[damagedid] + s_PlayerArmour[damagedid], playerid, weaponid, bodypart);
  2577. ClearAnimations(damagedid, 1);
  2578. PlayerDeath(damagedid, "KNIFE", "KILL_Knife_Ped_Damage", _, 5200);
  2579. SetTimerEx("WC_SecondKnifeAnim", 2200, false, "i", damagedid);
  2580. #if defined WC_OnPlayerDeath
  2581. WC_OnPlayerDeath(damagedid, playerid, weaponid);
  2582. #endif
  2583. DebugMessage(damagedid, "being knifed by %d", playerid);
  2584. DebugMessage(playerid, "knifing %d", damagedid);
  2585. new Float:x, Float:y, Float:z, Float:a;
  2586. GetPlayerFacingAngle(damagedid, a);
  2587. SetPlayerFacingAngle(playerid, a);
  2588. PosInFront(damagedid, -1.0, x, y, z);
  2589. SetPlayerVelocity(damagedid, 0.0, 0.0, 0.0);
  2590. SetPlayerVelocity(playerid, 0.0, 0.0, 0.0);
  2591. new forcesync = 2;
  2592. if (747 < GetPlayerAnimationIndex(playerid) > 748) {
  2593. DebugMessageRed(playerid, "applying knife anim for you too (current: %d)", GetPlayerAnimationIndex(playerid));
  2594. forcesync = 1;
  2595. }
  2596. ApplyAnimation(playerid, "KNIFE", "KILL_Knife_Player", 4.1, 0, 1, 1, 0, 1800, forcesync);
  2597. return 0;
  2598. }
  2599. }
  2600. if (HasSameTeam(playerid, damagedid)) {
  2601. AddRejectedHit(playerid, damagedid, HIT_SAME_TEAM, weaponid);
  2602. return 0;
  2603. }
  2604. // Both players should see eachother
  2605. if ((!IsPlayerStreamedIn(playerid, damagedid) && !IsPlayerPaused(damagedid)) || !IsPlayerStreamedIn(damagedid, playerid)) {
  2606. AddRejectedHit(playerid, damagedid, HIT_UNSTREAMED, weaponid, damagedid);
  2607. return 0;
  2608. }
  2609. new Float:bullets, err;
  2610. if ((err = ProcessDamage(damagedid, playerid, amount, weaponid, bodypart, bullets))) {
  2611. if (err == WC_INVALID_DAMAGE) {
  2612. AddRejectedHit(playerid, damagedid, HIT_INVALID_DAMAGE, weaponid, _:amount);
  2613. }
  2614. if (err != WC_INVALID_DISTANCE) {
  2615. #if defined OnInvalidWeaponDamage
  2616. OnInvalidWeaponDamage(playerid, damagedid, amount, weaponid, bodypart, err, true);
  2617. #endif
  2618. }
  2619. return 0;
  2620. }
  2621. new tick = GetTickCount();
  2622. if (tick == 0) tick = 1;
  2623. new idx = (s_LastHitIdx[playerid] + 1) % sizeof(s_LastHitTicks[]);
  2624. // JIT plugin fix
  2625. if (idx < 0) {
  2626. idx += sizeof(s_LastHitTicks[]);
  2627. }
  2628. s_LastHitIdx[playerid] = idx;
  2629. s_LastHitTicks[playerid][idx] = tick;
  2630. s_LastHitWeapons[playerid][idx] = weaponid;
  2631. s_HitsIssued[playerid] += 1;
  2632. #if WC_DEBUG
  2633. if (s_HitsIssued[playerid] > 1) {
  2634. new prev_tick_idx = (idx - 1) % sizeof(s_LastHitTicks[]);
  2635. // JIT plugin fix
  2636. if (prev_tick_idx < 0) {
  2637. prev_tick_idx += sizeof(s_LastHitTicks[]);
  2638. }
  2639. new prev_tick = s_LastHitTicks[playerid][prev_tick_idx];
  2640. DebugMessage(playerid, "(hit) last: %d last 3: %d", tick - prev_tick, AverageHitRate(playerid, 3));
  2641. }
  2642. #endif
  2643. new multiple_weapons;
  2644. new avg_rate = AverageHitRate(playerid, s_MaxHitRateSamples, multiple_weapons);
  2645. // Hit issue flood?
  2646. // Could be either a cheat or just lag
  2647. if (avg_rate != -1) {
  2648. if (multiple_weapons) {
  2649. if (avg_rate < 100) {
  2650. AddRejectedHit(playerid, damagedid, HIT_RATE_TOO_FAST_MULTIPLE, weaponid, avg_rate, s_MaxHitRateSamples);
  2651. return 0;
  2652. }
  2653. } else if (s_MaxWeaponShootRate[weaponid] - avg_rate > 20) {
  2654. AddRejectedHit(playerid, damagedid, HIT_RATE_TOO_FAST, weaponid, avg_rate, s_MaxHitRateSamples, s_MaxWeaponShootRate[weaponid]);
  2655. return 0;
  2656. }
  2657. }
  2658. if (IsBulletWeapon(weaponid) && _:amount != _:2.6400001049041748046875 && !(IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleSeat(playerid) == 0)) {
  2659. new valid = true;
  2660. if (!s_LastShot[playerid][e_Valid]) {
  2661. //AddRejectedHit(playerid, damagedid, HIT_LAST_SHOT_INVALID, weaponid);
  2662. valid = false;
  2663. DebugMessageRed(playerid, "last shot not valid");
  2664. } else if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  2665. // Let's assume someone won't hit 3 players with 1 shotgun shot, and that one OnPlayerWeaponShot can be out of sync
  2666. if (s_LastShot[playerid][e_Hits] >= 3) {
  2667. valid = false;
  2668. AddRejectedHit(playerid, damagedid, HIT_MULTIPLE_PLAYERS_SHOTGUN, weaponid, s_LastShot[playerid][e_Hits] + 1);
  2669. }
  2670. } else if (s_LastShot[playerid][e_Hits] > 0) {
  2671. // Sniper doesn't always send OnPlayerWeaponShot
  2672. if (s_LastShot[playerid][e_Hits] > 4 && weaponid != WEAPON_SNIPER) {
  2673. valid = false;
  2674. AddRejectedHit(playerid, damagedid, HIT_MULTIPLE_PLAYERS, weaponid, s_LastShot[playerid][e_Hits] + 1);
  2675. } else {
  2676. DebugMessageRed(playerid, "hit %d players with 1 shot", s_LastShot[playerid][e_Hits] + 1);
  2677. }
  2678. }
  2679. s_LastShot[playerid][e_Hits] += 1;
  2680. if (!valid) {
  2681. return 0;
  2682. }
  2683. }
  2684. if (npc) {
  2685. OnPlayerDamageDone(damagedid, amount, playerid, weaponid, bodypart);
  2686. } else {
  2687. InflictDamage(damagedid, amount, playerid, weaponid, bodypart);
  2688. }
  2689. // Don't send OnPlayerGiveDamage to the rest of the script, since it should not be used
  2690. return 0;
  2691. }
  2692. public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid, bodypart)
  2693. {
  2694. UpdateHealthBar(playerid, true);
  2695. if (s_IsDying[playerid]) {
  2696. return 0;
  2697. }
  2698. if (s_BeingResynced[playerid]) {
  2699. return 0;
  2700. }
  2701. if (!IsHighRateWeapon(weaponid)) {
  2702. DebugMessage(playerid, "OnPlayerTakeDamage(%d took %f from %d by %d on bodypart %d)", playerid, amount, issuerid, weaponid, bodypart);
  2703. }
  2704. // Ignore unreliable and invalid damage
  2705. if (weaponid < 0 || weaponid >= sizeof(s_ValidDamageTaken) || !s_ValidDamageTaken[weaponid]) {
  2706. return 0;
  2707. }
  2708. if (playerid == INVALID_PLAYER_ID || IsPlayerNPC(playerid)) {
  2709. return 0;
  2710. }
  2711. // Carjack damage
  2712. if (weaponid == 54 && _:amount == _:0.0) {
  2713. return 0;
  2714. }
  2715. // From stealth knife, can be any weaponid
  2716. if (_:amount == _:1833.33154296875) {
  2717. return 0;
  2718. }
  2719. // Climb bug
  2720. if (weaponid == WEAPON_COLLISION) {
  2721. if (s_CustomFallDamage) {
  2722. return 0;
  2723. }
  2724. new anim = GetPlayerAnimationIndex(playerid);
  2725. if (1061 <= anim <= 1067) {
  2726. DebugMessage(playerid, "climb bug prevented");
  2727. return 0;
  2728. }
  2729. }
  2730. // Being knifed client-side
  2731. if (weaponid == WEAPON_KNIFE) {
  2732. if (s_IsDying[playerid]) {
  2733. return 0;
  2734. }
  2735. // With the plugin, this part is never actually used (it can't happen)
  2736. if (_:amount == _:0.0) {
  2737. if (s_KnifeTimeout[playerid] != -1) {
  2738. KillTimer(s_KnifeTimeout[playerid]);
  2739. s_KnifeTimeout[playerid] = -1;
  2740. }
  2741. if (issuerid == INVALID_PLAYER_ID || HasSameTeam(playerid, issuerid)) {
  2742. ResyncPlayer(playerid);
  2743. return 0;
  2744. }
  2745. if (!OnPlayerDamage(playerid, amount, issuerid, weaponid, bodypart)) {
  2746. ResyncPlayer(playerid);
  2747. return 0;
  2748. }
  2749. // Make sure the values were not modified
  2750. weaponid = WEAPON_KNIFE;
  2751. amount = 0.0;
  2752. s_DamageDoneHealth[playerid] = s_PlayerHealth[playerid];
  2753. s_DamageDoneArmour[playerid] = s_PlayerArmour[playerid];
  2754. OnPlayerDamageDone(playerid, s_PlayerHealth[playerid] + s_PlayerArmour[playerid], issuerid, weaponid, bodypart);
  2755. PlayerDeath(playerid, "KNIFE", "KILL_Knife_Ped_Die", _, 4000 - GetPlayerPing(playerid));
  2756. #if defined WC_OnPlayerDeath
  2757. WC_OnPlayerDeath(playerid, issuerid, weaponid);
  2758. #endif
  2759. SetPlayerHealth(playerid, Float:0x7f7fffff);
  2760. DebugMessage(playerid, "being knifed by %d", issuerid);
  2761. DebugMessage(issuerid, "knifing %d", playerid);
  2762. new Float:x, Float:y, Float:z, Float:a;
  2763. GetPlayerFacingAngle(playerid, a);
  2764. SetPlayerFacingAngle(issuerid, a);
  2765. PosInFront(playerid, -1.0, x, y, z);
  2766. SetPlayerVelocity(playerid, 0.0, 0.0, 0.0);
  2767. SetPlayerVelocity(issuerid, 0.0, 0.0, 0.0);
  2768. new forcesync = 2;
  2769. if (GetPlayerAnimationIndex(issuerid) != 747) {
  2770. DebugMessageRed(issuerid, "applying knife anim for you too (current: %d)", GetPlayerAnimationIndex(issuerid));
  2771. forcesync = 1;
  2772. }
  2773. ApplyAnimation(issuerid, "KNIFE", "KILL_Knife_Player", 4.1, 0, 1, 1, 0, 1800, forcesync);
  2774. return 0;
  2775. }
  2776. }
  2777. // If it's lagcomp, only allow damage that's valid for both modes
  2778. if (s_LagCompMode && s_ValidDamageTaken[weaponid] != 2) {
  2779. if (issuerid != INVALID_PLAYER_ID && IsPlayerInAnyVehicle(issuerid) && GetPlayerVehicleSeat(issuerid) == 0 && (weaponid == WEAPON_M4 || weaponid == WEAPON_MINIGUN)) {
  2780. weaponid = weaponid == WEAPON_M4 ? WEAPON_VEHICLE_M4 : WEAPON_VEHICLE_MINIGUN;
  2781. } else {
  2782. return 0;
  2783. }
  2784. }
  2785. // Should still be damaged by grenades or fire after someone has died
  2786. if (issuerid != INVALID_PLAYER_ID) {
  2787. if (HasSameTeam(playerid, issuerid)) {
  2788. return 0;
  2789. }
  2790. if (s_IsDying[issuerid] && (IsBulletWeapon(weaponid) || IsMeleeWeapon(weaponid))) {
  2791. DebugMessageRed(playerid, "shot/punched by dead player (%d)", issuerid);
  2792. return 0;
  2793. }
  2794. if (s_BeingResynced[issuerid]) {
  2795. return 0;
  2796. }
  2797. }
  2798. new Float:bullets = 0.0, err;
  2799. if ((err = ProcessDamage(playerid, issuerid, amount, weaponid, bodypart, bullets))) {
  2800. if (err == WC_INVALID_DAMAGE) {
  2801. AddRejectedHit(issuerid, playerid, HIT_INVALID_DAMAGE, weaponid, _:amount);
  2802. }
  2803. if (err != WC_INVALID_DISTANCE) {
  2804. #if defined OnInvalidWeaponDamage
  2805. OnInvalidWeaponDamage(issuerid, playerid, amount, weaponid, bodypart, err, false);
  2806. #endif
  2807. }
  2808. return 0;
  2809. }
  2810. if (IsBulletWeapon(weaponid)) {
  2811. new Float:x, Float:y, Float:z;
  2812. GetPlayerPos(issuerid, x, y, z);
  2813. new Float:dist = GetPlayerDistanceFromPoint(playerid, x, y, z);
  2814. if (dist > s_WeaponRange[weaponid] + 2.0) {
  2815. AddRejectedHit(issuerid, playerid, HIT_OUT_OF_RANGE, weaponid, _:dist, _:s_WeaponRange[weaponid]);
  2816. return 0;
  2817. }
  2818. }
  2819. InflictDamage(playerid, amount, issuerid, weaponid, bodypart);
  2820. return 0;
  2821. }
  2822. public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
  2823. {
  2824. #if WC_CUSTOM_VENDING_MACHINES
  2825. if (s_VendingUseTimer[playerid] != -1) {
  2826. KillTimer(s_VendingUseTimer[playerid]);
  2827. s_VendingUseTimer[playerid] = -1;
  2828. }
  2829. #endif
  2830. s_LastShot[playerid][e_Valid] = false;
  2831. s_LastShot[playerid][e_Hits] = false;
  2832. if (s_CbugFroze[playerid] && GetTickCount() - s_CbugFroze[playerid] < 900) {
  2833. return 0;
  2834. }
  2835. s_CbugFroze[playerid] = 0;
  2836. new damagedid = INVALID_PLAYER_ID;
  2837. if (hittype == BULLET_HIT_TYPE_PLAYER && hitid != INVALID_PLAYER_ID) {
  2838. if (!IsPlayerConnected(hitid)) {
  2839. AddRejectedHit(playerid, hitid, HIT_DISCONNECTED, weaponid, hitid);
  2840. return 0;
  2841. }
  2842. damagedid = hitid;
  2843. }
  2844. if (hittype < 0 || hittype > 5) {
  2845. AddRejectedHit(playerid, damagedid, HIT_INVALID_HITTYPE, weaponid, hittype);
  2846. return 0;
  2847. }
  2848. #if WC_DEBUG
  2849. if (hittype == BULLET_HIT_TYPE_PLAYER) {
  2850. DebugMessage(playerid, "OnPlayerWeaponShot(%d shot %d with %d at %f, %f, %f)", playerid, hitid, weaponid, fX, fY, fZ);
  2851. } else if (hittype) {
  2852. DebugMessage(playerid, "OnPlayerWeaponShot(%d shot %d %d with %d at %f, %f, %f)", playerid, hittype, hitid, weaponid, fX, fY, fZ);
  2853. } else {
  2854. DebugMessage(playerid, "OnPlayerWeaponShot(%d shot with %d at %f, %f, %f)", playerid, weaponid, fX, fY, fZ);
  2855. }
  2856. #endif
  2857. if (s_BeingResynced[playerid]) {
  2858. AddRejectedHit(playerid, damagedid, HIT_BEING_RESYNCED, weaponid);
  2859. return 0;
  2860. }
  2861. if (!IsPlayerSpawned(playerid)) {
  2862. AddRejectedHit(playerid, damagedid, HIT_NOT_SPAWNED, weaponid);
  2863. return 0;
  2864. }
  2865. if (!IsBulletWeapon(weaponid)) {
  2866. AddRejectedHit(playerid, damagedid, HIT_INVALID_WEAPON, weaponid);
  2867. return 0;
  2868. }
  2869. new Float:fOriginX, Float:fOriginY, Float:fOriginZ, Float:fHitPosX, Float:fHitPosY, Float:fHitPosZ;
  2870. new Float:x, Float:y, Float:z;
  2871. GetPlayerPos(playerid, x, y, z);
  2872. GetPlayerLastShotVectors(playerid, fOriginX, fOriginY, fOriginZ, fHitPosX, fHitPosY, fHitPosZ);
  2873. new Float:length = VectorSize(fOriginX - fHitPosX, fOriginY - fHitPosY, fOriginZ - fHitPosZ);
  2874. new Float:origin_dist = VectorSize(fOriginX - x, fOriginY - y, fOriginZ - z);
  2875. if (origin_dist > 15.0) {
  2876. new in_veh = IsPlayerInAnyVehicle(hitid) || GetPlayerSurfingVehicleID(playerid);
  2877. if ((!in_veh && GetPlayerSurfingVehicleID(playerid) == INVALID_VEHICLE_ID) || origin_dist > 50.0) {
  2878. AddRejectedHit(playerid, damagedid, HIT_TOO_FAR_FROM_ORIGIN, weaponid, _:origin_dist);
  2879. return 0;
  2880. }
  2881. }
  2882. // Shot exceeding the max range?
  2883. if (hittype != BULLET_HIT_TYPE_NONE) {
  2884. if (length > s_WeaponRange[weaponid]) {
  2885. if (hittype == BULLET_HIT_TYPE_PLAYER) {
  2886. AddRejectedHit(playerid, damagedid, HIT_OUT_OF_RANGE, weaponid, _:length, _:s_WeaponRange[weaponid]);
  2887. }
  2888. return 0;
  2889. }
  2890. if (hittype == BULLET_HIT_TYPE_PLAYER) {
  2891. if (IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleID(playerid) == GetPlayerVehicleID(hitid)) {
  2892. AddRejectedHit(playerid, damagedid, HIT_SAME_VEHICLE, weaponid);
  2893. return 0;
  2894. }
  2895. new Float:dist = GetPlayerDistanceFromPoint(hitid, fHitPosX, fHitPosY, fHitPosZ);
  2896. new in_veh = IsPlayerInAnyVehicle(hitid);
  2897. if ((!in_veh && dist > 20.0) || dist > 50.0) {
  2898. AddRejectedHit(playerid, damagedid, HIT_TOO_FAR_FROM_SHOT, weaponid, _:dist);
  2899. return 0;
  2900. }
  2901. }
  2902. }
  2903. new tick = GetTickCount();
  2904. if (tick == 0) tick = 1;
  2905. new idx = (s_LastShotIdx[playerid] + 1) % sizeof(s_LastShotTicks[]);
  2906. // JIT plugin fix
  2907. if (idx < 0) {
  2908. idx += sizeof(s_LastShotTicks[]);
  2909. }
  2910. s_LastShotIdx[playerid] = idx;
  2911. s_LastShotTicks[playerid][idx] = tick;
  2912. s_LastShotWeapons[playerid][idx] = weaponid;
  2913. s_ShotsFired[playerid] += 1;
  2914. #if WC_DEBUG
  2915. if (s_ShotsFired[playerid] > 1) {
  2916. new prev_tick_idx = (idx - 1) % sizeof(s_LastShotTicks[]);
  2917. // JIT plugin fix
  2918. if (prev_tick_idx < 0) {
  2919. prev_tick_idx += sizeof(s_LastShotTicks[]);
  2920. }
  2921. new prev_tick = s_LastShotTicks[playerid][prev_tick_idx];
  2922. DebugMessage(playerid, "(shot) last: %d last 3: %d", tick - prev_tick, AverageShootRate(playerid, 3));
  2923. }
  2924. #endif
  2925. s_LastShot[playerid][e_Tick] = tick;
  2926. s_LastShot[playerid][e_Weapon] = weaponid;
  2927. s_LastShot[playerid][e_HitType] = hittype;
  2928. s_LastShot[playerid][e_HitId] = hitid;
  2929. s_LastShot[playerid][e_X] = fX;
  2930. s_LastShot[playerid][e_Y] = fY;
  2931. s_LastShot[playerid][e_Z] = fZ;
  2932. s_LastShot[playerid][e_OX] = fOriginX;
  2933. s_LastShot[playerid][e_OY] = fOriginY;
  2934. s_LastShot[playerid][e_OZ] = fOriginZ;
  2935. s_LastShot[playerid][e_HX] = fHitPosX;
  2936. s_LastShot[playerid][e_HY] = fHitPosY;
  2937. s_LastShot[playerid][e_HZ] = fHitPosZ;
  2938. s_LastShot[playerid][e_Length] = length;
  2939. s_LastShot[playerid][e_Hits] = 0;
  2940. new multiple_weapons;
  2941. new avg_rate = AverageShootRate(playerid, s_MaxShootRateSamples, multiple_weapons);
  2942. // Bullet flood?
  2943. // Could be either a cheat or just lag
  2944. if (avg_rate != -1) {
  2945. if (multiple_weapons) {
  2946. if (avg_rate < 100) {
  2947. AddRejectedHit(playerid, damagedid, SHOOTING_RATE_TOO_FAST_MULTIPLE, weaponid, avg_rate, s_MaxShootRateSamples);
  2948. return 0;
  2949. }
  2950. } else if (s_MaxWeaponShootRate[weaponid] - avg_rate > 20) {
  2951. AddRejectedHit(playerid, damagedid, SHOOTING_RATE_TOO_FAST, weaponid, avg_rate, s_MaxShootRateSamples, s_MaxWeaponShootRate[weaponid]);
  2952. return 0;
  2953. }
  2954. }
  2955. // Destroy vehicles with passengers in them
  2956. if (hittype == BULLET_HIT_TYPE_VEHICLE) {
  2957. if (hitid < 0 || hitid > MAX_VEHICLES || !WC_IsValidVehicle(hitid)) {
  2958. AddRejectedHit(playerid, damagedid, HIT_INVALID_VEHICLE, weaponid, hitid);
  2959. return 0;
  2960. }
  2961. new vehicleid = GetPlayerVehicleID(playerid);
  2962. // Shouldn't be possible to damage the vehicle you're in
  2963. if (hitid == vehicleid) {
  2964. AddRejectedHit(playerid, damagedid, HIT_OWN_VEHICLE, weaponid);
  2965. return 0;
  2966. }
  2967. if (s_VehiclePassengerDamage) {
  2968. new has_driver = false;
  2969. new has_passenger = false;
  2970. for (new otherid = 0; otherid < MAX_PLAYERS; otherid++) {
  2971. if (otherid == playerid || !IsPlayerConnected(otherid)) {
  2972. continue;
  2973. }
  2974. if (GetPlayerVehicleID(otherid) != hitid) {
  2975. continue;
  2976. }
  2977. new seat = GetPlayerVehicleSeat(otherid);
  2978. if (seat == 0) {
  2979. has_driver = true;
  2980. } else {
  2981. has_passenger = true;
  2982. }
  2983. }
  2984. if (!has_driver && has_passenger) {
  2985. new Float:health;
  2986. GetVehicleHealth(hitid, health);
  2987. if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  2988. health -= 120.0;
  2989. } else {
  2990. health -= s_WeaponDamage[weaponid] * 3.0;
  2991. }
  2992. if (health <= 0.0) {
  2993. health = 0.0;
  2994. }
  2995. SetVehicleHealth(hitid, health);
  2996. }
  2997. }
  2998. if (s_VehicleUnoccupiedDamage) {
  2999. new has_occupent = false;
  3000. for (new otherid = 0; otherid < MAX_PLAYERS; otherid++) {
  3001. if (otherid == playerid || !IsPlayerConnected(otherid)) {
  3002. continue;
  3003. }
  3004. if (GetPlayerVehicleID(otherid) != hitid) {
  3005. continue;
  3006. }
  3007. has_occupent = true;
  3008. }
  3009. if (!has_occupent) {
  3010. new Float:health;
  3011. GetVehicleHealth(hitid, health);
  3012. if (health >= 249.0) { //vehicles start on fire at 249 or under so theres no need to check once the vehicle is at or below 250
  3013. if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  3014. health -= 120.0;
  3015. } else {
  3016. health -= s_WeaponDamage[weaponid] * 3.0;
  3017. }
  3018. if (health <= 249.0) {
  3019. if (s_VehicleRespawnTimer[hitid] == -1) {
  3020. health = 249.0;
  3021. s_VehicleRespawnTimer[hitid] = SetTimerEx("WC_KillVehicle", 6000, false, "ii", hitid, playerid);
  3022. }
  3023. }
  3024. SetVehicleHealth(hitid, health);
  3025. }
  3026. }
  3027. }
  3028. }
  3029. new retval = 1;
  3030. #if defined WC_OnPlayerWeaponShot
  3031. retval = WC_OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, fX, fY, fZ);
  3032. #else
  3033. retval = 1;
  3034. #endif
  3035. s_LastShot[playerid][e_Valid] = !!retval;
  3036. // Valid shot?
  3037. if (retval) {
  3038. if (hittype == BULLET_HIT_TYPE_VEHICLE) {
  3039. s_LastVehicleShooter[hitid] = playerid;
  3040. }
  3041. }
  3042. return retval;
  3043. }
  3044. forward WC_KillVehicle(vehicleid, killerid);
  3045. public WC_KillVehicle(vehicleid, killerid)
  3046. {
  3047. OnVehicleDeath(vehicleid, killerid);
  3048. s_VehicleRespawnTimer[vehicleid] = SetTimerEx("WC_OnDeadVehicleSpawn", 10000, false, "i", vehicleid);
  3049. return 1;
  3050. }
  3051. forward WC_OnDeadVehicleSpawn(vehicleid);
  3052. public WC_OnDeadVehicleSpawn(vehicleid)
  3053. {
  3054. s_VehicleRespawnTimer[vehicleid] = -1;
  3055. return SetVehicleToRespawn(vehicleid);
  3056. }
  3057. public OnVehicleSpawn(vehicleid)
  3058. {
  3059. if (s_VehicleRespawnTimer[vehicleid] != -1) {
  3060. KillTimer(s_VehicleRespawnTimer[vehicleid]);
  3061. s_VehicleRespawnTimer[vehicleid] = -1;
  3062. }
  3063. s_VehicleAlive[vehicleid] = true;
  3064. #if defined WC_OnVehicleSpawn
  3065. return WC_OnVehicleSpawn(vehicleid);
  3066. #else
  3067. return 1;
  3068. #endif
  3069. }
  3070. public OnVehicleDeath(vehicleid, killerid)
  3071. {
  3072. if (s_VehicleRespawnTimer[vehicleid] != -1) {
  3073. KillTimer(s_VehicleRespawnTimer[vehicleid]);
  3074. s_VehicleRespawnTimer[vehicleid] = -1;
  3075. }
  3076. if (s_VehicleAlive[vehicleid]) {
  3077. s_VehicleAlive[vehicleid] = false;
  3078. #if defined WC_OnVehicleDeath
  3079. return WC_OnVehicleDeath(vehicleid, killerid);
  3080. #else
  3081. return 1;
  3082. #endif
  3083. }
  3084. return 1;
  3085. }
  3086. public OnPlayerEnterCheckpoint(playerid)
  3087. {
  3088. if (!IsPlayerSpawned(playerid)) {
  3089. return 1;
  3090. }
  3091. #if defined WC_OnPlayerEnterCheckpoint
  3092. return WC_OnPlayerEnterCheckpoint(playerid);
  3093. #else
  3094. return 1;
  3095. #endif
  3096. }
  3097. public OnPlayerLeaveCheckpoint(playerid)
  3098. {
  3099. // If they're dying, it will be called in PlayerDeath (when the death anim begins)
  3100. if (s_IsDying[playerid]) {
  3101. return 1;
  3102. }
  3103. #if defined WC_OnPlayerLeaveCheckpoint
  3104. return WC_OnPlayerLeaveCheckpoint(playerid);
  3105. #else
  3106. return 1;
  3107. #endif
  3108. }
  3109. /*
  3110. * Internal functions
  3111. */
  3112. static ScriptInit()
  3113. {
  3114. s_LagCompMode = GetServerVarAsInt("lagcompmode");
  3115. if (s_LagCompMode) {
  3116. SetKnifeSync(false);
  3117. } else {
  3118. s_DamageTakenSound = 0;
  3119. SetKnifeSync(true);
  3120. }
  3121. for (new i = 0; i < sizeof(s_ClassSpawnInfo); i++) {
  3122. s_ClassSpawnInfo[i][e_Skin] = -1;
  3123. }
  3124. s_HealthBarBorder = TextDrawCreate(610.01, 68.25, "\1");
  3125. if (s_HealthBarBorder == Text:INVALID_TEXT_DRAW) {
  3126. printf("(wc) WARN: Unable to create healthbar border textdraw");
  3127. } else {
  3128. s_InternalTextDraw[s_HealthBarBorder] = true;
  3129. TextDrawUseBox (s_HealthBarBorder, 1);
  3130. TextDrawLetterSize(s_HealthBarBorder, 0.0, 0.64);
  3131. TextDrawTextSize (s_HealthBarBorder, 543.75, 0.0);
  3132. TextDrawBoxColor (s_HealthBarBorder, 0x000000FF);
  3133. }
  3134. s_HealthBarBackground = TextDrawCreate(608.01, 70.25, "\1");
  3135. if (s_HealthBarBackground == Text:INVALID_TEXT_DRAW) {
  3136. printf("(wc) WARN: Unable to create healthbar background textdraw");
  3137. } else {
  3138. s_InternalTextDraw[s_HealthBarBackground] = true;
  3139. TextDrawUseBox (s_HealthBarBackground, 1);
  3140. TextDrawLetterSize(s_HealthBarBackground, 0.0, 0.2);
  3141. TextDrawTextSize (s_HealthBarBackground, 545.75, 0.0);
  3142. TextDrawBoxColor (s_HealthBarBackground, 0x5A0C10FF);
  3143. }
  3144. #if WC_CUSTOM_VENDING_MACHINES
  3145. if (s_CustomVendingMachines) {
  3146. CreateVendingMachines();
  3147. }
  3148. #endif
  3149. new tick = GetTickCount();
  3150. for (new playerid = 0; playerid < MAX_PLAYERS; playerid++) {
  3151. if (!IsPlayerConnected(playerid)) {
  3152. continue;
  3153. }
  3154. new team = GetPlayerTeam(playerid);
  3155. if (team == 0xFE) {
  3156. s_PlayerTeam[playerid] = NO_TEAM;
  3157. } else {
  3158. s_PlayerTeam[playerid] = team;
  3159. }
  3160. SetPlayerTeam(playerid, 0xFE);
  3161. DamageFeedUpdate(playerid);
  3162. new worldid = GetPlayerVirtualWorld(playerid);
  3163. if (worldid == WC_DEATH_WORLD) {
  3164. worldid = 0;
  3165. SetPlayerVirtualWorld(playerid, worldid);
  3166. }
  3167. s_World[playerid] = worldid;
  3168. s_LastUpdate[playerid] = tick;
  3169. s_DamageFeedLastUpdate[playerid] = tick;
  3170. s_LastStop[playerid] = tick;
  3171. s_LastVehicleEnterTime[playerid] = 0;
  3172. s_TrueDeath[playerid] = true;
  3173. s_InClassSelection[playerid] = true;
  3174. s_PlayerFallbackSpawnInfo[playerid][e_Skin] = -1;
  3175. s_AlreadyConnected[playerid] = true;
  3176. #if WC_CUSTOM_VENDING_MACHINES
  3177. RemoveDefaultVendingMachines(playerid);
  3178. #endif
  3179. if (PLAYER_STATE_ONFOOT <= GetPlayerState(playerid) <= PLAYER_STATE_PASSENGER) {
  3180. GetPlayerHealth(playerid, s_PlayerHealth[playerid]);
  3181. GetPlayerArmour(playerid, s_PlayerArmour[playerid]);
  3182. if (s_PlayerHealth[playerid] == 0.0) {
  3183. s_PlayerHealth[playerid] = s_PlayerMaxHealth[playerid];
  3184. }
  3185. UpdateHealthBar(playerid);
  3186. }
  3187. switch (GetPlayerState(playerid)) {
  3188. case PLAYER_STATE_ONFOOT,
  3189. PLAYER_STATE_DRIVER,
  3190. PLAYER_STATE_PASSENGER,
  3191. PLAYER_STATE_SPAWNED: {
  3192. SetHealthBarVisible(playerid, true);
  3193. }
  3194. default: {
  3195. SetHealthBarVisible(playerid, false);
  3196. }
  3197. }
  3198. }
  3199. }
  3200. static ScriptExit()
  3201. {
  3202. SetKnifeSync(true);
  3203. #if WC_CUSTOM_VENDING_MACHINES
  3204. DestroyVendingMachines();
  3205. #endif
  3206. for (new playerid = 0; playerid < MAX_PLAYERS; playerid++) {
  3207. #if WC_CUSTOM_VENDING_MACHINES
  3208. if (s_VendingUseTimer[playerid] != -1) {
  3209. KillTimer(s_VendingUseTimer[playerid]);
  3210. s_VendingUseTimer[playerid] = -1;
  3211. }
  3212. #endif
  3213. if (!IsPlayerConnected(playerid)) {
  3214. continue;
  3215. }
  3216. // Put things back the way they were
  3217. SetPlayerTeam(playerid, s_PlayerTeam[playerid]);
  3218. if (PLAYER_STATE_ONFOOT <= GetPlayerState(playerid) <= PLAYER_STATE_PASSENGER) {
  3219. new Float:health = s_PlayerHealth[playerid];
  3220. if (health == 0.0) {
  3221. health = s_PlayerMaxHealth[playerid];
  3222. }
  3223. SetPlayerHealth(playerid, health);
  3224. SetPlayerArmour(playerid, s_PlayerArmour[playerid]);
  3225. }
  3226. SetFakeHealth(playerid, 255);
  3227. SetFakeArmour(playerid, 255);
  3228. FreezeSyncData(playerid, false);
  3229. SetFakeFacingAngle(playerid, _);
  3230. SetHealthBarVisible(playerid, false);
  3231. if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3232. PlayerTextDrawDestroy(playerid, s_HealthBarForeground[playerid]);
  3233. s_InternalPlayerTextDraw[playerid][s_HealthBarForeground[playerid]] = false;
  3234. s_HealthBarForeground[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3235. }
  3236. if (s_DamageFeedGiven[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3237. PlayerTextDrawDestroy(playerid, s_DamageFeedGiven[playerid]);
  3238. s_InternalPlayerTextDraw[playerid][s_DamageFeedGiven[playerid]] = false;
  3239. s_DamageFeedGiven[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3240. }
  3241. if (s_DamageFeedTaken[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3242. PlayerTextDrawDestroy(playerid, s_DamageFeedTaken[playerid]);
  3243. s_InternalPlayerTextDraw[playerid][s_DamageFeedTaken[playerid]] = false;
  3244. s_DamageFeedTaken[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3245. }
  3246. }
  3247. if (s_HealthBarBorder != Text:INVALID_TEXT_DRAW) {
  3248. TextDrawDestroy(s_HealthBarBorder);
  3249. s_InternalTextDraw[s_HealthBarBorder] = false;
  3250. }
  3251. if (s_HealthBarBackground != Text:INVALID_TEXT_DRAW) {
  3252. TextDrawDestroy(s_HealthBarBackground);
  3253. s_InternalTextDraw[s_HealthBarBackground] = false;
  3254. }
  3255. }
  3256. static UpdatePlayerVirtualWorld(playerid)
  3257. {
  3258. new worldid = GetPlayerVirtualWorld(playerid);
  3259. if (worldid == WC_DEATH_WORLD) {
  3260. worldid = s_World[playerid];
  3261. } else if (worldid != s_World[playerid]) {
  3262. s_World[playerid] = worldid;
  3263. }
  3264. SetPlayerVirtualWorld(playerid, worldid);
  3265. }
  3266. static HasSameTeam(playerid, otherid)
  3267. {
  3268. if (otherid < 0 || otherid >= MAX_PLAYERS || playerid < 0 || playerid >= MAX_PLAYERS) {
  3269. return 0;
  3270. }
  3271. if (s_PlayerTeam[playerid] == NO_TEAM || s_PlayerTeam[otherid] == NO_TEAM) {
  3272. return 0;
  3273. }
  3274. return (s_PlayerTeam[playerid] == s_PlayerTeam[otherid]);
  3275. }
  3276. static IsPlayerPaused(playerid)
  3277. {
  3278. return (GetTickCount() - s_LastUpdate[playerid] > 2000);
  3279. }
  3280. static UpdateHealthBar(playerid, bool:force = false)
  3281. {
  3282. if (s_BeingResynced[playerid] || s_ForceClassSelection[playerid]) {
  3283. return;
  3284. }
  3285. new health = floatround(s_PlayerHealth[playerid] / s_PlayerMaxHealth[playerid] * 100.0, floatround_ceil);
  3286. new armour = floatround(s_PlayerArmour[playerid] / s_PlayerMaxArmour[playerid] * 100.0, floatround_ceil);
  3287. // Make the values reflect what the client should see
  3288. if (s_IsDying[playerid]) {
  3289. health = 0;
  3290. armour = 0;
  3291. } else {
  3292. if (health > 100) {
  3293. health = 100;
  3294. }
  3295. if (armour > 100) {
  3296. armour = 100;
  3297. }
  3298. }
  3299. if (force) {
  3300. s_LastSentHealth[playerid] = -1;
  3301. s_LastSentArmour[playerid] = -1;
  3302. } else if (s_HealthBarVisible[playerid] && s_HealthBarForeground[playerid] == PlayerText:INVALID_TEXT_DRAW && !s_IsDying[playerid]) {
  3303. s_LastSentHealth[playerid] = -1;
  3304. } else if (health == s_LastSentHealth[playerid] && armour == s_LastSentArmour[playerid]) {
  3305. return;
  3306. }
  3307. SetFakeHealth(playerid, health);
  3308. SetFakeArmour(playerid, armour);
  3309. UpdateSyncData(playerid);
  3310. if (health != s_LastSentHealth[playerid]) {
  3311. s_LastSentHealth[playerid] = health;
  3312. SetPlayerHealth(playerid, 8000000.0 + float(health));
  3313. if (s_HealthBarVisible[playerid] && !s_IsDying[playerid]) {
  3314. if (s_HealthBarForeground[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  3315. s_HealthBarForeground[playerid] = CreatePlayerTextDraw(
  3316. playerid,
  3317. 551.5 + float(health) * 0.5651,
  3318. 70.25,
  3319. "\1"
  3320. );
  3321. if (s_HealthBarForeground[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  3322. printf("(wc) WARN: Unable to create player healthbar foreground");
  3323. } else {
  3324. s_InternalPlayerTextDraw[playerid][s_HealthBarForeground[playerid]] = true;
  3325. PlayerTextDrawUseBox (playerid, s_HealthBarForeground[playerid], 1);
  3326. PlayerTextDrawLetterSize(playerid, s_HealthBarForeground[playerid], 0.0, 0.2);
  3327. PlayerTextDrawTextSize (playerid, s_HealthBarForeground[playerid], 545.75, 0.0);
  3328. PlayerTextDrawBoxColor (playerid, s_HealthBarForeground[playerid], 0xB51821FF);
  3329. PlayerTextDrawShow(playerid, s_HealthBarForeground[playerid]);
  3330. }
  3331. } else {
  3332. PlayerTextDrawSetPosition(playerid, s_HealthBarForeground[playerid], 551.5 + float(health) * 0.5651, 70.25);
  3333. PlayerTextDrawShow(playerid, s_HealthBarForeground[playerid]);
  3334. }
  3335. } else if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3336. PlayerTextDrawDestroy(playerid, s_HealthBarForeground[playerid]);
  3337. s_InternalPlayerTextDraw[playerid][s_HealthBarForeground[playerid]] = false;
  3338. s_HealthBarForeground[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3339. }
  3340. }
  3341. if (armour != s_LastSentArmour[playerid]) {
  3342. s_LastSentArmour[playerid] = armour;
  3343. SetPlayerArmour(playerid, float(armour));
  3344. }
  3345. }
  3346. static SetHealthBarVisible(playerid, bool:toggle)
  3347. {
  3348. if (s_HealthBarVisible[playerid] == toggle) {
  3349. return;
  3350. }
  3351. s_HealthBarVisible[playerid] = toggle;
  3352. if (toggle) {
  3353. if (s_HealthBarBorder != Text:INVALID_TEXT_DRAW) {
  3354. TextDrawShowForPlayer(playerid, s_HealthBarBorder);
  3355. }
  3356. if (s_HealthBarBackground != Text:INVALID_TEXT_DRAW) {
  3357. TextDrawShowForPlayer(playerid, s_HealthBarBackground);
  3358. }
  3359. UpdateHealthBar(playerid, true);
  3360. } else {
  3361. if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3362. PlayerTextDrawHide(playerid, s_HealthBarForeground[playerid]);
  3363. }
  3364. if (s_HealthBarBorder != Text:INVALID_TEXT_DRAW) {
  3365. TextDrawHideForPlayer(playerid, s_HealthBarBorder);
  3366. }
  3367. if (s_HealthBarBackground != Text:INVALID_TEXT_DRAW) {
  3368. TextDrawHideForPlayer(playerid, s_HealthBarBackground);
  3369. }
  3370. }
  3371. }
  3372. static SpawnPlayerInPlace(playerid) {
  3373. new Float:x, Float:y, Float:z, Float:r;
  3374. GetPlayerPos(playerid, x, y, z);
  3375. GetPlayerFacingAngle(playerid, r);
  3376. SetSpawnInfo(playerid, 0xFE, GetPlayerSkin(playerid), x, y, z, r, 0, 0, 0, 0, 0, 0);
  3377. s_SpawnInfoModified[playerid] = true;
  3378. SpawnPlayer(playerid);
  3379. }
  3380. static PosInFront(playerid, Float:distance, &Float:x, &Float:y, &Float:z)
  3381. {
  3382. new Float:a;
  3383. GetPlayerPos(playerid, x, y, z);
  3384. GetPlayerFacingAngle(playerid, a);
  3385. x += (distance * floatsin(-a, degrees));
  3386. y += (distance * floatcos(-a, degrees));
  3387. }
  3388. static Float:AngleBetweenPoints(Float:x1, Float:y1, Float:x2, Float:y2)
  3389. {
  3390. return -(90.0 - atan2(y1 - y2, x1 - x2));
  3391. }
  3392. static UpdateSyncData(playerid)
  3393. {
  3394. // Currently re-sending onfoot data is only supported
  3395. if (!IsPlayerConnected(playerid) || GetPlayerState(playerid) != PLAYER_STATE_ONFOOT) {
  3396. return;
  3397. }
  3398. for (new i = 0; i < MAX_PLAYERS; i++) {
  3399. if (i != playerid && IsPlayerConnected(i) && IsPlayerStreamedIn(playerid, i)) {
  3400. SendLastSyncData(playerid, i);
  3401. }
  3402. }
  3403. }
  3404. static WasPlayerInVehicle(playerid, time) {
  3405. if (!s_LastVehicleTick[playerid]) {
  3406. return 0;
  3407. }
  3408. if (GetTickCount() - time < s_LastVehicleTick[playerid]) {
  3409. return 1;
  3410. }
  3411. return 0;
  3412. }
  3413. #if WC_CUSTOM_VENDING_MACHINES
  3414. static RemoveDefaultVendingMachines(playerid)
  3415. {
  3416. RemoveBuildingForPlayer(playerid, 955, 0.0, 0.0, 0.0, 20000.0); // CJ_EXT_SPRUNK
  3417. RemoveBuildingForPlayer(playerid, 956, 0.0, 0.0, 0.0, 20000.0); // CJ_EXT_CANDY
  3418. RemoveBuildingForPlayer(playerid, 1209, 0.0, 0.0, 0.0, 20000.0); // vendmach
  3419. RemoveBuildingForPlayer(playerid, 1302, 0.0, 0.0, 0.0, 20000.0); // vendmachfd
  3420. RemoveBuildingForPlayer(playerid, 1775, 0.0, 0.0, 0.0, 20000.0); // CJ_SPRUNK1
  3421. RemoveBuildingForPlayer(playerid, 1776, 0.0, 0.0, 0.0, 20000.0); // CJ_CANDYVENDOR
  3422. RemoveBuildingForPlayer(playerid, 1977, 0.0, 0.0, 0.0, 20000.0); // vendin3
  3423. // Make sure they're all gone..
  3424. for (new i = 0; i < sizeof(sc_VendingMachines); i++) {
  3425. RemoveBuildingForPlayer(
  3426. playerid,
  3427. sc_VendingMachines[i][e_Model],
  3428. sc_VendingMachines[i][e_PosX],
  3429. sc_VendingMachines[i][e_PosY],
  3430. sc_VendingMachines[i][e_PosZ],
  3431. 1.0
  3432. );
  3433. }
  3434. }
  3435. static CreateVendingMachines()
  3436. {
  3437. DestroyVendingMachines();
  3438. for (new i = 0; i < sizeof(sc_VendingMachines); i++) {
  3439. #if WC_USE_STREAMER
  3440. s_VendingMachineObject[i] = CreateDynamicObject(
  3441. sc_VendingMachines[i][e_Model],
  3442. sc_VendingMachines[i][e_PosX],
  3443. sc_VendingMachines[i][e_PosY],
  3444. sc_VendingMachines[i][e_PosZ],
  3445. sc_VendingMachines[i][e_RotX],
  3446. sc_VendingMachines[i][e_RotY],
  3447. sc_VendingMachines[i][e_RotZ],
  3448. .interiorid = sc_VendingMachines[i][e_Interior]
  3449. );
  3450. #else
  3451. s_VendingMachineObject[i] = CreateObject(
  3452. sc_VendingMachines[i][e_Model],
  3453. sc_VendingMachines[i][e_PosX],
  3454. sc_VendingMachines[i][e_PosY],
  3455. sc_VendingMachines[i][e_PosZ],
  3456. sc_VendingMachines[i][e_RotX],
  3457. sc_VendingMachines[i][e_RotY],
  3458. sc_VendingMachines[i][e_RotZ]
  3459. );
  3460. #endif
  3461. }
  3462. }
  3463. static DestroyVendingMachines()
  3464. {
  3465. for (new i = 0; i < sizeof(s_VendingMachineObject); i++) {
  3466. if (s_VendingMachineObject[i] != -1) {
  3467. #if WC_USE_STREAMER
  3468. DestroyDynamicObject(s_VendingMachineObject[i]);
  3469. #else
  3470. DestroyObject(s_VendingMachineObject[i]);
  3471. #endif
  3472. s_VendingMachineObject[i] = -1;
  3473. }
  3474. }
  3475. }
  3476. #endif
  3477. forward WC_DeathSkipEnd(playerid);
  3478. public WC_DeathSkipEnd(playerid)
  3479. {
  3480. TogglePlayerControllable(playerid, true);
  3481. ResetPlayerWeapons(playerid);
  3482. for (new i = 0; i < 13; i++) {
  3483. if (s_SyncData[playerid][e_WeaponId][i]) {
  3484. GivePlayerWeapon(playerid, s_SyncData[playerid][e_WeaponId][i], s_SyncData[playerid][e_WeaponAmmo][i]);
  3485. }
  3486. }
  3487. GivePlayerWeapon(playerid, s_SyncData[playerid][e_Weapon], 0);
  3488. SetPlayerSpecialAction(playerid, 0);
  3489. }
  3490. forward WC_SpawnForStreamedIn(playerid);
  3491. public WC_SpawnForStreamedIn(playerid)
  3492. {
  3493. if (!IsPlayerConnected(playerid)) {
  3494. return;
  3495. }
  3496. SpawnPlayerForWorld(playerid);
  3497. for (new i = 0; i < MAX_PLAYERS; i++) {
  3498. if (i != playerid && IsPlayerConnected(i) && IsPlayerStreamedIn(playerid, i)) {
  3499. SendLastSyncData(playerid, i);
  3500. ClearAnimationsForPlayer(playerid, i);
  3501. }
  3502. }
  3503. }
  3504. forward WC_SetSpawnForStreamedIn(playerid);
  3505. public WC_SetSpawnForStreamedIn(playerid)
  3506. {
  3507. s_SpawnForStreamedIn[playerid] = true;
  3508. }
  3509. forward WC_SpawnPlayerInPlace(playerid);
  3510. public WC_SpawnPlayerInPlace(playerid)
  3511. {
  3512. SpawnPlayerInPlace(playerid);
  3513. }
  3514. static ProcessDamage(&playerid, &issuerid, &Float:amount, &weaponid, &bodypart, &Float:bullets)
  3515. {
  3516. if (amount < 0.0) {
  3517. return WC_INVALID_DAMAGE;
  3518. }
  3519. // Adjust invalid amounts caused by an animation bug
  3520. switch (amount) {
  3521. case 3.63000011444091796875,
  3522. 5.940000057220458984375,
  3523. 5.610000133514404296875: {
  3524. amount = 2.6400001049041748046875;
  3525. }
  3526. case 3.30000019073486328125: {
  3527. if (weaponid != WEAPON_SHOTGUN && weaponid != WEAPON_SAWEDOFF) {
  3528. amount = 2.6400001049041748046875;
  3529. }
  3530. }
  3531. case 4.950000286102294921875: {
  3532. if (IsMeleeWeapon(weaponid)) {
  3533. amount = 2.6400001049041748046875;
  3534. }
  3535. }
  3536. case 6.270000457763671875,
  3537. 6.93000030517578125,
  3538. 7.2600002288818359375,
  3539. 7.9200000762939453125,
  3540. 8.5799999237060546875,
  3541. 9.24000072479248046875,
  3542. 11.88000011444091796875,
  3543. 11.22000026702880859375: {
  3544. amount = 2.6400001049041748046875;
  3545. }
  3546. case 9.90000057220458984375: {
  3547. switch (weaponid) {
  3548. case WEAPON_VEHICLE, WEAPON_VEHICLE_M4, WEAPON_AK47,
  3549. WEAPON_M4, WEAPON_SHOTGUN, WEAPON_SAWEDOFF, WEAPON_SHOTGSPA: {}
  3550. default: {
  3551. amount = 6.6000003814697265625;
  3552. }
  3553. }
  3554. }
  3555. }
  3556. // Car parking
  3557. if (weaponid == WEAPON_HELIBLADES && _:amount != _:330.0) {
  3558. weaponid = WEAPON_CARPARK;
  3559. }
  3560. // Finish processing drown/fire/carpark quickly, since they are sent at very high rates
  3561. if (IsHighRateWeapon(weaponid)) {
  3562. // Apply reasonable bounds
  3563. if (weaponid == WEAPON_DROWN) {
  3564. if (amount > 10.0) amount = 10.0;
  3565. } else if (amount > 1.0) {
  3566. amount = 1.0;
  3567. }
  3568. // Adjust the damage if the multiplier is not 1.0
  3569. if (_:s_WeaponDamage[weaponid] != _:1.0) {
  3570. amount *= s_WeaponDamage[weaponid];
  3571. }
  3572. // Make sure the distance and issuer is valid; carpark can be self-inflicted so it doesn't require an issuer
  3573. if (weaponid == WEAPON_SPRAYCAN || weaponid == WEAPON_FIREEXTINGUISHER || (weaponid == WEAPON_CARPARK && issuerid != INVALID_PLAYER_ID)) {
  3574. if (issuerid == INVALID_PLAYER_ID) {
  3575. return WC_NO_ISSUER;
  3576. }
  3577. new Float:x, Float:y, Float:z, Float:dist;
  3578. GetPlayerPos(issuerid, x, y, z);
  3579. dist = GetPlayerDistanceFromPoint(playerid, x, y, z);
  3580. if (dist > 15.0) {
  3581. AddRejectedHit(issuerid, playerid, HIT_TOO_FAR_FROM_ORIGIN, weaponid, _:dist);
  3582. return WC_INVALID_DISTANCE;
  3583. }
  3584. }
  3585. return WC_NO_ERROR;
  3586. }
  3587. // Bullet or melee damage must have an issuerid, otherwise something has gone wrong (e.g. sniper bug)
  3588. if (issuerid == INVALID_PLAYER_ID && (IsBulletWeapon(weaponid) || IsMeleeWeapon(weaponid))) {
  3589. return WC_NO_ISSUER;
  3590. }
  3591. // Punching with a parachute
  3592. if (weaponid == WEAPON_PARACHUTE) {
  3593. weaponid = WEAPON_UNARMED;
  3594. }
  3595. // Collision damage should never be above 165
  3596. if (weaponid == WEAPON_COLLISION) {
  3597. if (amount > 165.0) {
  3598. amount = 1.0;
  3599. } else {
  3600. amount /= 165.0;
  3601. }
  3602. }
  3603. if (weaponid == WEAPON_EXPLOSION) {
  3604. // Explosions do at most 82.5 damage. This will later be multipled by the damage value
  3605. amount /= 82.5;
  3606. // Figure out what caused the explosion
  3607. if (issuerid != INVALID_PLAYER_ID && s_LastExplosive[issuerid]) {
  3608. weaponid = s_LastExplosive[issuerid];
  3609. }
  3610. }
  3611. // Check for pistol whip
  3612. switch (weaponid) {
  3613. case WEAPON_COLT45 .. WEAPON_SNIPER,
  3614. WEAPON_MINIGUN, WEAPON_SPRAYCAN, WEAPON_FIREEXTINGUISHER: {
  3615. // A pistol whip inflicts 2.64 damage
  3616. if (_:amount == _:2.6400001049041748046875) {
  3617. // Save the weapon in the bodypart argument (it's always BODY_PART_TORSO)
  3618. bodypart = weaponid;
  3619. weaponid = WEAPON_PISTOLWHIP;
  3620. }
  3621. }
  3622. }
  3623. new melee = IsMeleeWeapon(weaponid);
  3624. // Can't punch from a vehicle
  3625. if (melee && IsPlayerInAnyVehicle(issuerid)) {
  3626. return WC_INVALID_DAMAGE;
  3627. }
  3628. if (weaponid != WEAPON_PISTOLWHIP) {
  3629. switch (amount) {
  3630. case 1.32000005245208740234375,
  3631. 1.650000095367431640625,
  3632. 1.980000019073486328125,
  3633. 2.3100001811981201171875,
  3634. 2.6400001049041748046875,
  3635. 2.9700000286102294921875,
  3636. 3.96000003814697265625,
  3637. 4.28999996185302734375,
  3638. 4.62000036239624023437,
  3639. 5.280000209808349609375: {
  3640. // Damage is most likely from punching and switching weapon quickly
  3641. if (!melee) {
  3642. DebugMessage(issuerid, "weapon changed from %d to melee (punch & swap)", weaponid);
  3643. weaponid = WEAPON_UNARMED;
  3644. melee = true;
  3645. }
  3646. }
  3647. case 6.6000003814697265625: {
  3648. if (!melee) {
  3649. switch (weaponid) {
  3650. case WEAPON_UZI, WEAPON_TEC9, WEAPON_CHAINSAW,
  3651. WEAPON_SHOTGUN, WEAPON_SAWEDOFF: {}
  3652. default: {
  3653. DebugMessage(issuerid, "weapon changed from %d to melee (punch & swap)", weaponid);
  3654. weaponid = WEAPON_UNARMED;
  3655. melee = true;
  3656. }
  3657. }
  3658. }
  3659. }
  3660. case 54.12000274658203125: {
  3661. if (!melee) {
  3662. DebugMessage(issuerid, "weapon changed from %d to melee (punch & swap)", weaponid);
  3663. melee = true;
  3664. weaponid = WEAPON_UNARMED;
  3665. amount = 1.32000005245208740234375;
  3666. }
  3667. // Be extra sure about this one
  3668. if (GetPlayerFightingStyle(issuerid) != FIGHT_STYLE_KNEEHEAD) {
  3669. return WC_INVALID_DAMAGE;
  3670. }
  3671. }
  3672. // Melee damage has been tampered with
  3673. default: {
  3674. if (melee) {
  3675. return WC_INVALID_DAMAGE;
  3676. }
  3677. }
  3678. }
  3679. }
  3680. if (melee) {
  3681. new Float:x, Float:y, Float:z, Float:dist;
  3682. GetPlayerPos(issuerid, x, y, z);
  3683. dist = GetPlayerDistanceFromPoint(playerid, x, y, z);
  3684. if (dist > 15.0) {
  3685. AddRejectedHit(issuerid, playerid, HIT_TOO_FAR_FROM_ORIGIN, weaponid, _:dist);
  3686. return WC_INVALID_DISTANCE;
  3687. }
  3688. }
  3689. switch (weaponid) {
  3690. // The spas shotguns shoot 8 bullets, each inflicting 4.95 damage
  3691. case WEAPON_SHOTGSPA: {
  3692. bullets = amount / 4.950000286102294921875;
  3693. if (8.0 - bullets < -0.05) {
  3694. return WC_INVALID_DAMAGE;
  3695. }
  3696. }
  3697. // Shotguns and sawed-off shotguns shoot 15 bullets, each inflicting 3.3 damage
  3698. case WEAPON_SHOTGUN, WEAPON_SAWEDOFF: {
  3699. bullets = amount / 3.30000019073486328125;
  3700. if (15.0 - bullets < -0.05) {
  3701. return WC_INVALID_DAMAGE;
  3702. }
  3703. }
  3704. }
  3705. if (_:bullets) {
  3706. new Float:f = floatfract(bullets);
  3707. // The damage for each bullet has been tampered with
  3708. if (f > 0.01 && f < 0.99) {
  3709. return WC_INVALID_DAMAGE;
  3710. }
  3711. // Divide the damage amount by the number of bullets
  3712. amount /= bullets;
  3713. }
  3714. // Check chainsaw damage
  3715. if (weaponid == WEAPON_CHAINSAW) {
  3716. switch (amount) {
  3717. case 6.6000003814697265625,
  3718. 13.5300006866455078125,
  3719. 16.1700000762939453125,
  3720. 26.40000152587890625,
  3721. 27.060001373291015625: {}
  3722. default: {
  3723. return WC_INVALID_DAMAGE;
  3724. }
  3725. }
  3726. }
  3727. // Check deagle damage
  3728. if (weaponid == WEAPON_DEAGLE) {
  3729. switch (amount) {
  3730. case 46.200000762939453125,
  3731. 23.1000003814697265625: {}
  3732. default: {
  3733. return WC_INVALID_DAMAGE;
  3734. }
  3735. }
  3736. }
  3737. // Check gun damage
  3738. new Float:def_amount = 0.0;
  3739. switch (weaponid) {
  3740. case WEAPON_COLT45,
  3741. WEAPON_MP5: def_amount = 8.25;
  3742. case WEAPON_SILENCED: def_amount = 13.200000762939453125;
  3743. case WEAPON_UZI,
  3744. WEAPON_TEC9: def_amount = 6.6000003814697265625;
  3745. case WEAPON_AK47,
  3746. WEAPON_M4,
  3747. WEAPON_VEHICLE_M4: def_amount = 9.90000057220458984375;
  3748. case WEAPON_RIFLE: def_amount = 24.7500019073486328125;
  3749. case WEAPON_SNIPER: def_amount = 41.25;
  3750. case WEAPON_MINIGUN,
  3751. WEAPON_VEHICLE_MINIGUN: def_amount = 46.200000762939453125;
  3752. case WEAPON_VEHICLE: def_amount = 9.90000057220458984375;
  3753. }
  3754. if (_:def_amount && _:def_amount != _:amount) {
  3755. return WC_INVALID_DAMAGE;
  3756. }
  3757. // Adjust the damage
  3758. switch (s_DamageType[weaponid]) {
  3759. case DAMAGE_TYPE_MULTIPLIER: {
  3760. if (_:s_WeaponDamage[weaponid] != _:1.0) {
  3761. amount *= s_WeaponDamage[weaponid];
  3762. }
  3763. }
  3764. case DAMAGE_TYPE_STATIC: {
  3765. if (_:bullets) {
  3766. amount = s_WeaponDamage[weaponid] * bullets;
  3767. } else {
  3768. amount = s_WeaponDamage[weaponid];
  3769. }
  3770. }
  3771. case DAMAGE_TYPE_RANGE,
  3772. DAMAGE_TYPE_RANGE_MULTIPLIER: {
  3773. new Float:length = s_LastShot[issuerid][e_Length];
  3774. for (new i = s_DamageRangeSteps[weaponid] - 1; i >= 0; i--) {
  3775. if (i == 0 || length >= s_DamageRangeRanges[weaponid][i]) {
  3776. if (s_DamageType[weaponid] == DAMAGE_TYPE_RANGE_MULTIPLIER) {
  3777. if (_:s_DamageRangeValues[weaponid][i] != _:1.0) {
  3778. amount *= s_DamageRangeValues[weaponid][i];
  3779. }
  3780. } else {
  3781. if (_:bullets) {
  3782. amount = s_DamageRangeValues[weaponid][i] * bullets;
  3783. } else {
  3784. amount = s_DamageRangeValues[weaponid][i];
  3785. }
  3786. }
  3787. break;
  3788. }
  3789. }
  3790. }
  3791. }
  3792. return WC_NO_ERROR;
  3793. }
  3794. static InflictDamage(playerid, Float:amount, issuerid = INVALID_PLAYER_ID, weaponid = WEAPON_UNKNOWN, bodypart = BODY_PART_UNKNOWN, bool:ignore_armour = false)
  3795. {
  3796. if (!IsPlayerSpawned(playerid) || amount < 0.0) {
  3797. return;
  3798. }
  3799. if (!OnPlayerDamage(playerid, amount, issuerid, weaponid, bodypart)) {
  3800. UpdateHealthBar(playerid);
  3801. if (weaponid < 0 || weaponid > WEAPON_UNKNOWN) {
  3802. weaponid = WEAPON_UNKNOWN;
  3803. }
  3804. #if WC_DEBUG
  3805. new Float:length = 0.0;
  3806. if (issuerid != INVALID_PLAYER_ID) {
  3807. if (IsBulletWeapon(weaponid)) {
  3808. length = s_LastShot[issuerid][e_Length];
  3809. }
  3810. }
  3811. if (!IsHighRateWeapon(weaponid)) {
  3812. DebugMessageAll("!InflictDamage(%d, %.4f, %d, %d, %d) length = %f", playerid, amount, issuerid, weaponid, bodypart, length);
  3813. }
  3814. #endif
  3815. return;
  3816. }
  3817. if (weaponid < 0 || weaponid > WEAPON_UNKNOWN) {
  3818. weaponid = WEAPON_UNKNOWN;
  3819. }
  3820. #if WC_DEBUG
  3821. new Float:length = 0.0;
  3822. if (issuerid != INVALID_PLAYER_ID) {
  3823. if (IsBulletWeapon(weaponid)) {
  3824. length = s_LastShot[issuerid][e_Length];
  3825. }
  3826. }
  3827. if (!IsHighRateWeapon(weaponid)) {
  3828. DebugMessageAll("InflictDamage(%d, %.4f, %d, %d, %d) length = %f", playerid, amount, issuerid, weaponid, bodypart, length);
  3829. }
  3830. #endif
  3831. if (!ignore_armour && weaponid != WEAPON_COLLISION && weaponid != WEAPON_DROWN && weaponid != WEAPON_CARPARK && (!s_DamageArmourToggle[0] || (s_DamageArmour[weaponid][0] && (!s_DamageArmourToggle[1] || ((s_DamageArmour[weaponid][1] && bodypart == 3) || (!s_DamageArmour[weaponid][1])))))) {
  3832. if (amount <= 0.0) {
  3833. amount = s_PlayerHealth[playerid] + s_PlayerArmour[playerid];
  3834. }
  3835. s_PlayerArmour[playerid] -= amount;
  3836. } else {
  3837. if (amount <= 0.0) {
  3838. amount = s_PlayerHealth[playerid];
  3839. }
  3840. s_PlayerHealth[playerid] -= amount;
  3841. }
  3842. if (s_PlayerArmour[playerid] < 0.0) {
  3843. s_DamageDoneArmour[playerid] = amount + s_PlayerArmour[playerid];
  3844. s_DamageDoneHealth[playerid] = -s_PlayerArmour[playerid];
  3845. s_PlayerHealth[playerid] += s_PlayerArmour[playerid];
  3846. s_PlayerArmour[playerid] = 0.0;
  3847. } else {
  3848. s_DamageDoneArmour[playerid] = amount;
  3849. s_DamageDoneHealth[playerid] = 0.0;
  3850. }
  3851. if (s_PlayerHealth[playerid] <= 0.0) {
  3852. amount += s_PlayerHealth[playerid];
  3853. s_DamageDoneHealth[playerid] += s_PlayerHealth[playerid];
  3854. s_PlayerHealth[playerid] = 0.0;
  3855. }
  3856. OnPlayerDamageDone(playerid, amount, issuerid, weaponid, bodypart);
  3857. if (s_PlayerHealth[playerid] <= 0.0005) {
  3858. new vehicleid = GetPlayerVehicleID(playerid);
  3859. if (vehicleid) {
  3860. new modelid = GetVehicleModel(vehicleid);
  3861. new seat = GetPlayerVehicleSeat(playerid);
  3862. TogglePlayerControllable(playerid, false);
  3863. switch (modelid) {
  3864. case 509, 481, 510, 462, 448, 581, 522,
  3865. 461, 521, 523, 463, 586, 468, 471: {
  3866. new Float:vx, Float:vy, Float:vz;
  3867. GetVehicleVelocity(vehicleid, vx, vy, vz);
  3868. if (vx*vx + vy*vy + vz*vz >= 0.4) {
  3869. PlayerDeath(playerid, "PED", "BIKE_fallR", 0);
  3870. } else {
  3871. PlayerDeath(playerid, "PED", "BIKE_fall_off", 0);
  3872. }
  3873. }
  3874. default: {
  3875. if (seat & 1) {
  3876. PlayerDeath(playerid, "PED", "CAR_dead_LHS");
  3877. } else {
  3878. PlayerDeath(playerid, "PED", "CAR_dead_RHS");
  3879. }
  3880. }
  3881. }
  3882. } else if (GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK) {
  3883. PlayerDeath(playerid, "PED", "KO_skid_back", .freeze_sync = false);
  3884. } else {
  3885. if (gettime() - s_LastVehicleEnterTime[playerid] < 10) {
  3886. TogglePlayerControllable(playerid, false);
  3887. }
  3888. new anim = GetPlayerAnimationIndex(playerid);
  3889. if (anim == 1250 || (1538 <= anim <= 1544) || weaponid == WEAPON_DROWN) {
  3890. // In water
  3891. PlayerDeath(playerid, "PED", "Drown");
  3892. } else if (1195 <= anim <= 1198) {
  3893. // Jumping animation
  3894. PlayerDeath(playerid, "PED", "KO_skid_back");
  3895. } else if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  3896. if (IsPlayerBehindPlayer(issuerid, playerid)) {
  3897. MakePlayerFacePlayer(playerid, issuerid, true);
  3898. PlayerDeath(playerid, "PED", "KO_shot_front");
  3899. } else {
  3900. MakePlayerFacePlayer(playerid, issuerid);
  3901. PlayerDeath(playerid, "PED", "BIKE_fall_off");
  3902. }
  3903. } else if (WEAPON_RIFLE <= weaponid <= WEAPON_SNIPER) {
  3904. if (bodypart == 9) {
  3905. PlayerDeath(playerid, "PED", "KO_shot_face");
  3906. } else if (IsPlayerBehindPlayer(issuerid, playerid)) {
  3907. PlayerDeath(playerid, "PED", "KO_shot_front");
  3908. } else {
  3909. PlayerDeath(playerid, "PED", "KO_shot_stom");
  3910. }
  3911. } else if (IsBulletWeapon(weaponid)) {
  3912. if (bodypart == 9) {
  3913. PlayerDeath(playerid, "PED", "KO_shot_face");
  3914. } else {
  3915. PlayerDeath(playerid, "PED", "KO_shot_front");
  3916. }
  3917. } else if (weaponid == WEAPON_PISTOLWHIP) {
  3918. PlayerDeath(playerid, "PED", "KO_spin_R");
  3919. } else if (IsMeleeWeapon(weaponid) || weaponid == WEAPON_CARPARK) {
  3920. PlayerDeath(playerid, "PED", "KO_skid_front");
  3921. } else if (weaponid == WEAPON_SPRAYCAN || weaponid == WEAPON_FIREEXTINGUISHER) {
  3922. PlayerDeath(playerid, "KNIFE", "KILL_Knife_Ped_Die");
  3923. } else {
  3924. PlayerDeath(playerid, "PED", "KO_skid_back");
  3925. }
  3926. }
  3927. #if defined WC_OnPlayerDeath
  3928. if (s_CbugAllowed) {
  3929. WC_OnPlayerDeath(playerid, issuerid, weaponid);
  3930. } else {
  3931. s_DelayedDeathTimer[playerid] = SetTimerEx(#WC_DelayedDeath, 1200, false, "iii", playerid, issuerid, weaponid);
  3932. }
  3933. #endif
  3934. }
  3935. UpdateHealthBar(playerid);
  3936. }
  3937. forward WC_DelayedDeath(playerid, issuerid, reason);
  3938. public WC_DelayedDeath(playerid, issuerid, reason) {
  3939. s_DelayedDeathTimer[playerid] = -1;
  3940. #if defined WC_OnPlayerDeath
  3941. WC_OnPlayerDeath(playerid, issuerid, reason);
  3942. #endif
  3943. }
  3944. static PlayerDeath(playerid, animlib[32], animname[32], anim_lock = 0, respawn_time = -1, bool:freeze_sync = true, anim_freeze = 1)
  3945. {
  3946. s_PlayerHealth[playerid] = 0.0;
  3947. s_PlayerArmour[playerid] = 0.0;
  3948. s_IsDying[playerid] = true;
  3949. new action = GetPlayerSpecialAction(playerid);
  3950. if (action && action != SPECIAL_ACTION_DUCK) {
  3951. if (action == SPECIAL_ACTION_USEJETPACK) {
  3952. ClearAnimations(playerid);
  3953. }
  3954. SetPlayerSpecialAction(playerid, SPECIAL_ACTION_NONE);
  3955. if (action == SPECIAL_ACTION_USEJETPACK) {
  3956. new Float:vx, Float:vy, Float:vz;
  3957. GetPlayerVelocity(playerid, vx, vy, vz);
  3958. SetPlayerVelocity(playerid, vx, vy, vz);
  3959. }
  3960. }
  3961. OnPlayerPrepareDeath(playerid, animlib, animname, anim_lock, respawn_time);
  3962. UpdateHealthBar(playerid);
  3963. FreezeSyncData(playerid, freeze_sync);
  3964. if (respawn_time == -1) {
  3965. respawn_time = s_RespawnTime;
  3966. }
  3967. if (animlib[0] && animname[0]) {
  3968. ApplyAnimation(playerid, animlib, animname, 4.1, 0, anim_lock, anim_lock, anim_freeze, 0, 1);
  3969. }
  3970. if (s_DeathTimer[playerid] != -1) {
  3971. KillTimer(s_DeathTimer[playerid]);
  3972. }
  3973. s_DeathTimer[playerid] = SetTimerEx("WC_PlayerDeathRespawn", respawn_time, false, "i", playerid);
  3974. if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3975. PlayerTextDrawHide(playerid, s_HealthBarForeground[playerid]);
  3976. }
  3977. #if defined WC_OnPlayerLeaveCheckpoint
  3978. if (IsPlayerInCheckpoint(playerid)) {
  3979. WC_OnPlayerLeaveCheckpoint(playerid);
  3980. }
  3981. #endif
  3982. }
  3983. public OnPlayerPrepareDeath(playerid, animlib[32], animname[32], &anim_lock, &respawn_time)
  3984. {
  3985. #if defined WC_OnPlayerPrepareDeath
  3986. WC_OnPlayerPrepareDeath(playerid, animlib, animname, anim_lock, respawn_time);
  3987. #endif
  3988. }
  3989. public OnRejectedHit(playerid, hit[E_REJECTED_HIT])
  3990. {
  3991. #if WC_DEBUG
  3992. new output[256];
  3993. new reason = hit[e_Reason];
  3994. new i1 = hit[e_Info1];
  3995. new i2 = hit[e_Info2];
  3996. new i3 = hit[e_Info3];
  3997. new weapon = hit[e_Weapon];
  3998. new weapon_name[32];
  3999. WC_GetWeaponName(weapon, weapon_name);
  4000. format(output, sizeof(output), "(%s -> %s) %s", weapon_name, hit[e_Name], g_HitRejectReasons[reason]);
  4001. format(output, sizeof(output), output, i1, i2, i3);
  4002. DebugMessageRed(playerid, "Rejected hit: %s", output);
  4003. #endif
  4004. #if defined WC_OnRejectedHit
  4005. WC_OnRejectedHit(playerid, hit);
  4006. #endif
  4007. }
  4008. public OnPlayerDeathFinished(playerid, bool:cancelable)
  4009. {
  4010. if (s_PlayerHealth[playerid] == 0.0) {
  4011. s_PlayerHealth[playerid] = s_PlayerMaxHealth[playerid];
  4012. }
  4013. if (s_DeathTimer[playerid] != -1) {
  4014. KillTimer(s_DeathTimer[playerid]);
  4015. s_DeathTimer[playerid] = -1;
  4016. }
  4017. #if defined WC_OnPlayerDeathFinished
  4018. new retval = WC_OnPlayerDeathFinished(playerid, cancelable);
  4019. if (!retval && cancelable) {
  4020. return 0;
  4021. }
  4022. #endif
  4023. ResetPlayerWeapons(playerid);
  4024. return 1;
  4025. }
  4026. #if WC_CUSTOM_VENDING_MACHINES
  4027. public OnPlayerUseVendingMachine(playerid, &Float:health_given) {
  4028. #if defined WC_OnPlayerUseVendingMachine
  4029. return WC_OnPlayerUseVendingMachine(playerid, health_given);
  4030. #else
  4031. if (GetPlayerMoney(playerid) > 0) {
  4032. GivePlayerMoney(playerid, -1);
  4033. return 1;
  4034. } else {
  4035. return 0;
  4036. }
  4037. #endif
  4038. }
  4039. forward WC_VendingMachineUsed(playerid, Float:health_given);
  4040. public WC_VendingMachineUsed(playerid, Float:health_given)
  4041. {
  4042. s_VendingUseTimer[playerid] = -1;
  4043. if (GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && !s_IsDying[playerid]) {
  4044. new Float:health = s_PlayerHealth[playerid];
  4045. health += health_given;
  4046. if (health > s_PlayerMaxHealth[playerid]) {
  4047. health = s_PlayerMaxHealth[playerid];
  4048. }
  4049. WC_SetPlayerHealth(playerid, health);
  4050. }
  4051. }
  4052. #endif
  4053. forward WC_DamageFeedUpdate(playerid);
  4054. public WC_DamageFeedUpdate(playerid)
  4055. {
  4056. s_DamageFeedTimer[playerid] = -1;
  4057. if (IsPlayerConnected(playerid) && IsDamageFeedActive(playerid)) {
  4058. DamageFeedUpdate(playerid, true);
  4059. }
  4060. }
  4061. static DamageFeedUpdate(playerid, bool:modified = false)
  4062. {
  4063. if (!IsDamageFeedActive(playerid)) {
  4064. if (s_DamageFeedGiven[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  4065. PlayerTextDrawDestroy(playerid, s_DamageFeedGiven[playerid]);
  4066. s_InternalPlayerTextDraw[playerid][s_DamageFeedGiven[playerid]] = false;
  4067. s_DamageFeedGiven[playerid] = PlayerText:INVALID_TEXT_DRAW;
  4068. }
  4069. if (s_DamageFeedTaken[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  4070. PlayerTextDrawDestroy(playerid, s_DamageFeedTaken[playerid]);
  4071. s_InternalPlayerTextDraw[playerid][s_DamageFeedTaken[playerid]] = false;
  4072. s_DamageFeedTaken[playerid] = PlayerText:INVALID_TEXT_DRAW;
  4073. }
  4074. return;
  4075. }
  4076. if (s_DamageFeedGiven[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4077. new PlayerText:td = CreatePlayerTextDraw(playerid, 200.0, 365.0, "_");
  4078. if (td == PlayerText:INVALID_TEXT_DRAW) {
  4079. printf("(wc) WARN: Unable to create damage feed textdraw");
  4080. } else {
  4081. s_InternalPlayerTextDraw[playerid][td] = true;
  4082. PlayerTextDrawLetterSize(playerid, td, 0.2, 0.9);
  4083. PlayerTextDrawColor(playerid, td, 0x30FF50FF);
  4084. PlayerTextDrawFont(playerid, td, 1);
  4085. PlayerTextDrawSetShadow(playerid, td, 0);
  4086. PlayerTextDrawAlignment(playerid, td, 2);
  4087. PlayerTextDrawSetOutline(playerid, td, 1);
  4088. PlayerTextDrawBackgroundColor(playerid, td, 0x0000001A);
  4089. s_DamageFeedGiven[playerid] = td;
  4090. }
  4091. }
  4092. if (s_DamageFeedTaken[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4093. new PlayerText:td = CreatePlayerTextDraw(playerid, 440.0, 365.0, "_");
  4094. if (td == PlayerText:INVALID_TEXT_DRAW) {
  4095. printf("(wc) WARN: Unable to create damage feed textdraw");
  4096. } else {
  4097. s_InternalPlayerTextDraw[playerid][td] = true;
  4098. PlayerTextDrawLetterSize(playerid, td, 0.2, 0.9);
  4099. PlayerTextDrawColor(playerid, td, 0x33CCFFFF);
  4100. PlayerTextDrawFont(playerid, td, 1);
  4101. PlayerTextDrawSetShadow(playerid, td, 0);
  4102. PlayerTextDrawAlignment(playerid, td, 2);
  4103. PlayerTextDrawSetOutline(playerid, td, 1);
  4104. PlayerTextDrawBackgroundColor(playerid, td, 0x0000001A);
  4105. s_DamageFeedTaken[playerid] = td;
  4106. }
  4107. }
  4108. new tick = GetTickCount();
  4109. if (tick == 0) tick = 1;
  4110. new lowest_tick = tick + 1;
  4111. for (new i = 0; i < sizeof(s_DamageFeedHitsGiven[]) - 1; i++) {
  4112. if (!s_DamageFeedHitsGiven[playerid][i][e_Tick]) {
  4113. break;
  4114. }
  4115. if (tick - s_DamageFeedHitsGiven[playerid][i][e_Tick] >= s_DamageFeedHideDelay) {
  4116. modified = true;
  4117. for (new j = i; j < sizeof(s_DamageFeedHitsGiven[]) - 1; j++) {
  4118. s_DamageFeedHitsGiven[playerid][j][e_Tick] = 0;
  4119. }
  4120. break;
  4121. }
  4122. if (s_DamageFeedHitsGiven[playerid][i][e_Tick] < lowest_tick) {
  4123. lowest_tick = s_DamageFeedHitsGiven[playerid][i][e_Tick];
  4124. }
  4125. }
  4126. for (new i = 0; i < sizeof(s_DamageFeedHitsTaken[]) - 1; i++) {
  4127. if (!s_DamageFeedHitsTaken[playerid][i][e_Tick]) {
  4128. break;
  4129. }
  4130. if (tick - s_DamageFeedHitsTaken[playerid][i][e_Tick] >= s_DamageFeedHideDelay) {
  4131. modified = true;
  4132. for (new j = i; j < sizeof(s_DamageFeedHitsTaken[]) - 1; j++) {
  4133. s_DamageFeedHitsTaken[playerid][j][e_Tick] = 0;
  4134. }
  4135. break;
  4136. }
  4137. if (s_DamageFeedHitsTaken[playerid][i][e_Tick] < lowest_tick) {
  4138. lowest_tick = s_DamageFeedHitsTaken[playerid][i][e_Tick];
  4139. }
  4140. }
  4141. if (s_DamageFeedTimer[playerid] != -1) {
  4142. KillTimer(s_DamageFeedTimer[playerid]);
  4143. }
  4144. if (tick - s_DamageFeedLastUpdate[playerid] < s_DamageFeedMaxUpdateRate && modified) {
  4145. s_DamageFeedTimer[playerid] = SetTimerEx("WC_DamageFeedUpdate", s_DamageFeedMaxUpdateRate - (tick - s_DamageFeedLastUpdate[playerid]), false, "i", playerid);
  4146. } else {
  4147. if (lowest_tick == tick + 1) {
  4148. s_DamageFeedTimer[playerid] = -1;
  4149. modified = true;
  4150. } else {
  4151. s_DamageFeedTimer[playerid] = SetTimerEx("WC_DamageFeedUpdate", s_DamageFeedHideDelay - (tick - lowest_tick) + 10, false, "i", playerid);
  4152. }
  4153. if (modified) {
  4154. DamageFeedUpdateText(playerid);
  4155. s_DamageFeedLastUpdate[playerid] = tick;
  4156. }
  4157. }
  4158. }
  4159. static DamageFeedUpdateText(playerid)
  4160. {
  4161. new buf[64 * WC_FEED_HEIGHT] = "";
  4162. for (new i = 0; i < sizeof(s_DamageFeedHitsGiven[]) - 1; i++) {
  4163. if (!s_DamageFeedHitsGiven[playerid][i][e_Tick]) {
  4164. break;
  4165. }
  4166. new weapon[32];
  4167. if (s_DamageFeedHitsGiven[playerid][i][e_Weapon] == -1) {
  4168. weapon = "Multiple";
  4169. } else {
  4170. WC_GetWeaponName(s_DamageFeedHitsGiven[playerid][i][e_Weapon], weapon);
  4171. }
  4172. if (s_DamageFeedHitsGiven[playerid][i][e_Issuer] == INVALID_PLAYER_ID) {
  4173. format(
  4174. buf,
  4175. sizeof(buf),
  4176. "%s%s +%.2f~n~",
  4177. buf,
  4178. weapon,
  4179. s_DamageFeedHitsGiven[playerid][i][e_Amount] + 0.009
  4180. );
  4181. } else {
  4182. format(
  4183. buf,
  4184. sizeof(buf),
  4185. "%s%s - %s +%.2f~n~",
  4186. buf,
  4187. s_DamageFeedHitsGiven[playerid][i][e_Name],
  4188. weapon,
  4189. s_DamageFeedHitsGiven[playerid][i][e_Amount] + 0.009
  4190. );
  4191. }
  4192. }
  4193. if (s_DamageFeedGiven[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4194. printf("(wc) WARN: Doesn't have feed textdraw when needed");
  4195. } else {
  4196. if (buf[0]) {
  4197. PlayerTextDrawSetString(playerid, s_DamageFeedGiven[playerid], buf);
  4198. PlayerTextDrawShow(playerid, s_DamageFeedGiven[playerid]);
  4199. } else {
  4200. PlayerTextDrawHide(playerid, s_DamageFeedGiven[playerid]);
  4201. }
  4202. }
  4203. buf = "";
  4204. for (new i = 0; i < sizeof(s_DamageFeedHitsTaken[]) - 1; i++) {
  4205. if (!s_DamageFeedHitsTaken[playerid][i][e_Tick]) {
  4206. break;
  4207. }
  4208. new weapon[32];
  4209. if (s_DamageFeedHitsTaken[playerid][i][e_Weapon] == -1) {
  4210. weapon = "Multiple";
  4211. } else {
  4212. WC_GetWeaponName(s_DamageFeedHitsTaken[playerid][i][e_Weapon], weapon);
  4213. }
  4214. if (s_DamageFeedHitsTaken[playerid][i][e_Issuer] == INVALID_PLAYER_ID) {
  4215. format(
  4216. buf,
  4217. sizeof(buf),
  4218. "%s%s -%.2f~n~",
  4219. buf,
  4220. weapon,
  4221. s_DamageFeedHitsTaken[playerid][i][e_Amount] + 0.009
  4222. );
  4223. } else {
  4224. format(
  4225. buf,
  4226. sizeof(buf),
  4227. "%s%s - %s -%.2f~n~",
  4228. buf,
  4229. s_DamageFeedHitsTaken[playerid][i][e_Name],
  4230. weapon,
  4231. s_DamageFeedHitsTaken[playerid][i][e_Amount] + 0.009
  4232. );
  4233. }
  4234. }
  4235. if (s_DamageFeedTaken[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4236. printf("(wc) WARN: Doesn't have feed textdraw when needed");
  4237. } else {
  4238. if (buf[0]) {
  4239. PlayerTextDrawSetString(playerid, s_DamageFeedTaken[playerid], buf);
  4240. PlayerTextDrawShow(playerid, s_DamageFeedTaken[playerid]);
  4241. } else {
  4242. PlayerTextDrawHide(playerid, s_DamageFeedTaken[playerid]);
  4243. }
  4244. }
  4245. }
  4246. static DamageFeedAddHitGiven(playerid, issuerid, Float:amount, weapon)
  4247. {
  4248. for (new i = 0; i < MAX_PLAYERS; i++) {
  4249. if (s_Spectating[i] == playerid && i != playerid) {
  4250. DamageFeedAddHit(s_DamageFeedHitsGiven[i], i, issuerid, amount, weapon);
  4251. }
  4252. }
  4253. DamageFeedAddHit(s_DamageFeedHitsGiven[playerid], playerid, issuerid, amount, weapon);
  4254. }
  4255. static DamageFeedAddHitTaken(playerid, issuerid, Float:amount, weapon)
  4256. {
  4257. for (new i = 0; i < MAX_PLAYERS; i++) {
  4258. if (s_Spectating[i] == playerid && i != playerid) {
  4259. DamageFeedAddHit(s_DamageFeedHitsTaken[i], i, issuerid, amount, weapon);
  4260. }
  4261. }
  4262. DamageFeedAddHit(s_DamageFeedHitsTaken[playerid], playerid, issuerid, amount, weapon);
  4263. }
  4264. static DamageFeedAddHit(arr[WC_FEED_HEIGHT][E_DAMAGE_FEED_HIT], playerid, issuerid, Float:amount, weapon)
  4265. {
  4266. if (!IsDamageFeedActive(playerid)) {
  4267. return;
  4268. }
  4269. new tick = GetTickCount();
  4270. if (tick == 0) tick = 1;
  4271. new idx = -1;
  4272. for (new i = 0; i < sizeof(arr) - 1; i++) {
  4273. if (!arr[i][e_Tick]) {
  4274. break;
  4275. }
  4276. if (tick - arr[i][e_Tick] >= s_DamageFeedHideDelay) {
  4277. DamageFeedRemoveHit(arr, i);
  4278. break;
  4279. }
  4280. // Remove it and add it on top below
  4281. if (arr[i][e_Issuer] == issuerid) {
  4282. // Multiple weapons
  4283. if (arr[i][e_Weapon] != weapon) {
  4284. //weapon = -1;
  4285. }
  4286. amount += arr[i][e_Amount];
  4287. idx = i;
  4288. break;
  4289. }
  4290. }
  4291. if (idx == -1) {
  4292. idx = 0;
  4293. // Insert it at the top
  4294. for (new i = sizeof(arr) - 1; i >= 1; i--) {
  4295. arr[i] = arr[i - 1];
  4296. }
  4297. }
  4298. arr[idx][e_Tick] = tick;
  4299. arr[idx][e_Amount] = amount;
  4300. arr[idx][e_Issuer] = issuerid;
  4301. arr[idx][e_Weapon] = weapon;
  4302. GetPlayerName(issuerid, arr[idx][e_Name], MAX_PLAYER_NAME);
  4303. DamageFeedUpdate(playerid, true);
  4304. }
  4305. static DamageFeedRemoveHit(arr[WC_FEED_HEIGHT][E_DAMAGE_FEED_HIT], idx)
  4306. {
  4307. for (new i = 0; i < WC_FEED_HEIGHT; i++) {
  4308. if (i >= idx) {
  4309. arr[i][e_Tick] = 0;
  4310. }
  4311. }
  4312. }
  4313. static SaveSyncData(playerid)
  4314. {
  4315. GetPlayerHealth(playerid, s_SyncData[playerid][e_Health]);
  4316. GetPlayerArmour(playerid, s_SyncData[playerid][e_Armour]);
  4317. GetPlayerPos(playerid, s_SyncData[playerid][e_PosX], s_SyncData[playerid][e_PosY], s_SyncData[playerid][e_PosZ]);
  4318. GetPlayerFacingAngle(playerid, s_SyncData[playerid][e_PosA]);
  4319. s_SyncData[playerid][e_Skin] = GetPlayerSkin(playerid);
  4320. s_SyncData[playerid][e_Team] = GetPlayerTeam(playerid);
  4321. s_SyncData[playerid][e_Weapon] = GetPlayerWeapon(playerid);
  4322. for (new i = 0; i < 13; i++) {
  4323. GetPlayerWeaponData(playerid, i, s_SyncData[playerid][e_WeaponId][i], s_SyncData[playerid][e_WeaponAmmo][i]);
  4324. }
  4325. }
  4326. static MakePlayerFacePlayer(playerid, targetid, opposite = false, forcesync = true)
  4327. {
  4328. new Float:x1, Float:y1, Float:z1;
  4329. new Float:x2, Float:y2, Float:z2;
  4330. GetPlayerPos(playerid, x1, y1, z1);
  4331. GetPlayerPos(targetid, x2, y2, z2);
  4332. new Float:angle = AngleBetweenPoints(x2, y2, x1, y1);
  4333. if (opposite) {
  4334. angle += 180.0;
  4335. if (angle > 360.0) angle -= 360.0;
  4336. }
  4337. if (angle < 0.0) angle += 360.0;
  4338. if (angle > 360.0) angle -= 360.0;
  4339. SetPlayerFacingAngle(playerid, angle);
  4340. if (forcesync) {
  4341. SetFakeFacingAngle(playerid, angle);
  4342. UpdateSyncData(playerid);
  4343. }
  4344. }
  4345. static IsPlayerBehindPlayer(playerid, targetid, Float:diff = 90.0)
  4346. {
  4347. new Float:x1, Float:y1, Float:z1;
  4348. new Float:x2, Float:y2, Float:z2;
  4349. new Float:ang, Float:angdiff;
  4350. GetPlayerPos(playerid, x1, y1, z1);
  4351. GetPlayerPos(targetid, x2, y2, z2);
  4352. GetPlayerFacingAngle(targetid, ang);
  4353. angdiff = AngleBetweenPoints(x1, y1, x2, y2);
  4354. if (angdiff < 0.0) angdiff += 360.0;
  4355. if (angdiff > 360.0) angdiff -= 360.0;
  4356. ang = ang - angdiff;
  4357. if (ang > 180.0) ang -= 360.0;
  4358. if (ang < -180.0) ang += 360.0;
  4359. return floatabs(ang) > diff;
  4360. }
  4361. static AddRejectedHit(playerid, damagedid, reason, weapon, i1 = 0, i2 = 0, i3 = 0)
  4362. {
  4363. new idx = s_RejectedHitsIdx[playerid];
  4364. if (s_RejectedHits[playerid][idx][e_Time]) {
  4365. idx += 1;
  4366. if (idx >= sizeof(s_RejectedHits[])) {
  4367. idx = 0;
  4368. }
  4369. s_RejectedHitsIdx[playerid] = idx;
  4370. }
  4371. new time, hour, minute, second;
  4372. time = gettime(hour, minute, second);
  4373. s_RejectedHits[playerid][idx][e_Reason] = reason;
  4374. s_RejectedHits[playerid][idx][e_Time] = time;
  4375. s_RejectedHits[playerid][idx][e_Weapon] = weapon;
  4376. s_RejectedHits[playerid][idx][e_Hour] = hour;
  4377. s_RejectedHits[playerid][idx][e_Minute] = minute;
  4378. s_RejectedHits[playerid][idx][e_Second] = second;
  4379. s_RejectedHits[playerid][idx][e_Info1] = _:i1;
  4380. s_RejectedHits[playerid][idx][e_Info2] = _:i2;
  4381. s_RejectedHits[playerid][idx][e_Info3] = _:i3;
  4382. if (damagedid != INVALID_PLAYER_ID) {
  4383. GetPlayerName(damagedid, s_RejectedHits[playerid][idx][e_Name], MAX_PLAYER_NAME);
  4384. } else {
  4385. s_RejectedHits[playerid][idx][e_Name][0] = '#';
  4386. s_RejectedHits[playerid][idx][e_Name][1] = '\0';
  4387. }
  4388. OnRejectedHit(playerid, s_RejectedHits[playerid][idx]);
  4389. }
  4390. forward WC_SecondKnifeAnim(playerid);
  4391. public WC_SecondKnifeAnim(playerid)
  4392. {
  4393. ApplyAnimation(playerid, "KNIFE", "KILL_Knife_Ped_Die", 4.1, 0, 1, 1, 1, 3000, 1);
  4394. }
  4395. forward WC_PlayerDeathRespawn(playerid);
  4396. public WC_PlayerDeathRespawn(playerid)
  4397. {
  4398. if (!s_IsDying[playerid]) {
  4399. return;
  4400. }
  4401. s_IsDying[playerid] = false;
  4402. if (!OnPlayerDeathFinished(playerid, true)) {
  4403. UpdateHealthBar(playerid);
  4404. SetFakeFacingAngle(playerid, _);
  4405. FreezeSyncData(playerid, false);
  4406. return;
  4407. }
  4408. s_IsDying[playerid] = true;
  4409. s_TrueDeath[playerid] = false;
  4410. if (IsPlayerInAnyVehicle(playerid)) {
  4411. new Float:x, Float:y, Float:z;
  4412. GetPlayerPos(playerid, x, y, z);
  4413. SetPlayerPos(playerid, x, y, z);
  4414. }
  4415. SetPlayerVirtualWorld(playerid, WC_DEATH_WORLD);
  4416. SetFakeFacingAngle(playerid, _);
  4417. TogglePlayerSpectating(playerid, true);
  4418. TogglePlayerSpectating(playerid, false);
  4419. }
  4420. public OnInvalidWeaponDamage(playerid, damagedid, Float:amount, weaponid, bodypart, error, bool:given)
  4421. {
  4422. DebugMessageRedAll("OnInvalidWeaponDamage(%d, %d, %f, %d, %d, %d, %d)", playerid, damagedid, amount, weaponid, bodypart, error, given);
  4423. #if defined WC_OnInvalidWeaponDamage
  4424. WC_OnInvalidWeaponDamage(playerid, damagedid, Float:amount, weaponid, bodypart, error, bool:given);
  4425. #endif
  4426. }
  4427. public OnPlayerDamageDone(playerid, Float:amount, issuerid, weapon, bodypart)
  4428. {
  4429. new idx = s_PreviousHitI[playerid];
  4430. s_PreviousHitI[playerid] = (s_PreviousHitI[playerid] - 1) % sizeof(s_PreviousHits[]);
  4431. // JIT plugin fix
  4432. if (s_PreviousHitI[playerid] < 0) {
  4433. s_PreviousHitI[playerid] += sizeof(s_PreviousHits[]);
  4434. }
  4435. s_PreviousHits[playerid][idx][e_Tick] = GetTickCount();
  4436. s_PreviousHits[playerid][idx][e_Issuer] = issuerid;
  4437. s_PreviousHits[playerid][idx][e_Weapon] = weapon;
  4438. s_PreviousHits[playerid][idx][e_Amount] = amount;
  4439. s_PreviousHits[playerid][idx][e_Bodypart] = bodypart;
  4440. s_PreviousHits[playerid][idx][e_Health] = GetLastDamageHealth(playerid);
  4441. s_PreviousHits[playerid][idx][e_Armour] = GetLastDamageArmour(playerid);
  4442. if (!IsHighRateWeapon(weapon)) {
  4443. DebugMessageAll("OnPlayerDamageDone(%d did %f to %d with %d on bodypart %d)", issuerid, amount, playerid, weapon, bodypart);
  4444. if (s_DamageTakenSound) {
  4445. PlayerPlaySound(playerid, s_DamageTakenSound, 0.0, 0.0, 0.0);
  4446. for (new i = 0; i < MAX_PLAYERS; i++) {
  4447. if (s_Spectating[i] == playerid && i != playerid) {
  4448. PlayerPlaySound(i, s_DamageTakenSound, 0.0, 0.0, 0.0);
  4449. }
  4450. }
  4451. }
  4452. if (s_DamageGivenSound && issuerid != INVALID_PLAYER_ID) {
  4453. PlayerPlaySound(issuerid, s_DamageGivenSound, 0.0, 0.0, 0.0);
  4454. for (new i = 0; i < MAX_PLAYERS; i++) {
  4455. if (s_Spectating[i] == issuerid && i != issuerid) {
  4456. PlayerPlaySound(i, s_DamageGivenSound, 0.0, 0.0, 0.0);
  4457. }
  4458. }
  4459. }
  4460. }
  4461. if (issuerid != INVALID_PLAYER_ID) {
  4462. DamageFeedAddHitGiven(issuerid, playerid, amount, weapon);
  4463. }
  4464. DamageFeedAddHitTaken(playerid, issuerid, amount, weapon);
  4465. #if defined WC_OnPlayerDamageDone
  4466. WC_OnPlayerDamageDone(playerid, amount, issuerid, weapon, bodypart);
  4467. #endif
  4468. }
  4469. public OnPlayerDamage(&playerid, &Float:amount, &issuerid, &weapon, &bodypart)
  4470. {
  4471. #if defined WC_OnPlayerDamage
  4472. return WC_OnPlayerDamage(playerid, amount, issuerid, weapon, bodypart);
  4473. #else
  4474. return 1;
  4475. #endif
  4476. }
  4477. /*
  4478. * ALS callbacks
  4479. */
  4480. #if defined _ALS_OnGameModeInit
  4481. #undef OnGameModeInit
  4482. #else
  4483. #define _ALS_OnGameModeInit
  4484. #endif
  4485. #define OnGameModeInit WC_OnGameModeInit
  4486. #if defined WC_OnGameModeInit
  4487. forward WC_OnGameModeInit();
  4488. #endif
  4489. #if defined _ALS_OnGameModeExit
  4490. #undef OnGameModeExit
  4491. #else
  4492. #define _ALS_OnGameModeExit
  4493. #endif
  4494. #define OnGameModeExit WC_OnGameModeExit
  4495. #if defined WC_OnGameModeExit
  4496. forward WC_OnGameModeExit();
  4497. #endif
  4498. #if defined _ALS_OnFilterScriptInit
  4499. #undef OnFilterScriptInit
  4500. #else
  4501. #define _ALS_OnFilterScriptInit
  4502. #endif
  4503. #define OnFilterScriptInit WC_OnFilterScriptInit
  4504. #if defined WC_OnFilterScriptInit
  4505. forward WC_OnFilterScriptInit();
  4506. #endif
  4507. #if defined _ALS_OnFilterScriptExit
  4508. #undef OnFilterScriptExit
  4509. #else
  4510. #define _ALS_OnFilterScriptExit
  4511. #endif
  4512. #define OnFilterScriptExit WC_OnFilterScriptExit
  4513. #if defined WC_OnFilterScriptExit
  4514. forward WC_OnFilterScriptExit();
  4515. #endif
  4516. #if defined _ALS_OnPlayerConnect
  4517. #undef OnPlayerConnect
  4518. #else
  4519. #define _ALS_OnPlayerConnect
  4520. #endif
  4521. #define OnPlayerConnect WC_OnPlayerConnect
  4522. #if defined WC_OnPlayerConnect
  4523. forward WC_OnPlayerConnect(playerid);
  4524. #endif
  4525. #if defined _ALS_OnPlayerDisconnect
  4526. #undef OnPlayerDisconnect
  4527. #else
  4528. #define _ALS_OnPlayerDisconnect
  4529. #endif
  4530. #define OnPlayerDisconnect WC_OnPlayerDisconnect
  4531. #if defined WC_OnPlayerDisconnect
  4532. forward WC_OnPlayerDisconnect(playerid, reason);
  4533. #endif
  4534. #if defined _ALS_OnPlayerStreamIn
  4535. #undef OnPlayerStreamIn
  4536. #else
  4537. #define _ALS_OnPlayerStreamIn
  4538. #endif
  4539. #define OnPlayerStreamIn WC_OnPlayerStreamIn
  4540. #if defined WC_OnPlayerStreamIn
  4541. forward WC_OnPlayerStreamIn(playerid, forplayerid);
  4542. #endif
  4543. #if defined _ALS_OnVehicleDeath
  4544. #undef OnVehicleDeath
  4545. #else
  4546. #define _ALS_OnVehicleDeath
  4547. #endif
  4548. #define OnVehicleDeath WC_OnVehicleDeath
  4549. #if defined WC_OnVehicleDeath
  4550. forward WC_OnVehicleDeath(vehicleid, killerid);
  4551. #endif
  4552. #if defined _ALS_OnVehicleSpawn
  4553. #undef OnVehicleSpawn
  4554. #else
  4555. #define _ALS_OnVehicleSpawn
  4556. #endif
  4557. #define OnVehicleSpawn WC_OnVehicleSpawn
  4558. #if defined WC_OnVehicleSpawn
  4559. forward WC_OnVehicleSpawn(vehicleid);
  4560. #endif
  4561. #if defined _ALS_OnPlayerEnterVehicle
  4562. #undef OnPlayerEnterVehicle
  4563. #else
  4564. #define _ALS_OnPlayerEnterVehicle
  4565. #endif
  4566. #define OnPlayerEnterVehicle WC_OnPlayerEnterVehicle
  4567. #if defined WC_OnPlayerEnterVehicle
  4568. forward WC_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
  4569. #endif
  4570. #if defined _ALS_OnPlayerExitVehicle
  4571. #undef OnPlayerExitVehicle
  4572. #else
  4573. #define _ALS_OnPlayerExitVehicle
  4574. #endif
  4575. #define OnPlayerExitVehicle WC_OnPlayerExitVehicle
  4576. #if defined WC_OnPlayerExitVehicle
  4577. forward WC_OnPlayerExitVehicle(playerid, vehicleid);
  4578. #endif
  4579. #if defined _ALS_OnPlayerStateChange
  4580. #undef OnPlayerStateChange
  4581. #else
  4582. #define _ALS_OnPlayerStateChange
  4583. #endif
  4584. #define OnPlayerStateChange WC_OnPlayerStateChange
  4585. #if defined WC_OnPlayerStateChange
  4586. forward WC_OnPlayerStateChange(playerid, newstate, oldstate);
  4587. #endif
  4588. #if defined _ALS_OnPlayerPickUpPickup
  4589. #undef OnPlayerPickUpPickup
  4590. #else
  4591. #define _ALS_OnPlayerPickUpPickup
  4592. #endif
  4593. #define OnPlayerPickUpPickup WC_OnPlayerPickUpPickup
  4594. #if defined WC_OnPlayerPickUpPickup
  4595. forward WC_OnPlayerPickUpPickup(playerid, pickupid);
  4596. #endif
  4597. #if defined _ALS_OnPlayerUpdate
  4598. #undef OnPlayerUpdate
  4599. #else
  4600. #define _ALS_OnPlayerUpdate
  4601. #endif
  4602. #define OnPlayerUpdate WC_OnPlayerUpdate
  4603. #if defined WC_OnPlayerUpdate
  4604. forward WC_OnPlayerUpdate(playerid);
  4605. #endif
  4606. #if defined _ALS_OnPlayerSpawn
  4607. #undef OnPlayerSpawn
  4608. #else
  4609. #define _ALS_OnPlayerSpawn
  4610. #endif
  4611. #define OnPlayerSpawn WC_OnPlayerSpawn
  4612. #if defined WC_OnPlayerSpawn
  4613. forward WC_OnPlayerSpawn(playerid);
  4614. #endif
  4615. #if defined _ALS_OnPlayerRequestClass
  4616. #undef OnPlayerRequestClass
  4617. #else
  4618. #define _ALS_OnPlayerRequestClass
  4619. #endif
  4620. #define OnPlayerRequestClass WC_OnPlayerRequestClass
  4621. #if defined WC_OnPlayerRequestClass
  4622. forward WC_OnPlayerRequestClass(playerid, classid);
  4623. #endif
  4624. #if defined _ALS_OnPlayerDeath
  4625. #undef OnPlayerDeath
  4626. #else
  4627. #define _ALS_OnPlayerDeath
  4628. #endif
  4629. #define OnPlayerDeath WC_OnPlayerDeath
  4630. #if defined WC_OnPlayerDeath
  4631. forward WC_OnPlayerDeath(playerid, killerid, reason);
  4632. #endif
  4633. #if defined _ALS_OnPlayerKeyStateChange
  4634. #undef OnPlayerKeyStateChange
  4635. #else
  4636. #define _ALS_OnPlayerKeyStateChange
  4637. #endif
  4638. #define OnPlayerKeyStateChange WC_OnPlayerKeyStateChange
  4639. #if defined WC_OnPlayerKeyStateChange
  4640. forward WC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys);
  4641. #endif
  4642. #if defined _ALS_OnPlayerWeaponShot
  4643. #undef OnPlayerWeaponShot
  4644. #else
  4645. #define _ALS_OnPlayerWeaponShot
  4646. #endif
  4647. #define OnPlayerWeaponShot WC_OnPlayerWeaponShot
  4648. #if defined WC_OnPlayerWeaponShot
  4649. forward WC_OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ);
  4650. #endif
  4651. #if defined _ALS_OnPlayerEnterCheckpoint
  4652. #undef OnPlayerEnterCheckpoint
  4653. #else
  4654. #define _ALS_OnPlayerEnterCheckpoint
  4655. #endif
  4656. #define OnPlayerEnterCheckpoint WC_OnPlayerEnterCheckpoint
  4657. #if defined WC_OnPlayerEnterCheckpoint
  4658. forward WC_OnPlayerEnterCheckpoint(playerid);
  4659. #endif
  4660. #if defined _ALS_OnPlayerLeaveCheckpoint
  4661. #undef OnPlayerLeaveCheckpoint
  4662. #else
  4663. #define _ALS_OnPlayerLeaveCheckpoint
  4664. #endif
  4665. #define OnPlayerLeaveCheckpoint WC_OnPlayerLeaveCheckpoint
  4666. #if defined WC_OnPlayerLeaveCheckpoint
  4667. forward WC_OnPlayerLeaveCheckpoint(playerid);
  4668. #endif
  4669. #if defined _ALS_OnInvalidWeaponDamage
  4670. #undef OnInvalidWeaponDamage
  4671. #else
  4672. #define _ALS_OnInvalidWeaponDamage
  4673. #endif
  4674. #define OnInvalidWeaponDamage WC_OnInvalidWeaponDamage
  4675. #if defined WC_OnInvalidWeaponDamage
  4676. forward WC_OnInvalidWeaponDamage(playerid, damagedid, Float:amount, weaponid, bodypart, error, bool:given);
  4677. #endif
  4678. #if defined _ALS_OnPlayerDamageDone
  4679. #undef OnPlayerDamageDone
  4680. #else
  4681. #define _ALS_OnPlayerDamageDone
  4682. #endif
  4683. #define OnPlayerDamageDone WC_OnPlayerDamageDone
  4684. #if defined WC_OnPlayerDamageDone
  4685. forward WC_OnPlayerDamageDone(playerid, Float:amount, issuerid, weapon, bodypart);
  4686. #endif
  4687. #if defined _ALS_OnPlayerDamage
  4688. #undef OnPlayerDamage
  4689. #else
  4690. #define _ALS_OnPlayerDamage
  4691. #endif
  4692. #define OnPlayerDamage WC_OnPlayerDamage
  4693. #if defined WC_OnPlayerDamage
  4694. forward WC_OnPlayerDamage(&playerid, &Float:amount, &issuerid, &weapon, &bodypart);
  4695. #endif
  4696. #if defined _ALS_OnPlayerPrepareDeath
  4697. #undef OnPlayerPrepareDeath
  4698. #else
  4699. #define _ALS_OnPlayerPrepareDeath
  4700. #endif
  4701. #define OnPlayerPrepareDeath WC_OnPlayerPrepareDeath
  4702. #if defined WC_OnPlayerPrepareDeath
  4703. forward WC_OnPlayerPrepareDeath(playerid, animlib[32], animname[32], &anim_lock, &respawn_time);
  4704. #endif
  4705. #if defined _ALS_OnRejectedHit
  4706. #undef OnRejectedHit
  4707. #else
  4708. #define _ALS_OnRejectedHit
  4709. #endif
  4710. #define OnRejectedHit WC_OnRejectedHit
  4711. #if defined WC_OnRejectedHit
  4712. forward WC_OnRejectedHit(playerid, hit[E_REJECTED_HIT]);
  4713. #endif
  4714. #if WC_CUSTOM_VENDING_MACHINES
  4715. #if defined _ALS_OnPlayerUseVendingMachine
  4716. #undef OnPlayerUseVendingMachine
  4717. #else
  4718. #define _ALS_OnPlayerUseVendingMachine
  4719. #endif
  4720. #define OnPlayerUseVendingMachine WC_OnPlayerUseVendingMachine
  4721. #if defined WC_OnPlayerUseVendingMachine
  4722. forward WC_OnPlayerUseVendingMachine(playerid, &Float:health_given);
  4723. #endif
  4724. #endif
  4725. #if defined _ALS_OnPlayerDeathFinished
  4726. #undef OnPlayerDeathFinished
  4727. #else
  4728. #define _ALS_OnPlayerDeathFinished
  4729. #endif
  4730. #define OnPlayerDeathFinished WC_OnPlayerDeathFinished
  4731. #if defined WC_OnPlayerDeathFinished
  4732. forward WC_OnPlayerDeathFinished(playerid, bool:cancelable);
  4733. #endif
  4734. /*
  4735. * ALS functions
  4736. */
  4737. #if defined _ALS_SpawnPlayer
  4738. #undef SpawnPlayer
  4739. #else
  4740. #define _ALS_SpawnPlayer
  4741. #endif
  4742. #define SpawnPlayer WC_SpawnPlayer
  4743. #if defined _ALS_SetPlayerHealth
  4744. #undef SetPlayerHealth
  4745. #else
  4746. #define _ALS_SetPlayerHealth
  4747. #endif
  4748. #define SetPlayerHealth WC_SetPlayerHealth
  4749. #if defined _ALS_GetPlayerState
  4750. #undef GetPlayerState
  4751. #else
  4752. #define _ALS_GetPlayerState
  4753. #endif
  4754. #define GetPlayerState WC_GetPlayerState
  4755. #if defined _ALS_GetPlayerHealth
  4756. #undef GetPlayerHealth
  4757. #else
  4758. #define _ALS_GetPlayerHealth
  4759. #endif
  4760. #define GetPlayerHealth WC_GetPlayerHealth
  4761. #if defined _ALS_SetPlayerArmour
  4762. #undef SetPlayerArmour
  4763. #else
  4764. #define _ALS_SetPlayerArmour
  4765. #endif
  4766. #define SetPlayerArmour WC_SetPlayerArmour
  4767. #if defined _ALS_GetPlayerArmour
  4768. #undef GetPlayerArmour
  4769. #else
  4770. #define _ALS_GetPlayerArmour
  4771. #endif
  4772. #define GetPlayerArmour WC_GetPlayerArmour
  4773. #if defined _ALS_GetPlayerTeam
  4774. #undef GetPlayerTeam
  4775. #else
  4776. #define _ALS_GetPlayerTeam
  4777. #endif
  4778. #define GetPlayerTeam WC_GetPlayerTeam
  4779. #if defined _ALS_SetPlayerTeam
  4780. #undef SetPlayerTeam
  4781. #else
  4782. #define _ALS_SetPlayerTeam
  4783. #endif
  4784. #define SetPlayerTeam WC_SetPlayerTeam
  4785. #if defined _ALS_SendDeathMessage
  4786. #undef SendDeathMessage
  4787. #else
  4788. #define _ALS_SendDeathMessage
  4789. #endif
  4790. #define SendDeathMessage WC_SendDeathMessage
  4791. #if defined _ALS_GetWeaponName
  4792. #undef GetWeaponName
  4793. #else
  4794. #define _ALS_GetWeaponName
  4795. #endif
  4796. #define GetWeaponName WC_GetWeaponName
  4797. #if defined _ALS_ApplyAnimation
  4798. #undef ApplyAnimation
  4799. #else
  4800. #define _ALS_ApplyAnimation
  4801. #endif
  4802. #define ApplyAnimation WC_ApplyAnimation
  4803. #if defined _ALS_ClearAnimations
  4804. #undef ClearAnimations
  4805. #else
  4806. #define _ALS_ClearAnimations
  4807. #endif
  4808. #define ClearAnimations WC_ClearAnimations
  4809. #if defined _ALS_AddPlayerClass
  4810. #undef AddPlayerClass
  4811. #else
  4812. #define _ALS_AddPlayerClass
  4813. #endif
  4814. #define AddPlayerClass WC_AddPlayerClass
  4815. #if defined _ALS_AddPlayerClassEx
  4816. #undef AddPlayerClassEx
  4817. #else
  4818. #define _ALS_AddPlayerClassEx
  4819. #endif
  4820. #define AddPlayerClassEx WC_AddPlayerClassEx
  4821. #if defined _ALS_SetSpawnInfo
  4822. #undef SetSpawnInfo
  4823. #else
  4824. #define _ALS_SetSpawnInfo
  4825. #endif
  4826. #define SetSpawnInfo WC_SetSpawnInfo
  4827. #if defined _ALS_TogglePlayerSpectating
  4828. #undef TogglePlayerSpectating
  4829. #else
  4830. #define _ALS_TogglePlayerSpectating
  4831. #endif
  4832. #define TogglePlayerSpectating WC_TogglePlayerSpectating
  4833. #if defined _ALS_TogglePlayerControllable
  4834. #undef TogglePlayerControllable
  4835. #else
  4836. #define _ALS_TogglePlayerControllable
  4837. #endif
  4838. #define TogglePlayerControllable WC_TogglePlayerControllable
  4839. #if defined _ALS_SetPlayerPos
  4840. #undef SetPlayerPos
  4841. #else
  4842. #define _ALS_SetPlayerPos
  4843. #endif
  4844. #define SetPlayerPos WC_SetPlayerPos
  4845. #if defined _ALS_SetPlayerPosFindZ
  4846. #undef SetPlayerPosFindZ
  4847. #else
  4848. #define _ALS_SetPlayerPosFindZ
  4849. #endif
  4850. #define SetPlayerPosFindZ WC_SetPlayerPosFindZ
  4851. #if defined _ALS_SetPlayerVelocity
  4852. #undef SetPlayerVelocity
  4853. #else
  4854. #define _ALS_SetPlayerVelocity
  4855. #endif
  4856. #define SetPlayerVelocity WC_SetPlayerVelocity
  4857. #if defined _ALS_SetPlayerVirtualWorld
  4858. #undef SetPlayerVirtualWorld
  4859. #else
  4860. #define _ALS_SetPlayerVirtualWorld
  4861. #endif
  4862. #define SetPlayerVirtualWorld wc_SetPlayerVirtualWorld
  4863. #if defined _ALS_GetPlayerVirtualWorld
  4864. #undef GetPlayerVirtualWorld
  4865. #else
  4866. #define _ALS_GetPlayerVirtualWorld
  4867. #endif
  4868. #define GetPlayerVirtualWorld WC_GetPlayerVirtualWorld
  4869. #if defined _ALS_PlayerSpectatePlayer
  4870. #undef PlayerSpectatePlayer
  4871. #else
  4872. #define _ALS_PlayerSpectatePlayer
  4873. #endif
  4874. #define PlayerSpectatePlayer WC_PlayerSpectatePlayer
  4875. #if defined _ALS_DestroyVehicle
  4876. #undef DestroyVehicle
  4877. #else
  4878. #define _ALS_DestroyVehicle
  4879. #endif
  4880. #define DestroyVehicle WC_DestroyVehicle
  4881. #if defined _ALS_CreateVehicle
  4882. #undef CreateVehicle
  4883. #else
  4884. #define _ALS_CreateVehicle
  4885. #endif
  4886. #define CreateVehicle WC_CreateVehicle
  4887. #if defined _ALS_AddStaticVehicle
  4888. #undef AddStaticVehicle
  4889. #else
  4890. #define _ALS_AddStaticVehicle
  4891. #endif
  4892. #define AddStaticVehicle WC_AddStaticVehicle
  4893. #if defined _ALS_AddStaticVehicleEx
  4894. #undef AddStaticVehicleEx
  4895. #else
  4896. #define _ALS_AddStaticVehicleEx
  4897. #endif
  4898. #define AddStaticVehicleEx WC_AddStaticVehicleEx
  4899. #if defined _ALS_IsPlayerInCheckpoint
  4900. #undef IsPlayerInCheckpoint
  4901. #else
  4902. #define _ALS_IsPlayerInCheckpoint
  4903. #endif
  4904. #define IsPlayerInCheckpoint WC_IsPlayerInCheckpoint
  4905. #if defined _ALS_SetPlayerSpecialAction
  4906. #undef SetPlayerSpecialAction
  4907. #else
  4908. #define _ALS_SetPlayerSpecialAction
  4909. #endif
  4910. #define SetPlayerSpecialAction WC_SetPlayerSpecialAction
  4911. #if defined _ALS_TextDrawCreate
  4912. #undef TextDrawCreate
  4913. #else
  4914. #define _ALS_TextDrawCreate
  4915. #endif
  4916. #define TextDrawCreate WC_TextDrawCreate
  4917. #if defined _ALS_TextDrawDestroy
  4918. #undef TextDrawDestroy
  4919. #else
  4920. #define _ALS_TextDrawDestroy
  4921. #endif
  4922. #define TextDrawDestroy WC_TextDrawDestroy
  4923. #if defined _ALS_TextDrawLetterSize
  4924. #undef TextDrawLetterSize
  4925. #else
  4926. #define _ALS_TextDrawLetterSize
  4927. #endif
  4928. #define TextDrawLetterSize WC_TextDrawLetterSize
  4929. #if defined _ALS_TextDrawTextSize
  4930. #undef TextDrawTextSize
  4931. #else
  4932. #define _ALS_TextDrawTextSize
  4933. #endif
  4934. #define TextDrawTextSize WC_TextDrawTextSize
  4935. #if defined _ALS_TextDrawAlignment
  4936. #undef TextDrawAlignment
  4937. #else
  4938. #define _ALS_TextDrawAlignment
  4939. #endif
  4940. #define TextDrawAlignment WC_TextDrawAlignment
  4941. #if defined _ALS_TextDrawColor
  4942. #undef TextDrawColor
  4943. #else
  4944. #define _ALS_TextDrawColor
  4945. #endif
  4946. #define TextDrawColor WC_TextDrawColor
  4947. #if defined _ALS_TextDrawUseBox
  4948. #undef TextDrawUseBox
  4949. #else
  4950. #define _ALS_TextDrawUseBox
  4951. #endif
  4952. #define TextDrawUseBox WC_TextDrawUseBox
  4953. #if defined _ALS_TextDrawBoxColor
  4954. #undef TextDrawBoxColor
  4955. #else
  4956. #define _ALS_TextDrawBoxColor
  4957. #endif
  4958. #define TextDrawBoxColor WC_TextDrawBoxColor
  4959. #if defined _ALS_TextDrawSetShadow
  4960. #undef TextDrawSetShadow
  4961. #else
  4962. #define _ALS_TextDrawSetShadow
  4963. #endif
  4964. #define TextDrawSetShadow WC_TextDrawSetShadow
  4965. #if defined _ALS_TextDrawSetOutline
  4966. #undef TextDrawSetOutline
  4967. #else
  4968. #define _ALS_TextDrawSetOutline
  4969. #endif
  4970. #define TextDrawSetOutline WC_TextDrawSetOutline
  4971. #if defined _ALS_TextDrawBackgroundColor
  4972. #undef TextDrawBackgroundColor
  4973. #else
  4974. #define _ALS_TextDrawBackgroundColor
  4975. #endif
  4976. #define TextDrawBackgroundColor WC_TextDrawBackgroundColor
  4977. #if defined _ALS_TextDrawFont
  4978. #undef TextDrawFont
  4979. #else
  4980. #define _ALS_TextDrawFont
  4981. #endif
  4982. #define TextDrawFont WC_TextDrawFont
  4983. #if defined _ALS_TextDrawSetProportional
  4984. #undef TextDrawSetProportional
  4985. #else
  4986. #define _ALS_TextDrawSetProportional
  4987. #endif
  4988. #define TextDrawSetProportional WC_TextDrawSetProportional
  4989. #if defined _ALS_TextDrawSetSelectable
  4990. #undef TextDrawSetSelectable
  4991. #else
  4992. #define _ALS_TextDrawSetSelectable
  4993. #endif
  4994. #define TextDrawSetSelectable WC_TextDrawSetSelectable
  4995. #if defined _ALS_TextDrawShowForPlayer
  4996. #undef TextDrawShowForPlayer
  4997. #else
  4998. #define _ALS_TextDrawShowForPlayer
  4999. #endif
  5000. #define TextDrawShowForPlayer WC_TextDrawShowForPlayer
  5001. #if defined _ALS_TextDrawHideForPlayer
  5002. #undef TextDrawHideForPlayer
  5003. #else
  5004. #define _ALS_TextDrawHideForPlayer
  5005. #endif
  5006. #define TextDrawHideForPlayer WC_TextDrawHideForPlayer
  5007. #if defined _ALS_TextDrawShowForAll
  5008. #undef TextDrawShowForAll
  5009. #else
  5010. #define _ALS_TextDrawShowForAll
  5011. #endif
  5012. #define TextDrawShowForAll WC_TextDrawShowForAll
  5013. #if defined _ALS_TextDrawHideForAll
  5014. #undef TextDrawHideForAll
  5015. #else
  5016. #define _ALS_TextDrawHideForAll
  5017. #endif
  5018. #define TextDrawHideForAll WC_TextDrawHideForAll
  5019. #if defined _ALS_TextDrawSetString
  5020. #undef TextDrawSetString
  5021. #else
  5022. #define _ALS_TextDrawSetString
  5023. #endif
  5024. #define TextDrawSetString WC_TextDrawSetString
  5025. #if defined _ALS_TextDrawSetPreviewModel
  5026. #undef TextDrawSetPreviewModel
  5027. #else
  5028. #define _ALS_TextDrawSetPreviewModel
  5029. #endif
  5030. #define TextDrawSetPreviewModel WC_TextDrawSetPreviewModel
  5031. #if defined _ALS_TextDrawSetPreviewRot
  5032. #undef TextDrawSetPreviewRot
  5033. #else
  5034. #define _ALS_TextDrawSetPreviewRot
  5035. #endif
  5036. #define TextDrawSetPreviewRot WC_TextDrawSetPreviewRot
  5037. #if defined _ALS_TextDrawSetPreviewVehCol
  5038. #undef TextDrawSetPreviewVehCol
  5039. #else
  5040. #define _ALS_TextDrawSetPreviewVehCol
  5041. #endif
  5042. #define TextDrawSetPreviewVehCol WC_TextDrawSetPreviewVehCol
  5043. #if defined _ALS_CreatePlayerTextDraw
  5044. #undef CreatePlayerTextDraw
  5045. #else
  5046. #define _ALS_CreatePlayerTextDraw
  5047. #endif
  5048. #define CreatePlayerTextDraw WC_CreatePlayerTextDraw
  5049. #if defined _ALS_PlayerTextDrawDestroy
  5050. #undef PlayerTextDrawDestroy
  5051. #else
  5052. #define _ALS_PlayerTextDrawDestroy
  5053. #endif
  5054. #define PlayerTextDrawDestroy WC_PlayerTextDrawDestroy
  5055. #if defined _ALS_PlayerTextDrawLetterSize
  5056. #undef PlayerTextDrawLetterSize
  5057. #else
  5058. #define _ALS_PlayerTextDrawLetterSize
  5059. #endif
  5060. #define PlayerTextDrawLetterSize WC_PlayerTextDrawLetterSize
  5061. #if defined _ALS_PlayerTextDrawTextSize
  5062. #undef PlayerTextDrawTextSize
  5063. #else
  5064. #define _ALS_PlayerTextDrawTextSize
  5065. #endif
  5066. #define PlayerTextDrawTextSize WC_PlayerTextDrawTextSize
  5067. #if defined _ALS_PlayerTextDrawAlignment
  5068. #undef PlayerTextDrawAlignment
  5069. #else
  5070. #define _ALS_PlayerTextDrawAlignment
  5071. #endif
  5072. #define PlayerTextDrawAlignment WC_PlayerTextDrawAlignment
  5073. #if defined _ALS_PlayerTextDrawColor
  5074. #undef PlayerTextDrawColor
  5075. #else
  5076. #define _ALS_PlayerTextDrawColor
  5077. #endif
  5078. #define PlayerTextDrawColor WC_PlayerTextDrawColor
  5079. #if defined _ALS_PlayerTextDrawUseBox
  5080. #undef PlayerTextDrawUseBox
  5081. #else
  5082. #define _ALS_PlayerTextDrawUseBox
  5083. #endif
  5084. #define PlayerTextDrawUseBox WC_PlayerTextDrawUseBox
  5085. #if defined _ALS_PlayerTextDrawBoxColor
  5086. #undef PlayerTextDrawBoxColor
  5087. #else
  5088. #define _ALS_PlayerTextDrawBoxColor
  5089. #endif
  5090. #define PlayerTextDrawBoxColor WC_PlayerTextDrawBoxColor
  5091. #if defined _ALS_PlayerTextDrawSetShadow
  5092. #undef PlayerTextDrawSetShadow
  5093. #else
  5094. #define _ALS_PlayerTextDrawSetShadow
  5095. #endif
  5096. #define PlayerTextDrawSetShadow WC_PlayerTextDrawSetShadow
  5097. #if defined _ALS_PlayerTextDrawSetOutline
  5098. #undef PlayerTextDrawSetOutline
  5099. #else
  5100. #define _ALS_PlayerTextDrawSetOutline
  5101. #endif
  5102. #define PlayerTextDrawSetOutline WC_PlayerTextDrawSetOutline
  5103. #if defined _ALS_PlayerTextDrawBackgroundCo
  5104. #undef PlayerTextDrawBackgroundColor
  5105. #else
  5106. #define _ALS_PlayerTextDrawBackgroundCo
  5107. #endif
  5108. #define PlayerTextDrawBackgroundColor WC_PlayerTextDrawBackgroundColo
  5109. #if defined _ALS_PlayerTextDrawFont
  5110. #undef PlayerTextDrawFont
  5111. #else
  5112. #define _ALS_PlayerTextDrawFont
  5113. #endif
  5114. #define PlayerTextDrawFont WC_PlayerTextDrawFont
  5115. #if defined _ALS_PlayerTextDrawSetProportio
  5116. #undef PlayerTextDrawSetProportional
  5117. #else
  5118. #define _ALS_PlayerTextDrawSetProportio
  5119. #endif
  5120. #define PlayerTextDrawSetProportional WC_PlayerTextDrawSetProportiona
  5121. #if defined _ALS_PlayerTextDrawSetSelectabl
  5122. #undef PlayerTextDrawSetSelectable
  5123. #else
  5124. #define _ALS_PlayerTextDrawSetSelectabl
  5125. #endif
  5126. #define PlayerTextDrawSetSelectable WC_PlayerTextDrawSetSelectable
  5127. #if defined _ALS_PlayerTextDrawShow
  5128. #undef PlayerTextDrawShow
  5129. #else
  5130. #define _ALS_PlayerTextDrawShow
  5131. #endif
  5132. #define PlayerTextDrawShow WC_PlayerTextDrawShow
  5133. #if defined _ALS_PlayerTextDrawHide
  5134. #undef PlayerTextDrawHide
  5135. #else
  5136. #define _ALS_PlayerTextDrawHide
  5137. #endif
  5138. #define PlayerTextDrawHide WC_PlayerTextDrawHide
  5139. #if defined _ALS_PlayerTextDrawSetString
  5140. #undef PlayerTextDrawSetString
  5141. #else
  5142. #define _ALS_PlayerTextDrawSetString
  5143. #endif
  5144. #define PlayerTextDrawSetString WC_PlayerTextDrawSetString
  5145. #if defined _ALS_PlayerTextDrawSetPreviewMo
  5146. #undef PlayerTextDrawSetPreviewModel
  5147. #else
  5148. #define _ALS_PlayerTextDrawSetPreviewMo
  5149. #endif
  5150. #define PlayerTextDrawSetPreviewModel WC_PlayerTextDrawSetPreviewMode
  5151. #if defined _ALS_PlayerTextDrawSetPreviewRo
  5152. #undef PlayerTextDrawSetPreviewRot
  5153. #else
  5154. #define _ALS_PlayerTextDrawSetPreviewRo
  5155. #endif
  5156. #define PlayerTextDrawSetPreviewRot WC_PlayerTextDrawSetPreviewRot
  5157. #if defined _ALS_PlayerTextDrawSetPreviewVe
  5158. #undef PlayerTextDrawSetPreviewVehCol
  5159. #else
  5160. #define _ALS_PlayerTextDrawSetPreviewVe
  5161. #endif
  5162. #define PlayerTextDrawSetPreviewVehCol WC_PlayerTextDrawSetPreviewVehC