1
0

weapon-config.inc 163 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332
  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 vehicleid = CreateVehicle(modelid, x, y, z, angle, color1, color2, respawn_delay, addsiren);
  1474. if (vehicleid != INVALID_VEHICLE_ID) {
  1475. s_VehicleAlive[vehicleid] = true;
  1476. return vehicleid;
  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 vehicleid = AddStaticVehicle(modelid, x, y, z, angle, color1, color2);
  1483. if (vehicleid != INVALID_VEHICLE_ID) {
  1484. s_VehicleAlive[vehicleid] = true;
  1485. return vehicleid;
  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. //GameTextForPlayer(playerid, "~r~C-bug is not allowed", 3000, 3);
  2205. //ApplyAnimation(playerid, "SWORD", "sword_block", 4.0, 0, 0, 0, 0, 0, 1);
  2206. //FreezeSyncData(playerid, false);
  2207. ClearAnimations(playerid, 1);
  2208. //GivePlayerWeapon(playerid, weapon, 0);
  2209. }
  2210. public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
  2211. {
  2212. if ((!s_CbugAllowed)&& !IsPlayerDying(playerid) && GetPlayerState(playerid) == PLAYER_STATE_ONFOOT) {
  2213. if (newkeys & KEY_CROUCH) {
  2214. new tick = GetTickCount();
  2215. new diff = tick - s_LastShot[playerid][e_Tick];
  2216. if (s_LastShot[playerid][e_Tick] && diff < 1200 && !s_CbugFroze[playerid]) {
  2217. PlayerPlaySound(playerid, 1055, 0.0, 0.0, 0.0);
  2218. if (s_LastShot[playerid][e_Valid] && floatabs(s_LastShot[playerid][e_HX]) > 1.0 && floatabs(s_LastShot[playerid][e_HY]) > 1.0) {
  2219. SetPlayerFacingAngle(playerid, AngleBetweenPoints(
  2220. s_LastShot[playerid][e_HX],
  2221. s_LastShot[playerid][e_HY],
  2222. s_LastShot[playerid][e_OX],
  2223. s_LastShot[playerid][e_OY]
  2224. ));
  2225. }
  2226. new w, a;
  2227. GetPlayerWeaponData(playerid, 0, w, a);
  2228. ClearAnimations(playerid, 1);
  2229. //ApplyAnimation(playerid, "PED", "IDLE_stance", 4.1, 1, 0, 0, 0, 0, 1);
  2230. //FreezeSyncData(playerid, true);
  2231. //GivePlayerWeapon(playerid, w, 0);
  2232. //SetTimerEx("WC_CbugPunishment", 600, false, "ii", playerid, GetPlayerWeapon(playerid));
  2233. s_CbugFroze[playerid] = tick;
  2234. for (new i = 0; i < MAX_PLAYERS; i++) {
  2235. if (!IsPlayerConnected(i) && !IsPlayerDying(i)) {
  2236. continue;
  2237. }
  2238. for (new j = 0; j < sizeof(s_PreviousHits[]); j++) {
  2239. if (s_PreviousHits[i][j][e_Issuer] == playerid && tick - s_PreviousHits[i][j][e_Tick] <= 1200) {
  2240. s_PreviousHits[i][j][e_Issuer] = INVALID_PLAYER_ID;
  2241. new Float:health = WC_GetPlayerHealth(i);
  2242. new Float:armour = WC_GetPlayerArmour(i);
  2243. if (s_IsDying[i]) {
  2244. if (s_DelayedDeathTimer[i] == -1) {
  2245. continue;
  2246. }
  2247. KillTimer(s_DelayedDeathTimer[i]);
  2248. s_DelayedDeathTimer[i] = -1;
  2249. ClearAnimations(i, 1);
  2250. SetFakeFacingAngle(i, _);
  2251. FreezeSyncData(i, false);
  2252. s_IsDying[i] = false;
  2253. if (s_DeathTimer[i] != -1) {
  2254. KillTimer(s_DeathTimer[i]);
  2255. s_DeathTimer[i] = -1;
  2256. }
  2257. }
  2258. health += s_PreviousHits[i][j][e_Health];
  2259. armour += s_PreviousHits[i][j][e_Armour];
  2260. WC_SetPlayerHealth(i, health, armour);
  2261. }
  2262. }
  2263. }
  2264. }
  2265. }
  2266. }
  2267. if (GetPlayerState(playerid) == PLAYER_STATE_ONFOOT) {
  2268. #if WC_CUSTOM_VENDING_MACHINES
  2269. if (s_CustomVendingMachines
  2270. && newkeys == KEY_SECONDARY_ATTACK
  2271. && !oldkeys
  2272. && s_VendingUseTimer[playerid] == -1
  2273. && GetPlayerAnimationIndex(playerid) != 1660) {
  2274. new bool:failed = false;
  2275. if (GetPlayerMoney(playerid) <= 0 || s_PlayerHealth[playerid] >= s_PlayerMaxHealth[playerid]) {
  2276. failed = true;
  2277. }
  2278. new Float:z;
  2279. GetPlayerPos(playerid, z, z, z);
  2280. for (new i = 0; i < sizeof(sc_VendingMachines); i++) {
  2281. if (floatabs(z - sc_VendingMachines[i][e_PosZ]) > 1.5) {
  2282. continue;
  2283. }
  2284. if (IsPlayerInRangeOfPoint(playerid, 0.5, sc_VendingMachines[i][e_FrontX], sc_VendingMachines[i][e_FrontY], z)) {
  2285. if (failed) {
  2286. PlayerPlaySound(playerid, 1055, 0.0, 0.0, 0.0);
  2287. break;
  2288. }
  2289. new Float:health_given = 35.0;
  2290. if (OnPlayerUseVendingMachine(playerid, health_given)) {
  2291. s_VendingUseTimer[playerid] = SetTimerEx("WC_VendingMachineUsed", 2500, false, "if", playerid, health_given);
  2292. SetPlayerFacingAngle(playerid, sc_VendingMachines[i][e_RotZ]);
  2293. SetPlayerPos(playerid, sc_VendingMachines[i][e_FrontX], sc_VendingMachines[i][e_FrontY], z);
  2294. ApplyAnimation(playerid, "VENDING", "VEND_USE", 4.1, 0, 0, 1, 0, 0, 1);
  2295. PlayerPlaySound(playerid, 42600, 0.0, 0.0, 0.0);
  2296. } else {
  2297. PlayerPlaySound(playerid, 1055, 0.0, 0.0, 0.0);
  2298. }
  2299. break;
  2300. }
  2301. }
  2302. }
  2303. #endif
  2304. if (newkeys & KEY_FIRE) {
  2305. new weap = GetPlayerWeapon(playerid);
  2306. switch (weap) {
  2307. case WEAPON_BOMB, WEAPON_SATCHEL: {
  2308. s_LastExplosive[playerid] = WEAPON_SATCHEL;
  2309. }
  2310. case WEAPON_ROCKETLAUNCHER, WEAPON_HEATSEEKER, WEAPON_GRENADE: {
  2311. s_LastExplosive[playerid] = weap;
  2312. }
  2313. }
  2314. }
  2315. }
  2316. #if defined WC_OnPlayerKeyStateChange
  2317. return WC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys);
  2318. #else
  2319. return 1;
  2320. #endif
  2321. }
  2322. public OnPlayerStreamIn(playerid, forplayerid)
  2323. {
  2324. // Send ped floor_hit_f
  2325. if (s_IsDying[playerid]) {
  2326. SendLastSyncData(playerid, forplayerid, 0x2e040000 + 1150);
  2327. }
  2328. #if defined WC_OnPlayerStreamIn
  2329. return WC_OnPlayerStreamIn(playerid, forplayerid);
  2330. #else
  2331. return 1;
  2332. #endif
  2333. }
  2334. public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
  2335. {
  2336. #if WC_CUSTOM_VENDING_MACHINES
  2337. if (s_VendingUseTimer[playerid] != -1) {
  2338. KillTimer(s_VendingUseTimer[playerid]);
  2339. s_VendingUseTimer[playerid] = -1;
  2340. }
  2341. #endif
  2342. s_LastVehicleEnterTime[playerid] = gettime();
  2343. s_LastVehicleTick[playerid] = GetTickCount();
  2344. #if defined WC_OnPlayerEnterVehicle
  2345. return WC_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
  2346. #else
  2347. return 1;
  2348. #endif
  2349. }
  2350. public OnPlayerExitVehicle(playerid, vehicleid)
  2351. {
  2352. s_LastVehicleTick[playerid] = GetTickCount();
  2353. #if defined WC_OnPlayerExitVehicle
  2354. return WC_OnPlayerExitVehicle(playerid, vehicleid);
  2355. #else
  2356. return 1;
  2357. #endif
  2358. }
  2359. public OnPlayerStateChange(playerid, newstate, oldstate)
  2360. {
  2361. if (s_Spectating[playerid] != INVALID_PLAYER_ID && newstate != PLAYER_STATE_SPECTATING) {
  2362. s_Spectating[playerid] = INVALID_PLAYER_ID;
  2363. }
  2364. #if WC_CUSTOM_VENDING_MACHINES
  2365. if (s_VendingUseTimer[playerid] != -1) {
  2366. KillTimer(s_VendingUseTimer[playerid]);
  2367. s_VendingUseTimer[playerid] = -1;
  2368. }
  2369. #endif
  2370. if (s_IsDying[playerid] && (newstate == PLAYER_STATE_DRIVER || newstate == PLAYER_STATE_PASSENGER)) {
  2371. TogglePlayerControllable(playerid, false);
  2372. }
  2373. if (oldstate == PLAYER_STATE_DRIVER || oldstate == PLAYER_STATE_PASSENGER) {
  2374. s_LastVehicleTick[playerid] = GetTickCount();
  2375. if (newstate == PLAYER_STATE_ONFOOT) {
  2376. new Float:vx, Float:vy, Float:vz;
  2377. GetPlayerVelocity(playerid, vx, vy, vz);
  2378. if (vx*vx + vy*vy + vz*vz <= 0.05) {
  2379. for (new i = 0; i < MAX_PLAYERS; i++) {
  2380. if (i != playerid && IsPlayerConnected(i) && IsPlayerStreamedIn(playerid, i)) {
  2381. SendLastSyncData(playerid, i);
  2382. ClearAnimationsForPlayer(playerid, i);
  2383. }
  2384. }
  2385. }
  2386. }
  2387. }
  2388. switch (newstate) {
  2389. case PLAYER_STATE_ONFOOT,
  2390. PLAYER_STATE_DRIVER,
  2391. PLAYER_STATE_PASSENGER: {
  2392. SetHealthBarVisible(playerid, true);
  2393. }
  2394. default: {
  2395. SetHealthBarVisible(playerid, false);
  2396. }
  2397. }
  2398. #if defined WC_OnPlayerStateChange
  2399. return WC_OnPlayerStateChange(playerid, newstate, oldstate);
  2400. #else
  2401. return 1;
  2402. #endif
  2403. }
  2404. public OnPlayerPickUpPickup(playerid, pickupid)
  2405. {
  2406. if (!IsPlayerSpawned(playerid)) {
  2407. return 0;
  2408. }
  2409. #if defined WC_OnPlayerPickUpPickup
  2410. return WC_OnPlayerPickUpPickup(playerid, pickupid);
  2411. #else
  2412. return 1;
  2413. #endif
  2414. }
  2415. public OnPlayerUpdate(playerid)
  2416. {
  2417. if (s_IsDying[playerid]) {
  2418. return 1;
  2419. }
  2420. if (s_DeathSkip[playerid] == 1) {
  2421. if (s_DeathSkipTick[playerid]) {
  2422. if (GetTickCount() - s_DeathSkipTick[playerid] > 1000) {
  2423. new Float:x, Float:y, Float:z, Float:r;
  2424. GetPlayerPos(playerid, x, y, z);
  2425. GetPlayerFacingAngle(playerid, r);
  2426. SetSpawnInfo(playerid, 0xFE, GetPlayerSkin(playerid), x, y, z, r, 0, 0, 0, 0, 0, 0);
  2427. s_DeathSkipTick[playerid] = 0;
  2428. ApplyAnimation(playerid, "PED", "IDLE_stance", 4.1, 1, 0, 0, 0, 1, 1);
  2429. }
  2430. } else {
  2431. if (GetPlayerAnimationIndex(playerid) != 1189) {
  2432. s_DeathSkip[playerid] = 0;
  2433. WC_DeathSkipEnd(playerid);
  2434. DebugMessage(playerid, "Death skip end");
  2435. }
  2436. }
  2437. }
  2438. if (s_SpawnForStreamedIn[playerid]) {
  2439. WC_SpawnForStreamedIn(playerid);
  2440. s_SpawnForStreamedIn[playerid] = false;
  2441. }
  2442. new tick = GetTickCount();
  2443. s_LastUpdate[playerid] = tick;
  2444. // Detect fall damage based on velocity and animation
  2445. if (s_CustomFallDamage) {
  2446. new Float:vz, Float:z;
  2447. GetPlayerVelocity(playerid, vz, vz, vz);
  2448. GetPlayerPos(playerid, z, z, z);
  2449. new surfing = GetPlayerSurfingVehicleID(playerid);
  2450. if (surfing && surfing == INVALID_VEHICLE_ID) {
  2451. surfing = GetPlayerSurfingObjectID(playerid) != INVALID_OBJECT_ID;
  2452. } else {
  2453. surfing = 1;
  2454. }
  2455. if (surfing || tick - s_LastStop[playerid] < 2000) {
  2456. vz = 0.0;
  2457. s_LastZVelo[playerid] = 0.0;
  2458. } else {
  2459. if (vz != 0.0) {
  2460. s_LastZVelo[playerid] = vz;
  2461. }
  2462. if (z - s_LastZ[playerid] > 1.0) {
  2463. s_LastZVelo[playerid] = 0.1;
  2464. vz = 0.1;
  2465. }
  2466. }
  2467. s_LastZ[playerid] = z;
  2468. new anim = GetPlayerAnimationIndex(playerid);
  2469. if (anim != s_LastAnim[playerid]) {
  2470. new prev = s_LastAnim[playerid];
  2471. s_LastAnim[playerid] = anim;
  2472. if (((prev == 1130 && vz == 0.0) || 1128 <= anim <= 1134 || anim == 1208)) {
  2473. new Float:amount = -1.0;
  2474. DebugMessage(playerid, "vz: %f anim: %d prev: %d", vz, anim, prev);
  2475. vz = s_LastZVelo[playerid];
  2476. if (vz <= s_FallDeathVelocity) {
  2477. amount = 0.0;
  2478. } else if (vz <= -0.2) {
  2479. if (vz == -0.2) {
  2480. amount = s_WeaponDamage[WEAPON_COLLISION] * 0.2;
  2481. } else {
  2482. amount = (vz + 0.2) / (s_FallDeathVelocity + 0.2);
  2483. amount *= s_WeaponDamage[WEAPON_COLLISION];
  2484. }
  2485. }
  2486. if (GetPlayerWeapon(playerid) == WEAPON_PARACHUTE && anim == 1134) {
  2487. amount = -1.0;
  2488. }
  2489. if (amount >= 0.0) {
  2490. DebugMessage(playerid, "fall dmg: %.5f (vz: %f, anim: %d, prev: %d)", amount, vz, anim, prev);
  2491. InflictDamage(playerid, amount, INVALID_PLAYER_ID, WEAPON_COLLISION, 3);
  2492. if (amount == 0.0) {
  2493. amount = s_PlayerHealth[playerid];
  2494. }
  2495. }
  2496. }
  2497. }
  2498. }
  2499. #if defined WC_OnPlayerUpdate
  2500. return WC_OnPlayerUpdate(playerid);
  2501. #else
  2502. return 1;
  2503. #endif
  2504. }
  2505. public OnPlayerGiveDamage(playerid, damagedid, Float:amount, weaponid, bodypart)
  2506. {
  2507. if (!IsHighRateWeapon(weaponid)) {
  2508. DebugMessage(playerid, "OnPlayerGiveDamage(%d gave %f to %d using %d on bodypart %d)", playerid, amount, damagedid, weaponid, bodypart);
  2509. }
  2510. // Nobody got damaged
  2511. if (damagedid == INVALID_PLAYER_ID) {
  2512. #if defined OnInvalidWeaponDamage
  2513. OnInvalidWeaponDamage(playerid, damagedid, amount, weaponid, bodypart, WC_NO_DAMAGED, true);
  2514. #endif
  2515. AddRejectedHit(playerid, damagedid, HIT_NO_DAMAGEDID, weaponid);
  2516. return 0;
  2517. }
  2518. if (s_IsDying[damagedid]) {
  2519. AddRejectedHit(playerid, damagedid, HIT_DYING_PLAYER, weaponid);
  2520. return 0;
  2521. }
  2522. if (!s_LagCompMode) {
  2523. new npc = IsPlayerNPC(damagedid);
  2524. if (weaponid == WEAPON_KNIFE && _:amount == _:0.0) {
  2525. if (s_KnifeTimeout[damagedid] != -1) {
  2526. KillTimer(s_KnifeTimeout[damagedid]);
  2527. }
  2528. s_KnifeTimeout[damagedid] = SetTimerEx("WC_SetSpawnForStreamedIn", 2500, false, "i", damagedid);
  2529. }
  2530. if (!npc) {
  2531. return 0;
  2532. }
  2533. }
  2534. // Ignore unreliable and invalid damage
  2535. if (weaponid < 0 || weaponid >= sizeof(s_ValidDamageGiven) || !s_ValidDamageGiven[weaponid]) {
  2536. // Fire is synced as taken damage (because it's not reliable as given), so no need to show a rejected hit.
  2537. // Vehicle damage is also synced as taken, so no need to show that either.
  2538. if (weaponid != WEAPON_FLAMETHROWER && weaponid != WEAPON_VEHICLE) {
  2539. AddRejectedHit(playerid, damagedid, HIT_INVALID_WEAPON, weaponid);
  2540. }
  2541. return 0;
  2542. }
  2543. if (!IsPlayerSpawned(playerid)) {
  2544. // Make sure the rejected hit wasn't added in OnPlayerWeaponShot
  2545. if (!IsBulletWeapon(weaponid) || s_LastShot[playerid][e_Valid]) {
  2546. AddRejectedHit(playerid, damagedid, HIT_NOT_SPAWNED, weaponid);
  2547. }
  2548. return 0;
  2549. }
  2550. new npc = IsPlayerNPC(damagedid);
  2551. // From stealth knife, can be any weapon
  2552. if (_:amount == _:1833.33154296875) {
  2553. return 0;
  2554. }
  2555. if (weaponid == WEAPON_KNIFE) {
  2556. if (_:amount == _:0.0) {
  2557. // Resync without bothering the player being knifed
  2558. if (npc || HasSameTeam(playerid, damagedid)) {
  2559. if (s_KnifeTimeout[damagedid] != -1) {
  2560. KillTimer(s_KnifeTimeout[damagedid]);
  2561. }
  2562. s_KnifeTimeout[damagedid] = SetTimerEx("WC_SpawnForStreamedIn", 150, false, "i", damagedid);
  2563. ClearAnimations(playerid, 1);
  2564. SetPlayerArmedWeapon(playerid, 0);
  2565. return 0;
  2566. }
  2567. if (!OnPlayerDamage(damagedid, amount, playerid, weaponid, bodypart)) {
  2568. if (s_KnifeTimeout[damagedid] != -1) {
  2569. KillTimer(s_KnifeTimeout[damagedid]);
  2570. }
  2571. s_KnifeTimeout[damagedid] = SetTimerEx("WC_SpawnForStreamedIn", 150, false, "i", damagedid);
  2572. ClearAnimations(playerid, 1);
  2573. SetPlayerArmedWeapon(playerid, 0);
  2574. return 0;
  2575. }
  2576. s_DamageDoneHealth[playerid] = s_PlayerHealth[playerid];
  2577. s_DamageDoneArmour[playerid] = s_PlayerArmour[playerid];
  2578. OnPlayerDamageDone(damagedid, s_PlayerHealth[damagedid] + s_PlayerArmour[damagedid], playerid, weaponid, bodypart);
  2579. ClearAnimations(damagedid, 1);
  2580. PlayerDeath(damagedid, "KNIFE", "KILL_Knife_Ped_Damage", _, 5200);
  2581. SetTimerEx("WC_SecondKnifeAnim", 2200, false, "i", damagedid);
  2582. #if defined WC_OnPlayerDeath
  2583. WC_OnPlayerDeath(damagedid, playerid, weaponid);
  2584. #endif
  2585. DebugMessage(damagedid, "being knifed by %d", playerid);
  2586. DebugMessage(playerid, "knifing %d", damagedid);
  2587. new Float:x, Float:y, Float:z, Float:a;
  2588. GetPlayerFacingAngle(damagedid, a);
  2589. SetPlayerFacingAngle(playerid, a);
  2590. PosInFront(damagedid, -1.0, x, y, z);
  2591. SetPlayerVelocity(damagedid, 0.0, 0.0, 0.0);
  2592. SetPlayerVelocity(playerid, 0.0, 0.0, 0.0);
  2593. new forcesync = 2;
  2594. if (747 < GetPlayerAnimationIndex(playerid) > 748) {
  2595. DebugMessageRed(playerid, "applying knife anim for you too (current: %d)", GetPlayerAnimationIndex(playerid));
  2596. forcesync = 1;
  2597. }
  2598. ApplyAnimation(playerid, "KNIFE", "KILL_Knife_Player", 4.1, 0, 1, 1, 0, 1800, forcesync);
  2599. return 0;
  2600. }
  2601. }
  2602. if (HasSameTeam(playerid, damagedid)) {
  2603. AddRejectedHit(playerid, damagedid, HIT_SAME_TEAM, weaponid);
  2604. return 0;
  2605. }
  2606. // Both players should see eachother
  2607. if ((!IsPlayerStreamedIn(playerid, damagedid) && !IsPlayerPaused(damagedid)) || !IsPlayerStreamedIn(damagedid, playerid)) {
  2608. AddRejectedHit(playerid, damagedid, HIT_UNSTREAMED, weaponid, damagedid);
  2609. return 0;
  2610. }
  2611. new Float:bullets, err;
  2612. if ((err = ProcessDamage(damagedid, playerid, amount, weaponid, bodypart, bullets))) {
  2613. if (err == WC_INVALID_DAMAGE) {
  2614. AddRejectedHit(playerid, damagedid, HIT_INVALID_DAMAGE, weaponid, _:amount);
  2615. }
  2616. if (err != WC_INVALID_DISTANCE) {
  2617. #if defined OnInvalidWeaponDamage
  2618. OnInvalidWeaponDamage(playerid, damagedid, amount, weaponid, bodypart, err, true);
  2619. #endif
  2620. }
  2621. return 0;
  2622. }
  2623. new tick = GetTickCount();
  2624. if (tick == 0) tick = 1;
  2625. new idx = (s_LastHitIdx[playerid] + 1) % sizeof(s_LastHitTicks[]);
  2626. // JIT plugin fix
  2627. if (idx < 0) {
  2628. idx += sizeof(s_LastHitTicks[]);
  2629. }
  2630. s_LastHitIdx[playerid] = idx;
  2631. s_LastHitTicks[playerid][idx] = tick;
  2632. s_LastHitWeapons[playerid][idx] = weaponid;
  2633. s_HitsIssued[playerid] += 1;
  2634. #if WC_DEBUG
  2635. if (s_HitsIssued[playerid] > 1) {
  2636. new prev_tick_idx = (idx - 1) % sizeof(s_LastHitTicks[]);
  2637. // JIT plugin fix
  2638. if (prev_tick_idx < 0) {
  2639. prev_tick_idx += sizeof(s_LastHitTicks[]);
  2640. }
  2641. new prev_tick = s_LastHitTicks[playerid][prev_tick_idx];
  2642. DebugMessage(playerid, "(hit) last: %d last 3: %d", tick - prev_tick, AverageHitRate(playerid, 3));
  2643. }
  2644. #endif
  2645. new multiple_weapons;
  2646. new avg_rate = AverageHitRate(playerid, s_MaxHitRateSamples, multiple_weapons);
  2647. // Hit issue flood?
  2648. // Could be either a cheat or just lag
  2649. if (avg_rate != -1) {
  2650. if (multiple_weapons) {
  2651. if (avg_rate < 100) {
  2652. AddRejectedHit(playerid, damagedid, HIT_RATE_TOO_FAST_MULTIPLE, weaponid, avg_rate, s_MaxHitRateSamples);
  2653. return 0;
  2654. }
  2655. } else if (s_MaxWeaponShootRate[weaponid] - avg_rate > 20) {
  2656. AddRejectedHit(playerid, damagedid, HIT_RATE_TOO_FAST, weaponid, avg_rate, s_MaxHitRateSamples, s_MaxWeaponShootRate[weaponid]);
  2657. return 0;
  2658. }
  2659. }
  2660. if (IsBulletWeapon(weaponid) && _:amount != _:2.6400001049041748046875 && !(IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleSeat(playerid) == 0)) {
  2661. new valid = true;
  2662. if (!s_LastShot[playerid][e_Valid]) {
  2663. //AddRejectedHit(playerid, damagedid, HIT_LAST_SHOT_INVALID, weaponid);
  2664. valid = false;
  2665. DebugMessageRed(playerid, "last shot not valid");
  2666. } else if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  2667. // Let's assume someone won't hit 3 players with 1 shotgun shot, and that one OnPlayerWeaponShot can be out of sync
  2668. if (s_LastShot[playerid][e_Hits] >= 3) {
  2669. valid = false;
  2670. AddRejectedHit(playerid, damagedid, HIT_MULTIPLE_PLAYERS_SHOTGUN, weaponid, s_LastShot[playerid][e_Hits] + 1);
  2671. }
  2672. } else if (s_LastShot[playerid][e_Hits] > 0) {
  2673. // Sniper doesn't always send OnPlayerWeaponShot
  2674. if (s_LastShot[playerid][e_Hits] > 4 && weaponid != WEAPON_SNIPER) {
  2675. valid = false;
  2676. AddRejectedHit(playerid, damagedid, HIT_MULTIPLE_PLAYERS, weaponid, s_LastShot[playerid][e_Hits] + 1);
  2677. } else {
  2678. DebugMessageRed(playerid, "hit %d players with 1 shot", s_LastShot[playerid][e_Hits] + 1);
  2679. }
  2680. }
  2681. s_LastShot[playerid][e_Hits] += 1;
  2682. if (!valid) {
  2683. return 0;
  2684. }
  2685. }
  2686. if (npc) {
  2687. OnPlayerDamageDone(damagedid, amount, playerid, weaponid, bodypart);
  2688. } else {
  2689. InflictDamage(damagedid, amount, playerid, weaponid, bodypart);
  2690. }
  2691. // Don't send OnPlayerGiveDamage to the rest of the script, since it should not be used
  2692. return 0;
  2693. }
  2694. public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid, bodypart)
  2695. {
  2696. UpdateHealthBar(playerid, true);
  2697. if (s_IsDying[playerid]) {
  2698. return 0;
  2699. }
  2700. if (s_BeingResynced[playerid]) {
  2701. return 0;
  2702. }
  2703. if (!IsHighRateWeapon(weaponid)) {
  2704. DebugMessage(playerid, "OnPlayerTakeDamage(%d took %f from %d by %d on bodypart %d)", playerid, amount, issuerid, weaponid, bodypart);
  2705. }
  2706. // Ignore unreliable and invalid damage
  2707. if (weaponid < 0 || weaponid >= sizeof(s_ValidDamageTaken) || !s_ValidDamageTaken[weaponid]) {
  2708. return 0;
  2709. }
  2710. if (playerid == INVALID_PLAYER_ID || IsPlayerNPC(playerid)) {
  2711. return 0;
  2712. }
  2713. // Carjack damage
  2714. if (weaponid == 54 && _:amount == _:0.0) {
  2715. return 0;
  2716. }
  2717. // From stealth knife, can be any weaponid
  2718. if (_:amount == _:1833.33154296875) {
  2719. return 0;
  2720. }
  2721. // Climb bug
  2722. if (weaponid == WEAPON_COLLISION) {
  2723. if (s_CustomFallDamage) {
  2724. return 0;
  2725. }
  2726. new anim = GetPlayerAnimationIndex(playerid);
  2727. if (1061 <= anim <= 1067) {
  2728. DebugMessage(playerid, "climb bug prevented");
  2729. return 0;
  2730. }
  2731. }
  2732. // Being knifed client-side
  2733. if (weaponid == WEAPON_KNIFE) {
  2734. if (s_IsDying[playerid]) {
  2735. return 0;
  2736. }
  2737. // With the plugin, this part is never actually used (it can't happen)
  2738. if (_:amount == _:0.0) {
  2739. if (s_KnifeTimeout[playerid] != -1) {
  2740. KillTimer(s_KnifeTimeout[playerid]);
  2741. s_KnifeTimeout[playerid] = -1;
  2742. }
  2743. if (issuerid == INVALID_PLAYER_ID || HasSameTeam(playerid, issuerid)) {
  2744. ResyncPlayer(playerid);
  2745. return 0;
  2746. }
  2747. if (!OnPlayerDamage(playerid, amount, issuerid, weaponid, bodypart)) {
  2748. ResyncPlayer(playerid);
  2749. return 0;
  2750. }
  2751. // Make sure the values were not modified
  2752. weaponid = WEAPON_KNIFE;
  2753. amount = 0.0;
  2754. s_DamageDoneHealth[playerid] = s_PlayerHealth[playerid];
  2755. s_DamageDoneArmour[playerid] = s_PlayerArmour[playerid];
  2756. OnPlayerDamageDone(playerid, s_PlayerHealth[playerid] + s_PlayerArmour[playerid], issuerid, weaponid, bodypart);
  2757. PlayerDeath(playerid, "KNIFE", "KILL_Knife_Ped_Die", _, 4000 - GetPlayerPing(playerid));
  2758. #if defined WC_OnPlayerDeath
  2759. WC_OnPlayerDeath(playerid, issuerid, weaponid);
  2760. #endif
  2761. SetPlayerHealth(playerid, Float:0x7f7fffff);
  2762. DebugMessage(playerid, "being knifed by %d", issuerid);
  2763. DebugMessage(issuerid, "knifing %d", playerid);
  2764. new Float:x, Float:y, Float:z, Float:a;
  2765. GetPlayerFacingAngle(playerid, a);
  2766. SetPlayerFacingAngle(issuerid, a);
  2767. PosInFront(playerid, -1.0, x, y, z);
  2768. SetPlayerVelocity(playerid, 0.0, 0.0, 0.0);
  2769. SetPlayerVelocity(issuerid, 0.0, 0.0, 0.0);
  2770. new forcesync = 2;
  2771. if (GetPlayerAnimationIndex(issuerid) != 747) {
  2772. DebugMessageRed(issuerid, "applying knife anim for you too (current: %d)", GetPlayerAnimationIndex(issuerid));
  2773. forcesync = 1;
  2774. }
  2775. ApplyAnimation(issuerid, "KNIFE", "KILL_Knife_Player", 4.1, 0, 1, 1, 0, 1800, forcesync);
  2776. return 0;
  2777. }
  2778. }
  2779. // If it's lagcomp, only allow damage that's valid for both modes
  2780. if (s_LagCompMode && s_ValidDamageTaken[weaponid] != 2) {
  2781. if (issuerid != INVALID_PLAYER_ID && IsPlayerInAnyVehicle(issuerid) && GetPlayerVehicleSeat(issuerid) == 0 && (weaponid == WEAPON_M4 || weaponid == WEAPON_MINIGUN)) {
  2782. weaponid = weaponid == WEAPON_M4 ? WEAPON_VEHICLE_M4 : WEAPON_VEHICLE_MINIGUN;
  2783. } else {
  2784. return 0;
  2785. }
  2786. }
  2787. // Should still be damaged by grenades or fire after someone has died
  2788. if (issuerid != INVALID_PLAYER_ID) {
  2789. if (HasSameTeam(playerid, issuerid)) {
  2790. return 0;
  2791. }
  2792. if (s_IsDying[issuerid] && (IsBulletWeapon(weaponid) || IsMeleeWeapon(weaponid))) {
  2793. DebugMessageRed(playerid, "shot/punched by dead player (%d)", issuerid);
  2794. return 0;
  2795. }
  2796. if (s_BeingResynced[issuerid]) {
  2797. return 0;
  2798. }
  2799. }
  2800. new Float:bullets = 0.0, err;
  2801. if ((err = ProcessDamage(playerid, issuerid, amount, weaponid, bodypart, bullets))) {
  2802. if (err == WC_INVALID_DAMAGE) {
  2803. AddRejectedHit(issuerid, playerid, HIT_INVALID_DAMAGE, weaponid, _:amount);
  2804. }
  2805. if (err != WC_INVALID_DISTANCE) {
  2806. #if defined OnInvalidWeaponDamage
  2807. OnInvalidWeaponDamage(issuerid, playerid, amount, weaponid, bodypart, err, false);
  2808. #endif
  2809. }
  2810. return 0;
  2811. }
  2812. if (IsBulletWeapon(weaponid)) {
  2813. new Float:x, Float:y, Float:z;
  2814. GetPlayerPos(issuerid, x, y, z);
  2815. new Float:dist = GetPlayerDistanceFromPoint(playerid, x, y, z);
  2816. if (dist > s_WeaponRange[weaponid] + 2.0) {
  2817. AddRejectedHit(issuerid, playerid, HIT_OUT_OF_RANGE, weaponid, _:dist, _:s_WeaponRange[weaponid]);
  2818. return 0;
  2819. }
  2820. }
  2821. InflictDamage(playerid, amount, issuerid, weaponid, bodypart);
  2822. return 0;
  2823. }
  2824. public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
  2825. {
  2826. #if WC_CUSTOM_VENDING_MACHINES
  2827. if (s_VendingUseTimer[playerid] != -1) {
  2828. KillTimer(s_VendingUseTimer[playerid]);
  2829. s_VendingUseTimer[playerid] = -1;
  2830. }
  2831. #endif
  2832. s_LastShot[playerid][e_Valid] = false;
  2833. s_LastShot[playerid][e_Hits] = false;
  2834. if (s_CbugFroze[playerid] && GetTickCount() - s_CbugFroze[playerid] < 900) {
  2835. return 0;
  2836. }
  2837. s_CbugFroze[playerid] = 0;
  2838. new damagedid = INVALID_PLAYER_ID;
  2839. if (hittype == BULLET_HIT_TYPE_PLAYER && hitid != INVALID_PLAYER_ID) {
  2840. if (!IsPlayerConnected(hitid)) {
  2841. AddRejectedHit(playerid, hitid, HIT_DISCONNECTED, weaponid, hitid);
  2842. return 0;
  2843. }
  2844. damagedid = hitid;
  2845. }
  2846. if (hittype < 0 || hittype > 5) {
  2847. AddRejectedHit(playerid, damagedid, HIT_INVALID_HITTYPE, weaponid, hittype);
  2848. return 0;
  2849. }
  2850. #if WC_DEBUG
  2851. if (hittype == BULLET_HIT_TYPE_PLAYER) {
  2852. DebugMessage(playerid, "OnPlayerWeaponShot(%d shot %d with %d at %f, %f, %f)", playerid, hitid, weaponid, fX, fY, fZ);
  2853. } else if (hittype) {
  2854. DebugMessage(playerid, "OnPlayerWeaponShot(%d shot %d %d with %d at %f, %f, %f)", playerid, hittype, hitid, weaponid, fX, fY, fZ);
  2855. } else {
  2856. DebugMessage(playerid, "OnPlayerWeaponShot(%d shot with %d at %f, %f, %f)", playerid, weaponid, fX, fY, fZ);
  2857. }
  2858. #endif
  2859. if (s_BeingResynced[playerid]) {
  2860. AddRejectedHit(playerid, damagedid, HIT_BEING_RESYNCED, weaponid);
  2861. return 0;
  2862. }
  2863. if (!IsPlayerSpawned(playerid)) {
  2864. AddRejectedHit(playerid, damagedid, HIT_NOT_SPAWNED, weaponid);
  2865. return 0;
  2866. }
  2867. if (!IsBulletWeapon(weaponid)) {
  2868. AddRejectedHit(playerid, damagedid, HIT_INVALID_WEAPON, weaponid);
  2869. return 0;
  2870. }
  2871. new Float:fOriginX, Float:fOriginY, Float:fOriginZ, Float:fHitPosX, Float:fHitPosY, Float:fHitPosZ;
  2872. new Float:x, Float:y, Float:z;
  2873. GetPlayerPos(playerid, x, y, z);
  2874. GetPlayerLastShotVectors(playerid, fOriginX, fOriginY, fOriginZ, fHitPosX, fHitPosY, fHitPosZ);
  2875. new Float:length = VectorSize(fOriginX - fHitPosX, fOriginY - fHitPosY, fOriginZ - fHitPosZ);
  2876. new Float:origin_dist = VectorSize(fOriginX - x, fOriginY - y, fOriginZ - z);
  2877. if (origin_dist > 15.0) {
  2878. new in_veh = IsPlayerInAnyVehicle(hitid) || GetPlayerSurfingVehicleID(playerid);
  2879. if ((!in_veh && GetPlayerSurfingVehicleID(playerid) == INVALID_VEHICLE_ID) || origin_dist > 50.0) {
  2880. AddRejectedHit(playerid, damagedid, HIT_TOO_FAR_FROM_ORIGIN, weaponid, _:origin_dist);
  2881. return 0;
  2882. }
  2883. }
  2884. // Shot exceeding the max range?
  2885. if (hittype != BULLET_HIT_TYPE_NONE) {
  2886. if (length > s_WeaponRange[weaponid]) {
  2887. if (hittype == BULLET_HIT_TYPE_PLAYER) {
  2888. AddRejectedHit(playerid, damagedid, HIT_OUT_OF_RANGE, weaponid, _:length, _:s_WeaponRange[weaponid]);
  2889. }
  2890. return 0;
  2891. }
  2892. if (hittype == BULLET_HIT_TYPE_PLAYER) {
  2893. if (IsPlayerInAnyVehicle(playerid) && GetPlayerVehicleID(playerid) == GetPlayerVehicleID(hitid)) {
  2894. AddRejectedHit(playerid, damagedid, HIT_SAME_VEHICLE, weaponid);
  2895. return 0;
  2896. }
  2897. new Float:dist = GetPlayerDistanceFromPoint(hitid, fHitPosX, fHitPosY, fHitPosZ);
  2898. new in_veh = IsPlayerInAnyVehicle(hitid);
  2899. if ((!in_veh && dist > 20.0) || dist > 50.0) {
  2900. AddRejectedHit(playerid, damagedid, HIT_TOO_FAR_FROM_SHOT, weaponid, _:dist);
  2901. return 0;
  2902. }
  2903. }
  2904. }
  2905. new tick = GetTickCount();
  2906. if (tick == 0) tick = 1;
  2907. new idx = (s_LastShotIdx[playerid] + 1) % sizeof(s_LastShotTicks[]);
  2908. // JIT plugin fix
  2909. if (idx < 0) {
  2910. idx += sizeof(s_LastShotTicks[]);
  2911. }
  2912. s_LastShotIdx[playerid] = idx;
  2913. s_LastShotTicks[playerid][idx] = tick;
  2914. s_LastShotWeapons[playerid][idx] = weaponid;
  2915. s_ShotsFired[playerid] += 1;
  2916. #if WC_DEBUG
  2917. if (s_ShotsFired[playerid] > 1) {
  2918. new prev_tick_idx = (idx - 1) % sizeof(s_LastShotTicks[]);
  2919. // JIT plugin fix
  2920. if (prev_tick_idx < 0) {
  2921. prev_tick_idx += sizeof(s_LastShotTicks[]);
  2922. }
  2923. new prev_tick = s_LastShotTicks[playerid][prev_tick_idx];
  2924. DebugMessage(playerid, "(shot) last: %d last 3: %d", tick - prev_tick, AverageShootRate(playerid, 3));
  2925. }
  2926. #endif
  2927. s_LastShot[playerid][e_Tick] = tick;
  2928. s_LastShot[playerid][e_Weapon] = weaponid;
  2929. s_LastShot[playerid][e_HitType] = hittype;
  2930. s_LastShot[playerid][e_HitId] = hitid;
  2931. s_LastShot[playerid][e_X] = fX;
  2932. s_LastShot[playerid][e_Y] = fY;
  2933. s_LastShot[playerid][e_Z] = fZ;
  2934. s_LastShot[playerid][e_OX] = fOriginX;
  2935. s_LastShot[playerid][e_OY] = fOriginY;
  2936. s_LastShot[playerid][e_OZ] = fOriginZ;
  2937. s_LastShot[playerid][e_HX] = fHitPosX;
  2938. s_LastShot[playerid][e_HY] = fHitPosY;
  2939. s_LastShot[playerid][e_HZ] = fHitPosZ;
  2940. s_LastShot[playerid][e_Length] = length;
  2941. s_LastShot[playerid][e_Hits] = 0;
  2942. new multiple_weapons;
  2943. new avg_rate = AverageShootRate(playerid, s_MaxShootRateSamples, multiple_weapons);
  2944. // Bullet flood?
  2945. // Could be either a cheat or just lag
  2946. if (avg_rate != -1) {
  2947. if (multiple_weapons) {
  2948. if (avg_rate < 100) {
  2949. AddRejectedHit(playerid, damagedid, SHOOTING_RATE_TOO_FAST_MULTIPLE, weaponid, avg_rate, s_MaxShootRateSamples);
  2950. return 0;
  2951. }
  2952. } else if (s_MaxWeaponShootRate[weaponid] - avg_rate > 20) {
  2953. AddRejectedHit(playerid, damagedid, SHOOTING_RATE_TOO_FAST, weaponid, avg_rate, s_MaxShootRateSamples, s_MaxWeaponShootRate[weaponid]);
  2954. return 0;
  2955. }
  2956. }
  2957. // Destroy vehicles with passengers in them
  2958. if (hittype == BULLET_HIT_TYPE_VEHICLE) {
  2959. if (hitid < 0 || hitid > MAX_VEHICLES || !WC_IsValidVehicle(hitid)) {
  2960. AddRejectedHit(playerid, damagedid, HIT_INVALID_VEHICLE, weaponid, hitid);
  2961. return 0;
  2962. }
  2963. new vehicleid = GetPlayerVehicleID(playerid);
  2964. // Shouldn't be possible to damage the vehicle you're in
  2965. if (hitid == vehicleid) {
  2966. AddRejectedHit(playerid, damagedid, HIT_OWN_VEHICLE, weaponid);
  2967. return 0;
  2968. }
  2969. if (s_VehiclePassengerDamage) {
  2970. new has_driver = false;
  2971. new has_passenger = false;
  2972. for (new otherid = 0; otherid < MAX_PLAYERS; otherid++) {
  2973. if (otherid == playerid || !IsPlayerConnected(otherid)) {
  2974. continue;
  2975. }
  2976. if (GetPlayerVehicleID(otherid) != hitid) {
  2977. continue;
  2978. }
  2979. new seat = GetPlayerVehicleSeat(otherid);
  2980. if (seat == 0) {
  2981. has_driver = true;
  2982. } else {
  2983. has_passenger = true;
  2984. }
  2985. }
  2986. if (!has_driver && has_passenger) {
  2987. new Float:health;
  2988. GetVehicleHealth(hitid, health);
  2989. if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  2990. health -= 120.0;
  2991. } else {
  2992. health -= s_WeaponDamage[weaponid] * 3.0;
  2993. }
  2994. if (health <= 0.0) {
  2995. health = 0.0;
  2996. }
  2997. SetVehicleHealth(hitid, health);
  2998. }
  2999. }
  3000. if (s_VehicleUnoccupiedDamage) {
  3001. new has_occupent = false;
  3002. for (new otherid = 0; otherid < MAX_PLAYERS; otherid++) {
  3003. if (otherid == playerid || !IsPlayerConnected(otherid)) {
  3004. continue;
  3005. }
  3006. if (GetPlayerVehicleID(otherid) != hitid) {
  3007. continue;
  3008. }
  3009. has_occupent = true;
  3010. }
  3011. if (!has_occupent) {
  3012. new Float:health;
  3013. GetVehicleHealth(hitid, health);
  3014. 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
  3015. if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  3016. health -= 120.0;
  3017. } else {
  3018. health -= s_WeaponDamage[weaponid] * 3.0;
  3019. }
  3020. if (health <= 249.0) {
  3021. if (s_VehicleRespawnTimer[hitid] == -1) {
  3022. health = 249.0;
  3023. s_VehicleRespawnTimer[hitid] = SetTimerEx("WC_KillVehicle", 6000, false, "ii", hitid, playerid);
  3024. }
  3025. }
  3026. SetVehicleHealth(hitid, health);
  3027. }
  3028. }
  3029. }
  3030. }
  3031. new retval = 1;
  3032. #if defined WC_OnPlayerWeaponShot
  3033. retval = WC_OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, fX, fY, fZ);
  3034. #else
  3035. retval = 1;
  3036. #endif
  3037. s_LastShot[playerid][e_Valid] = !!retval;
  3038. // Valid shot?
  3039. if (retval) {
  3040. if (hittype == BULLET_HIT_TYPE_VEHICLE) {
  3041. s_LastVehicleShooter[hitid] = playerid;
  3042. }
  3043. }
  3044. return retval;
  3045. }
  3046. forward WC_KillVehicle(vehicleid, killerid);
  3047. public WC_KillVehicle(vehicleid, killerid)
  3048. {
  3049. OnVehicleDeath(vehicleid, killerid);
  3050. s_VehicleRespawnTimer[vehicleid] = SetTimerEx("WC_OnDeadVehicleSpawn", 10000, false, "i", vehicleid);
  3051. return 1;
  3052. }
  3053. forward WC_OnDeadVehicleSpawn(vehicleid);
  3054. public WC_OnDeadVehicleSpawn(vehicleid)
  3055. {
  3056. s_VehicleRespawnTimer[vehicleid] = -1;
  3057. return SetVehicleToRespawn(vehicleid);
  3058. }
  3059. public OnVehicleSpawn(vehicleid)
  3060. {
  3061. if (s_VehicleRespawnTimer[vehicleid] != -1) {
  3062. KillTimer(s_VehicleRespawnTimer[vehicleid]);
  3063. s_VehicleRespawnTimer[vehicleid] = -1;
  3064. }
  3065. s_VehicleAlive[vehicleid] = true;
  3066. #if defined WC_OnVehicleSpawn
  3067. return WC_OnVehicleSpawn(vehicleid);
  3068. #else
  3069. return 1;
  3070. #endif
  3071. }
  3072. public OnVehicleDeath(vehicleid, killerid)
  3073. {
  3074. if (s_VehicleRespawnTimer[vehicleid] != -1) {
  3075. KillTimer(s_VehicleRespawnTimer[vehicleid]);
  3076. s_VehicleRespawnTimer[vehicleid] = -1;
  3077. }
  3078. if (s_VehicleAlive[vehicleid]) {
  3079. s_VehicleAlive[vehicleid] = false;
  3080. #if defined WC_OnVehicleDeath
  3081. return WC_OnVehicleDeath(vehicleid, killerid);
  3082. #else
  3083. return 1;
  3084. #endif
  3085. }
  3086. return 1;
  3087. }
  3088. public OnPlayerEnterCheckpoint(playerid)
  3089. {
  3090. if (!IsPlayerSpawned(playerid)) {
  3091. return 1;
  3092. }
  3093. #if defined WC_OnPlayerEnterCheckpoint
  3094. return WC_OnPlayerEnterCheckpoint(playerid);
  3095. #else
  3096. return 1;
  3097. #endif
  3098. }
  3099. public OnPlayerLeaveCheckpoint(playerid)
  3100. {
  3101. // If they're dying, it will be called in PlayerDeath (when the death anim begins)
  3102. if (s_IsDying[playerid]) {
  3103. return 1;
  3104. }
  3105. #if defined WC_OnPlayerLeaveCheckpoint
  3106. return WC_OnPlayerLeaveCheckpoint(playerid);
  3107. #else
  3108. return 1;
  3109. #endif
  3110. }
  3111. /*
  3112. * Internal functions
  3113. */
  3114. static ScriptInit()
  3115. {
  3116. s_LagCompMode = GetServerVarAsInt("lagcompmode");
  3117. if (s_LagCompMode) {
  3118. SetKnifeSync(false);
  3119. } else {
  3120. s_DamageTakenSound = 0;
  3121. SetKnifeSync(true);
  3122. }
  3123. for (new i = 0; i < sizeof(s_ClassSpawnInfo); i++) {
  3124. s_ClassSpawnInfo[i][e_Skin] = -1;
  3125. }
  3126. s_HealthBarBorder = TextDrawCreate(610.01, 68.25, "\1");
  3127. if (s_HealthBarBorder == Text:INVALID_TEXT_DRAW) {
  3128. printf("(wc) WARN: Unable to create healthbar border textdraw");
  3129. } else {
  3130. s_InternalTextDraw[s_HealthBarBorder] = true;
  3131. TextDrawUseBox (s_HealthBarBorder, 1);
  3132. TextDrawLetterSize(s_HealthBarBorder, 0.0, 0.64);
  3133. TextDrawTextSize (s_HealthBarBorder, 543.75, 0.0);
  3134. TextDrawBoxColor (s_HealthBarBorder, 0x000000FF);
  3135. }
  3136. s_HealthBarBackground = TextDrawCreate(608.01, 70.25, "\1");
  3137. if (s_HealthBarBackground == Text:INVALID_TEXT_DRAW) {
  3138. printf("(wc) WARN: Unable to create healthbar background textdraw");
  3139. } else {
  3140. s_InternalTextDraw[s_HealthBarBackground] = true;
  3141. TextDrawUseBox (s_HealthBarBackground, 1);
  3142. TextDrawLetterSize(s_HealthBarBackground, 0.0, 0.2);
  3143. TextDrawTextSize (s_HealthBarBackground, 545.75, 0.0);
  3144. TextDrawBoxColor (s_HealthBarBackground, 0x5A0C10FF);
  3145. }
  3146. #if WC_CUSTOM_VENDING_MACHINES
  3147. if (s_CustomVendingMachines) {
  3148. CreateVendingMachines();
  3149. }
  3150. #endif
  3151. new tick = GetTickCount();
  3152. for (new playerid = 0; playerid < MAX_PLAYERS; playerid++) {
  3153. if (!IsPlayerConnected(playerid)) {
  3154. continue;
  3155. }
  3156. new team = GetPlayerTeam(playerid);
  3157. if (team == 0xFE) {
  3158. s_PlayerTeam[playerid] = NO_TEAM;
  3159. } else {
  3160. s_PlayerTeam[playerid] = team;
  3161. }
  3162. SetPlayerTeam(playerid, 0xFE);
  3163. DamageFeedUpdate(playerid);
  3164. new worldid = GetPlayerVirtualWorld(playerid);
  3165. if (worldid == WC_DEATH_WORLD) {
  3166. worldid = 0;
  3167. SetPlayerVirtualWorld(playerid, worldid);
  3168. }
  3169. s_World[playerid] = worldid;
  3170. s_LastUpdate[playerid] = tick;
  3171. s_DamageFeedLastUpdate[playerid] = tick;
  3172. s_LastStop[playerid] = tick;
  3173. s_LastVehicleEnterTime[playerid] = 0;
  3174. s_TrueDeath[playerid] = true;
  3175. s_InClassSelection[playerid] = true;
  3176. s_PlayerFallbackSpawnInfo[playerid][e_Skin] = -1;
  3177. s_AlreadyConnected[playerid] = true;
  3178. #if WC_CUSTOM_VENDING_MACHINES
  3179. RemoveDefaultVendingMachines(playerid);
  3180. #endif
  3181. if (PLAYER_STATE_ONFOOT <= GetPlayerState(playerid) <= PLAYER_STATE_PASSENGER) {
  3182. GetPlayerHealth(playerid, s_PlayerHealth[playerid]);
  3183. GetPlayerArmour(playerid, s_PlayerArmour[playerid]);
  3184. if (s_PlayerHealth[playerid] == 0.0) {
  3185. s_PlayerHealth[playerid] = s_PlayerMaxHealth[playerid];
  3186. }
  3187. UpdateHealthBar(playerid);
  3188. }
  3189. switch (GetPlayerState(playerid)) {
  3190. case PLAYER_STATE_ONFOOT,
  3191. PLAYER_STATE_DRIVER,
  3192. PLAYER_STATE_PASSENGER,
  3193. PLAYER_STATE_SPAWNED: {
  3194. SetHealthBarVisible(playerid, true);
  3195. }
  3196. default: {
  3197. SetHealthBarVisible(playerid, false);
  3198. }
  3199. }
  3200. }
  3201. }
  3202. static ScriptExit()
  3203. {
  3204. SetKnifeSync(true);
  3205. #if WC_CUSTOM_VENDING_MACHINES
  3206. DestroyVendingMachines();
  3207. #endif
  3208. for (new playerid = 0; playerid < MAX_PLAYERS; playerid++) {
  3209. #if WC_CUSTOM_VENDING_MACHINES
  3210. if (s_VendingUseTimer[playerid] != -1) {
  3211. KillTimer(s_VendingUseTimer[playerid]);
  3212. s_VendingUseTimer[playerid] = -1;
  3213. }
  3214. #endif
  3215. if (!IsPlayerConnected(playerid)) {
  3216. continue;
  3217. }
  3218. // Put things back the way they were
  3219. SetPlayerTeam(playerid, s_PlayerTeam[playerid]);
  3220. if (PLAYER_STATE_ONFOOT <= GetPlayerState(playerid) <= PLAYER_STATE_PASSENGER) {
  3221. new Float:health = s_PlayerHealth[playerid];
  3222. if (health == 0.0) {
  3223. health = s_PlayerMaxHealth[playerid];
  3224. }
  3225. SetPlayerHealth(playerid, health);
  3226. SetPlayerArmour(playerid, s_PlayerArmour[playerid]);
  3227. }
  3228. SetFakeHealth(playerid, 255);
  3229. SetFakeArmour(playerid, 255);
  3230. FreezeSyncData(playerid, false);
  3231. SetFakeFacingAngle(playerid, _);
  3232. SetHealthBarVisible(playerid, false);
  3233. if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3234. PlayerTextDrawDestroy(playerid, s_HealthBarForeground[playerid]);
  3235. s_InternalPlayerTextDraw[playerid][s_HealthBarForeground[playerid]] = false;
  3236. s_HealthBarForeground[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3237. }
  3238. if (s_DamageFeedGiven[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3239. PlayerTextDrawDestroy(playerid, s_DamageFeedGiven[playerid]);
  3240. s_InternalPlayerTextDraw[playerid][s_DamageFeedGiven[playerid]] = false;
  3241. s_DamageFeedGiven[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3242. }
  3243. if (s_DamageFeedTaken[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3244. PlayerTextDrawDestroy(playerid, s_DamageFeedTaken[playerid]);
  3245. s_InternalPlayerTextDraw[playerid][s_DamageFeedTaken[playerid]] = false;
  3246. s_DamageFeedTaken[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3247. }
  3248. }
  3249. if (s_HealthBarBorder != Text:INVALID_TEXT_DRAW) {
  3250. TextDrawDestroy(s_HealthBarBorder);
  3251. s_InternalTextDraw[s_HealthBarBorder] = false;
  3252. }
  3253. if (s_HealthBarBackground != Text:INVALID_TEXT_DRAW) {
  3254. TextDrawDestroy(s_HealthBarBackground);
  3255. s_InternalTextDraw[s_HealthBarBackground] = false;
  3256. }
  3257. }
  3258. static UpdatePlayerVirtualWorld(playerid)
  3259. {
  3260. new worldid = GetPlayerVirtualWorld(playerid);
  3261. if (worldid == WC_DEATH_WORLD) {
  3262. worldid = s_World[playerid];
  3263. } else if (worldid != s_World[playerid]) {
  3264. s_World[playerid] = worldid;
  3265. }
  3266. SetPlayerVirtualWorld(playerid, worldid);
  3267. }
  3268. static HasSameTeam(playerid, otherid)
  3269. {
  3270. if (otherid < 0 || otherid >= MAX_PLAYERS || playerid < 0 || playerid >= MAX_PLAYERS) {
  3271. return 0;
  3272. }
  3273. if (s_PlayerTeam[playerid] == NO_TEAM || s_PlayerTeam[otherid] == NO_TEAM) {
  3274. return 0;
  3275. }
  3276. return (s_PlayerTeam[playerid] == s_PlayerTeam[otherid]);
  3277. }
  3278. static IsPlayerPaused(playerid)
  3279. {
  3280. return (GetTickCount() - s_LastUpdate[playerid] > 2000);
  3281. }
  3282. static UpdateHealthBar(playerid, bool:force = false)
  3283. {
  3284. if (s_BeingResynced[playerid] || s_ForceClassSelection[playerid]) {
  3285. return;
  3286. }
  3287. new health = floatround(s_PlayerHealth[playerid] / s_PlayerMaxHealth[playerid] * 100.0, floatround_ceil);
  3288. new armour = floatround(s_PlayerArmour[playerid] / s_PlayerMaxArmour[playerid] * 100.0, floatround_ceil);
  3289. // Make the values reflect what the client should see
  3290. if (s_IsDying[playerid]) {
  3291. health = 0;
  3292. armour = 0;
  3293. } else {
  3294. if (health > 100) {
  3295. health = 100;
  3296. }
  3297. if (armour > 100) {
  3298. armour = 100;
  3299. }
  3300. }
  3301. if (force) {
  3302. s_LastSentHealth[playerid] = -1;
  3303. s_LastSentArmour[playerid] = -1;
  3304. } else if (s_HealthBarVisible[playerid] && s_HealthBarForeground[playerid] == PlayerText:INVALID_TEXT_DRAW && !s_IsDying[playerid]) {
  3305. s_LastSentHealth[playerid] = -1;
  3306. } else if (health == s_LastSentHealth[playerid] && armour == s_LastSentArmour[playerid]) {
  3307. return;
  3308. }
  3309. SetFakeHealth(playerid, health);
  3310. SetFakeArmour(playerid, armour);
  3311. UpdateSyncData(playerid);
  3312. if (health != s_LastSentHealth[playerid]) {
  3313. s_LastSentHealth[playerid] = health;
  3314. SetPlayerHealth(playerid, 8000000.0 + float(health));
  3315. if (s_HealthBarVisible[playerid] && !s_IsDying[playerid]) {
  3316. if (s_HealthBarForeground[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  3317. s_HealthBarForeground[playerid] = CreatePlayerTextDraw(
  3318. playerid,
  3319. 551.5 + float(health) * 0.5651,
  3320. 70.25,
  3321. "\1"
  3322. );
  3323. if (s_HealthBarForeground[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  3324. printf("(wc) WARN: Unable to create player healthbar foreground");
  3325. } else {
  3326. s_InternalPlayerTextDraw[playerid][s_HealthBarForeground[playerid]] = true;
  3327. PlayerTextDrawUseBox (playerid, s_HealthBarForeground[playerid], 1);
  3328. PlayerTextDrawLetterSize(playerid, s_HealthBarForeground[playerid], 0.0, 0.2);
  3329. PlayerTextDrawTextSize (playerid, s_HealthBarForeground[playerid], 545.75, 0.0);
  3330. PlayerTextDrawBoxColor (playerid, s_HealthBarForeground[playerid], 0xB51821FF);
  3331. PlayerTextDrawShow(playerid, s_HealthBarForeground[playerid]);
  3332. }
  3333. } else {
  3334. PlayerTextDrawSetPosition(playerid, s_HealthBarForeground[playerid], 551.5 + float(health) * 0.5651, 70.25);
  3335. PlayerTextDrawShow(playerid, s_HealthBarForeground[playerid]);
  3336. }
  3337. } else if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3338. PlayerTextDrawDestroy(playerid, s_HealthBarForeground[playerid]);
  3339. s_InternalPlayerTextDraw[playerid][s_HealthBarForeground[playerid]] = false;
  3340. s_HealthBarForeground[playerid] = PlayerText:INVALID_TEXT_DRAW;
  3341. }
  3342. }
  3343. if (armour != s_LastSentArmour[playerid]) {
  3344. s_LastSentArmour[playerid] = armour;
  3345. SetPlayerArmour(playerid, float(armour));
  3346. }
  3347. }
  3348. static SetHealthBarVisible(playerid, bool:toggle)
  3349. {
  3350. if (s_HealthBarVisible[playerid] == toggle) {
  3351. return;
  3352. }
  3353. s_HealthBarVisible[playerid] = toggle;
  3354. if (toggle) {
  3355. if (s_HealthBarBorder != Text:INVALID_TEXT_DRAW) {
  3356. TextDrawShowForPlayer(playerid, s_HealthBarBorder);
  3357. }
  3358. if (s_HealthBarBackground != Text:INVALID_TEXT_DRAW) {
  3359. TextDrawShowForPlayer(playerid, s_HealthBarBackground);
  3360. }
  3361. UpdateHealthBar(playerid, true);
  3362. } else {
  3363. if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3364. PlayerTextDrawHide(playerid, s_HealthBarForeground[playerid]);
  3365. }
  3366. if (s_HealthBarBorder != Text:INVALID_TEXT_DRAW) {
  3367. TextDrawHideForPlayer(playerid, s_HealthBarBorder);
  3368. }
  3369. if (s_HealthBarBackground != Text:INVALID_TEXT_DRAW) {
  3370. TextDrawHideForPlayer(playerid, s_HealthBarBackground);
  3371. }
  3372. }
  3373. }
  3374. static SpawnPlayerInPlace(playerid) {
  3375. new Float:x, Float:y, Float:z, Float:r;
  3376. GetPlayerPos(playerid, x, y, z);
  3377. GetPlayerFacingAngle(playerid, r);
  3378. SetSpawnInfo(playerid, 0xFE, GetPlayerSkin(playerid), x, y, z, r, 0, 0, 0, 0, 0, 0);
  3379. s_SpawnInfoModified[playerid] = true;
  3380. SpawnPlayer(playerid);
  3381. }
  3382. static PosInFront(playerid, Float:distance, &Float:x, &Float:y, &Float:z)
  3383. {
  3384. new Float:a;
  3385. GetPlayerPos(playerid, x, y, z);
  3386. GetPlayerFacingAngle(playerid, a);
  3387. x += (distance * floatsin(-a, degrees));
  3388. y += (distance * floatcos(-a, degrees));
  3389. }
  3390. static Float:AngleBetweenPoints(Float:x1, Float:y1, Float:x2, Float:y2)
  3391. {
  3392. return -(90.0 - atan2(y1 - y2, x1 - x2));
  3393. }
  3394. static UpdateSyncData(playerid)
  3395. {
  3396. // Currently re-sending onfoot data is only supported
  3397. if (!IsPlayerConnected(playerid) || GetPlayerState(playerid) != PLAYER_STATE_ONFOOT) {
  3398. return;
  3399. }
  3400. for (new i = 0; i < MAX_PLAYERS; i++) {
  3401. if (i != playerid && IsPlayerConnected(i) && IsPlayerStreamedIn(playerid, i)) {
  3402. SendLastSyncData(playerid, i);
  3403. }
  3404. }
  3405. }
  3406. static WasPlayerInVehicle(playerid, time) {
  3407. if (!s_LastVehicleTick[playerid]) {
  3408. return 0;
  3409. }
  3410. if (GetTickCount() - time < s_LastVehicleTick[playerid]) {
  3411. return 1;
  3412. }
  3413. return 0;
  3414. }
  3415. #if WC_CUSTOM_VENDING_MACHINES
  3416. static RemoveDefaultVendingMachines(playerid)
  3417. {
  3418. RemoveBuildingForPlayer(playerid, 955, 0.0, 0.0, 0.0, 20000.0); // CJ_EXT_SPRUNK
  3419. RemoveBuildingForPlayer(playerid, 956, 0.0, 0.0, 0.0, 20000.0); // CJ_EXT_CANDY
  3420. RemoveBuildingForPlayer(playerid, 1209, 0.0, 0.0, 0.0, 20000.0); // vendmach
  3421. RemoveBuildingForPlayer(playerid, 1302, 0.0, 0.0, 0.0, 20000.0); // vendmachfd
  3422. RemoveBuildingForPlayer(playerid, 1775, 0.0, 0.0, 0.0, 20000.0); // CJ_SPRUNK1
  3423. RemoveBuildingForPlayer(playerid, 1776, 0.0, 0.0, 0.0, 20000.0); // CJ_CANDYVENDOR
  3424. RemoveBuildingForPlayer(playerid, 1977, 0.0, 0.0, 0.0, 20000.0); // vendin3
  3425. // Make sure they're all gone..
  3426. for (new i = 0; i < sizeof(sc_VendingMachines); i++) {
  3427. RemoveBuildingForPlayer(
  3428. playerid,
  3429. sc_VendingMachines[i][e_Model],
  3430. sc_VendingMachines[i][e_PosX],
  3431. sc_VendingMachines[i][e_PosY],
  3432. sc_VendingMachines[i][e_PosZ],
  3433. 1.0
  3434. );
  3435. }
  3436. }
  3437. static CreateVendingMachines()
  3438. {
  3439. DestroyVendingMachines();
  3440. for (new i = 0; i < sizeof(sc_VendingMachines); i++) {
  3441. #if WC_USE_STREAMER
  3442. s_VendingMachineObject[i] = CreateDynamicObject(
  3443. sc_VendingMachines[i][e_Model],
  3444. sc_VendingMachines[i][e_PosX],
  3445. sc_VendingMachines[i][e_PosY],
  3446. sc_VendingMachines[i][e_PosZ],
  3447. sc_VendingMachines[i][e_RotX],
  3448. sc_VendingMachines[i][e_RotY],
  3449. sc_VendingMachines[i][e_RotZ],
  3450. .interiorid = sc_VendingMachines[i][e_Interior]
  3451. );
  3452. #else
  3453. s_VendingMachineObject[i] = CreateObject(
  3454. sc_VendingMachines[i][e_Model],
  3455. sc_VendingMachines[i][e_PosX],
  3456. sc_VendingMachines[i][e_PosY],
  3457. sc_VendingMachines[i][e_PosZ],
  3458. sc_VendingMachines[i][e_RotX],
  3459. sc_VendingMachines[i][e_RotY],
  3460. sc_VendingMachines[i][e_RotZ]
  3461. );
  3462. #endif
  3463. }
  3464. }
  3465. static DestroyVendingMachines()
  3466. {
  3467. for (new i = 0; i < sizeof(s_VendingMachineObject); i++) {
  3468. if (s_VendingMachineObject[i] != -1) {
  3469. #if WC_USE_STREAMER
  3470. DestroyDynamicObject(s_VendingMachineObject[i]);
  3471. #else
  3472. DestroyObject(s_VendingMachineObject[i]);
  3473. #endif
  3474. s_VendingMachineObject[i] = -1;
  3475. }
  3476. }
  3477. }
  3478. #endif
  3479. forward WC_DeathSkipEnd(playerid);
  3480. public WC_DeathSkipEnd(playerid)
  3481. {
  3482. TogglePlayerControllable(playerid, true);
  3483. ResetPlayerWeapons(playerid);
  3484. for (new i = 0; i < 13; i++) {
  3485. if (s_SyncData[playerid][e_WeaponId][i]) {
  3486. GivePlayerWeapon(playerid, s_SyncData[playerid][e_WeaponId][i], s_SyncData[playerid][e_WeaponAmmo][i]);
  3487. }
  3488. }
  3489. GivePlayerWeapon(playerid, s_SyncData[playerid][e_Weapon], 0);
  3490. SetPlayerSpecialAction(playerid, 0);
  3491. }
  3492. forward WC_SpawnForStreamedIn(playerid);
  3493. public WC_SpawnForStreamedIn(playerid)
  3494. {
  3495. if (!IsPlayerConnected(playerid)) {
  3496. return;
  3497. }
  3498. SpawnPlayerForWorld(playerid);
  3499. for (new i = 0; i < MAX_PLAYERS; i++) {
  3500. if (i != playerid && IsPlayerConnected(i) && IsPlayerStreamedIn(playerid, i)) {
  3501. SendLastSyncData(playerid, i);
  3502. ClearAnimationsForPlayer(playerid, i);
  3503. }
  3504. }
  3505. }
  3506. forward WC_SetSpawnForStreamedIn(playerid);
  3507. public WC_SetSpawnForStreamedIn(playerid)
  3508. {
  3509. s_SpawnForStreamedIn[playerid] = true;
  3510. }
  3511. forward WC_SpawnPlayerInPlace(playerid);
  3512. public WC_SpawnPlayerInPlace(playerid)
  3513. {
  3514. SpawnPlayerInPlace(playerid);
  3515. }
  3516. static ProcessDamage(&playerid, &issuerid, &Float:amount, &weaponid, &bodypart, &Float:bullets)
  3517. {
  3518. if (amount < 0.0) {
  3519. return WC_INVALID_DAMAGE;
  3520. }
  3521. // Adjust invalid amounts caused by an animation bug
  3522. switch (amount) {
  3523. case 3.63000011444091796875,
  3524. 5.940000057220458984375,
  3525. 5.610000133514404296875: {
  3526. amount = 2.6400001049041748046875;
  3527. }
  3528. case 3.30000019073486328125: {
  3529. if (weaponid != WEAPON_SHOTGUN && weaponid != WEAPON_SAWEDOFF) {
  3530. amount = 2.6400001049041748046875;
  3531. }
  3532. }
  3533. case 4.950000286102294921875: {
  3534. if (IsMeleeWeapon(weaponid)) {
  3535. amount = 2.6400001049041748046875;
  3536. }
  3537. }
  3538. case 6.270000457763671875,
  3539. 6.93000030517578125,
  3540. 7.2600002288818359375,
  3541. 7.9200000762939453125,
  3542. 8.5799999237060546875,
  3543. 9.24000072479248046875,
  3544. 11.88000011444091796875,
  3545. 11.22000026702880859375: {
  3546. amount = 2.6400001049041748046875;
  3547. }
  3548. case 9.90000057220458984375: {
  3549. switch (weaponid) {
  3550. case WEAPON_VEHICLE, WEAPON_VEHICLE_M4, WEAPON_AK47,
  3551. WEAPON_M4, WEAPON_SHOTGUN, WEAPON_SAWEDOFF, WEAPON_SHOTGSPA: {}
  3552. default: {
  3553. amount = 6.6000003814697265625;
  3554. }
  3555. }
  3556. }
  3557. }
  3558. // Car parking
  3559. if (weaponid == WEAPON_HELIBLADES && _:amount != _:330.0) {
  3560. weaponid = WEAPON_CARPARK;
  3561. }
  3562. // Finish processing drown/fire/carpark quickly, since they are sent at very high rates
  3563. if (IsHighRateWeapon(weaponid)) {
  3564. // Apply reasonable bounds
  3565. if (weaponid == WEAPON_DROWN) {
  3566. if (amount > 10.0) amount = 10.0;
  3567. } else if (amount > 1.0) {
  3568. amount = 1.0;
  3569. }
  3570. // Adjust the damage if the multiplier is not 1.0
  3571. if (_:s_WeaponDamage[weaponid] != _:1.0) {
  3572. amount *= s_WeaponDamage[weaponid];
  3573. }
  3574. // Make sure the distance and issuer is valid; carpark can be self-inflicted so it doesn't require an issuer
  3575. if (weaponid == WEAPON_SPRAYCAN || weaponid == WEAPON_FIREEXTINGUISHER || (weaponid == WEAPON_CARPARK && issuerid != INVALID_PLAYER_ID)) {
  3576. if (issuerid == INVALID_PLAYER_ID) {
  3577. return WC_NO_ISSUER;
  3578. }
  3579. new Float:x, Float:y, Float:z, Float:dist;
  3580. GetPlayerPos(issuerid, x, y, z);
  3581. dist = GetPlayerDistanceFromPoint(playerid, x, y, z);
  3582. if (dist > 15.0) {
  3583. AddRejectedHit(issuerid, playerid, HIT_TOO_FAR_FROM_ORIGIN, weaponid, _:dist);
  3584. return WC_INVALID_DISTANCE;
  3585. }
  3586. }
  3587. return WC_NO_ERROR;
  3588. }
  3589. // Bullet or melee damage must have an issuerid, otherwise something has gone wrong (e.g. sniper bug)
  3590. if (issuerid == INVALID_PLAYER_ID && (IsBulletWeapon(weaponid) || IsMeleeWeapon(weaponid))) {
  3591. return WC_NO_ISSUER;
  3592. }
  3593. // Punching with a parachute
  3594. if (weaponid == WEAPON_PARACHUTE) {
  3595. weaponid = WEAPON_UNARMED;
  3596. }
  3597. // Collision damage should never be above 165
  3598. if (weaponid == WEAPON_COLLISION) {
  3599. if (amount > 165.0) {
  3600. amount = 1.0;
  3601. } else {
  3602. amount /= 165.0;
  3603. }
  3604. }
  3605. if (weaponid == WEAPON_EXPLOSION) {
  3606. // Explosions do at most 82.5 damage. This will later be multipled by the damage value
  3607. amount /= 82.5;
  3608. // Figure out what caused the explosion
  3609. if (issuerid != INVALID_PLAYER_ID && s_LastExplosive[issuerid]) {
  3610. weaponid = s_LastExplosive[issuerid];
  3611. }
  3612. }
  3613. // Check for pistol whip
  3614. switch (weaponid) {
  3615. case WEAPON_COLT45 .. WEAPON_SNIPER,
  3616. WEAPON_MINIGUN, WEAPON_SPRAYCAN, WEAPON_FIREEXTINGUISHER: {
  3617. // A pistol whip inflicts 2.64 damage
  3618. if (_:amount == _:2.6400001049041748046875) {
  3619. // Save the weapon in the bodypart argument (it's always BODY_PART_TORSO)
  3620. bodypart = weaponid;
  3621. weaponid = WEAPON_PISTOLWHIP;
  3622. }
  3623. }
  3624. }
  3625. new melee = IsMeleeWeapon(weaponid);
  3626. // Can't punch from a vehicle
  3627. if (melee && IsPlayerInAnyVehicle(issuerid)) {
  3628. return WC_INVALID_DAMAGE;
  3629. }
  3630. if (weaponid != WEAPON_PISTOLWHIP) {
  3631. switch (amount) {
  3632. case 1.32000005245208740234375,
  3633. 1.650000095367431640625,
  3634. 1.980000019073486328125,
  3635. 2.3100001811981201171875,
  3636. 2.6400001049041748046875,
  3637. 2.9700000286102294921875,
  3638. 3.96000003814697265625,
  3639. 4.28999996185302734375,
  3640. 4.62000036239624023437,
  3641. 5.280000209808349609375: {
  3642. // Damage is most likely from punching and switching weapon quickly
  3643. if (!melee) {
  3644. DebugMessage(issuerid, "weapon changed from %d to melee (punch & swap)", weaponid);
  3645. weaponid = WEAPON_UNARMED;
  3646. melee = true;
  3647. }
  3648. }
  3649. case 6.6000003814697265625: {
  3650. if (!melee) {
  3651. switch (weaponid) {
  3652. case WEAPON_UZI, WEAPON_TEC9, WEAPON_CHAINSAW,
  3653. WEAPON_SHOTGUN, WEAPON_SAWEDOFF: {}
  3654. default: {
  3655. DebugMessage(issuerid, "weapon changed from %d to melee (punch & swap)", weaponid);
  3656. weaponid = WEAPON_UNARMED;
  3657. melee = true;
  3658. }
  3659. }
  3660. }
  3661. }
  3662. case 54.12000274658203125: {
  3663. if (!melee) {
  3664. DebugMessage(issuerid, "weapon changed from %d to melee (punch & swap)", weaponid);
  3665. melee = true;
  3666. weaponid = WEAPON_UNARMED;
  3667. amount = 1.32000005245208740234375;
  3668. }
  3669. // Be extra sure about this one
  3670. if (GetPlayerFightingStyle(issuerid) != FIGHT_STYLE_KNEEHEAD) {
  3671. return WC_INVALID_DAMAGE;
  3672. }
  3673. }
  3674. // Melee damage has been tampered with
  3675. default: {
  3676. if (melee) {
  3677. return WC_INVALID_DAMAGE;
  3678. }
  3679. }
  3680. }
  3681. }
  3682. if (melee) {
  3683. new Float:x, Float:y, Float:z, Float:dist;
  3684. GetPlayerPos(issuerid, x, y, z);
  3685. dist = GetPlayerDistanceFromPoint(playerid, x, y, z);
  3686. if (dist > 15.0) {
  3687. AddRejectedHit(issuerid, playerid, HIT_TOO_FAR_FROM_ORIGIN, weaponid, _:dist);
  3688. return WC_INVALID_DISTANCE;
  3689. }
  3690. }
  3691. switch (weaponid) {
  3692. // The spas shotguns shoot 8 bullets, each inflicting 4.95 damage
  3693. case WEAPON_SHOTGSPA: {
  3694. bullets = amount / 4.950000286102294921875;
  3695. if (8.0 - bullets < -0.05) {
  3696. return WC_INVALID_DAMAGE;
  3697. }
  3698. }
  3699. // Shotguns and sawed-off shotguns shoot 15 bullets, each inflicting 3.3 damage
  3700. case WEAPON_SHOTGUN, WEAPON_SAWEDOFF: {
  3701. bullets = amount / 3.30000019073486328125;
  3702. if (15.0 - bullets < -0.05) {
  3703. return WC_INVALID_DAMAGE;
  3704. }
  3705. }
  3706. }
  3707. if (_:bullets) {
  3708. new Float:f = floatfract(bullets);
  3709. // The damage for each bullet has been tampered with
  3710. if (f > 0.01 && f < 0.99) {
  3711. return WC_INVALID_DAMAGE;
  3712. }
  3713. // Divide the damage amount by the number of bullets
  3714. amount /= bullets;
  3715. }
  3716. // Check chainsaw damage
  3717. if (weaponid == WEAPON_CHAINSAW) {
  3718. switch (amount) {
  3719. case 6.6000003814697265625,
  3720. 13.5300006866455078125,
  3721. 16.1700000762939453125,
  3722. 26.40000152587890625,
  3723. 27.060001373291015625: {}
  3724. default: {
  3725. return WC_INVALID_DAMAGE;
  3726. }
  3727. }
  3728. }
  3729. // Check deagle damage
  3730. if (weaponid == WEAPON_DEAGLE) {
  3731. switch (amount) {
  3732. case 46.200000762939453125,
  3733. 23.1000003814697265625: {}
  3734. default: {
  3735. return WC_INVALID_DAMAGE;
  3736. }
  3737. }
  3738. }
  3739. // Check gun damage
  3740. new Float:def_amount = 0.0;
  3741. switch (weaponid) {
  3742. case WEAPON_COLT45,
  3743. WEAPON_MP5: def_amount = 8.25;
  3744. case WEAPON_SILENCED: def_amount = 13.200000762939453125;
  3745. case WEAPON_UZI,
  3746. WEAPON_TEC9: def_amount = 6.6000003814697265625;
  3747. case WEAPON_AK47,
  3748. WEAPON_M4,
  3749. WEAPON_VEHICLE_M4: def_amount = 9.90000057220458984375;
  3750. case WEAPON_RIFLE: def_amount = 24.7500019073486328125;
  3751. case WEAPON_SNIPER: def_amount = 41.25;
  3752. case WEAPON_MINIGUN,
  3753. WEAPON_VEHICLE_MINIGUN: def_amount = 46.200000762939453125;
  3754. case WEAPON_VEHICLE: def_amount = 9.90000057220458984375;
  3755. }
  3756. if (_:def_amount && _:def_amount != _:amount) {
  3757. return WC_INVALID_DAMAGE;
  3758. }
  3759. // Adjust the damage
  3760. switch (s_DamageType[weaponid]) {
  3761. case DAMAGE_TYPE_MULTIPLIER: {
  3762. if (_:s_WeaponDamage[weaponid] != _:1.0) {
  3763. amount *= s_WeaponDamage[weaponid];
  3764. }
  3765. }
  3766. case DAMAGE_TYPE_STATIC: {
  3767. if (_:bullets) {
  3768. amount = s_WeaponDamage[weaponid] * bullets;
  3769. } else {
  3770. amount = s_WeaponDamage[weaponid];
  3771. }
  3772. }
  3773. case DAMAGE_TYPE_RANGE,
  3774. DAMAGE_TYPE_RANGE_MULTIPLIER: {
  3775. new Float:length = s_LastShot[issuerid][e_Length];
  3776. for (new i = s_DamageRangeSteps[weaponid] - 1; i >= 0; i--) {
  3777. if (i == 0 || length >= s_DamageRangeRanges[weaponid][i]) {
  3778. if (s_DamageType[weaponid] == DAMAGE_TYPE_RANGE_MULTIPLIER) {
  3779. if (_:s_DamageRangeValues[weaponid][i] != _:1.0) {
  3780. amount *= s_DamageRangeValues[weaponid][i];
  3781. }
  3782. } else {
  3783. if (_:bullets) {
  3784. amount = s_DamageRangeValues[weaponid][i] * bullets;
  3785. } else {
  3786. amount = s_DamageRangeValues[weaponid][i];
  3787. }
  3788. }
  3789. break;
  3790. }
  3791. }
  3792. }
  3793. }
  3794. return WC_NO_ERROR;
  3795. }
  3796. static InflictDamage(playerid, Float:amount, issuerid = INVALID_PLAYER_ID, weaponid = WEAPON_UNKNOWN, bodypart = BODY_PART_UNKNOWN, bool:ignore_armour = false)
  3797. {
  3798. if (!IsPlayerSpawned(playerid) || amount < 0.0) {
  3799. return;
  3800. }
  3801. if (!OnPlayerDamage(playerid, amount, issuerid, weaponid, bodypart)) {
  3802. UpdateHealthBar(playerid);
  3803. if (weaponid < 0 || weaponid > WEAPON_UNKNOWN) {
  3804. weaponid = WEAPON_UNKNOWN;
  3805. }
  3806. #if WC_DEBUG
  3807. new Float:length = 0.0;
  3808. if (issuerid != INVALID_PLAYER_ID) {
  3809. if (IsBulletWeapon(weaponid)) {
  3810. length = s_LastShot[issuerid][e_Length];
  3811. }
  3812. }
  3813. if (!IsHighRateWeapon(weaponid)) {
  3814. DebugMessageAll("!InflictDamage(%d, %.4f, %d, %d, %d) length = %f", playerid, amount, issuerid, weaponid, bodypart, length);
  3815. }
  3816. #endif
  3817. return;
  3818. }
  3819. if (weaponid < 0 || weaponid > WEAPON_UNKNOWN) {
  3820. weaponid = WEAPON_UNKNOWN;
  3821. }
  3822. #if WC_DEBUG
  3823. new Float:length = 0.0;
  3824. if (issuerid != INVALID_PLAYER_ID) {
  3825. if (IsBulletWeapon(weaponid)) {
  3826. length = s_LastShot[issuerid][e_Length];
  3827. }
  3828. }
  3829. if (!IsHighRateWeapon(weaponid)) {
  3830. DebugMessageAll("InflictDamage(%d, %.4f, %d, %d, %d) length = %f", playerid, amount, issuerid, weaponid, bodypart, length);
  3831. }
  3832. #endif
  3833. 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])))))) {
  3834. if (amount <= 0.0) {
  3835. amount = s_PlayerHealth[playerid] + s_PlayerArmour[playerid];
  3836. }
  3837. s_PlayerArmour[playerid] -= amount;
  3838. } else {
  3839. if (amount <= 0.0) {
  3840. amount = s_PlayerHealth[playerid];
  3841. }
  3842. s_PlayerHealth[playerid] -= amount;
  3843. }
  3844. if (s_PlayerArmour[playerid] < 0.0) {
  3845. s_DamageDoneArmour[playerid] = amount + s_PlayerArmour[playerid];
  3846. s_DamageDoneHealth[playerid] = -s_PlayerArmour[playerid];
  3847. s_PlayerHealth[playerid] += s_PlayerArmour[playerid];
  3848. s_PlayerArmour[playerid] = 0.0;
  3849. } else {
  3850. s_DamageDoneArmour[playerid] = amount;
  3851. s_DamageDoneHealth[playerid] = 0.0;
  3852. }
  3853. if (s_PlayerHealth[playerid] <= 0.0) {
  3854. amount += s_PlayerHealth[playerid];
  3855. s_DamageDoneHealth[playerid] += s_PlayerHealth[playerid];
  3856. s_PlayerHealth[playerid] = 0.0;
  3857. }
  3858. OnPlayerDamageDone(playerid, amount, issuerid, weaponid, bodypart);
  3859. if (s_PlayerHealth[playerid] <= 0.0005) {
  3860. new vehicleid = GetPlayerVehicleID(playerid);
  3861. if (vehicleid) {
  3862. new modelid = GetVehicleModel(vehicleid);
  3863. new seat = GetPlayerVehicleSeat(playerid);
  3864. TogglePlayerControllable(playerid, false);
  3865. switch (modelid) {
  3866. case 509, 481, 510, 462, 448, 581, 522,
  3867. 461, 521, 523, 463, 586, 468, 471: {
  3868. new Float:vx, Float:vy, Float:vz;
  3869. GetVehicleVelocity(vehicleid, vx, vy, vz);
  3870. if (vx*vx + vy*vy + vz*vz >= 0.4) {
  3871. PlayerDeath(playerid, "PED", "BIKE_fallR", 0);
  3872. } else {
  3873. PlayerDeath(playerid, "PED", "BIKE_fall_off", 0);
  3874. }
  3875. }
  3876. default: {
  3877. if (seat & 1) {
  3878. PlayerDeath(playerid, "PED", "CAR_dead_LHS");
  3879. } else {
  3880. PlayerDeath(playerid, "PED", "CAR_dead_RHS");
  3881. }
  3882. }
  3883. }
  3884. } else if (GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK) {
  3885. PlayerDeath(playerid, "PED", "KO_skid_back", .freeze_sync = false);
  3886. } else {
  3887. if (gettime() - s_LastVehicleEnterTime[playerid] < 10) {
  3888. TogglePlayerControllable(playerid, false);
  3889. }
  3890. new anim = GetPlayerAnimationIndex(playerid);
  3891. if (anim == 1250 || (1538 <= anim <= 1544) || weaponid == WEAPON_DROWN) {
  3892. // In water
  3893. PlayerDeath(playerid, "PED", "Drown");
  3894. } else if (1195 <= anim <= 1198) {
  3895. // Jumping animation
  3896. PlayerDeath(playerid, "PED", "KO_skid_back");
  3897. } else if (WEAPON_SHOTGUN <= weaponid <= WEAPON_SHOTGSPA) {
  3898. if (IsPlayerBehindPlayer(issuerid, playerid)) {
  3899. MakePlayerFacePlayer(playerid, issuerid, true);
  3900. PlayerDeath(playerid, "PED", "KO_shot_front");
  3901. } else {
  3902. MakePlayerFacePlayer(playerid, issuerid);
  3903. PlayerDeath(playerid, "PED", "BIKE_fall_off");
  3904. }
  3905. } else if (WEAPON_RIFLE <= weaponid <= WEAPON_SNIPER) {
  3906. if (bodypart == 9) {
  3907. PlayerDeath(playerid, "PED", "KO_shot_face");
  3908. } else if (IsPlayerBehindPlayer(issuerid, playerid)) {
  3909. PlayerDeath(playerid, "PED", "KO_shot_front");
  3910. } else {
  3911. PlayerDeath(playerid, "PED", "KO_shot_stom");
  3912. }
  3913. } else if (IsBulletWeapon(weaponid)) {
  3914. if (bodypart == 9) {
  3915. PlayerDeath(playerid, "PED", "KO_shot_face");
  3916. } else {
  3917. PlayerDeath(playerid, "PED", "KO_shot_front");
  3918. }
  3919. } else if (weaponid == WEAPON_PISTOLWHIP) {
  3920. PlayerDeath(playerid, "PED", "KO_spin_R");
  3921. } else if (IsMeleeWeapon(weaponid) || weaponid == WEAPON_CARPARK) {
  3922. PlayerDeath(playerid, "PED", "KO_skid_front");
  3923. } else if (weaponid == WEAPON_SPRAYCAN || weaponid == WEAPON_FIREEXTINGUISHER) {
  3924. PlayerDeath(playerid, "KNIFE", "KILL_Knife_Ped_Die");
  3925. } else {
  3926. PlayerDeath(playerid, "PED", "KO_skid_back");
  3927. }
  3928. }
  3929. #if defined WC_OnPlayerDeath
  3930. if (s_CbugAllowed) {
  3931. WC_OnPlayerDeath(playerid, issuerid, weaponid);
  3932. } else {
  3933. s_DelayedDeathTimer[playerid] = SetTimerEx(#WC_DelayedDeath, 1200, false, "iii", playerid, issuerid, weaponid);
  3934. }
  3935. #endif
  3936. }
  3937. UpdateHealthBar(playerid);
  3938. }
  3939. forward WC_DelayedDeath(playerid, issuerid, reason);
  3940. public WC_DelayedDeath(playerid, issuerid, reason) {
  3941. s_DelayedDeathTimer[playerid] = -1;
  3942. #if defined WC_OnPlayerDeath
  3943. WC_OnPlayerDeath(playerid, issuerid, reason);
  3944. #endif
  3945. }
  3946. static PlayerDeath(playerid, animlib[32], animname[32], anim_lock = 0, respawn_time = -1, bool:freeze_sync = true, anim_freeze = 1)
  3947. {
  3948. s_PlayerHealth[playerid] = 0.0;
  3949. s_PlayerArmour[playerid] = 0.0;
  3950. s_IsDying[playerid] = true;
  3951. new action = GetPlayerSpecialAction(playerid);
  3952. if (action && action != SPECIAL_ACTION_DUCK) {
  3953. if (action == SPECIAL_ACTION_USEJETPACK) {
  3954. ClearAnimations(playerid);
  3955. }
  3956. SetPlayerSpecialAction(playerid, SPECIAL_ACTION_NONE);
  3957. if (action == SPECIAL_ACTION_USEJETPACK) {
  3958. new Float:vx, Float:vy, Float:vz;
  3959. GetPlayerVelocity(playerid, vx, vy, vz);
  3960. SetPlayerVelocity(playerid, vx, vy, vz);
  3961. }
  3962. }
  3963. OnPlayerPrepareDeath(playerid, animlib, animname, anim_lock, respawn_time);
  3964. UpdateHealthBar(playerid);
  3965. FreezeSyncData(playerid, freeze_sync);
  3966. if (respawn_time == -1) {
  3967. respawn_time = s_RespawnTime;
  3968. }
  3969. if (animlib[0] && animname[0]) {
  3970. ApplyAnimation(playerid, animlib, animname, 4.1, 0, anim_lock, anim_lock, anim_freeze, 0, 1);
  3971. }
  3972. if (s_DeathTimer[playerid] != -1) {
  3973. KillTimer(s_DeathTimer[playerid]);
  3974. }
  3975. s_DeathTimer[playerid] = SetTimerEx("WC_PlayerDeathRespawn", respawn_time, false, "i", playerid);
  3976. if (s_HealthBarForeground[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  3977. PlayerTextDrawHide(playerid, s_HealthBarForeground[playerid]);
  3978. }
  3979. #if defined WC_OnPlayerLeaveCheckpoint
  3980. if (IsPlayerInCheckpoint(playerid)) {
  3981. WC_OnPlayerLeaveCheckpoint(playerid);
  3982. }
  3983. #endif
  3984. }
  3985. public OnPlayerPrepareDeath(playerid, animlib[32], animname[32], &anim_lock, &respawn_time)
  3986. {
  3987. #if defined WC_OnPlayerPrepareDeath
  3988. WC_OnPlayerPrepareDeath(playerid, animlib, animname, anim_lock, respawn_time);
  3989. #endif
  3990. }
  3991. public OnRejectedHit(playerid, hit[E_REJECTED_HIT])
  3992. {
  3993. #if WC_DEBUG
  3994. new output[256];
  3995. new reason = hit[e_Reason];
  3996. new i1 = hit[e_Info1];
  3997. new i2 = hit[e_Info2];
  3998. new i3 = hit[e_Info3];
  3999. new weapon = hit[e_Weapon];
  4000. new weapon_name[32];
  4001. WC_GetWeaponName(weapon, weapon_name);
  4002. format(output, sizeof(output), "(%s -> %s) %s", weapon_name, hit[e_Name], g_HitRejectReasons[reason]);
  4003. format(output, sizeof(output), output, i1, i2, i3);
  4004. DebugMessageRed(playerid, "Rejected hit: %s", output);
  4005. #endif
  4006. #if defined WC_OnRejectedHit
  4007. WC_OnRejectedHit(playerid, hit);
  4008. #endif
  4009. }
  4010. public OnPlayerDeathFinished(playerid, bool:cancelable)
  4011. {
  4012. if (s_PlayerHealth[playerid] == 0.0) {
  4013. s_PlayerHealth[playerid] = s_PlayerMaxHealth[playerid];
  4014. }
  4015. if (s_DeathTimer[playerid] != -1) {
  4016. KillTimer(s_DeathTimer[playerid]);
  4017. s_DeathTimer[playerid] = -1;
  4018. }
  4019. #if defined WC_OnPlayerDeathFinished
  4020. new retval = WC_OnPlayerDeathFinished(playerid, cancelable);
  4021. if (!retval && cancelable) {
  4022. return 0;
  4023. }
  4024. #endif
  4025. ResetPlayerWeapons(playerid);
  4026. return 1;
  4027. }
  4028. #if WC_CUSTOM_VENDING_MACHINES
  4029. public OnPlayerUseVendingMachine(playerid, &Float:health_given) {
  4030. #if defined WC_OnPlayerUseVendingMachine
  4031. return WC_OnPlayerUseVendingMachine(playerid, health_given);
  4032. #else
  4033. if (GetPlayerMoney(playerid) > 0) {
  4034. GivePlayerMoney(playerid, -1);
  4035. return 1;
  4036. } else {
  4037. return 0;
  4038. }
  4039. #endif
  4040. }
  4041. forward WC_VendingMachineUsed(playerid, Float:health_given);
  4042. public WC_VendingMachineUsed(playerid, Float:health_given)
  4043. {
  4044. s_VendingUseTimer[playerid] = -1;
  4045. if (GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && !s_IsDying[playerid]) {
  4046. new Float:health = s_PlayerHealth[playerid];
  4047. health += health_given;
  4048. if (health > s_PlayerMaxHealth[playerid]) {
  4049. health = s_PlayerMaxHealth[playerid];
  4050. }
  4051. WC_SetPlayerHealth(playerid, health);
  4052. }
  4053. }
  4054. #endif
  4055. forward WC_DamageFeedUpdate(playerid);
  4056. public WC_DamageFeedUpdate(playerid)
  4057. {
  4058. s_DamageFeedTimer[playerid] = -1;
  4059. if (IsPlayerConnected(playerid) && IsDamageFeedActive(playerid)) {
  4060. DamageFeedUpdate(playerid, true);
  4061. }
  4062. }
  4063. static DamageFeedUpdate(playerid, bool:modified = false)
  4064. {
  4065. if (!IsDamageFeedActive(playerid)) {
  4066. if (s_DamageFeedGiven[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  4067. PlayerTextDrawDestroy(playerid, s_DamageFeedGiven[playerid]);
  4068. s_InternalPlayerTextDraw[playerid][s_DamageFeedGiven[playerid]] = false;
  4069. s_DamageFeedGiven[playerid] = PlayerText:INVALID_TEXT_DRAW;
  4070. }
  4071. if (s_DamageFeedTaken[playerid] != PlayerText:INVALID_TEXT_DRAW) {
  4072. PlayerTextDrawDestroy(playerid, s_DamageFeedTaken[playerid]);
  4073. s_InternalPlayerTextDraw[playerid][s_DamageFeedTaken[playerid]] = false;
  4074. s_DamageFeedTaken[playerid] = PlayerText:INVALID_TEXT_DRAW;
  4075. }
  4076. return;
  4077. }
  4078. if (s_DamageFeedGiven[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4079. new PlayerText:td = CreatePlayerTextDraw(playerid, 200.0, 365.0, "_");
  4080. if (td == PlayerText:INVALID_TEXT_DRAW) {
  4081. printf("(wc) WARN: Unable to create damage feed textdraw");
  4082. } else {
  4083. s_InternalPlayerTextDraw[playerid][td] = true;
  4084. PlayerTextDrawLetterSize(playerid, td, 0.2, 0.9);
  4085. PlayerTextDrawColor(playerid, td, 0x30FF50FF);
  4086. PlayerTextDrawFont(playerid, td, 1);
  4087. PlayerTextDrawSetShadow(playerid, td, 0);
  4088. PlayerTextDrawAlignment(playerid, td, 2);
  4089. PlayerTextDrawSetOutline(playerid, td, 1);
  4090. PlayerTextDrawBackgroundColor(playerid, td, 0x0000001A);
  4091. s_DamageFeedGiven[playerid] = td;
  4092. }
  4093. }
  4094. if (s_DamageFeedTaken[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4095. new PlayerText:td = CreatePlayerTextDraw(playerid, 440.0, 365.0, "_");
  4096. if (td == PlayerText:INVALID_TEXT_DRAW) {
  4097. printf("(wc) WARN: Unable to create damage feed textdraw");
  4098. } else {
  4099. s_InternalPlayerTextDraw[playerid][td] = true;
  4100. PlayerTextDrawLetterSize(playerid, td, 0.2, 0.9);
  4101. PlayerTextDrawColor(playerid, td, 0x33CCFFFF);
  4102. PlayerTextDrawFont(playerid, td, 1);
  4103. PlayerTextDrawSetShadow(playerid, td, 0);
  4104. PlayerTextDrawAlignment(playerid, td, 2);
  4105. PlayerTextDrawSetOutline(playerid, td, 1);
  4106. PlayerTextDrawBackgroundColor(playerid, td, 0x0000001A);
  4107. s_DamageFeedTaken[playerid] = td;
  4108. }
  4109. }
  4110. new tick = GetTickCount();
  4111. if (tick == 0) tick = 1;
  4112. new lowest_tick = tick + 1;
  4113. for (new i = 0; i < sizeof(s_DamageFeedHitsGiven[]) - 1; i++) {
  4114. if (!s_DamageFeedHitsGiven[playerid][i][e_Tick]) {
  4115. break;
  4116. }
  4117. if (tick - s_DamageFeedHitsGiven[playerid][i][e_Tick] >= s_DamageFeedHideDelay) {
  4118. modified = true;
  4119. for (new j = i; j < sizeof(s_DamageFeedHitsGiven[]) - 1; j++) {
  4120. s_DamageFeedHitsGiven[playerid][j][e_Tick] = 0;
  4121. }
  4122. break;
  4123. }
  4124. if (s_DamageFeedHitsGiven[playerid][i][e_Tick] < lowest_tick) {
  4125. lowest_tick = s_DamageFeedHitsGiven[playerid][i][e_Tick];
  4126. }
  4127. }
  4128. for (new i = 0; i < sizeof(s_DamageFeedHitsTaken[]) - 1; i++) {
  4129. if (!s_DamageFeedHitsTaken[playerid][i][e_Tick]) {
  4130. break;
  4131. }
  4132. if (tick - s_DamageFeedHitsTaken[playerid][i][e_Tick] >= s_DamageFeedHideDelay) {
  4133. modified = true;
  4134. for (new j = i; j < sizeof(s_DamageFeedHitsTaken[]) - 1; j++) {
  4135. s_DamageFeedHitsTaken[playerid][j][e_Tick] = 0;
  4136. }
  4137. break;
  4138. }
  4139. if (s_DamageFeedHitsTaken[playerid][i][e_Tick] < lowest_tick) {
  4140. lowest_tick = s_DamageFeedHitsTaken[playerid][i][e_Tick];
  4141. }
  4142. }
  4143. if (s_DamageFeedTimer[playerid] != -1) {
  4144. KillTimer(s_DamageFeedTimer[playerid]);
  4145. }
  4146. if (tick - s_DamageFeedLastUpdate[playerid] < s_DamageFeedMaxUpdateRate && modified) {
  4147. s_DamageFeedTimer[playerid] = SetTimerEx("WC_DamageFeedUpdate", s_DamageFeedMaxUpdateRate - (tick - s_DamageFeedLastUpdate[playerid]), false, "i", playerid);
  4148. } else {
  4149. if (lowest_tick == tick + 1) {
  4150. s_DamageFeedTimer[playerid] = -1;
  4151. modified = true;
  4152. } else {
  4153. s_DamageFeedTimer[playerid] = SetTimerEx("WC_DamageFeedUpdate", s_DamageFeedHideDelay - (tick - lowest_tick) + 10, false, "i", playerid);
  4154. }
  4155. if (modified) {
  4156. DamageFeedUpdateText(playerid);
  4157. s_DamageFeedLastUpdate[playerid] = tick;
  4158. }
  4159. }
  4160. }
  4161. static DamageFeedUpdateText(playerid)
  4162. {
  4163. new buf[64 * WC_FEED_HEIGHT] = "";
  4164. for (new i = 0; i < sizeof(s_DamageFeedHitsGiven[]) - 1; i++) {
  4165. if (!s_DamageFeedHitsGiven[playerid][i][e_Tick]) {
  4166. break;
  4167. }
  4168. new weapon[32];
  4169. if (s_DamageFeedHitsGiven[playerid][i][e_Weapon] == -1) {
  4170. weapon = "Multiple";
  4171. } else {
  4172. WC_GetWeaponName(s_DamageFeedHitsGiven[playerid][i][e_Weapon], weapon);
  4173. }
  4174. if (s_DamageFeedHitsGiven[playerid][i][e_Issuer] == INVALID_PLAYER_ID) {
  4175. format(
  4176. buf,
  4177. sizeof(buf),
  4178. "%s%s +%.2f~n~",
  4179. buf,
  4180. weapon,
  4181. s_DamageFeedHitsGiven[playerid][i][e_Amount] + 0.009
  4182. );
  4183. } else {
  4184. format(
  4185. buf,
  4186. sizeof(buf),
  4187. "%s%s - %s +%.2f~n~",
  4188. buf,
  4189. s_DamageFeedHitsGiven[playerid][i][e_Name],
  4190. weapon,
  4191. s_DamageFeedHitsGiven[playerid][i][e_Amount] + 0.009
  4192. );
  4193. }
  4194. }
  4195. if (s_DamageFeedGiven[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4196. printf("(wc) WARN: Doesn't have feed textdraw when needed");
  4197. } else {
  4198. if (buf[0]) {
  4199. PlayerTextDrawSetString(playerid, s_DamageFeedGiven[playerid], buf);
  4200. PlayerTextDrawShow(playerid, s_DamageFeedGiven[playerid]);
  4201. } else {
  4202. PlayerTextDrawHide(playerid, s_DamageFeedGiven[playerid]);
  4203. }
  4204. }
  4205. buf = "";
  4206. for (new i = 0; i < sizeof(s_DamageFeedHitsTaken[]) - 1; i++) {
  4207. if (!s_DamageFeedHitsTaken[playerid][i][e_Tick]) {
  4208. break;
  4209. }
  4210. new weapon[32];
  4211. if (s_DamageFeedHitsTaken[playerid][i][e_Weapon] == -1) {
  4212. weapon = "Multiple";
  4213. } else {
  4214. WC_GetWeaponName(s_DamageFeedHitsTaken[playerid][i][e_Weapon], weapon);
  4215. }
  4216. if (s_DamageFeedHitsTaken[playerid][i][e_Issuer] == INVALID_PLAYER_ID) {
  4217. format(
  4218. buf,
  4219. sizeof(buf),
  4220. "%s%s -%.2f~n~",
  4221. buf,
  4222. weapon,
  4223. s_DamageFeedHitsTaken[playerid][i][e_Amount] + 0.009
  4224. );
  4225. } else {
  4226. format(
  4227. buf,
  4228. sizeof(buf),
  4229. "%s%s - %s -%.2f~n~",
  4230. buf,
  4231. s_DamageFeedHitsTaken[playerid][i][e_Name],
  4232. weapon,
  4233. s_DamageFeedHitsTaken[playerid][i][e_Amount] + 0.009
  4234. );
  4235. }
  4236. }
  4237. if (s_DamageFeedTaken[playerid] == PlayerText:INVALID_TEXT_DRAW) {
  4238. printf("(wc) WARN: Doesn't have feed textdraw when needed");
  4239. } else {
  4240. if (buf[0]) {
  4241. PlayerTextDrawSetString(playerid, s_DamageFeedTaken[playerid], buf);
  4242. PlayerTextDrawShow(playerid, s_DamageFeedTaken[playerid]);
  4243. } else {
  4244. PlayerTextDrawHide(playerid, s_DamageFeedTaken[playerid]);
  4245. }
  4246. }
  4247. }
  4248. static DamageFeedAddHitGiven(playerid, issuerid, Float:amount, weapon)
  4249. {
  4250. for (new i = 0; i < MAX_PLAYERS; i++) {
  4251. if (s_Spectating[i] == playerid && i != playerid) {
  4252. DamageFeedAddHit(s_DamageFeedHitsGiven[i], i, issuerid, amount, weapon);
  4253. }
  4254. }
  4255. DamageFeedAddHit(s_DamageFeedHitsGiven[playerid], playerid, issuerid, amount, weapon);
  4256. }
  4257. static DamageFeedAddHitTaken(playerid, issuerid, Float:amount, weapon)
  4258. {
  4259. for (new i = 0; i < MAX_PLAYERS; i++) {
  4260. if (s_Spectating[i] == playerid && i != playerid) {
  4261. DamageFeedAddHit(s_DamageFeedHitsTaken[i], i, issuerid, amount, weapon);
  4262. }
  4263. }
  4264. DamageFeedAddHit(s_DamageFeedHitsTaken[playerid], playerid, issuerid, amount, weapon);
  4265. }
  4266. static DamageFeedAddHit(arr[WC_FEED_HEIGHT][E_DAMAGE_FEED_HIT], playerid, issuerid, Float:amount, weapon)
  4267. {
  4268. if (!IsDamageFeedActive(playerid)) {
  4269. return;
  4270. }
  4271. new tick = GetTickCount();
  4272. if (tick == 0) tick = 1;
  4273. new idx = -1;
  4274. for (new i = 0; i < sizeof(arr) - 1; i++) {
  4275. if (!arr[i][e_Tick]) {
  4276. break;
  4277. }
  4278. if (tick - arr[i][e_Tick] >= s_DamageFeedHideDelay) {
  4279. DamageFeedRemoveHit(arr, i);
  4280. break;
  4281. }
  4282. // Remove it and add it on top below
  4283. if (arr[i][e_Issuer] == issuerid) {
  4284. // Multiple weapons
  4285. if (arr[i][e_Weapon] != weapon) {
  4286. //weapon = -1;
  4287. }
  4288. amount += arr[i][e_Amount];
  4289. idx = i;
  4290. break;
  4291. }
  4292. }
  4293. if (idx == -1) {
  4294. idx = 0;
  4295. // Insert it at the top
  4296. for (new i = sizeof(arr) - 1; i >= 1; i--) {
  4297. arr[i] = arr[i - 1];
  4298. }
  4299. }
  4300. arr[idx][e_Tick] = tick;
  4301. arr[idx][e_Amount] = amount;
  4302. arr[idx][e_Issuer] = issuerid;
  4303. arr[idx][e_Weapon] = weapon;
  4304. GetPlayerName(issuerid, arr[idx][e_Name], MAX_PLAYER_NAME);
  4305. DamageFeedUpdate(playerid, true);
  4306. }
  4307. static DamageFeedRemoveHit(arr[WC_FEED_HEIGHT][E_DAMAGE_FEED_HIT], idx)
  4308. {
  4309. for (new i = 0; i < WC_FEED_HEIGHT; i++) {
  4310. if (i >= idx) {
  4311. arr[i][e_Tick] = 0;
  4312. }
  4313. }
  4314. }
  4315. static SaveSyncData(playerid)
  4316. {
  4317. GetPlayerHealth(playerid, s_SyncData[playerid][e_Health]);
  4318. GetPlayerArmour(playerid, s_SyncData[playerid][e_Armour]);
  4319. GetPlayerPos(playerid, s_SyncData[playerid][e_PosX], s_SyncData[playerid][e_PosY], s_SyncData[playerid][e_PosZ]);
  4320. GetPlayerFacingAngle(playerid, s_SyncData[playerid][e_PosA]);
  4321. s_SyncData[playerid][e_Skin] = GetPlayerSkin(playerid);
  4322. s_SyncData[playerid][e_Team] = GetPlayerTeam(playerid);
  4323. s_SyncData[playerid][e_Weapon] = GetPlayerWeapon(playerid);
  4324. for (new i = 0; i < 13; i++) {
  4325. GetPlayerWeaponData(playerid, i, s_SyncData[playerid][e_WeaponId][i], s_SyncData[playerid][e_WeaponAmmo][i]);
  4326. }
  4327. }
  4328. static MakePlayerFacePlayer(playerid, targetid, opposite = false, forcesync = true)
  4329. {
  4330. new Float:x1, Float:y1, Float:z1;
  4331. new Float:x2, Float:y2, Float:z2;
  4332. GetPlayerPos(playerid, x1, y1, z1);
  4333. GetPlayerPos(targetid, x2, y2, z2);
  4334. new Float:angle = AngleBetweenPoints(x2, y2, x1, y1);
  4335. if (opposite) {
  4336. angle += 180.0;
  4337. if (angle > 360.0) angle -= 360.0;
  4338. }
  4339. if (angle < 0.0) angle += 360.0;
  4340. if (angle > 360.0) angle -= 360.0;
  4341. SetPlayerFacingAngle(playerid, angle);
  4342. if (forcesync) {
  4343. SetFakeFacingAngle(playerid, angle);
  4344. UpdateSyncData(playerid);
  4345. }
  4346. }
  4347. static IsPlayerBehindPlayer(playerid, targetid, Float:diff = 90.0)
  4348. {
  4349. new Float:x1, Float:y1, Float:z1;
  4350. new Float:x2, Float:y2, Float:z2;
  4351. new Float:ang, Float:angdiff;
  4352. GetPlayerPos(playerid, x1, y1, z1);
  4353. GetPlayerPos(targetid, x2, y2, z2);
  4354. GetPlayerFacingAngle(targetid, ang);
  4355. angdiff = AngleBetweenPoints(x1, y1, x2, y2);
  4356. if (angdiff < 0.0) angdiff += 360.0;
  4357. if (angdiff > 360.0) angdiff -= 360.0;
  4358. ang = ang - angdiff;
  4359. if (ang > 180.0) ang -= 360.0;
  4360. if (ang < -180.0) ang += 360.0;
  4361. return floatabs(ang) > diff;
  4362. }
  4363. static AddRejectedHit(playerid, damagedid, reason, weapon, i1 = 0, i2 = 0, i3 = 0)
  4364. {
  4365. new idx = s_RejectedHitsIdx[playerid];
  4366. if (s_RejectedHits[playerid][idx][e_Time]) {
  4367. idx += 1;
  4368. if (idx >= sizeof(s_RejectedHits[])) {
  4369. idx = 0;
  4370. }
  4371. s_RejectedHitsIdx[playerid] = idx;
  4372. }
  4373. new time, hour, minute, second;
  4374. time = gettime(hour, minute, second);
  4375. s_RejectedHits[playerid][idx][e_Reason] = reason;
  4376. s_RejectedHits[playerid][idx][e_Time] = time;
  4377. s_RejectedHits[playerid][idx][e_Weapon] = weapon;
  4378. s_RejectedHits[playerid][idx][e_Hour] = hour;
  4379. s_RejectedHits[playerid][idx][e_Minute] = minute;
  4380. s_RejectedHits[playerid][idx][e_Second] = second;
  4381. s_RejectedHits[playerid][idx][e_Info1] = _:i1;
  4382. s_RejectedHits[playerid][idx][e_Info2] = _:i2;
  4383. s_RejectedHits[playerid][idx][e_Info3] = _:i3;
  4384. if (damagedid != INVALID_PLAYER_ID) {
  4385. GetPlayerName(damagedid, s_RejectedHits[playerid][idx][e_Name], MAX_PLAYER_NAME);
  4386. } else {
  4387. s_RejectedHits[playerid][idx][e_Name][0] = '#';
  4388. s_RejectedHits[playerid][idx][e_Name][1] = '\0';
  4389. }
  4390. OnRejectedHit(playerid, s_RejectedHits[playerid][idx]);
  4391. }
  4392. forward WC_SecondKnifeAnim(playerid);
  4393. public WC_SecondKnifeAnim(playerid)
  4394. {
  4395. ApplyAnimation(playerid, "KNIFE", "KILL_Knife_Ped_Die", 4.1, 0, 1, 1, 1, 3000, 1);
  4396. }
  4397. forward WC_PlayerDeathRespawn(playerid);
  4398. public WC_PlayerDeathRespawn(playerid)
  4399. {
  4400. if (!s_IsDying[playerid]) {
  4401. return;
  4402. }
  4403. s_IsDying[playerid] = false;
  4404. if (!OnPlayerDeathFinished(playerid, true)) {
  4405. UpdateHealthBar(playerid);
  4406. SetFakeFacingAngle(playerid, _);
  4407. FreezeSyncData(playerid, false);
  4408. return;
  4409. }
  4410. s_IsDying[playerid] = true;
  4411. s_TrueDeath[playerid] = false;
  4412. if (IsPlayerInAnyVehicle(playerid)) {
  4413. new Float:x, Float:y, Float:z;
  4414. GetPlayerPos(playerid, x, y, z);
  4415. SetPlayerPos(playerid, x, y, z);
  4416. }
  4417. SetPlayerVirtualWorld(playerid, WC_DEATH_WORLD);
  4418. SetFakeFacingAngle(playerid, _);
  4419. TogglePlayerSpectating(playerid, true);
  4420. TogglePlayerSpectating(playerid, false);
  4421. }
  4422. public OnInvalidWeaponDamage(playerid, damagedid, Float:amount, weaponid, bodypart, error, bool:given)
  4423. {
  4424. DebugMessageRedAll("OnInvalidWeaponDamage(%d, %d, %f, %d, %d, %d, %d)", playerid, damagedid, amount, weaponid, bodypart, error, given);
  4425. #if defined WC_OnInvalidWeaponDamage
  4426. WC_OnInvalidWeaponDamage(playerid, damagedid, Float:amount, weaponid, bodypart, error, bool:given);
  4427. #endif
  4428. }
  4429. public OnPlayerDamageDone(playerid, Float:amount, issuerid, weapon, bodypart)
  4430. {
  4431. new idx = s_PreviousHitI[playerid];
  4432. s_PreviousHitI[playerid] = (s_PreviousHitI[playerid] - 1) % sizeof(s_PreviousHits[]);
  4433. // JIT plugin fix
  4434. if (s_PreviousHitI[playerid] < 0) {
  4435. s_PreviousHitI[playerid] += sizeof(s_PreviousHits[]);
  4436. }
  4437. s_PreviousHits[playerid][idx][e_Tick] = GetTickCount();
  4438. s_PreviousHits[playerid][idx][e_Issuer] = issuerid;
  4439. s_PreviousHits[playerid][idx][e_Weapon] = weapon;
  4440. s_PreviousHits[playerid][idx][e_Amount] = amount;
  4441. s_PreviousHits[playerid][idx][e_Bodypart] = bodypart;
  4442. s_PreviousHits[playerid][idx][e_Health] = GetLastDamageHealth(playerid);
  4443. s_PreviousHits[playerid][idx][e_Armour] = GetLastDamageArmour(playerid);
  4444. if (!IsHighRateWeapon(weapon)) {
  4445. DebugMessageAll("OnPlayerDamageDone(%d did %f to %d with %d on bodypart %d)", issuerid, amount, playerid, weapon, bodypart);
  4446. if (s_DamageTakenSound) {
  4447. PlayerPlaySound(playerid, s_DamageTakenSound, 0.0, 0.0, 0.0);
  4448. for (new i = 0; i < MAX_PLAYERS; i++) {
  4449. if (s_Spectating[i] == playerid && i != playerid) {
  4450. PlayerPlaySound(i, s_DamageTakenSound, 0.0, 0.0, 0.0);
  4451. }
  4452. }
  4453. }
  4454. if (s_DamageGivenSound && issuerid != INVALID_PLAYER_ID) {
  4455. PlayerPlaySound(issuerid, s_DamageGivenSound, 0.0, 0.0, 0.0);
  4456. for (new i = 0; i < MAX_PLAYERS; i++) {
  4457. if (s_Spectating[i] == issuerid && i != issuerid) {
  4458. PlayerPlaySound(i, s_DamageGivenSound, 0.0, 0.0, 0.0);
  4459. }
  4460. }
  4461. }
  4462. }
  4463. if (issuerid != INVALID_PLAYER_ID) {
  4464. DamageFeedAddHitGiven(issuerid, playerid, amount, weapon);
  4465. }
  4466. DamageFeedAddHitTaken(playerid, issuerid, amount, weapon);
  4467. #if defined WC_OnPlayerDamageDone
  4468. WC_OnPlayerDamageDone(playerid, amount, issuerid, weapon, bodypart);
  4469. #endif
  4470. }
  4471. public OnPlayerDamage(&playerid, &Float:amount, &issuerid, &weapon, &bodypart)
  4472. {
  4473. #if defined WC_OnPlayerDamage
  4474. return WC_OnPlayerDamage(playerid, amount, issuerid, weapon, bodypart);
  4475. #else
  4476. return 1;
  4477. #endif
  4478. }
  4479. /*
  4480. * ALS callbacks
  4481. */
  4482. #if defined _ALS_OnGameModeInit
  4483. #undef OnGameModeInit
  4484. #else
  4485. #define _ALS_OnGameModeInit
  4486. #endif
  4487. #define OnGameModeInit WC_OnGameModeInit
  4488. #if defined WC_OnGameModeInit
  4489. forward WC_OnGameModeInit();
  4490. #endif
  4491. #if defined _ALS_OnGameModeExit
  4492. #undef OnGameModeExit
  4493. #else
  4494. #define _ALS_OnGameModeExit
  4495. #endif
  4496. #define OnGameModeExit WC_OnGameModeExit
  4497. #if defined WC_OnGameModeExit
  4498. forward WC_OnGameModeExit();
  4499. #endif
  4500. #if defined _ALS_OnFilterScriptInit
  4501. #undef OnFilterScriptInit
  4502. #else
  4503. #define _ALS_OnFilterScriptInit
  4504. #endif
  4505. #define OnFilterScriptInit WC_OnFilterScriptInit
  4506. #if defined WC_OnFilterScriptInit
  4507. forward WC_OnFilterScriptInit();
  4508. #endif
  4509. #if defined _ALS_OnFilterScriptExit
  4510. #undef OnFilterScriptExit
  4511. #else
  4512. #define _ALS_OnFilterScriptExit
  4513. #endif
  4514. #define OnFilterScriptExit WC_OnFilterScriptExit
  4515. #if defined WC_OnFilterScriptExit
  4516. forward WC_OnFilterScriptExit();
  4517. #endif
  4518. #if defined _ALS_OnPlayerConnect
  4519. #undef OnPlayerConnect
  4520. #else
  4521. #define _ALS_OnPlayerConnect
  4522. #endif
  4523. #define OnPlayerConnect WC_OnPlayerConnect
  4524. #if defined WC_OnPlayerConnect
  4525. forward WC_OnPlayerConnect(playerid);
  4526. #endif
  4527. #if defined _ALS_OnPlayerDisconnect
  4528. #undef OnPlayerDisconnect
  4529. #else
  4530. #define _ALS_OnPlayerDisconnect
  4531. #endif
  4532. #define OnPlayerDisconnect WC_OnPlayerDisconnect
  4533. #if defined WC_OnPlayerDisconnect
  4534. forward WC_OnPlayerDisconnect(playerid, reason);
  4535. #endif
  4536. #if defined _ALS_OnPlayerStreamIn
  4537. #undef OnPlayerStreamIn
  4538. #else
  4539. #define _ALS_OnPlayerStreamIn
  4540. #endif
  4541. #define OnPlayerStreamIn WC_OnPlayerStreamIn
  4542. #if defined WC_OnPlayerStreamIn
  4543. forward WC_OnPlayerStreamIn(playerid, forplayerid);
  4544. #endif
  4545. #if defined _ALS_OnVehicleDeath
  4546. #undef OnVehicleDeath
  4547. #else
  4548. #define _ALS_OnVehicleDeath
  4549. #endif
  4550. #define OnVehicleDeath WC_OnVehicleDeath
  4551. #if defined WC_OnVehicleDeath
  4552. forward WC_OnVehicleDeath(vehicleid, killerid);
  4553. #endif
  4554. #if defined _ALS_OnVehicleSpawn
  4555. #undef OnVehicleSpawn
  4556. #else
  4557. #define _ALS_OnVehicleSpawn
  4558. #endif
  4559. #define OnVehicleSpawn WC_OnVehicleSpawn
  4560. #if defined WC_OnVehicleSpawn
  4561. forward WC_OnVehicleSpawn(vehicleid);
  4562. #endif
  4563. #if defined _ALS_OnPlayerEnterVehicle
  4564. #undef OnPlayerEnterVehicle
  4565. #else
  4566. #define _ALS_OnPlayerEnterVehicle
  4567. #endif
  4568. #define OnPlayerEnterVehicle WC_OnPlayerEnterVehicle
  4569. #if defined WC_OnPlayerEnterVehicle
  4570. forward WC_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
  4571. #endif
  4572. #if defined _ALS_OnPlayerExitVehicle
  4573. #undef OnPlayerExitVehicle
  4574. #else
  4575. #define _ALS_OnPlayerExitVehicle
  4576. #endif
  4577. #define OnPlayerExitVehicle WC_OnPlayerExitVehicle
  4578. #if defined WC_OnPlayerExitVehicle
  4579. forward WC_OnPlayerExitVehicle(playerid, vehicleid);
  4580. #endif
  4581. #if defined _ALS_OnPlayerStateChange
  4582. #undef OnPlayerStateChange
  4583. #else
  4584. #define _ALS_OnPlayerStateChange
  4585. #endif
  4586. #define OnPlayerStateChange WC_OnPlayerStateChange
  4587. #if defined WC_OnPlayerStateChange
  4588. forward WC_OnPlayerStateChange(playerid, newstate, oldstate);
  4589. #endif
  4590. #if defined _ALS_OnPlayerPickUpPickup
  4591. #undef OnPlayerPickUpPickup
  4592. #else
  4593. #define _ALS_OnPlayerPickUpPickup
  4594. #endif
  4595. #define OnPlayerPickUpPickup WC_OnPlayerPickUpPickup
  4596. #if defined WC_OnPlayerPickUpPickup
  4597. forward WC_OnPlayerPickUpPickup(playerid, pickupid);
  4598. #endif
  4599. #if defined _ALS_OnPlayerUpdate
  4600. #undef OnPlayerUpdate
  4601. #else
  4602. #define _ALS_OnPlayerUpdate
  4603. #endif
  4604. #define OnPlayerUpdate WC_OnPlayerUpdate
  4605. #if defined WC_OnPlayerUpdate
  4606. forward WC_OnPlayerUpdate(playerid);
  4607. #endif
  4608. #if defined _ALS_OnPlayerSpawn
  4609. #undef OnPlayerSpawn
  4610. #else
  4611. #define _ALS_OnPlayerSpawn
  4612. #endif
  4613. #define OnPlayerSpawn WC_OnPlayerSpawn
  4614. #if defined WC_OnPlayerSpawn
  4615. forward WC_OnPlayerSpawn(playerid);
  4616. #endif
  4617. #if defined _ALS_OnPlayerRequestClass
  4618. #undef OnPlayerRequestClass
  4619. #else
  4620. #define _ALS_OnPlayerRequestClass
  4621. #endif
  4622. #define OnPlayerRequestClass WC_OnPlayerRequestClass
  4623. #if defined WC_OnPlayerRequestClass
  4624. forward WC_OnPlayerRequestClass(playerid, classid);
  4625. #endif
  4626. #if defined _ALS_OnPlayerDeath
  4627. #undef OnPlayerDeath
  4628. #else
  4629. #define _ALS_OnPlayerDeath
  4630. #endif
  4631. #define OnPlayerDeath WC_OnPlayerDeath
  4632. #if defined WC_OnPlayerDeath
  4633. forward WC_OnPlayerDeath(playerid, killerid, reason);
  4634. #endif
  4635. #if defined _ALS_OnPlayerKeyStateChange
  4636. #undef OnPlayerKeyStateChange
  4637. #else
  4638. #define _ALS_OnPlayerKeyStateChange
  4639. #endif
  4640. #define OnPlayerKeyStateChange WC_OnPlayerKeyStateChange
  4641. #if defined WC_OnPlayerKeyStateChange
  4642. forward WC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys);
  4643. #endif
  4644. #if defined _ALS_OnPlayerWeaponShot
  4645. #undef OnPlayerWeaponShot
  4646. #else
  4647. #define _ALS_OnPlayerWeaponShot
  4648. #endif
  4649. #define OnPlayerWeaponShot WC_OnPlayerWeaponShot
  4650. #if defined WC_OnPlayerWeaponShot
  4651. forward WC_OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ);
  4652. #endif
  4653. #if defined _ALS_OnPlayerEnterCheckpoint
  4654. #undef OnPlayerEnterCheckpoint
  4655. #else
  4656. #define _ALS_OnPlayerEnterCheckpoint
  4657. #endif
  4658. #define OnPlayerEnterCheckpoint WC_OnPlayerEnterCheckpoint
  4659. #if defined WC_OnPlayerEnterCheckpoint
  4660. forward WC_OnPlayerEnterCheckpoint(playerid);
  4661. #endif
  4662. #if defined _ALS_OnPlayerLeaveCheckpoint
  4663. #undef OnPlayerLeaveCheckpoint
  4664. #else
  4665. #define _ALS_OnPlayerLeaveCheckpoint
  4666. #endif
  4667. #define OnPlayerLeaveCheckpoint WC_OnPlayerLeaveCheckpoint
  4668. #if defined WC_OnPlayerLeaveCheckpoint
  4669. forward WC_OnPlayerLeaveCheckpoint(playerid);
  4670. #endif
  4671. #if defined _ALS_OnInvalidWeaponDamage
  4672. #undef OnInvalidWeaponDamage
  4673. #else
  4674. #define _ALS_OnInvalidWeaponDamage
  4675. #endif
  4676. #define OnInvalidWeaponDamage WC_OnInvalidWeaponDamage
  4677. #if defined WC_OnInvalidWeaponDamage
  4678. forward WC_OnInvalidWeaponDamage(playerid, damagedid, Float:amount, weaponid, bodypart, error, bool:given);
  4679. #endif
  4680. #if defined _ALS_OnPlayerDamageDone
  4681. #undef OnPlayerDamageDone
  4682. #else
  4683. #define _ALS_OnPlayerDamageDone
  4684. #endif
  4685. #define OnPlayerDamageDone WC_OnPlayerDamageDone
  4686. #if defined WC_OnPlayerDamageDone
  4687. forward WC_OnPlayerDamageDone(playerid, Float:amount, issuerid, weapon, bodypart);
  4688. #endif
  4689. #if defined _ALS_OnPlayerDamage
  4690. #undef OnPlayerDamage
  4691. #else
  4692. #define _ALS_OnPlayerDamage
  4693. #endif
  4694. #define OnPlayerDamage WC_OnPlayerDamage
  4695. #if defined WC_OnPlayerDamage
  4696. forward WC_OnPlayerDamage(&playerid, &Float:amount, &issuerid, &weapon, &bodypart);
  4697. #endif
  4698. #if defined _ALS_OnPlayerPrepareDeath
  4699. #undef OnPlayerPrepareDeath
  4700. #else
  4701. #define _ALS_OnPlayerPrepareDeath
  4702. #endif
  4703. #define OnPlayerPrepareDeath WC_OnPlayerPrepareDeath
  4704. #if defined WC_OnPlayerPrepareDeath
  4705. forward WC_OnPlayerPrepareDeath(playerid, animlib[32], animname[32], &anim_lock, &respawn_time);
  4706. #endif
  4707. #if defined _ALS_OnRejectedHit
  4708. #undef OnRejectedHit
  4709. #else
  4710. #define _ALS_OnRejectedHit
  4711. #endif
  4712. #define OnRejectedHit WC_OnRejectedHit
  4713. #if defined WC_OnRejectedHit
  4714. forward WC_OnRejectedHit(playerid, hit[E_REJECTED_HIT]);
  4715. #endif
  4716. #if WC_CUSTOM_VENDING_MACHINES
  4717. #if defined _ALS_OnPlayerUseVendingMachine
  4718. #undef OnPlayerUseVendingMachine
  4719. #else
  4720. #define _ALS_OnPlayerUseVendingMachine
  4721. #endif
  4722. #define OnPlayerUseVendingMachine WC_OnPlayerUseVendingMachine
  4723. #if defined WC_OnPlayerUseVendingMachine
  4724. forward WC_OnPlayerUseVendingMachine(playerid, &Float:health_given);
  4725. #endif
  4726. #endif
  4727. #if defined _ALS_OnPlayerDeathFinished
  4728. #undef OnPlayerDeathFinished
  4729. #else
  4730. #define _ALS_OnPlayerDeathFinished
  4731. #endif
  4732. #define OnPlayerDeathFinished WC_OnPlayerDeathFinished
  4733. #if defined WC_OnPlayerDeathFinished
  4734. forward WC_OnPlayerDeathFinished(playerid, bool:cancelable);
  4735. #endif
  4736. /*
  4737. * ALS functions
  4738. */
  4739. #if defined _ALS_SpawnPlayer
  4740. #undef SpawnPlayer
  4741. #else
  4742. #define _ALS_SpawnPlayer
  4743. #endif
  4744. #define SpawnPlayer WC_SpawnPlayer
  4745. #if defined _ALS_SetPlayerHealth
  4746. #undef SetPlayerHealth
  4747. #else
  4748. #define _ALS_SetPlayerHealth
  4749. #endif
  4750. #define SetPlayerHealth WC_SetPlayerHealth
  4751. #if defined _ALS_GetPlayerState
  4752. #undef GetPlayerState
  4753. #else
  4754. #define _ALS_GetPlayerState
  4755. #endif
  4756. #define GetPlayerState WC_GetPlayerState
  4757. #if defined _ALS_GetPlayerHealth
  4758. #undef GetPlayerHealth
  4759. #else
  4760. #define _ALS_GetPlayerHealth
  4761. #endif
  4762. #define GetPlayerHealth WC_GetPlayerHealth
  4763. #if defined _ALS_SetPlayerArmour
  4764. #undef SetPlayerArmour
  4765. #else
  4766. #define _ALS_SetPlayerArmour
  4767. #endif
  4768. #define SetPlayerArmour WC_SetPlayerArmour
  4769. #if defined _ALS_GetPlayerArmour
  4770. #undef GetPlayerArmour
  4771. #else
  4772. #define _ALS_GetPlayerArmour
  4773. #endif
  4774. #define GetPlayerArmour WC_GetPlayerArmour
  4775. #if defined _ALS_GetPlayerTeam
  4776. #undef GetPlayerTeam
  4777. #else
  4778. #define _ALS_GetPlayerTeam
  4779. #endif
  4780. #define GetPlayerTeam WC_GetPlayerTeam
  4781. #if defined _ALS_SetPlayerTeam
  4782. #undef SetPlayerTeam
  4783. #else
  4784. #define _ALS_SetPlayerTeam
  4785. #endif
  4786. #define SetPlayerTeam WC_SetPlayerTeam
  4787. #if defined _ALS_SendDeathMessage
  4788. #undef SendDeathMessage
  4789. #else
  4790. #define _ALS_SendDeathMessage
  4791. #endif
  4792. #define SendDeathMessage WC_SendDeathMessage
  4793. #if defined _ALS_GetWeaponName
  4794. #undef GetWeaponName
  4795. #else
  4796. #define _ALS_GetWeaponName
  4797. #endif
  4798. #define GetWeaponName WC_GetWeaponName
  4799. #if defined _ALS_ApplyAnimation
  4800. #undef ApplyAnimation
  4801. #else
  4802. #define _ALS_ApplyAnimation
  4803. #endif
  4804. #define ApplyAnimation WC_ApplyAnimation
  4805. #if defined _ALS_ClearAnimations
  4806. #undef ClearAnimations
  4807. #else
  4808. #define _ALS_ClearAnimations
  4809. #endif
  4810. #define ClearAnimations WC_ClearAnimations
  4811. #if defined _ALS_AddPlayerClass
  4812. #undef AddPlayerClass
  4813. #else
  4814. #define _ALS_AddPlayerClass
  4815. #endif
  4816. #define AddPlayerClass WC_AddPlayerClass
  4817. #if defined _ALS_AddPlayerClassEx
  4818. #undef AddPlayerClassEx
  4819. #else
  4820. #define _ALS_AddPlayerClassEx
  4821. #endif
  4822. #define AddPlayerClassEx WC_AddPlayerClassEx
  4823. #if defined _ALS_SetSpawnInfo
  4824. #undef SetSpawnInfo
  4825. #else
  4826. #define _ALS_SetSpawnInfo
  4827. #endif
  4828. #define SetSpawnInfo WC_SetSpawnInfo
  4829. #if defined _ALS_TogglePlayerSpectating
  4830. #undef TogglePlayerSpectating
  4831. #else
  4832. #define _ALS_TogglePlayerSpectating
  4833. #endif
  4834. #define TogglePlayerSpectating WC_TogglePlayerSpectating
  4835. #if defined _ALS_TogglePlayerControllable
  4836. #undef TogglePlayerControllable
  4837. #else
  4838. #define _ALS_TogglePlayerControllable
  4839. #endif
  4840. #define TogglePlayerControllable WC_TogglePlayerControllable
  4841. #if defined _ALS_SetPlayerPos
  4842. #undef SetPlayerPos
  4843. #else
  4844. #define _ALS_SetPlayerPos
  4845. #endif
  4846. #define SetPlayerPos WC_SetPlayerPos
  4847. #if defined _ALS_SetPlayerPosFindZ
  4848. #undef SetPlayerPosFindZ
  4849. #else
  4850. #define _ALS_SetPlayerPosFindZ
  4851. #endif
  4852. #define SetPlayerPosFindZ WC_SetPlayerPosFindZ
  4853. #if defined _ALS_SetPlayerVelocity
  4854. #undef SetPlayerVelocity
  4855. #else
  4856. #define _ALS_SetPlayerVelocity
  4857. #endif
  4858. #define SetPlayerVelocity WC_SetPlayerVelocity
  4859. #if defined _ALS_SetPlayerVirtualWorld
  4860. #undef SetPlayerVirtualWorld
  4861. #else
  4862. #define _ALS_SetPlayerVirtualWorld
  4863. #endif
  4864. #define SetPlayerVirtualWorld wc_SetPlayerVirtualWorld
  4865. #if defined _ALS_GetPlayerVirtualWorld
  4866. #undef GetPlayerVirtualWorld
  4867. #else
  4868. #define _ALS_GetPlayerVirtualWorld
  4869. #endif
  4870. #define GetPlayerVirtualWorld WC_GetPlayerVirtualWorld
  4871. #if defined _ALS_PlayerSpectatePlayer
  4872. #undef PlayerSpectatePlayer
  4873. #else
  4874. #define _ALS_PlayerSpectatePlayer
  4875. #endif
  4876. #define PlayerSpectatePlayer WC_PlayerSpectatePlayer
  4877. #if defined _ALS_DestroyVehicle
  4878. #undef DestroyVehicle
  4879. #else
  4880. #define _ALS_DestroyVehicle
  4881. #endif
  4882. #define DestroyVehicle WC_DestroyVehicle
  4883. #if defined _ALS_CreateVehicle
  4884. #undef CreateVehicle
  4885. #else
  4886. #define _ALS_CreateVehicle
  4887. #endif
  4888. #define CreateVehicle WC_CreateVehicle
  4889. #if defined _ALS_AddStaticVehicle
  4890. #undef AddStaticVehicle
  4891. #else
  4892. #define _ALS_AddStaticVehicle
  4893. #endif
  4894. #define AddStaticVehicle WC_AddStaticVehicle
  4895. #if defined _ALS_AddStaticVehicleEx
  4896. #undef AddStaticVehicleEx
  4897. #else
  4898. #define _ALS_AddStaticVehicleEx
  4899. #endif
  4900. #define AddStaticVehicleEx WC_AddStaticVehicleEx
  4901. #if defined _ALS_IsPlayerInCheckpoint
  4902. #undef IsPlayerInCheckpoint
  4903. #else
  4904. #define _ALS_IsPlayerInCheckpoint
  4905. #endif
  4906. #define IsPlayerInCheckpoint WC_IsPlayerInCheckpoint
  4907. #if defined _ALS_SetPlayerSpecialAction
  4908. #undef SetPlayerSpecialAction
  4909. #else
  4910. #define _ALS_SetPlayerSpecialAction
  4911. #endif
  4912. #define SetPlayerSpecialAction WC_SetPlayerSpecialAction
  4913. #if defined _ALS_TextDrawCreate
  4914. #undef TextDrawCreate
  4915. #else
  4916. #define _ALS_TextDrawCreate
  4917. #endif
  4918. #define TextDrawCreate WC_TextDrawCreate
  4919. #if defined _ALS_TextDrawDestroy
  4920. #undef TextDrawDestroy
  4921. #else
  4922. #define _ALS_TextDrawDestroy
  4923. #endif
  4924. #define TextDrawDestroy WC_TextDrawDestroy
  4925. #if defined _ALS_TextDrawLetterSize
  4926. #undef TextDrawLetterSize
  4927. #else
  4928. #define _ALS_TextDrawLetterSize
  4929. #endif
  4930. #define TextDrawLetterSize WC_TextDrawLetterSize
  4931. #if defined _ALS_TextDrawTextSize
  4932. #undef TextDrawTextSize
  4933. #else
  4934. #define _ALS_TextDrawTextSize
  4935. #endif
  4936. #define TextDrawTextSize WC_TextDrawTextSize
  4937. #if defined _ALS_TextDrawAlignment
  4938. #undef TextDrawAlignment
  4939. #else
  4940. #define _ALS_TextDrawAlignment
  4941. #endif
  4942. #define TextDrawAlignment WC_TextDrawAlignment
  4943. #if defined _ALS_TextDrawColor
  4944. #undef TextDrawColor
  4945. #else
  4946. #define _ALS_TextDrawColor
  4947. #endif
  4948. #define TextDrawColor WC_TextDrawColor
  4949. #if defined _ALS_TextDrawUseBox
  4950. #undef TextDrawUseBox
  4951. #else
  4952. #define _ALS_TextDrawUseBox
  4953. #endif
  4954. #define TextDrawUseBox WC_TextDrawUseBox
  4955. #if defined _ALS_TextDrawBoxColor
  4956. #undef TextDrawBoxColor
  4957. #else
  4958. #define _ALS_TextDrawBoxColor
  4959. #endif
  4960. #define TextDrawBoxColor WC_TextDrawBoxColor
  4961. #if defined _ALS_TextDrawSetShadow
  4962. #undef TextDrawSetShadow
  4963. #else
  4964. #define _ALS_TextDrawSetShadow
  4965. #endif
  4966. #define TextDrawSetShadow WC_TextDrawSetShadow
  4967. #if defined _ALS_TextDrawSetOutline
  4968. #undef TextDrawSetOutline
  4969. #else
  4970. #define _ALS_TextDrawSetOutline
  4971. #endif
  4972. #define TextDrawSetOutline WC_TextDrawSetOutline
  4973. #if defined _ALS_TextDrawBackgroundColor
  4974. #undef TextDrawBackgroundColor
  4975. #else
  4976. #define _ALS_TextDrawBackgroundColor
  4977. #endif
  4978. #define TextDrawBackgroundColor WC_TextDrawBackgroundColor
  4979. #if defined _ALS_TextDrawFont
  4980. #undef TextDrawFont
  4981. #else
  4982. #define _ALS_TextDrawFont
  4983. #endif
  4984. #define TextDrawFont WC_TextDrawFont
  4985. #if defined _ALS_TextDrawSetProportional
  4986. #undef TextDrawSetProportional
  4987. #else
  4988. #define _ALS_TextDrawSetProportional
  4989. #endif
  4990. #define TextDrawSetProportional WC_TextDrawSetProportional
  4991. #if defined _ALS_TextDrawSetSelectable
  4992. #undef TextDrawSetSelectable
  4993. #else
  4994. #define _ALS_TextDrawSetSelectable
  4995. #endif
  4996. #define TextDrawSetSelectable WC_TextDrawSetSelectable
  4997. #if defined _ALS_TextDrawShowForPlayer
  4998. #undef TextDrawShowForPlayer
  4999. #else
  5000. #define _ALS_TextDrawShowForPlayer
  5001. #endif
  5002. #define TextDrawShowForPlayer WC_TextDrawShowForPlayer
  5003. #if defined _ALS_TextDrawHideForPlayer
  5004. #undef TextDrawHideForPlayer
  5005. #else
  5006. #define _ALS_TextDrawHideForPlayer
  5007. #endif
  5008. #define TextDrawHideForPlayer WC_TextDrawHideForPlayer
  5009. #if defined _ALS_TextDrawShowForAll
  5010. #undef TextDrawShowForAll
  5011. #else
  5012. #define _ALS_TextDrawShowForAll
  5013. #endif
  5014. #define TextDrawShowForAll WC_TextDrawShowForAll
  5015. #if defined _ALS_TextDrawHideForAll
  5016. #undef TextDrawHideForAll
  5017. #else
  5018. #define _ALS_TextDrawHideForAll
  5019. #endif
  5020. #define TextDrawHideForAll WC_TextDrawHideForAll
  5021. #if defined _ALS_TextDrawSetString
  5022. #undef TextDrawSetString
  5023. #else
  5024. #define _ALS_TextDrawSetString
  5025. #endif
  5026. #define TextDrawSetString WC_TextDrawSetString
  5027. #if defined _ALS_TextDrawSetPreviewModel
  5028. #undef TextDrawSetPreviewModel
  5029. #else
  5030. #define _ALS_TextDrawSetPreviewModel
  5031. #endif
  5032. #define TextDrawSetPreviewModel WC_TextDrawSetPreviewModel
  5033. #if defined _ALS_TextDrawSetPreviewRot
  5034. #undef TextDrawSetPreviewRot
  5035. #else
  5036. #define _ALS_TextDrawSetPreviewRot
  5037. #endif
  5038. #define TextDrawSetPreviewRot WC_TextDrawSetPreviewRot
  5039. #if defined _ALS_TextDrawSetPreviewVehCol
  5040. #undef TextDrawSetPreviewVehCol
  5041. #else
  5042. #define _ALS_TextDrawSetPreviewVehCol
  5043. #endif
  5044. #define TextDrawSetPreviewVehCol WC_TextDrawSetPreviewVehCol
  5045. #if defined _ALS_CreatePlayerTextDraw
  5046. #undef CreatePlayerTextDraw
  5047. #else
  5048. #define _ALS_CreatePlayerTextDraw
  5049. #endif
  5050. #define CreatePlayerTextDraw WC_CreatePlayerTextDraw
  5051. #if defined _ALS_PlayerTextDrawDestroy
  5052. #undef PlayerTextDrawDestroy
  5053. #else
  5054. #define _ALS_PlayerTextDrawDestroy
  5055. #endif
  5056. #define PlayerTextDrawDestroy WC_PlayerTextDrawDestroy
  5057. #if defined _ALS_PlayerTextDrawLetterSize
  5058. #undef PlayerTextDrawLetterSize
  5059. #else
  5060. #define _ALS_PlayerTextDrawLetterSize
  5061. #endif
  5062. #define PlayerTextDrawLetterSize WC_PlayerTextDrawLetterSize
  5063. #if defined _ALS_PlayerTextDrawTextSize
  5064. #undef PlayerTextDrawTextSize
  5065. #else
  5066. #define _ALS_PlayerTextDrawTextSize
  5067. #endif
  5068. #define PlayerTextDrawTextSize WC_PlayerTextDrawTextSize
  5069. #if defined _ALS_PlayerTextDrawAlignment
  5070. #undef PlayerTextDrawAlignment
  5071. #else
  5072. #define _ALS_PlayerTextDrawAlignment
  5073. #endif
  5074. #define PlayerTextDrawAlignment WC_PlayerTextDrawAlignment
  5075. #if defined _ALS_PlayerTextDrawColor
  5076. #undef PlayerTextDrawColor
  5077. #else
  5078. #define _ALS_PlayerTextDrawColor
  5079. #endif
  5080. #define PlayerTextDrawColor WC_PlayerTextDrawColor
  5081. #if defined _ALS_PlayerTextDrawUseBox
  5082. #undef PlayerTextDrawUseBox
  5083. #else
  5084. #define _ALS_PlayerTextDrawUseBox
  5085. #endif
  5086. #define PlayerTextDrawUseBox WC_PlayerTextDrawUseBox
  5087. #if defined _ALS_PlayerTextDrawBoxColor
  5088. #undef PlayerTextDrawBoxColor
  5089. #else
  5090. #define _ALS_PlayerTextDrawBoxColor
  5091. #endif
  5092. #define PlayerTextDrawBoxColor WC_PlayerTextDrawBoxColor
  5093. #if defined _ALS_PlayerTextDrawSetShadow
  5094. #undef PlayerTextDrawSetShadow
  5095. #else
  5096. #define _ALS_PlayerTextDrawSetShadow
  5097. #endif
  5098. #define PlayerTextDrawSetShadow WC_PlayerTextDrawSetShadow
  5099. #if defined _ALS_PlayerTextDrawSetOutline
  5100. #undef PlayerTextDrawSetOutline
  5101. #else
  5102. #define _ALS_PlayerTextDrawSetOutline
  5103. #endif
  5104. #define PlayerTextDrawSetOutline WC_PlayerTextDrawSetOutline
  5105. #if defined _ALS_PlayerTextDrawBackgroundCo
  5106. #undef PlayerTextDrawBackgroundColor
  5107. #else
  5108. #define _ALS_PlayerTextDrawBackgroundCo
  5109. #endif
  5110. #define PlayerTextDrawBackgroundColor WC_PlayerTextDrawBackgroundColo
  5111. #if defined _ALS_PlayerTextDrawFont
  5112. #undef PlayerTextDrawFont
  5113. #else
  5114. #define _ALS_PlayerTextDrawFont
  5115. #endif
  5116. #define PlayerTextDrawFont WC_PlayerTextDrawFont
  5117. #if defined _ALS_PlayerTextDrawSetProportio
  5118. #undef PlayerTextDrawSetProportional
  5119. #else
  5120. #define _ALS_PlayerTextDrawSetProportio
  5121. #endif
  5122. #define PlayerTextDrawSetProportional WC_PlayerTextDrawSetProportiona
  5123. #if defined _ALS_PlayerTextDrawSetSelectabl
  5124. #undef PlayerTextDrawSetSelectable
  5125. #else
  5126. #define _ALS_PlayerTextDrawSetSelectabl
  5127. #endif
  5128. #define PlayerTextDrawSetSelectable WC_PlayerTextDrawSetSelectable
  5129. #if defined _ALS_PlayerTextDrawShow
  5130. #undef PlayerTextDrawShow
  5131. #else
  5132. #define _ALS_PlayerTextDrawShow
  5133. #endif
  5134. #define PlayerTextDrawShow WC_PlayerTextDrawShow
  5135. #if defined _ALS_PlayerTextDrawHide
  5136. #undef PlayerTextDrawHide
  5137. #else
  5138. #define _ALS_PlayerTextDrawHide
  5139. #endif
  5140. #define PlayerTextDrawHide WC_PlayerTextDrawHide
  5141. #if defined _ALS_PlayerTextDrawSetString
  5142. #undef PlayerTextDrawSetString
  5143. #else
  5144. #define _ALS_PlayerTextDrawSetString
  5145. #endif
  5146. #define PlayerTextDrawSetString WC_PlayerTextDrawSetString
  5147. #if defined _ALS_PlayerTextDrawSetPreviewMo
  5148. #undef PlayerTextDrawSetPreviewModel
  5149. #else
  5150. #define _ALS_PlayerTextDrawSetPreviewMo
  5151. #endif
  5152. #define PlayerTextDrawSetPreviewModel WC_PlayerTextDrawSetPreviewMode
  5153. #if defined _ALS_PlayerTextDrawSetPreviewRo
  5154. #undef PlayerTextDrawSetPreviewRot
  5155. #else
  5156. #define _ALS_PlayerTextDrawSetPreviewRo
  5157. #endif
  5158. #define PlayerTextDrawSetPreviewRot WC_PlayerTextDrawSetPreviewRot
  5159. #if defined _ALS_PlayerTextDrawSetPreviewVe
  5160. #undef PlayerTextDrawSetPreviewVehCol
  5161. #else
  5162. #define _ALS_PlayerTextDrawSetPreviewVe
  5163. #endif
  5164. #define PlayerTextDrawSetPreviewVehCol WC_PlayerTextDrawSetPreviewVehC