Q3_Interface.cpp 263 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287
  1. // ICARUS Engine Interface File
  2. //
  3. // This file is the only section of the ICARUS systems that
  4. // is not directly portable from engine to engine.
  5. //
  6. // -- jweier
  7. // leave this line at the top for PCH reasons...
  8. #include "g_headers.h"
  9. #include "g_local.h"
  10. #include "g_functions.h"
  11. #include "Q3_Interface.h"
  12. #include "anims.h"
  13. #include "b_local.h"
  14. #include "events.h"
  15. #include "g_nav.h"
  16. #include "..\cgame\cg_camera.h"
  17. #include "..\game\objectives.h"
  18. #include "g_roff.h"
  19. #include "..\cgame\cg_local.h"
  20. #include "wp_saber.h"
  21. #include "g_vehicles.h"
  22. extern cvar_t *com_buildScript;
  23. extern void InitMover( gentity_t *ent );
  24. extern void MatchTeam( gentity_t *teamLeader, int moverState, int time );
  25. //extern void SetMoverState( gentity_t *ent, moverState_t moverState, int time );
  26. extern void ChangeWeapon( gentity_t *ent, int newWeapon );
  27. extern char *G_GetLocationForEnt( gentity_t *ent );
  28. extern void NPC_BSSearchStart( int homeWp, bState_t bState );
  29. extern void InitMoverTrData( gentity_t *ent );
  30. extern qboolean SpotWouldTelefrag2( gentity_t *mover, vec3_t dest );
  31. extern cvar_t *g_sex;
  32. extern cvar_t *g_timescale;
  33. extern void G_SetEnemy( gentity_t *self, gentity_t *enemy );
  34. //extern void FX_BorgTeleport( vec3_t org );
  35. static void Q3_SetWeapon (int entID, const char *wp_name);
  36. static void Q3_SetItem (int entID, const char *item_name);
  37. extern void CG_ChangeWeapon( int num );
  38. extern int TAG_GetOrigin2( const char *owner, const char *name, vec3_t origin );
  39. extern void G_TeamRetaliation ( gentity_t *targ, gentity_t *attacker, qboolean stopIcarus );
  40. extern void G_PlayDoorLoopSound( gentity_t *ent );
  41. extern void G_PlayDoorSound( gentity_t *ent, int type );
  42. extern void NPC_SetLookTarget( gentity_t *self, int entNum, int clearTime );
  43. extern void NPC_ClearLookTarget( gentity_t *self );
  44. extern void WP_SaberSetColor( gentity_t *ent, int saberNum, int bladeNum, char *colorName );
  45. extern void WP_SetSaber( gentity_t *ent, int saberNum, char *saberName );
  46. extern qboolean PM_HasAnimation( gentity_t *ent, int animation );
  47. extern void G_ChangePlayerModel( gentity_t *ent, const char *newModel );
  48. extern vehicleType_t TranslateVehicleName( char *name );
  49. extern void WP_SetSaberOrigin( gentity_t *self, vec3_t newOrg );
  50. extern void JET_FlyStart( gentity_t *self );
  51. extern void JET_FlyStop( gentity_t *self );
  52. extern void Rail_LockCenterOfTrack(const char* trackName);
  53. extern void Rail_UnLockCenterOfTrack(const char* trackName);
  54. extern void G_GetBoltPosition( gentity_t *self, int boltIndex, vec3_t pos, int modelIndex = 0 );
  55. extern qboolean G_DoDismemberment( gentity_t *self, vec3_t point, int mod, int damage, int hitLoc, qboolean force = qfalse );
  56. extern int BMS_START;
  57. extern int BMS_MID;
  58. extern int BMS_END;
  59. extern cvar_t *g_skippingcin;
  60. extern qboolean stop_icarus;
  61. static void PrisonerObjCheck(const char *name,const char *data);
  62. #define stringIDExpand(str, strEnum) str, strEnum, ENUM2STRING(strEnum)
  63. //#define stringIDExpand(str, strEnum) str,strEnum
  64. /*
  65. stringID_table_t tagsTable [] =
  66. {
  67. }
  68. */
  69. stringID_table_t BSTable[] =
  70. {
  71. ENUM2STRING(BS_DEFAULT),//# default behavior for that NPC
  72. ENUM2STRING(BS_ADVANCE_FIGHT),//# Advance to captureGoal and shoot enemies if you can
  73. ENUM2STRING(BS_SLEEP),//# Play awake script when startled by sound
  74. ENUM2STRING(BS_FOLLOW_LEADER),//# Follow your leader and shoot any enemies you come across
  75. ENUM2STRING(BS_JUMP),//# Face navgoal and jump to it.
  76. ENUM2STRING(BS_SEARCH),//# Using current waypoint as a base), search the immediate branches of waypoints for enemies
  77. ENUM2STRING(BS_WANDER),//# Wander down random waypoint paths
  78. ENUM2STRING(BS_NOCLIP),//# Moves through walls), etc.
  79. ENUM2STRING(BS_REMOVE),//# Waits for player to leave PVS then removes itself
  80. ENUM2STRING(BS_CINEMATIC),//# Does nothing but face it's angles and move to a goal if it has one
  81. ENUM2STRING(BS_FLEE),//# Run toward the nav goal, avoiding danger
  82. //the rest are internal only
  83. "", -1,
  84. };
  85. stringID_table_t BSETTable[] =
  86. {
  87. ENUM2STRING(BSET_SPAWN),//# script to use when first spawned
  88. ENUM2STRING(BSET_USE),//# script to use when used
  89. ENUM2STRING(BSET_AWAKE),//# script to use when awoken/startled
  90. ENUM2STRING(BSET_ANGER),//# script to use when aquire an enemy
  91. ENUM2STRING(BSET_ATTACK),//# script to run when you attack
  92. ENUM2STRING(BSET_VICTORY),//# script to run when you kill someone
  93. ENUM2STRING(BSET_LOSTENEMY),//# script to run when you can't find your enemy
  94. ENUM2STRING(BSET_PAIN),//# script to use when take pain
  95. ENUM2STRING(BSET_FLEE),//# script to use when take pain below 50% of health
  96. ENUM2STRING(BSET_DEATH),//# script to use when killed
  97. ENUM2STRING(BSET_DELAYED),//# script to run when self->delayScriptTime is reached
  98. ENUM2STRING(BSET_BLOCKED),//# script to run when blocked by a friendly NPC or player
  99. ENUM2STRING(BSET_BUMPED),//# script to run when bumped into a friendly NPC or player (can set bumpRadius)
  100. ENUM2STRING(BSET_STUCK),//# script to run when blocked by a wall
  101. ENUM2STRING(BSET_FFIRE),//# script to run when player shoots their own teammates
  102. ENUM2STRING(BSET_FFDEATH),//# script to run when player kills a teammate
  103. stringIDExpand("", BSET_INVALID),
  104. "", -1,
  105. };
  106. stringID_table_t WPTable[] =
  107. {
  108. "NULL",WP_NONE,
  109. ENUM2STRING(WP_NONE),
  110. // Player weapons
  111. ENUM2STRING(WP_SABER), // NOTE: lots of code assumes this is the first weapon (... which is crap) so be careful -Ste.
  112. ENUM2STRING(WP_BLASTER_PISTOL), // apparently some enemy only version of the blaster
  113. ENUM2STRING(WP_BLASTER),
  114. ENUM2STRING(WP_DISRUPTOR),
  115. ENUM2STRING(WP_BOWCASTER),
  116. ENUM2STRING(WP_REPEATER),
  117. ENUM2STRING(WP_DEMP2),
  118. ENUM2STRING(WP_FLECHETTE),
  119. ENUM2STRING(WP_ROCKET_LAUNCHER),
  120. ENUM2STRING(WP_THERMAL),
  121. ENUM2STRING(WP_TRIP_MINE),
  122. ENUM2STRING(WP_DET_PACK),
  123. ENUM2STRING(WP_CONCUSSION),
  124. ENUM2STRING(WP_MELEE), // Any ol' melee attack
  125. //NOTE: player can only have up to 16 weapons), anything after that is enemy only
  126. ENUM2STRING(WP_STUN_BATON),
  127. // NPC enemy weapons
  128. ENUM2STRING(WP_BRYAR_PISTOL),
  129. ENUM2STRING(WP_EMPLACED_GUN),
  130. ENUM2STRING(WP_BOT_LASER), // Probe droid - Laser blast
  131. ENUM2STRING(WP_TURRET), // turret guns
  132. ENUM2STRING(WP_ATST_MAIN),
  133. ENUM2STRING(WP_ATST_SIDE),
  134. ENUM2STRING(WP_TIE_FIGHTER),
  135. ENUM2STRING(WP_RAPID_FIRE_CONC),
  136. ENUM2STRING(WP_JAWA),
  137. ENUM2STRING(WP_TUSKEN_RIFLE),
  138. ENUM2STRING(WP_TUSKEN_STAFF),
  139. ENUM2STRING(WP_SCEPTER),
  140. ENUM2STRING(WP_NOGHRI_STICK),
  141. "", NULL
  142. };
  143. stringID_table_t INVTable[] =
  144. {
  145. ENUM2STRING(INV_ELECTROBINOCULARS),
  146. ENUM2STRING(INV_BACTA_CANISTER),
  147. ENUM2STRING(INV_SEEKER),
  148. ENUM2STRING(INV_LIGHTAMP_GOGGLES),
  149. ENUM2STRING(INV_SENTRY),
  150. "", NULL
  151. };
  152. stringID_table_t eventTable[] =
  153. {
  154. //BOTH_h
  155. //END
  156. "", EV_BAD,
  157. };
  158. stringID_table_t DMSTable[] =
  159. {
  160. "NULL",-1,
  161. ENUM2STRING(DM_AUTO), //# let the game determine the dynamic music as normal
  162. ENUM2STRING(DM_SILENCE), //# stop the music
  163. ENUM2STRING(DM_EXPLORE), //# force the exploration music to play
  164. ENUM2STRING(DM_ACTION), //# force the action music to play
  165. ENUM2STRING(DM_BOSS), //# force the boss battle music to play (if there is any)
  166. ENUM2STRING(DM_DEATH), //# force the "player dead" music to play
  167. "", -1
  168. };
  169. stringID_table_t HLTable[] =
  170. {
  171. "NULL",-1,
  172. ENUM2STRING(HL_FOOT_RT),
  173. ENUM2STRING(HL_FOOT_LT),
  174. ENUM2STRING(HL_LEG_RT),
  175. ENUM2STRING(HL_LEG_LT),
  176. ENUM2STRING(HL_WAIST),
  177. ENUM2STRING(HL_BACK_RT),
  178. ENUM2STRING(HL_BACK_LT),
  179. ENUM2STRING(HL_BACK),
  180. ENUM2STRING(HL_CHEST_RT),
  181. ENUM2STRING(HL_CHEST_LT),
  182. ENUM2STRING(HL_CHEST),
  183. ENUM2STRING(HL_ARM_RT),
  184. ENUM2STRING(HL_ARM_LT),
  185. ENUM2STRING(HL_HAND_RT),
  186. ENUM2STRING(HL_HAND_LT),
  187. ENUM2STRING(HL_HEAD),
  188. ENUM2STRING(HL_GENERIC1),
  189. ENUM2STRING(HL_GENERIC2),
  190. ENUM2STRING(HL_GENERIC3),
  191. ENUM2STRING(HL_GENERIC4),
  192. ENUM2STRING(HL_GENERIC5),
  193. ENUM2STRING(HL_GENERIC6),
  194. "", -1
  195. };
  196. stringID_table_t setTable[] =
  197. {
  198. ENUM2STRING(SET_SPAWNSCRIPT),//0
  199. ENUM2STRING(SET_USESCRIPT),
  200. ENUM2STRING(SET_AWAKESCRIPT),
  201. ENUM2STRING(SET_ANGERSCRIPT),
  202. ENUM2STRING(SET_ATTACKSCRIPT),
  203. ENUM2STRING(SET_VICTORYSCRIPT),
  204. ENUM2STRING(SET_PAINSCRIPT),
  205. ENUM2STRING(SET_FLEESCRIPT),
  206. ENUM2STRING(SET_DEATHSCRIPT),
  207. ENUM2STRING(SET_DELAYEDSCRIPT),
  208. ENUM2STRING(SET_BLOCKEDSCRIPT),
  209. ENUM2STRING(SET_FFIRESCRIPT),
  210. ENUM2STRING(SET_FFDEATHSCRIPT),
  211. ENUM2STRING(SET_MINDTRICKSCRIPT),
  212. ENUM2STRING(SET_NO_MINDTRICK),
  213. ENUM2STRING(SET_ORIGIN),
  214. ENUM2STRING(SET_TELEPORT_DEST),
  215. ENUM2STRING(SET_ANGLES),
  216. ENUM2STRING(SET_XVELOCITY),
  217. ENUM2STRING(SET_YVELOCITY),
  218. ENUM2STRING(SET_ZVELOCITY),
  219. ENUM2STRING(SET_Z_OFFSET),
  220. ENUM2STRING(SET_ENEMY),
  221. ENUM2STRING(SET_LEADER),
  222. ENUM2STRING(SET_NAVGOAL),
  223. ENUM2STRING(SET_ANIM_UPPER),
  224. ENUM2STRING(SET_ANIM_LOWER),
  225. ENUM2STRING(SET_ANIM_BOTH),
  226. ENUM2STRING(SET_ANIM_HOLDTIME_LOWER),
  227. ENUM2STRING(SET_ANIM_HOLDTIME_UPPER),
  228. ENUM2STRING(SET_ANIM_HOLDTIME_BOTH),
  229. ENUM2STRING(SET_PLAYER_TEAM),
  230. ENUM2STRING(SET_ENEMY_TEAM),
  231. ENUM2STRING(SET_BEHAVIOR_STATE),
  232. ENUM2STRING(SET_BEHAVIOR_STATE),
  233. ENUM2STRING(SET_HEALTH),
  234. ENUM2STRING(SET_ARMOR),
  235. ENUM2STRING(SET_DEFAULT_BSTATE),
  236. ENUM2STRING(SET_CAPTURE),
  237. ENUM2STRING(SET_DPITCH),
  238. ENUM2STRING(SET_DYAW),
  239. ENUM2STRING(SET_EVENT),
  240. ENUM2STRING(SET_TEMP_BSTATE),
  241. ENUM2STRING(SET_COPY_ORIGIN),
  242. ENUM2STRING(SET_VIEWTARGET),
  243. ENUM2STRING(SET_WEAPON),
  244. ENUM2STRING(SET_ITEM),
  245. ENUM2STRING(SET_WALKSPEED),
  246. ENUM2STRING(SET_RUNSPEED),
  247. ENUM2STRING(SET_YAWSPEED),
  248. ENUM2STRING(SET_AGGRESSION),
  249. ENUM2STRING(SET_AIM),
  250. ENUM2STRING(SET_FRICTION),
  251. ENUM2STRING(SET_GRAVITY),
  252. ENUM2STRING(SET_IGNOREPAIN),
  253. ENUM2STRING(SET_IGNOREENEMIES),
  254. ENUM2STRING(SET_IGNOREALERTS),
  255. ENUM2STRING(SET_DONTSHOOT),
  256. ENUM2STRING(SET_DONTFIRE),
  257. ENUM2STRING(SET_LOCKED_ENEMY),
  258. ENUM2STRING(SET_NOTARGET),
  259. ENUM2STRING(SET_LEAN),
  260. ENUM2STRING(SET_CROUCHED),
  261. ENUM2STRING(SET_WALKING),
  262. ENUM2STRING(SET_RUNNING),
  263. ENUM2STRING(SET_CHASE_ENEMIES),
  264. ENUM2STRING(SET_LOOK_FOR_ENEMIES),
  265. ENUM2STRING(SET_FACE_MOVE_DIR),
  266. ENUM2STRING(SET_ALT_FIRE),
  267. ENUM2STRING(SET_DONT_FLEE),
  268. ENUM2STRING(SET_FORCED_MARCH),
  269. ENUM2STRING(SET_NO_RESPONSE),
  270. ENUM2STRING(SET_NO_COMBAT_TALK),
  271. ENUM2STRING(SET_NO_ALERT_TALK),
  272. ENUM2STRING(SET_UNDYING),
  273. ENUM2STRING(SET_TREASONED),
  274. ENUM2STRING(SET_DISABLE_SHADER_ANIM),
  275. ENUM2STRING(SET_SHADER_ANIM),
  276. ENUM2STRING(SET_INVINCIBLE),
  277. ENUM2STRING(SET_NOAVOID),
  278. ENUM2STRING(SET_SHOOTDIST),
  279. ENUM2STRING(SET_TARGETNAME),
  280. ENUM2STRING(SET_TARGET),
  281. ENUM2STRING(SET_TARGET2),
  282. ENUM2STRING(SET_LOCATION),
  283. ENUM2STRING(SET_PAINTARGET),
  284. ENUM2STRING(SET_TIMESCALE),
  285. ENUM2STRING(SET_VISRANGE),
  286. ENUM2STRING(SET_EARSHOT),
  287. ENUM2STRING(SET_VIGILANCE),
  288. ENUM2STRING(SET_HFOV),
  289. ENUM2STRING(SET_VFOV),
  290. ENUM2STRING(SET_DELAYSCRIPTTIME),
  291. ENUM2STRING(SET_FORWARDMOVE),
  292. ENUM2STRING(SET_RIGHTMOVE),
  293. ENUM2STRING(SET_LOCKYAW),
  294. ENUM2STRING(SET_SOLID),
  295. ENUM2STRING(SET_CAMERA_GROUP),
  296. ENUM2STRING(SET_CAMERA_GROUP_Z_OFS),
  297. ENUM2STRING(SET_CAMERA_GROUP_TAG),
  298. ENUM2STRING(SET_LOOK_TARGET),
  299. ENUM2STRING(SET_ADDRHANDBOLT_MODEL),
  300. ENUM2STRING(SET_REMOVERHANDBOLT_MODEL),
  301. ENUM2STRING(SET_ADDLHANDBOLT_MODEL),
  302. ENUM2STRING(SET_REMOVELHANDBOLT_MODEL),
  303. ENUM2STRING(SET_FACEAUX),
  304. ENUM2STRING(SET_FACEBLINK),
  305. ENUM2STRING(SET_FACEBLINKFROWN),
  306. ENUM2STRING(SET_FACEFROWN),
  307. ENUM2STRING(SET_FACENORMAL),
  308. ENUM2STRING(SET_FACEEYESCLOSED),
  309. ENUM2STRING(SET_FACEEYESOPENED),
  310. ENUM2STRING(SET_SCROLLTEXT),
  311. ENUM2STRING(SET_LCARSTEXT),
  312. ENUM2STRING(SET_CENTERTEXT),
  313. ENUM2STRING(SET_SCROLLTEXTCOLOR),
  314. ENUM2STRING(SET_CAPTIONTEXTCOLOR),
  315. ENUM2STRING(SET_CENTERTEXTCOLOR),
  316. ENUM2STRING(SET_PLAYER_USABLE),
  317. ENUM2STRING(SET_STARTFRAME),
  318. ENUM2STRING(SET_ENDFRAME),
  319. ENUM2STRING(SET_ANIMFRAME),
  320. ENUM2STRING(SET_LOOP_ANIM),
  321. ENUM2STRING(SET_INTERFACE),
  322. ENUM2STRING(SET_SHIELDS),
  323. ENUM2STRING(SET_NO_KNOCKBACK),
  324. ENUM2STRING(SET_INVISIBLE),
  325. ENUM2STRING(SET_VAMPIRE),
  326. ENUM2STRING(SET_FORCE_INVINCIBLE),
  327. ENUM2STRING(SET_GREET_ALLIES),
  328. ENUM2STRING(SET_PLAYER_LOCKED),
  329. ENUM2STRING(SET_LOCK_PLAYER_WEAPONS),
  330. ENUM2STRING(SET_NO_IMPACT_DAMAGE),
  331. ENUM2STRING(SET_PARM1),
  332. ENUM2STRING(SET_PARM2),
  333. ENUM2STRING(SET_PARM3),
  334. ENUM2STRING(SET_PARM4),
  335. ENUM2STRING(SET_PARM5),
  336. ENUM2STRING(SET_PARM6),
  337. ENUM2STRING(SET_PARM7),
  338. ENUM2STRING(SET_PARM8),
  339. ENUM2STRING(SET_PARM9),
  340. ENUM2STRING(SET_PARM10),
  341. ENUM2STRING(SET_PARM11),
  342. ENUM2STRING(SET_PARM12),
  343. ENUM2STRING(SET_PARM13),
  344. ENUM2STRING(SET_PARM14),
  345. ENUM2STRING(SET_PARM15),
  346. ENUM2STRING(SET_PARM16),
  347. ENUM2STRING(SET_DEFEND_TARGET),
  348. ENUM2STRING(SET_WAIT),
  349. ENUM2STRING(SET_COUNT),
  350. ENUM2STRING(SET_SHOT_SPACING),
  351. ENUM2STRING(SET_VIDEO_PLAY),
  352. ENUM2STRING(SET_VIDEO_FADE_IN),
  353. ENUM2STRING(SET_VIDEO_FADE_OUT),
  354. ENUM2STRING(SET_REMOVE_TARGET),
  355. ENUM2STRING(SET_LOADGAME),
  356. ENUM2STRING(SET_MENU_SCREEN),
  357. ENUM2STRING(SET_OBJECTIVE_SHOW),
  358. ENUM2STRING(SET_OBJECTIVE_HIDE),
  359. ENUM2STRING(SET_OBJECTIVE_SUCCEEDED),
  360. ENUM2STRING(SET_OBJECTIVE_SUCCEEDED_NO_UPDATE),
  361. ENUM2STRING(SET_OBJECTIVE_FAILED),
  362. ENUM2STRING(SET_MISSIONFAILED),
  363. ENUM2STRING(SET_TACTICAL_SHOW),
  364. ENUM2STRING(SET_TACTICAL_HIDE),
  365. ENUM2STRING(SET_FOLLOWDIST),
  366. ENUM2STRING(SET_SCALE),
  367. ENUM2STRING(SET_OBJECTIVE_CLEARALL),
  368. ENUM2STRING(SET_OBJECTIVE_LIGHTSIDE),
  369. ENUM2STRING(SET_MISSIONSTATUSTEXT),
  370. ENUM2STRING(SET_WIDTH),
  371. ENUM2STRING(SET_CLOSINGCREDITS),
  372. ENUM2STRING(SET_SKILL),
  373. ENUM2STRING(SET_MISSIONSTATUSTIME),
  374. ENUM2STRING(SET_FORCE_HEAL_LEVEL),
  375. ENUM2STRING(SET_FORCE_JUMP_LEVEL),
  376. ENUM2STRING(SET_FORCE_SPEED_LEVEL),
  377. ENUM2STRING(SET_FORCE_PUSH_LEVEL),
  378. ENUM2STRING(SET_FORCE_PULL_LEVEL),
  379. ENUM2STRING(SET_FORCE_MINDTRICK_LEVEL),
  380. ENUM2STRING(SET_FORCE_GRIP_LEVEL),
  381. ENUM2STRING(SET_FORCE_LIGHTNING_LEVEL),
  382. ENUM2STRING(SET_SABER_THROW),
  383. ENUM2STRING(SET_SABER_DEFENSE),
  384. ENUM2STRING(SET_SABER_OFFENSE),
  385. ENUM2STRING(SET_FORCE_RAGE_LEVEL),
  386. ENUM2STRING(SET_FORCE_PROTECT_LEVEL),
  387. ENUM2STRING(SET_FORCE_ABSORB_LEVEL),
  388. ENUM2STRING(SET_FORCE_DRAIN_LEVEL),
  389. ENUM2STRING(SET_FORCE_SIGHT_LEVEL),
  390. ENUM2STRING(SET_SABER1_COLOR1),
  391. ENUM2STRING(SET_SABER1_COLOR2),
  392. ENUM2STRING(SET_SABER2_COLOR1),
  393. ENUM2STRING(SET_SABER2_COLOR2),
  394. ENUM2STRING(SET_DISMEMBER_LIMB),
  395. ENUM2STRING(SET_VIEWENTITY),
  396. ENUM2STRING(SET_WATCHTARGET),
  397. ENUM2STRING(SET_SABERACTIVE),
  398. ENUM2STRING(SET_SABER1BLADEON),
  399. ENUM2STRING(SET_SABER1BLADEOFF),
  400. ENUM2STRING(SET_SABER2BLADEON),
  401. ENUM2STRING(SET_SABER2BLADEOFF),
  402. ENUM2STRING(SET_ADJUST_AREA_PORTALS),
  403. ENUM2STRING(SET_DMG_BY_HEAVY_WEAP_ONLY),
  404. ENUM2STRING(SET_SHIELDED),
  405. ENUM2STRING(SET_NO_GROUPS),
  406. ENUM2STRING(SET_FIRE_WEAPON),
  407. ENUM2STRING(SET_FIRE_WEAPON_NO_ANIM),
  408. ENUM2STRING(SET_SAFE_REMOVE),
  409. ENUM2STRING(SET_BOBA_JET_PACK),
  410. ENUM2STRING(SET_INACTIVE),
  411. ENUM2STRING(SET_FUNC_USABLE_VISIBLE),
  412. ENUM2STRING(SET_END_SCREENDISSOLVE),
  413. ENUM2STRING(SET_LOOPSOUND),
  414. ENUM2STRING(SET_ICARUS_FREEZE),
  415. ENUM2STRING(SET_ICARUS_UNFREEZE),
  416. ENUM2STRING(SET_SABER1),
  417. ENUM2STRING(SET_SABER2),
  418. ENUM2STRING(SET_PLAYERMODEL),
  419. ENUM2STRING(SET_VEHICLE),
  420. ENUM2STRING(SET_SECURITY_KEY),
  421. ENUM2STRING(SET_DAMAGEENTITY),
  422. ENUM2STRING(SET_USE_CP_NEAREST),
  423. ENUM2STRING(SET_MORELIGHT),
  424. ENUM2STRING(SET_CINEMATIC_SKIPSCRIPT),
  425. ENUM2STRING(SET_RAILCENTERTRACKLOCKED),
  426. ENUM2STRING(SET_RAILCENTERTRACKUNLOCKED),
  427. ENUM2STRING(SET_NO_FORCE),
  428. ENUM2STRING(SET_NO_FALLTODEATH),
  429. ENUM2STRING(SET_DISMEMBERABLE),
  430. ENUM2STRING(SET_NO_ACROBATICS),
  431. ENUM2STRING(SET_MUSIC_STATE),
  432. ENUM2STRING(SET_USE_SUBTITLES),
  433. ENUM2STRING(SET_CLEAN_DAMAGING_ENTS),
  434. ENUM2STRING(SET_HUD),
  435. //JKA
  436. ENUM2STRING(SET_NO_PVS_CULL),
  437. ENUM2STRING(SET_CLOAK),
  438. ENUM2STRING(SET_RENDER_CULL_RADIUS),
  439. ENUM2STRING(SET_DISTSQRD_TO_PLAYER),
  440. ENUM2STRING(SET_FORCE_HEAL),
  441. ENUM2STRING(SET_FORCE_SPEED),
  442. ENUM2STRING(SET_FORCE_PUSH),
  443. ENUM2STRING(SET_FORCE_PUSH_FAKE),
  444. ENUM2STRING(SET_FORCE_PULL),
  445. ENUM2STRING(SET_FORCE_MIND_TRICK),
  446. ENUM2STRING(SET_FORCE_GRIP),
  447. ENUM2STRING(SET_FORCE_LIGHTNING),
  448. ENUM2STRING(SET_FORCE_SABERTHROW),
  449. ENUM2STRING(SET_FORCE_RAGE),
  450. ENUM2STRING(SET_FORCE_PROTECT),
  451. ENUM2STRING(SET_FORCE_ABSORB),
  452. ENUM2STRING(SET_FORCE_DRAIN),
  453. ENUM2STRING(SET_WINTER_GEAR),
  454. ENUM2STRING(SET_NO_ANGLES),
  455. ENUM2STRING(SET_SABER_ORIGIN),
  456. ENUM2STRING(SET_SKIN),
  457. "", SET_,
  458. };
  459. qboolean COM_ParseString( char **data, char **s );
  460. //=======================================================================
  461. vec4_t textcolor_caption;
  462. vec4_t textcolor_center;
  463. vec4_t textcolor_scroll;
  464. /*
  465. -------------------------
  466. void Q3_SetTaskID( gentity_t *ent, taskID_t taskType, int taskID )
  467. -------------------------
  468. */
  469. static void Q3_TaskIDSet( gentity_t *ent, taskID_t taskType, int taskID )
  470. {
  471. if ( taskType < TID_CHAN_VOICE || taskType >= NUM_TIDS )
  472. {
  473. return;
  474. }
  475. //Might be stomping an old task, so complete and clear previous task if there was one
  476. Q3_TaskIDComplete( ent, taskType );
  477. ent->taskID[taskType] = taskID;
  478. }
  479. /*
  480. -------------------------
  481. SetTextColor
  482. -------------------------
  483. */
  484. static void SetTextColor ( vec4_t textcolor,const char *color)
  485. {
  486. if (Q_stricmp(color,"BLACK") == 0)
  487. {
  488. Vector4Copy( colorTable[CT_BLACK], textcolor );
  489. }
  490. else if (Q_stricmp(color,"RED") == 0)
  491. {
  492. Vector4Copy( colorTable[CT_RED], textcolor );
  493. }
  494. else if (Q_stricmp(color,"GREEN") == 0)
  495. {
  496. Vector4Copy( colorTable[CT_GREEN], textcolor );
  497. }
  498. else if (Q_stricmp(color,"YELLOW") == 0)
  499. {
  500. Vector4Copy( colorTable[CT_YELLOW], textcolor );
  501. }
  502. else if (Q_stricmp(color,"BLUE") == 0)
  503. {
  504. Vector4Copy( colorTable[CT_BLUE], textcolor );
  505. }
  506. else if (Q_stricmp(color,"CYAN") == 0)
  507. {
  508. Vector4Copy( colorTable[CT_CYAN], textcolor );
  509. }
  510. else if (Q_stricmp(color,"MAGENTA") == 0)
  511. {
  512. Vector4Copy( colorTable[CT_MAGENTA], textcolor );
  513. }
  514. else if (Q_stricmp(color,"WHITE") == 0)
  515. {
  516. Vector4Copy( colorTable[CT_WHITE], textcolor );
  517. }
  518. else
  519. {
  520. Vector4Copy( colorTable[CT_WHITE], textcolor );
  521. }
  522. return;
  523. }
  524. /*
  525. -------------------------
  526. void Q3_ClearTaskID( int *taskID )
  527. WARNING: Clearing a taskID will make that task never finish unless you intend to
  528. return the same taskID from somewhere else.
  529. -------------------------
  530. */
  531. void Q3_TaskIDClear( int *taskID )
  532. {
  533. *taskID = -1;
  534. }
  535. /*
  536. -------------------------
  537. qboolean Q3_TaskIDPending( gentity_t *ent, taskID_t taskType )
  538. -------------------------
  539. */
  540. qboolean Q3_TaskIDPending( gentity_t *ent, taskID_t taskType )
  541. {
  542. if ( ent->m_iIcarusID == IIcarusInterface::ICARUS_INVALID /*!ent->sequencer || !ent->taskManager*/ )
  543. {
  544. return qfalse;
  545. }
  546. if ( taskType < TID_CHAN_VOICE || taskType >= NUM_TIDS )
  547. {
  548. return qfalse;
  549. }
  550. if ( ent->taskID[taskType] >= 0 )//-1 is none
  551. {
  552. return qtrue;
  553. }
  554. return qfalse;
  555. }
  556. /*
  557. -------------------------
  558. void Q3_TaskIDComplete( gentity_t *ent, taskID_t taskType )
  559. -------------------------
  560. */
  561. void Q3_TaskIDComplete( gentity_t *ent, taskID_t taskType )
  562. {
  563. if ( taskType < TID_CHAN_VOICE || taskType >= NUM_TIDS )
  564. {
  565. return;
  566. }
  567. if ( ent->m_iIcarusID != IIcarusInterface::ICARUS_INVALID /*ent->taskManager*/ && Q3_TaskIDPending( ent, taskType ) )
  568. {//Complete it
  569. IIcarusInterface::GetIcarus()->Completed( ent->m_iIcarusID, ent->taskID[taskType] );
  570. //See if any other tasks have the name number and clear them so we don't complete more than once
  571. int clearTask = ent->taskID[taskType];
  572. for ( int tid = 0; tid < NUM_TIDS; tid++ )
  573. {
  574. if ( ent->taskID[tid] == clearTask )
  575. {
  576. Q3_TaskIDClear( &ent->taskID[tid] );
  577. }
  578. }
  579. //clear it - should be cleared in for loop above
  580. //Q3_TaskIDClear( &ent->taskID[taskType] );
  581. }
  582. //otherwise, wasn't waiting for a task to complete anyway
  583. }
  584. /*
  585. ============
  586. Q3_CheckStringCounterIncrement
  587. Description :
  588. Return type : static float
  589. Argument : const char *string
  590. ============
  591. */
  592. static float Q3_CheckStringCounterIncrement( const char *string )
  593. {
  594. char *numString;
  595. float val = 0.0f;
  596. if ( string[0] == '+' )
  597. {//We want to increment whatever the value is by whatever follows the +
  598. if ( string[1] )
  599. {
  600. numString = (char *)&string[1];
  601. val = atof( numString );
  602. }
  603. }
  604. else if ( string[0] == '-' )
  605. {//we want to decrement
  606. if ( string[1] )
  607. {
  608. numString = (char *)&string[1];
  609. val = atof( numString ) * -1;
  610. }
  611. }
  612. return val;
  613. }
  614. /*
  615. -------------------------
  616. Q3_GetAnimLower
  617. -------------------------
  618. */
  619. static char *Q3_GetAnimLower( gentity_t *ent )
  620. {
  621. if ( ent->client == NULL )
  622. {
  623. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_GetAnimLower: attempted to read animation state off non-client!\n" );
  624. return NULL;
  625. }
  626. int anim = ent->client->ps.legsAnim;
  627. return (char *) GetStringForID( animTable, anim );
  628. }
  629. /*
  630. -------------------------
  631. Q3_GetAnimUpper
  632. -------------------------
  633. */
  634. static char *Q3_GetAnimUpper( gentity_t *ent )
  635. {
  636. if ( ent->client == NULL )
  637. {
  638. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_GetAnimUpper: attempted to read animation state off non-client!\n" );
  639. return NULL;
  640. }
  641. int anim = ent->client->ps.torsoAnim;
  642. return (char *) GetStringForID( animTable, anim );
  643. }
  644. /*
  645. -------------------------
  646. Q3_GetAnimBoth
  647. -------------------------
  648. */
  649. static char *Q3_GetAnimBoth( gentity_t *ent )
  650. {
  651. char *lowerName, *upperName;
  652. lowerName = Q3_GetAnimLower( ent );
  653. upperName = Q3_GetAnimUpper( ent );
  654. if ( VALIDSTRING( lowerName ) == false )
  655. {
  656. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_GetAnimBoth: NULL legs animation string found!\n" );
  657. return NULL;
  658. }
  659. if ( VALIDSTRING( upperName ) == false )
  660. {
  661. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_GetAnimBoth: NULL torso animation string found!\n" );
  662. return NULL;
  663. }
  664. if ( stricmp( lowerName, upperName ) )
  665. {
  666. #ifdef _DEBUG // sigh, cut down on tester reports that aren't important
  667. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_GetAnimBoth: legs and torso animations did not match : returning legs\n" );
  668. #endif
  669. }
  670. return lowerName;
  671. }
  672. /*
  673. -------------------------
  674. Q3_SetObjective
  675. -------------------------
  676. */
  677. extern qboolean G_CheckPlayerDarkSide( void );
  678. static void Q3_SetObjective(const char *ObjEnum, int status)
  679. {
  680. int objectiveID;
  681. gclient_t *client;
  682. objectives_t *objective;
  683. int *objectivesShown;
  684. client = &level.clients[0];
  685. objectiveID = GetIDForString( objectiveTable, ObjEnum );
  686. objective = &client->sess.mission_objectives[objectiveID];
  687. objectivesShown = &client->sess.missionObjectivesShown;
  688. switch (status)
  689. {
  690. case SET_OBJ_HIDE :
  691. objective->display = OBJECTIVE_HIDE;
  692. break;
  693. case SET_OBJ_SHOW :
  694. objective->display = OBJECTIVE_SHOW;
  695. objectivesShown++;
  696. missionInfo_Updated = qtrue; // Activate flashing text
  697. break;
  698. case SET_OBJ_PENDING :
  699. objective->status = OBJECTIVE_STAT_PENDING;
  700. if (objective->display != OBJECTIVE_HIDE)
  701. {
  702. objectivesShown++;
  703. missionInfo_Updated = qtrue; // Activate flashing text
  704. }
  705. break;
  706. case SET_OBJ_SUCCEEDED :
  707. objective->status = OBJECTIVE_STAT_SUCCEEDED;
  708. if (objective->display != OBJECTIVE_HIDE)
  709. {
  710. objectivesShown++;
  711. missionInfo_Updated = qtrue; // Activate flashing text
  712. }
  713. break;
  714. case SET_OBJ_FAILED :
  715. objective->status = OBJECTIVE_STAT_FAILED;
  716. if (objective->display != OBJECTIVE_HIDE)
  717. {
  718. objectivesShown++;
  719. missionInfo_Updated = qtrue; // Activate flashing text
  720. }
  721. break;
  722. }
  723. if ( objectiveID == LIGHTSIDE_OBJ
  724. && status == SET_OBJ_FAILED )
  725. {//don't do this unless we just set that specific objective (just turned to the dark side) with this SET_OBJECTIVE command
  726. G_CheckPlayerDarkSide();
  727. }
  728. }
  729. /*
  730. -------------------------
  731. Q3_SetMissionFailed
  732. -------------------------
  733. */
  734. extern void G_PlayerGuiltDeath( void );
  735. static void Q3_SetMissionFailed(const char *TextEnum)
  736. {
  737. gentity_t *ent = &g_entities[0];
  738. if ( ent->health >= 0 )
  739. {
  740. G_PlayerGuiltDeath();
  741. }
  742. ent->health = 0;
  743. //FIXME: what about other NPCs? Scripts?
  744. // statusTextIndex is looked at on the client side.
  745. statusTextIndex = GetIDForString( missionFailedTable, TextEnum );
  746. cg.missionStatusShow = qtrue;
  747. if ( ent->client )
  748. {//hold this screen up for at least 2 seconds
  749. ent->client->respawnTime = level.time + 2000;
  750. }
  751. }
  752. /*
  753. -------------------------
  754. Q3_SetStatusText
  755. -------------------------
  756. */
  757. static void Q3_SetStatusText(const char *StatusTextEnum)
  758. {
  759. int statusTextID;
  760. statusTextID = GetIDForString( statusTextTable, StatusTextEnum );
  761. switch (statusTextID)
  762. {
  763. case STAT_INSUBORDINATION:
  764. case STAT_YOUCAUSEDDEATHOFTEAMMATE:
  765. case STAT_DIDNTPROTECTTECH:
  766. case STAT_DIDNTPROTECT7OF9:
  767. case STAT_NOTSTEALTHYENOUGH:
  768. case STAT_STEALTHTACTICSNECESSARY:
  769. case STAT_WATCHYOURSTEP:
  770. case STAT_JUDGEMENTMUCHDESIRED:
  771. statusTextIndex = statusTextID;
  772. break;
  773. default:
  774. assert(0);
  775. break;
  776. }
  777. }
  778. /*
  779. -------------------------
  780. Q3_ObjectiveClearAll
  781. -------------------------
  782. */
  783. static void Q3_ObjectiveClearAll(void)
  784. {
  785. client = &level.clients[0];
  786. memset(client->sess.mission_objectives,0,sizeof(client->sess.mission_objectives));
  787. }
  788. /*
  789. =============
  790. Q3_SetCaptionTextColor
  791. Change color text prints in
  792. =============
  793. */
  794. static void Q3_SetCaptionTextColor ( const char *color)
  795. {
  796. SetTextColor(textcolor_caption,color);
  797. }
  798. /*
  799. =============
  800. Q3_SetCenterTextColor
  801. Change color text prints in
  802. =============
  803. */
  804. static void Q3_SetCenterTextColor ( const char *color)
  805. {
  806. SetTextColor(textcolor_center,color);
  807. }
  808. /*
  809. =============
  810. Q3_SetScrollTextColor
  811. Change color text prints in
  812. =============
  813. */
  814. static void Q3_SetScrollTextColor ( const char *color)
  815. {
  816. SetTextColor(textcolor_scroll,color);
  817. }
  818. /*
  819. =============
  820. Q3_ScrollText
  821. Prints a message in the center of the screen
  822. =============
  823. */
  824. static void Q3_ScrollText ( const char *id)
  825. {
  826. gi.SendServerCommand( NULL, "st \"%s\"", id);
  827. return;
  828. }
  829. /*
  830. =============
  831. Q3_LCARSText
  832. Prints a message in the center of the screen giving it an LCARS frame around it
  833. =============
  834. */
  835. static void Q3_LCARSText ( const char *id)
  836. {
  837. gi.SendServerCommand( NULL, "lt \"%s\"", id);
  838. return;
  839. }
  840. /*
  841. =============
  842. `
  843. Returns the sequencer of the entity by the given name
  844. =============
  845. */
  846. /*static gentity_t *Q3_GetEntityByName( const char *name )
  847. {
  848. gentity_t *ent;
  849. entitylist_t::iterator ei;
  850. char temp[1024];
  851. if ( name == NULL || name[0] == NULL )
  852. return NULL;
  853. strncpy( (char *) temp, name, sizeof(temp) );
  854. temp[sizeof(temp)-1] = 0;
  855. ei = ICARUS_EntList.find( strupr( (char *) temp ) );
  856. if ( ei == ICARUS_EntList.end() )
  857. return NULL;
  858. ent = &g_entities[(*ei).second];
  859. return ent;
  860. // this now returns the ent instead of the sequencer -- dmv 06/27/01
  861. // if (ent == NULL)
  862. // return NULL;
  863. // return ent->sequencer;
  864. }*/
  865. /*
  866. =============
  867. Q3_GetTime
  868. Get the current game time
  869. =============
  870. */
  871. /*static DWORD Q3_GetTime( void )
  872. {
  873. return level.time;
  874. }*/
  875. /*
  876. =============
  877. G_AddSexToPlayerString
  878. Take any string, look for "jaden_male/" replace with "jaden_fmle/" based on "sex"
  879. And: Take any string, look for "/mr_" replace with "/ms_" based on "sex"
  880. returns qtrue if changed to ms
  881. =============
  882. */
  883. static qboolean G_AddSexToPlayerString ( char *string, qboolean qDoBoth )
  884. {
  885. char *start;
  886. if VALIDSTRING( string ) {
  887. if ( g_sex->string[0] == 'f' ) {
  888. start = strstr( string, "jaden_male/" );
  889. if ( start != NULL ) {
  890. strncpy( start, "jaden_fmle", 10 );
  891. return qtrue;
  892. } else {
  893. start = strrchr( string, '/' ); //get the last slash before the wav
  894. if (start != NULL) {
  895. if (!strncmp( start, "/mr_", 4) ) {
  896. if (qDoBoth) { //we want to change mr to ms
  897. start[2] = 's'; //change mr to ms
  898. return qtrue;
  899. } else { //IF qDoBoth
  900. return qfalse; //don't want this one
  901. }
  902. }
  903. } //IF found slash
  904. }
  905. } //IF Female
  906. else { //i'm male
  907. start = strrchr( string, '/' ); //get the last slash before the wav
  908. if (start != NULL) {
  909. if (!strncmp( start, "/ms_", 4) ) {
  910. return qfalse; //don't want this one
  911. }
  912. } //IF found slash
  913. }
  914. } //if VALIDSTRING
  915. return qtrue;
  916. }
  917. /*
  918. /*
  919. =============
  920. Q3_SetAngles
  921. Sets the angles of an entity directly
  922. =============
  923. */
  924. static void Q3_SetDYaw( int entID, float data );
  925. static void Q3_SetAngles( int entID, vec3_t angles )
  926. {
  927. gentity_t *ent = &g_entities[entID];
  928. if ( !ent )
  929. {
  930. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAngles: bad ent %d\n", entID);
  931. return;
  932. }
  933. if (ent->client)
  934. {
  935. SetClientViewAngle( ent, angles );
  936. if ( ent->NPC )
  937. {
  938. Q3_SetDYaw( entID, angles[YAW] );
  939. }
  940. }
  941. else
  942. {
  943. VectorCopy( angles, ent->s.angles );
  944. VectorCopy( angles, ent->s.apos.trBase );
  945. VectorCopy( angles, ent->currentAngles );
  946. }
  947. gi.linkentity( ent );
  948. }
  949. /*
  950. =============
  951. Q3_SetOrigin
  952. Sets the origin of an entity directly
  953. =============
  954. */
  955. static void Q3_SetOrigin( int entID, vec3_t origin )
  956. {
  957. gentity_t *ent = &g_entities[entID];
  958. if ( !ent )
  959. {
  960. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetOrigin: bad ent %d\n", entID);
  961. return;
  962. }
  963. gi.unlinkentity (ent);
  964. if(ent->client)
  965. {
  966. VectorCopy(origin, ent->client->ps.origin);
  967. VectorCopy(origin, ent->currentOrigin);
  968. ent->client->ps.origin[2] += 1;
  969. VectorClear (ent->client->ps.velocity);
  970. ent->client->ps.pm_time = 160; // hold time
  971. ent->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
  972. ent->client->ps.eFlags ^= EF_TELEPORT_BIT;
  973. // G_KillBox (ent);
  974. }
  975. else
  976. {
  977. G_SetOrigin( ent, origin );
  978. }
  979. gi.linkentity( ent );
  980. }
  981. /*
  982. ============
  983. MoveOwner
  984. Description :
  985. Return type : void
  986. Argument : gentity_t *self
  987. ============
  988. */
  989. void MoveOwner( gentity_t *self )
  990. {
  991. self->nextthink = level.time + FRAMETIME;
  992. self->e_ThinkFunc = thinkF_G_FreeEntity;
  993. if ( !self->owner || !self->owner->inuse )
  994. {
  995. return;
  996. }
  997. if ( SpotWouldTelefrag2( self->owner, self->currentOrigin ) )
  998. {
  999. self->e_ThinkFunc = thinkF_MoveOwner;
  1000. }
  1001. else
  1002. {
  1003. G_SetOrigin( self->owner, self->currentOrigin );
  1004. gi.linkentity( self->owner );
  1005. Q3_TaskIDComplete( self->owner, TID_MOVE_NAV );
  1006. }
  1007. }
  1008. /*
  1009. =============
  1010. Q3_SetTeleportDest
  1011. Copies passed origin to ent running script once there is nothing there blocking the spot
  1012. =============
  1013. */
  1014. static qboolean Q3_SetTeleportDest( int entID, vec3_t org )
  1015. {
  1016. gentity_t *teleEnt = &g_entities[entID];
  1017. if ( teleEnt )
  1018. {
  1019. if ( SpotWouldTelefrag2( teleEnt, org ) )
  1020. {
  1021. gentity_t *teleporter = G_Spawn();
  1022. G_SetOrigin( teleporter, org );
  1023. gi.linkentity( teleporter );
  1024. teleporter->owner = teleEnt;
  1025. teleporter->e_ThinkFunc = thinkF_MoveOwner;
  1026. teleporter->nextthink = level.time + FRAMETIME;
  1027. return qfalse;
  1028. }
  1029. else
  1030. {
  1031. G_SetOrigin( teleEnt, org );
  1032. gi.linkentity( teleEnt );
  1033. }
  1034. }
  1035. return qtrue;
  1036. }
  1037. /*
  1038. =============
  1039. Q3_SetCopyOrigin
  1040. Copies origin of found ent into ent running script
  1041. =============`
  1042. */
  1043. static void Q3_SetCopyOrigin( int entID, const char *name )
  1044. {
  1045. gentity_t *found = G_Find( NULL, FOFS(targetname), (char *) name);
  1046. if(found)
  1047. {
  1048. Q3_SetOrigin( entID, found->currentOrigin );
  1049. SetClientViewAngle( &g_entities[entID], found->s.angles );
  1050. }
  1051. else
  1052. {
  1053. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetCopyOrigin: ent %s not found!\n", name);
  1054. }
  1055. }
  1056. /*
  1057. =============
  1058. Q3_SetVelocity
  1059. Set the velocity of an entity directly
  1060. =============
  1061. */
  1062. static void Q3_SetVelocity( int entID, int axis, float speed )
  1063. {
  1064. gentity_t *found = &g_entities[entID];
  1065. //FIXME: Not supported
  1066. if(!found)
  1067. {
  1068. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetVelocity invalid entID %d\n", entID);
  1069. return;
  1070. }
  1071. if(!found->client)
  1072. {
  1073. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetVelocity: not a client %d\n", entID);
  1074. return;
  1075. }
  1076. //FIXME: add or set?
  1077. found->client->ps.velocity[axis] += speed;
  1078. found->client->ps.pm_time = 500;
  1079. found->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
  1080. }
  1081. /*
  1082. ============
  1083. Q3_SetAdjustAreaPortals
  1084. Description :
  1085. Return type : void
  1086. Argument : int entID
  1087. Argument : qboolean shields
  1088. ============
  1089. */
  1090. static void Q3_SetAdjustAreaPortals( int entID, qboolean adjust )
  1091. {
  1092. gentity_t *ent = &g_entities[entID];
  1093. if ( !ent )
  1094. {
  1095. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAdjustAreaPortals: invalid entID %d\n", entID);
  1096. return;
  1097. }
  1098. ent->svFlags = (adjust) ? (ent->svFlags|SVF_MOVER_ADJ_AREA_PORTALS) : (ent->svFlags&~SVF_MOVER_ADJ_AREA_PORTALS);
  1099. }
  1100. /*
  1101. ============
  1102. Q3_SetDmgByHeavyWeapOnly
  1103. Description :
  1104. Return type : void
  1105. Argument : int entID
  1106. Argument : qboolean dmg
  1107. ============
  1108. */
  1109. static void Q3_SetDmgByHeavyWeapOnly( int entID, qboolean dmg )
  1110. {
  1111. gentity_t *ent = &g_entities[entID];
  1112. if ( !ent )
  1113. {
  1114. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDmgByHeavyWeapOnly: invalid entID %d\n", entID);
  1115. return;
  1116. }
  1117. ent->flags = (dmg) ? (ent->flags|FL_DMG_BY_HEAVY_WEAP_ONLY) : (ent->flags&~FL_DMG_BY_HEAVY_WEAP_ONLY);
  1118. }
  1119. /*
  1120. ============
  1121. Q3_SetShielded
  1122. Description :
  1123. Return type : void
  1124. Argument : int entID
  1125. Argument : qboolean dmg
  1126. ============
  1127. */
  1128. static void Q3_SetShielded( int entID, qboolean dmg )
  1129. {
  1130. gentity_t *ent = &g_entities[entID];
  1131. if ( !ent )
  1132. {
  1133. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetShielded: invalid entID %d\n", entID);
  1134. return;
  1135. }
  1136. ent->flags = (dmg) ? (ent->flags|FL_SHIELDED) : (ent->flags&~FL_SHIELDED);
  1137. }
  1138. /*
  1139. ============
  1140. Q3_SetNoGroups
  1141. Description :
  1142. Return type : void
  1143. Argument : int entID
  1144. Argument : qboolean dmg
  1145. ============
  1146. */
  1147. static void Q3_SetNoGroups( int entID, qboolean noGroups )
  1148. {
  1149. gentity_t *ent = &g_entities[entID];
  1150. if ( !ent )
  1151. {
  1152. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoGroups: invalid entID %d\n", entID);
  1153. return;
  1154. }
  1155. if ( !ent->NPC )
  1156. {
  1157. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoGroups: ent %s is not an NPC!\n", ent->targetname );
  1158. return;
  1159. }
  1160. ent->NPC->scriptFlags = noGroups ? (ent->NPC->scriptFlags|SCF_NO_GROUPS) : (ent->NPC->scriptFlags&~SCF_NO_GROUPS);
  1161. }
  1162. /*
  1163. =============
  1164. moverCallback
  1165. Utility function
  1166. =============
  1167. */
  1168. extern void misc_model_breakable_gravity_init( gentity_t *ent, qboolean dropToFloor );
  1169. void moverCallback( gentity_t *ent )
  1170. {
  1171. //complete the task
  1172. Q3_TaskIDComplete( ent, TID_MOVE_NAV );
  1173. // play sound
  1174. ent->s.loopSound = 0;//stop looping sound
  1175. G_PlayDoorSound( ent, BMS_END );//play end sound
  1176. if ( ent->moverState == MOVER_1TO2 )
  1177. {//reached open
  1178. // reached pos2
  1179. MatchTeam( ent, MOVER_POS2, level.time );
  1180. //SetMoverState( ent, MOVER_POS2, level.time );
  1181. }
  1182. else if ( ent->moverState == MOVER_2TO1 )
  1183. {//reached closed
  1184. MatchTeam( ent, MOVER_POS1, level.time );
  1185. //SetMoverState( ent, MOVER_POS1, level.time );
  1186. //close the portal
  1187. if ( ent->svFlags & SVF_MOVER_ADJ_AREA_PORTALS )
  1188. {
  1189. gi.AdjustAreaPortalState( ent, qfalse );
  1190. }
  1191. }
  1192. if ( ent->e_BlockedFunc == blockedF_Blocked_Mover )
  1193. {
  1194. ent->e_BlockedFunc = blockedF_NULL;
  1195. }
  1196. if ( !Q_stricmp( "misc_model_breakable", ent->classname ) && ent->physicsBounce )
  1197. {//a gravity-affected model
  1198. misc_model_breakable_gravity_init( ent, qfalse );
  1199. }
  1200. }
  1201. /*
  1202. =============
  1203. anglerCallback
  1204. Utility function
  1205. =============
  1206. */
  1207. void anglerCallback( gentity_t *ent )
  1208. {
  1209. //Complete the task
  1210. Q3_TaskIDComplete( ent, TID_ANGLE_FACE );
  1211. // play sound
  1212. ent->s.loopSound = 0;//stop looping sound
  1213. G_PlayDoorSound( ent, BMS_END );//play end sound
  1214. //Set the currentAngles, clear all movement
  1215. VectorMA( ent->s.apos.trBase, (ent->s.apos.trDuration*0.001f), ent->s.apos.trDelta, ent->currentAngles );
  1216. VectorCopy( ent->currentAngles, ent->s.apos.trBase );
  1217. VectorClear( ent->s.apos.trDelta );
  1218. ent->s.apos.trDuration = 1;
  1219. ent->s.apos.trType = TR_STATIONARY;
  1220. ent->s.apos.trTime = level.time;
  1221. //Stop thinking
  1222. ent->e_ReachedFunc = reachedF_NULL;
  1223. if ( ent->e_ThinkFunc == thinkF_anglerCallback )
  1224. {
  1225. ent->e_ThinkFunc = thinkF_NULL;
  1226. }
  1227. //link
  1228. gi.linkentity( ent );
  1229. }
  1230. /*
  1231. =============
  1232. moveAndRotateCallback
  1233. Utility function
  1234. =============
  1235. */
  1236. void moveAndRotateCallback( gentity_t *ent )
  1237. {
  1238. //stop turning
  1239. anglerCallback( ent );
  1240. //stop moving
  1241. moverCallback( ent );
  1242. }
  1243. void Blocked_Mover( gentity_t *ent, gentity_t *other ) {
  1244. // remove anything other than a client -- no longer the case
  1245. // don't remove security keys or goodie keys
  1246. if ( (other->s.eType == ET_ITEM) && (other->item->giTag >= INV_GOODIE_KEY && other->item->giTag <= INV_SECURITY_KEY) )
  1247. {
  1248. // should we be doing anything special if a key blocks it... move it somehow..?
  1249. }
  1250. // if your not a client, or your a dead client remove yourself...
  1251. else if ( other->s.number && (!other->client || (other->client && other->health <= 0 && other->contents == CONTENTS_CORPSE && !other->message)) )
  1252. {
  1253. if ( !IIcarusInterface::GetIcarus()->IsRunning( other->m_iIcarusID ) /*!other->taskManager || !other->taskManager->IsRunning()*/ )
  1254. {
  1255. // if an item or weapon can we do a little explosion..?
  1256. G_FreeEntity( other );
  1257. return;
  1258. }
  1259. }
  1260. if ( ent->damage ) {
  1261. G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH );
  1262. }
  1263. }
  1264. /*
  1265. =============
  1266. Q3_Lerp2Start
  1267. Lerps the origin of an entity to its starting position
  1268. =============
  1269. // NEEDED???
  1270. */
  1271. /*static void Q3_Lerp2Start( int entID, int taskID, float duration )
  1272. {
  1273. gentity_t *ent = &g_entities[entID];
  1274. if(!ent)
  1275. {
  1276. Quake3Game()->DebugPrint( WL_WARNING, "Q3_Lerp2Start: invalid entID %d\n", entID);
  1277. return;
  1278. }
  1279. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  1280. {
  1281. Quake3Game()->DebugPrint( WL_ERROR, "Q3_Lerp2Start: ent %d is NOT a mover!\n", entID);
  1282. return;
  1283. }
  1284. if ( ent->s.eType != ET_MOVER )
  1285. {
  1286. ent->s.eType = ET_MOVER;
  1287. }
  1288. //FIXME: set up correctly!!!
  1289. ent->moverState = MOVER_2TO1;
  1290. ent->s.eType = ET_MOVER;
  1291. ent->e_ReachedFunc = reachedF_moverCallback; //Callsback the the completion of the move
  1292. if ( ent->damage )
  1293. {
  1294. ent->e_BlockedFunc = blockedF_Blocked_Mover;
  1295. }
  1296. ent->s.pos.trDuration = duration * 10; //In seconds
  1297. ent->s.pos.trTime = level.time;
  1298. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  1299. // starting sound
  1300. G_PlayDoorLoopSound( ent );
  1301. G_PlayDoorSound( ent, BMS_START ); //??
  1302. gi.linkentity( ent );
  1303. }*/
  1304. /*
  1305. =============
  1306. Q3_Lerp2End
  1307. Lerps the origin of an entity to its ending position
  1308. =============
  1309. // NEEDED???
  1310. */
  1311. /*static void Q3_Lerp2End( int entID, int taskID, float duration )
  1312. {
  1313. gentity_t *ent = &g_entities[entID];
  1314. if(!ent)
  1315. {
  1316. Quake3Game()->DebugPrint( WL_WARNING, "Q3_Lerp2End: invalid entID %d\n", entID);
  1317. return;
  1318. }
  1319. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  1320. {
  1321. Quake3Game()->DebugPrint( WL_ERROR, "Q3_Lerp2End: ent %d is NOT a mover!\n", entID);
  1322. return;
  1323. }
  1324. if ( ent->s.eType != ET_MOVER )
  1325. {
  1326. ent->s.eType = ET_MOVER;
  1327. }
  1328. if ( ent->moverState == MOVER_POS1 )
  1329. {//open the portal
  1330. if ( ent->svFlags & SVF_MOVER_ADJ_AREA_PORTALS )
  1331. {
  1332. gi.AdjustAreaPortalState( ent, qtrue );
  1333. }
  1334. }
  1335. //FIXME: set up correctly!!!
  1336. ent->moverState = MOVER_1TO2;
  1337. ent->s.eType = ET_MOVER;
  1338. ent->e_ReachedFunc = reachedF_moverCallback; //Callsback the the completion of the move
  1339. if ( ent->damage )
  1340. {
  1341. ent->e_BlockedFunc = blockedF_Blocked_Mover;
  1342. }
  1343. ent->s.pos.trDuration = duration * 10; //In seconds
  1344. ent->s.time = level.time;
  1345. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  1346. // starting sound
  1347. G_PlayDoorLoopSound( ent );
  1348. G_PlayDoorSound( ent, BMS_START ); //??
  1349. gi.linkentity( ent );
  1350. }*/
  1351. /*
  1352. =============
  1353. Q3_Lerp2Pos
  1354. Lerps the origin and angles of an entity to the destination values
  1355. =============
  1356. */
  1357. /*static void Q3_Lerp2Pos( int taskID, int entID, vec3_t origin, vec3_t angles, float duration )
  1358. {
  1359. gentity_t *ent = &g_entities[entID];
  1360. vec3_t ang;
  1361. int i;
  1362. if(!ent)
  1363. {
  1364. Quake3Game()->DebugPrint( WL_WARNING, "Q3_Lerp2Pos: invalid entID %d\n", entID);
  1365. return;
  1366. }
  1367. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  1368. {
  1369. Quake3Game()->DebugPrint( WL_ERROR, "Q3_Lerp2Pos: ent %d is NOT a mover!\n", entID);
  1370. return;
  1371. }
  1372. if ( ent->s.eType != ET_MOVER )
  1373. {
  1374. ent->s.eType = ET_MOVER;
  1375. }
  1376. //Don't allow a zero duration
  1377. if ( duration == 0 )
  1378. duration = 1;
  1379. //
  1380. // Movement
  1381. moverState_t moverState = ent->moverState;
  1382. if ( moverState == MOVER_POS1 || moverState == MOVER_2TO1 )
  1383. {
  1384. VectorCopy( ent->currentOrigin, ent->pos1 );
  1385. VectorCopy( origin, ent->pos2 );
  1386. if ( moverState == MOVER_POS1 )
  1387. {//open the portal
  1388. if ( ent->svFlags & SVF_MOVER_ADJ_AREA_PORTALS )
  1389. {
  1390. gi.AdjustAreaPortalState( ent, qtrue );
  1391. }
  1392. }
  1393. moverState = MOVER_1TO2;
  1394. }
  1395. else /*if ( moverState == MOVER_POS2 || moverState == MOVER_1TO2 )*/
  1396. /* {
  1397. VectorCopy( ent->currentOrigin, ent->pos2 );
  1398. VectorCopy( origin, ent->pos1 );
  1399. moverState = MOVER_2TO1;
  1400. }
  1401. InitMoverTrData( ent );
  1402. ent->s.pos.trDuration = duration;
  1403. // start it going
  1404. MatchTeam( ent, moverState, level.time );
  1405. //SetMoverState( ent, moverState, level.time );
  1406. //Only do the angles if specified
  1407. if ( angles != NULL )
  1408. {
  1409. //
  1410. // Rotation
  1411. for ( i = 0; i < 3; i++ )
  1412. {
  1413. ang[i] = AngleDelta( angles[i], ent->currentAngles[i] );
  1414. ent->s.apos.trDelta[i] = ( ang[i] / ( duration * 0.001f ) );
  1415. }
  1416. VectorCopy( ent->currentAngles, ent->s.apos.trBase );
  1417. if ( ent->alt_fire )
  1418. {
  1419. ent->s.apos.trType = TR_LINEAR_STOP;
  1420. }
  1421. else
  1422. {
  1423. ent->s.apos.trType = TR_NONLINEAR_STOP;
  1424. }
  1425. ent->s.apos.trDuration = duration;
  1426. ent->s.apos.trTime = level.time;
  1427. ent->e_ReachedFunc = reachedF_moveAndRotateCallback;
  1428. Q3_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
  1429. }
  1430. else
  1431. {
  1432. //Setup the last bits of information
  1433. ent->e_ReachedFunc = reachedF_moverCallback;
  1434. }
  1435. if ( ent->damage )
  1436. {
  1437. ent->e_BlockedFunc = blockedF_Blocked_Mover;
  1438. }
  1439. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  1440. // starting sound
  1441. G_PlayDoorLoopSound( ent );
  1442. G_PlayDoorSound( ent, BMS_START ); //??
  1443. gi.linkentity( ent );
  1444. }*/
  1445. /*
  1446. =============
  1447. Q3_Lerp2Origin
  1448. Lerps the origin to the destination value
  1449. =============
  1450. */
  1451. static void Q3_Lerp2Origin( int taskID, int entID, vec3_t origin, float duration )
  1452. {
  1453. gentity_t *ent = &g_entities[entID];
  1454. if(!ent)
  1455. {
  1456. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_Lerp2Origin: invalid entID %d\n", entID);
  1457. return;
  1458. }
  1459. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  1460. {
  1461. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_Lerp2Origin: ent %d is NOT a mover!\n", entID);
  1462. return;
  1463. }
  1464. if ( ent->s.eType != ET_MOVER )
  1465. {
  1466. ent->s.eType = ET_MOVER;
  1467. }
  1468. moverState_t moverState = ent->moverState;
  1469. if ( moverState == MOVER_POS1 || moverState == MOVER_2TO1 )
  1470. {
  1471. VectorCopy( ent->currentOrigin, ent->pos1 );
  1472. VectorCopy( origin, ent->pos2 );
  1473. if ( moverState == MOVER_POS1 )
  1474. {//open the portal
  1475. if ( ent->svFlags & SVF_MOVER_ADJ_AREA_PORTALS )
  1476. {
  1477. gi.AdjustAreaPortalState( ent, qtrue );
  1478. }
  1479. }
  1480. moverState = MOVER_1TO2;
  1481. }
  1482. else if ( moverState == MOVER_POS2 || moverState == MOVER_1TO2 )
  1483. {
  1484. VectorCopy( ent->currentOrigin, ent->pos2 );
  1485. VectorCopy( origin, ent->pos1 );
  1486. moverState = MOVER_2TO1;
  1487. }
  1488. InitMoverTrData( ent ); //FIXME: This will probably break normal things that are being moved...
  1489. ent->s.pos.trDuration = duration;
  1490. // start it going
  1491. MatchTeam( ent, moverState, level.time );
  1492. //SetMoverState( ent, moverState, level.time );
  1493. ent->e_ReachedFunc = reachedF_moverCallback;
  1494. if ( ent->damage )
  1495. {
  1496. ent->e_BlockedFunc = blockedF_Blocked_Mover;
  1497. }
  1498. if ( taskID != -1 )
  1499. {
  1500. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  1501. }
  1502. // starting sound
  1503. G_PlayDoorLoopSound( ent );//start looping sound
  1504. G_PlayDoorSound( ent, BMS_START ); //play start sound
  1505. gi.linkentity( ent );
  1506. }
  1507. static void Q3_SetOriginOffset( int entID, int axis, float offset )
  1508. {
  1509. gentity_t *ent = &g_entities[entID];
  1510. if(!ent)
  1511. {
  1512. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetOriginOffset: invalid entID %d\n", entID);
  1513. return;
  1514. }
  1515. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  1516. {
  1517. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetOriginOffset: ent %d is NOT a mover!\n", entID);
  1518. return;
  1519. }
  1520. vec3_t origin;
  1521. VectorCopy( ent->s.origin, origin );
  1522. origin[axis] += offset;
  1523. float duration = 0;
  1524. if ( ent->speed )
  1525. {
  1526. duration = fabs(offset)/fabs(ent->speed)*1000.0f;
  1527. }
  1528. Q3_Lerp2Origin( -1, entID, origin, duration );
  1529. }
  1530. /*
  1531. =============
  1532. Q3_LerpAngles
  1533. Lerps the angles to the destination value
  1534. =============
  1535. */
  1536. /*static void Q3_Lerp2Angles( int taskID, int entID, vec3_t angles, float duration )
  1537. {
  1538. gentity_t *ent = &g_entities[entID];
  1539. vec3_t ang;
  1540. int i;
  1541. if(!ent)
  1542. {
  1543. Quake3Game()->DebugPrint( WL_WARNING, "Q3_Lerp2Angles: invalid entID %d\n", entID);
  1544. return;
  1545. }
  1546. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  1547. {
  1548. Quake3Game()->DebugPrint( WL_ERROR, "Q3_Lerp2Angles: ent %d is NOT a mover!\n", entID);
  1549. return;
  1550. }
  1551. //If we want an instant move, don't send 0...
  1552. ent->s.apos.trDuration = (duration>0) ? duration : 1;
  1553. for ( i = 0; i < 3; i++ )
  1554. {
  1555. ang [i] = AngleSubtract( angles[i], ent->currentAngles[i]);
  1556. ent->s.apos.trDelta[i] = ( ang[i] / ( ent->s.apos.trDuration * 0.001f ) );
  1557. }
  1558. VectorCopy( ent->currentAngles, ent->s.apos.trBase );
  1559. if ( ent->alt_fire )
  1560. {
  1561. ent->s.apos.trType = TR_LINEAR_STOP;
  1562. }
  1563. else
  1564. {
  1565. ent->s.apos.trType = TR_NONLINEAR_STOP;
  1566. }
  1567. ent->s.apos.trTime = level.time;
  1568. Q3_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
  1569. //ent->e_ReachedFunc = reachedF_NULL;
  1570. ent->e_ThinkFunc = thinkF_anglerCallback;
  1571. ent->nextthink = level.time + duration;
  1572. gi.linkentity( ent );
  1573. }*/
  1574. /*
  1575. =============
  1576. Q3_GetTag
  1577. Gets the value of a tag by the give name
  1578. =============
  1579. */
  1580. /*static int Q3_GetTag( int entID, const char *name, int lookup, vec3_t info )
  1581. {
  1582. gentity_t *ent = &g_entities[ entID ];
  1583. VALIDATEB( ent );
  1584. switch ( lookup )
  1585. {
  1586. case TYPE_ORIGIN:
  1587. //return TAG_GetOrigin( ent->targetname, name, info );
  1588. return TAG_GetOrigin( ent->ownername, name, info );
  1589. break;
  1590. case TYPE_ANGLES:
  1591. //return TAG_GetAngles( ent->targetname, name, info );
  1592. return TAG_GetAngles( ent->ownername, name, info );
  1593. break;
  1594. }
  1595. return false;
  1596. }*/
  1597. /*
  1598. =============
  1599. Q3_SetNavGoal
  1600. Sets the navigational goal of an entity
  1601. =============
  1602. */
  1603. static qboolean Q3_SetNavGoal( int entID, const char *name )
  1604. {
  1605. gentity_t *ent = &g_entities[ entID ];
  1606. vec3_t goalPos;
  1607. if ( !ent->health )
  1608. {
  1609. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNavGoal: tried to set a navgoal (\"%s\") on a corpse! \"%s\"\n", name, ent->script_targetname );
  1610. return qfalse;
  1611. }
  1612. if ( !ent->NPC )
  1613. {
  1614. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNavGoal: tried to set a navgoal (\"%s\") on a non-NPC: \"%s\"\n", name, ent->script_targetname );
  1615. return qfalse;
  1616. }
  1617. if ( !ent->NPC->tempGoal )
  1618. {
  1619. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNavGoal: tried to set a navgoal (\"%s\") on a dead NPC: \"%s\"\n", name, ent->script_targetname );
  1620. return qfalse;
  1621. }
  1622. if ( !ent->NPC->tempGoal->inuse )
  1623. {
  1624. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNavGoal: NPC's (\"%s\") navgoal is freed: \"%s\"\n", name, ent->script_targetname );
  1625. return qfalse;
  1626. }
  1627. if( Q_stricmp( "null", name) == 0
  1628. || Q_stricmp( "NULL", name) == 0 )
  1629. {
  1630. ent->NPC->goalEntity = NULL;
  1631. Q3_TaskIDComplete( ent, TID_MOVE_NAV );
  1632. return qfalse;
  1633. }
  1634. else
  1635. {
  1636. //Get the position of the goal
  1637. if ( TAG_GetOrigin2( NULL, name, goalPos ) == false )
  1638. {
  1639. gentity_t *targ = G_Find(NULL, FOFS(targetname), (char*)name);
  1640. if ( !targ )
  1641. {
  1642. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNavGoal: can't find NAVGOAL \"%s\"\n", name );
  1643. return qfalse;
  1644. }
  1645. else
  1646. {
  1647. ent->NPC->goalEntity = targ;
  1648. ent->NPC->goalRadius = sqrt(ent->maxs[0]+ent->maxs[0]) + sqrt(targ->maxs[0]+targ->maxs[0]);
  1649. ent->NPC->aiFlags &= ~NPCAI_TOUCHED_GOAL;
  1650. }
  1651. }
  1652. else
  1653. {
  1654. int goalRadius = TAG_GetRadius( NULL, name );
  1655. NPC_SetMoveGoal( ent, goalPos, goalRadius, qtrue );
  1656. //We know we want to clear the lastWaypoint here
  1657. ent->NPC->goalEntity->lastWaypoint = WAYPOINT_NONE;
  1658. ent->NPC->aiFlags &= ~NPCAI_TOUCHED_GOAL;
  1659. #ifdef _DEBUG
  1660. //this is *only* for debugging navigation
  1661. ent->NPC->tempGoal->target = G_NewString( name );
  1662. #endif// _DEBUG
  1663. return qtrue;
  1664. }
  1665. }
  1666. return qfalse;
  1667. }
  1668. //-----------------------------------------------
  1669. /*
  1670. ============
  1671. SetLowerAnim
  1672. Description :
  1673. Return type : static void
  1674. Argument : int entID
  1675. Argument : int animID
  1676. ============
  1677. */
  1678. static void SetLowerAnim( int entID, int animID)
  1679. {
  1680. gentity_t *ent = &g_entities[entID];
  1681. if ( !ent )
  1682. {
  1683. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "SetLowerAnim: invalid entID %d\n", entID);
  1684. return;
  1685. }
  1686. if ( !ent->client )
  1687. {
  1688. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "SetLowerAnim: ent %d is NOT a player or NPC!\n", entID);
  1689. return;
  1690. }
  1691. NPC_SetAnim(ent,SETANIM_LEGS,animID,SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD|SETANIM_FLAG_OVERRIDE);
  1692. }
  1693. /*
  1694. ============
  1695. SetUpperAnim
  1696. Description :
  1697. Return type : static void
  1698. Argument : int entID
  1699. Argument : int animID
  1700. ============
  1701. */
  1702. static void SetUpperAnim ( int entID, int animID)
  1703. {
  1704. gentity_t *ent = &g_entities[entID];
  1705. if ( !ent )
  1706. {
  1707. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "SetUpperAnim: invalid entID %d\n", entID);
  1708. return;
  1709. }
  1710. if ( !ent->client )
  1711. {
  1712. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "SetLowerAnim: ent %d is NOT a player or NPC!\n", entID);
  1713. return;
  1714. }
  1715. NPC_SetAnim(ent,SETANIM_TORSO,animID,SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD|SETANIM_FLAG_OVERRIDE);
  1716. }
  1717. //-----------------------------------------------
  1718. /*
  1719. =============
  1720. Q3_SetAnimUpper
  1721. Sets the upper animation of an entity
  1722. =============
  1723. */
  1724. static qboolean Q3_SetAnimUpper( int entID, const char *anim_name )
  1725. {
  1726. int animID = 0;
  1727. animID = GetIDForString( animTable, anim_name );
  1728. if( animID == -1 )
  1729. {
  1730. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAnimUpper: unknown animation sequence '%s'\n", anim_name );
  1731. return qfalse;
  1732. }
  1733. if ( !PM_HasAnimation( &g_entities[entID], animID ) )
  1734. {
  1735. return qfalse;
  1736. }
  1737. SetUpperAnim( entID, animID );
  1738. return qtrue;
  1739. }
  1740. /*
  1741. =============
  1742. Q3_SetAnimLower
  1743. Sets the lower animation of an entity
  1744. =============
  1745. */
  1746. static qboolean Q3_SetAnimLower( int entID, const char *anim_name )
  1747. {
  1748. int animID = 0;
  1749. //FIXME: Setting duck anim does not actually duck!
  1750. animID = GetIDForString( animTable, anim_name );
  1751. if( animID == -1 )
  1752. {
  1753. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAnimLower: unknown animation sequence '%s'\n", anim_name );
  1754. return qfalse;
  1755. }
  1756. if ( !PM_HasAnimation( &g_entities[entID], animID ) )
  1757. {
  1758. return qfalse;
  1759. }
  1760. SetLowerAnim( entID, animID );
  1761. return qtrue;
  1762. }
  1763. /*
  1764. ============
  1765. Q3_SetAnimHoldTime
  1766. Description :
  1767. Return type : static void
  1768. Argument : int entID
  1769. Argument : int int_data
  1770. Argument : qboolean lower
  1771. ============
  1772. */
  1773. extern void PM_SetTorsoAnimTimer( gentity_t *ent, int *torsoAnimTimer, int time );
  1774. extern void PM_SetLegsAnimTimer( gentity_t *ent, int *legsAnimTimer, int time );
  1775. static void Q3_SetAnimHoldTime( int entID, int int_data, qboolean lower )
  1776. {
  1777. gentity_t *ent = &g_entities[entID];
  1778. if ( !ent )
  1779. {
  1780. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAnimHoldTime: invalid entID %d\n", entID);
  1781. return;
  1782. }
  1783. if ( !ent->client )
  1784. {
  1785. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetAnimHoldTime: ent %d is NOT a player or NPC!\n", entID);
  1786. return;
  1787. }
  1788. if(lower)
  1789. {
  1790. PM_SetLegsAnimTimer( ent, &ent->client->ps.legsAnimTimer, int_data );
  1791. }
  1792. else
  1793. {
  1794. PM_SetTorsoAnimTimer( ent, &ent->client->ps.torsoAnimTimer, int_data );
  1795. }
  1796. }
  1797. /*
  1798. =============
  1799. Q3_SetEnemy
  1800. Sets the enemy of an entity
  1801. =============
  1802. */
  1803. static void Q3_SetEnemy( int entID, const char *name )
  1804. {
  1805. gentity_t *ent = &g_entities[entID];
  1806. if ( !ent )
  1807. {
  1808. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetEnemy: invalid entID %d\n", entID);
  1809. return;
  1810. }
  1811. if( !Q_stricmp("NONE", name) || !Q_stricmp("NULL", name))
  1812. {
  1813. if(ent->NPC)
  1814. {
  1815. G_ClearEnemy(ent);
  1816. }
  1817. else
  1818. {
  1819. ent->enemy = NULL;
  1820. }
  1821. }
  1822. else
  1823. {
  1824. gentity_t *enemy = G_Find( NULL, FOFS(targetname), (char *) name);
  1825. if(enemy == NULL)
  1826. {
  1827. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetEnemy: no such enemy: '%s'\n", name );
  1828. return;
  1829. }
  1830. /*else if(enemy->health <= 0)
  1831. {
  1832. //Quake3Game()->DebugPrint( WL_ERROR, "Q3_SetEnemy: ERROR - desired enemy has health %d\n", enemy->health );
  1833. return;
  1834. }*/
  1835. else
  1836. {
  1837. if(ent->NPC)
  1838. {
  1839. G_SetEnemy( ent, enemy );
  1840. ent->cantHitEnemyCounter = 0;
  1841. }
  1842. else
  1843. {
  1844. G_SetEnemy(ent, enemy);
  1845. }
  1846. }
  1847. }
  1848. }
  1849. /*
  1850. =============
  1851. Q3_SetLeader
  1852. Sets the leader of an NPC
  1853. =============
  1854. */
  1855. static void Q3_SetLeader( int entID, const char *name )
  1856. {
  1857. gentity_t *ent = &g_entities[entID];
  1858. if ( !ent )
  1859. {
  1860. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLeader: invalid entID %d\n", entID);
  1861. return;
  1862. }
  1863. if ( !ent->client )
  1864. {
  1865. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetLeader: ent %d is NOT a player or NPC!\n", entID);
  1866. return;
  1867. }
  1868. if( !Q_stricmp("NONE", name) || !Q_stricmp("NULL", name))
  1869. {
  1870. ent->client->leader = NULL;
  1871. }
  1872. else
  1873. {
  1874. gentity_t *leader = G_Find( NULL, FOFS(targetname), (char *) name);
  1875. if(leader == NULL)
  1876. {
  1877. //Quake3Game()->DebugPrint( WL_ERROR,"Q3_SetEnemy: unable to locate enemy: '%s'\n", name );
  1878. return;
  1879. }
  1880. else if(leader->health <= 0)
  1881. {
  1882. //Quake3Game()->DebugPrint( WL_ERROR,"Q3_SetEnemy: ERROR - desired enemy has health %d\n", enemy->health );
  1883. return;
  1884. }
  1885. else
  1886. {
  1887. ent->client->leader = leader;
  1888. }
  1889. }
  1890. }
  1891. stringID_table_t teamTable [] =
  1892. {
  1893. ENUM2STRING(TEAM_FREE),
  1894. // ENUM2STRING(TEAM_STARFLEET),
  1895. // ENUM2STRING(TEAM_BORG),
  1896. // ENUM2STRING(TEAM_PARASITE),
  1897. // ENUM2STRING(TEAM_SCAVENGERS),
  1898. // ENUM2STRING(TEAM_KLINGON),
  1899. // ENUM2STRING(TEAM_MALON),
  1900. // ENUM2STRING(TEAM_HIROGEN),
  1901. // ENUM2STRING(TEAM_IMPERIAL),
  1902. // ENUM2STRING(TEAM_STASIS),
  1903. // ENUM2STRING(TEAM_8472),
  1904. // ENUM2STRING(TEAM_BOTS),
  1905. // ENUM2STRING(TEAM_FORGE),
  1906. // ENUM2STRING(TEAM_DISGUISE),
  1907. ENUM2STRING(TEAM_PLAYER),
  1908. ENUM2STRING(TEAM_ENEMY),
  1909. ENUM2STRING(TEAM_NEUTRAL),
  1910. "", TEAM_FREE,
  1911. };
  1912. /*
  1913. ============
  1914. Q3_SetPlayerTeam
  1915. Description :
  1916. Return type : static void
  1917. Argument : int entID
  1918. Argument : const char *teamName
  1919. ============
  1920. */
  1921. static void Q3_SetPlayerTeam( int entID, const char *teamName )
  1922. {
  1923. gentity_t *ent = &g_entities[entID];
  1924. team_t newTeam;
  1925. if ( !ent )
  1926. {
  1927. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetPlayerTeam: invalid entID %d\n", entID);
  1928. return;
  1929. }
  1930. if ( !ent->client )
  1931. {
  1932. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetPlayerTeam: ent %d is NOT a player or NPC!\n", entID);
  1933. return;
  1934. }
  1935. newTeam = (team_t)GetIDForString( teamTable, teamName );
  1936. ent->client->playerTeam = newTeam;
  1937. }
  1938. /*
  1939. ============
  1940. Q3_SetEnemyTeam
  1941. Description :
  1942. Return type : static void
  1943. Argument : int entID
  1944. Argument : const char *teamName
  1945. ============
  1946. */
  1947. static void Q3_SetEnemyTeam( int entID, const char *teamName )
  1948. {
  1949. gentity_t *ent = &g_entities[entID];
  1950. if ( !ent )
  1951. {
  1952. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetEnemyTeam: invalid entID %d\n", entID);
  1953. return;
  1954. }
  1955. if ( !ent->client )
  1956. {
  1957. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetEnemyTeam: ent %d is NOT a player or NPC!\n", entID);
  1958. return;
  1959. }
  1960. ent->client->enemyTeam = (team_t)GetIDForString( teamTable, teamName );
  1961. }
  1962. /*
  1963. ============
  1964. Q3_SetHealth
  1965. Description :
  1966. Return type : static void
  1967. Argument : int entID
  1968. Argument : int data
  1969. ============
  1970. */
  1971. static void Q3_SetHealth( int entID, int data )
  1972. {
  1973. gentity_t *ent = &g_entities[entID];
  1974. if ( !ent )
  1975. {
  1976. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetHealth: invalid entID %d\n", entID);
  1977. return;
  1978. }
  1979. // FIXME : should we really let you set health on a dead guy?
  1980. // this close to gold I won't change it, but warn you about it
  1981. if( ent->health <= 0 )
  1982. {
  1983. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetHealth: trying to set health on a dead guy! %d\n", entID);
  1984. }
  1985. if ( data < 0 )
  1986. {
  1987. data = 0;
  1988. }
  1989. ent->health = data;
  1990. // should adjust max if new health is higher than max
  1991. if ( ent->health > ent->max_health )
  1992. {
  1993. ent->max_health = ent->health;
  1994. }
  1995. if(!ent->client)
  1996. {
  1997. return;
  1998. }
  1999. ent->client->ps.stats[STAT_HEALTH] = data;
  2000. if ( ent->s.number == 0 )
  2001. {//clamp health to max
  2002. if ( ent->client->ps.stats[STAT_HEALTH] > ent->client->ps.stats[STAT_MAX_HEALTH] )
  2003. {
  2004. ent->health = ent->client->ps.stats[STAT_HEALTH] = ent->client->ps.stats[STAT_MAX_HEALTH];
  2005. }
  2006. if ( data == 0 )
  2007. {//artificially "killing" the player", don't let him respawn right away
  2008. ent->client->ps.pm_type = PM_DEAD;
  2009. //delay respawn for 2 seconds
  2010. ent->client->respawnTime = level.time + 2000;
  2011. //stop all scripts
  2012. if (Q_stricmpn(level.mapname,"_holo",5)) {
  2013. stop_icarus = qtrue;
  2014. }
  2015. //make the team killable
  2016. //G_MakeTeamVulnerable();
  2017. }
  2018. }
  2019. }
  2020. /*
  2021. ============
  2022. Q3_SetArmor
  2023. Description :
  2024. Return type : static void
  2025. Argument : int entID
  2026. Argument : int data
  2027. ============
  2028. */
  2029. static void Q3_SetArmor( int entID, int data )
  2030. {
  2031. gentity_t *ent = &g_entities[entID];
  2032. if ( !ent )
  2033. {
  2034. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetArmor: invalid entID %d\n", entID);
  2035. return;
  2036. }
  2037. if(!ent->client)
  2038. {
  2039. return;
  2040. }
  2041. ent->client->ps.stats[STAT_ARMOR] = data;
  2042. if ( ent->s.number == 0 )
  2043. {//clamp armor to max_health
  2044. if ( ent->client->ps.stats[STAT_ARMOR] > ent->client->ps.stats[STAT_MAX_HEALTH] )
  2045. {
  2046. ent->client->ps.stats[STAT_ARMOR] = ent->client->ps.stats[STAT_MAX_HEALTH];
  2047. }
  2048. }
  2049. }
  2050. /*
  2051. ============
  2052. Q3_SetBState
  2053. Description :
  2054. Return type : static qboolean
  2055. Argument : int entID
  2056. Argument : const char *bs_name
  2057. FIXME: this should be a general NPC wrapper function
  2058. that is called ANY time a bState is changed...
  2059. ============
  2060. */
  2061. static qboolean Q3_SetBState( int entID, const char *bs_name )
  2062. {
  2063. gentity_t *ent = &g_entities[entID];
  2064. bState_t bSID;
  2065. if ( !ent )
  2066. {
  2067. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetBState: invalid entID %d\n", entID);
  2068. return qtrue;
  2069. }
  2070. if ( !ent->NPC )
  2071. {
  2072. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetBState: '%s' is not an NPC\n", ent->targetname );
  2073. return qtrue;//ok to complete
  2074. }
  2075. bSID = (bState_t)(GetIDForString( BSTable, bs_name ));
  2076. if ( bSID > -1 )
  2077. {
  2078. if ( bSID == BS_SEARCH || bSID == BS_WANDER )
  2079. {
  2080. //FIXME: Reimplement
  2081. if( ent->waypoint != WAYPOINT_NONE )
  2082. {
  2083. NPC_BSSearchStart( ent->waypoint, bSID );
  2084. }
  2085. else
  2086. {
  2087. ent->waypoint = NAV::GetNearestNode(ent);
  2088. if( ent->waypoint != WAYPOINT_NONE )
  2089. {
  2090. NPC_BSSearchStart( ent->waypoint, bSID );
  2091. }
  2092. else
  2093. {
  2094. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetBState: '%s' is not in a valid waypoint to search from!\n", ent->targetname );
  2095. return qtrue;
  2096. }
  2097. }
  2098. }
  2099. ent->NPC->tempBehavior = BS_DEFAULT;//need to clear any temp behaviour
  2100. if ( ent->NPC->behaviorState == BS_NOCLIP && bSID != BS_NOCLIP )
  2101. {//need to rise up out of the floor after noclipping
  2102. ent->currentOrigin[2] += 0.125;
  2103. G_SetOrigin( ent, ent->currentOrigin );
  2104. gi.linkentity( ent );
  2105. }
  2106. ent->NPC->behaviorState = bSID;
  2107. if ( bSID == BS_DEFAULT )
  2108. {
  2109. ent->NPC->defaultBehavior = bSID;
  2110. }
  2111. }
  2112. ent->NPC->aiFlags &= ~NPCAI_TOUCHED_GOAL;
  2113. // if ( bSID == BS_FLY )
  2114. // {//FIXME: need a set bState wrapper
  2115. // ent->client->moveType = MT_FLYSWIM;
  2116. // }
  2117. // else
  2118. {
  2119. //FIXME: these are presumptions!
  2120. //Q3_SetGravity( entID, g_gravity->value );
  2121. //ent->client->moveType = MT_RUNJUMP;
  2122. }
  2123. if ( bSID == BS_NOCLIP )
  2124. {
  2125. ent->client->noclip = true;
  2126. }
  2127. else
  2128. {
  2129. ent->client->noclip = false;
  2130. }
  2131. /*
  2132. if ( bSID == BS_FACE || bSID == BS_POINT_AND_SHOOT || bSID == BS_FACE_ENEMY )
  2133. {
  2134. ent->NPC->aimTime = level.time + 5 * 1000;//try for 5 seconds
  2135. return qfalse;//need to wait for task complete message
  2136. }
  2137. */
  2138. // if ( bSID == BS_SNIPER || bSID == BS_ADVANCE_FIGHT )
  2139. if ( bSID == BS_ADVANCE_FIGHT )
  2140. {
  2141. return qfalse;//need to wait for task complete message
  2142. }
  2143. /*
  2144. if ( bSID == BS_SHOOT || bSID == BS_POINT_AND_SHOOT )
  2145. {//Let them shoot right NOW
  2146. ent->NPC->shotTime = ent->attackDebounceTime = level.time;
  2147. }
  2148. */
  2149. if ( bSID == BS_JUMP )
  2150. {
  2151. ent->NPC->jumpState = JS_FACING;
  2152. }
  2153. return qtrue;//ok to complete
  2154. }
  2155. /*
  2156. ============
  2157. Q3_SetTempBState
  2158. Description :
  2159. Return type : static qboolean
  2160. Argument : int entID
  2161. Argument : const char *bs_name
  2162. ============
  2163. */
  2164. static qboolean Q3_SetTempBState( int entID, const char *bs_name )
  2165. {
  2166. gentity_t *ent = &g_entities[entID];
  2167. bState_t bSID;
  2168. if ( !ent )
  2169. {
  2170. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetTempBState: invalid entID %d\n", entID);
  2171. return qtrue;
  2172. }
  2173. if ( !ent->NPC )
  2174. {
  2175. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetTempBState: '%s' is not an NPC\n", ent->targetname );
  2176. return qtrue;//ok to complete
  2177. }
  2178. bSID = (bState_t)(GetIDForString( BSTable, bs_name ));
  2179. if ( bSID > -1 )
  2180. {
  2181. ent->NPC->tempBehavior = bSID;
  2182. }
  2183. /*
  2184. if ( bSID == BS_FACE || bSID == BS_POINT_AND_SHOOT || bSID == BS_FACE_ENEMY )
  2185. {
  2186. ent->NPC->aimTime = level.time + 5 * 1000;//try for 5 seconds
  2187. return qfalse;//need to wait for task complete message
  2188. }
  2189. */
  2190. /*
  2191. if ( bSID == BS_SHOOT || bSID == BS_POINT_AND_SHOOT )
  2192. {//Let them shoot right NOW
  2193. ent->NPC->shotTime = ent->attackDebounceTime = level.time;
  2194. }
  2195. */
  2196. return qtrue;//ok to complete
  2197. }
  2198. /*
  2199. ============
  2200. Q3_SetDefaultBState
  2201. Description :
  2202. Return type : static void
  2203. Argument : int entID
  2204. Argument : const char *bs_name
  2205. ============
  2206. */
  2207. static void Q3_SetDefaultBState( int entID, const char *bs_name )
  2208. {
  2209. gentity_t *ent = &g_entities[entID];
  2210. bState_t bSID;
  2211. if ( !ent )
  2212. {
  2213. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDefaultBState: invalid entID %d\n", entID);
  2214. return;
  2215. }
  2216. if ( !ent->NPC )
  2217. {
  2218. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetDefaultBState: '%s' is not an NPC\n", ent->targetname );
  2219. return;
  2220. }
  2221. bSID = (bState_t)(GetIDForString( BSTable, bs_name ));
  2222. if ( bSID > -1 )
  2223. {
  2224. ent->NPC->defaultBehavior = bSID;
  2225. }
  2226. }
  2227. /*
  2228. ============
  2229. Q3_SetDPitch
  2230. Description :
  2231. Return type : static void
  2232. Argument : int entID
  2233. Argument : float data
  2234. ============
  2235. */
  2236. static void Q3_SetDPitch( int entID, float data )
  2237. {
  2238. gentity_t *ent = &g_entities[entID];
  2239. if ( !ent )
  2240. {
  2241. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDPitch: invalid entID %d\n", entID);
  2242. return;
  2243. }
  2244. if ( !ent->NPC || !ent->client )
  2245. {
  2246. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetDPitch: '%s' is not an NPC\n", ent->targetname );
  2247. return;
  2248. }
  2249. int pitchMin = -ent->client->renderInfo.headPitchRangeUp + 1;
  2250. int pitchMax = ent->client->renderInfo.headPitchRangeDown - 1;
  2251. //clamp angle to -180 -> 180
  2252. data = AngleNormalize180( data );
  2253. //Clamp it to my valid range
  2254. if ( data < -1 )
  2255. {
  2256. if ( data < pitchMin )
  2257. {
  2258. data = pitchMin;
  2259. }
  2260. }
  2261. else if ( data > 1 )
  2262. {
  2263. if ( data > pitchMax )
  2264. {
  2265. data = pitchMax;
  2266. }
  2267. }
  2268. ent->NPC->lockedDesiredPitch = ent->NPC->desiredPitch = data;
  2269. }
  2270. /*
  2271. ============
  2272. Q3_SetDYaw
  2273. Description :
  2274. Return type : static void
  2275. Argument : int entID
  2276. Argument : float data
  2277. ============
  2278. */
  2279. static void Q3_SetDYaw( int entID, float data )
  2280. {
  2281. gentity_t *ent = &g_entities[entID];
  2282. if ( !ent )
  2283. {
  2284. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDYaw: invalid entID %d\n", entID);
  2285. return;
  2286. }
  2287. if ( !ent->NPC )
  2288. {
  2289. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetDYaw: '%s' is not an NPC\n", ent->targetname );
  2290. return;
  2291. }
  2292. if(!ent->enemy)
  2293. {//don't mess with this if they're aiming at someone
  2294. ent->NPC->lockedDesiredYaw = ent->NPC->desiredYaw = ent->s.angles[1] = data;
  2295. }
  2296. else
  2297. {
  2298. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Could not set DYAW: '%s' has an enemy (%s)!\n", ent->targetname, ent->enemy->targetname );
  2299. }
  2300. }
  2301. /*
  2302. ============
  2303. Q3_SetShootDist
  2304. Description :
  2305. Return type : static void
  2306. Argument : int entID
  2307. Argument : float data
  2308. ============
  2309. */
  2310. static void Q3_SetShootDist( int entID, float data )
  2311. {
  2312. gentity_t *ent = &g_entities[entID];
  2313. if ( !ent )
  2314. {
  2315. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetShootDist: invalid entID %d\n", entID);
  2316. return;
  2317. }
  2318. if ( !ent->NPC )
  2319. {
  2320. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetShootDist: '%s' is not an NPC\n", ent->targetname );
  2321. return;
  2322. }
  2323. ent->NPC->stats.shootDistance = data;
  2324. }
  2325. /*
  2326. ============
  2327. Q3_SetVisrange
  2328. Description :
  2329. Return type : static void
  2330. Argument : int entID
  2331. Argument : float data
  2332. ============
  2333. */
  2334. static void Q3_SetVisrange( int entID, float data )
  2335. {
  2336. gentity_t *ent = &g_entities[entID];
  2337. if ( !ent )
  2338. {
  2339. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetVisrange: invalid entID %d\n", entID);
  2340. return;
  2341. }
  2342. if ( !ent->NPC )
  2343. {
  2344. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetVisrange: '%s' is not an NPC\n", ent->targetname );
  2345. return;
  2346. }
  2347. ent->NPC->stats.visrange = data;
  2348. }
  2349. /*
  2350. ============
  2351. Q3_SetEarshot
  2352. Description :
  2353. Return type : static void
  2354. Argument : int entID
  2355. Argument : float data
  2356. ============
  2357. */
  2358. static void Q3_SetEarshot( int entID, float data )
  2359. {
  2360. gentity_t *ent = &g_entities[entID];
  2361. if ( !ent )
  2362. {
  2363. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetEarshot: invalid entID %d\n", entID);
  2364. return;
  2365. }
  2366. if ( !ent->NPC )
  2367. {
  2368. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetEarshot: '%s' is not an NPC\n", ent->targetname );
  2369. return;
  2370. }
  2371. ent->NPC->stats.earshot = data;
  2372. }
  2373. /*
  2374. ============
  2375. Q3_SetVigilance
  2376. Description :
  2377. Return type : static void
  2378. Argument : int entID
  2379. Argument : float data
  2380. ============
  2381. */
  2382. static void Q3_SetVigilance( int entID, float data )
  2383. {
  2384. gentity_t *ent = &g_entities[entID];
  2385. if ( !ent )
  2386. {
  2387. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetVigilance: invalid entID %d\n", entID);
  2388. return;
  2389. }
  2390. if ( !ent->NPC )
  2391. {
  2392. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetVigilance: '%s' is not an NPC\n", ent->targetname );
  2393. return;
  2394. }
  2395. ent->NPC->stats.vigilance = data;
  2396. }
  2397. /*
  2398. ============
  2399. Q3_SetVFOV
  2400. Description :
  2401. Return type : static void
  2402. Argument : int entID
  2403. Argument : int data
  2404. ============
  2405. */
  2406. static void Q3_SetVFOV( int entID, int data )
  2407. {
  2408. gentity_t *ent = &g_entities[entID];
  2409. if ( !ent )
  2410. {
  2411. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetVFOV: invalid entID %d\n", entID);
  2412. return;
  2413. }
  2414. if ( !ent->NPC )
  2415. {
  2416. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetVFOV: '%s' is not an NPC\n", ent->targetname );
  2417. return;
  2418. }
  2419. ent->NPC->stats.vfov = data;
  2420. }
  2421. /*
  2422. ============
  2423. Q3_SetHFOV
  2424. Description :
  2425. Return type : static void
  2426. Argument : int entID
  2427. Argument : int data
  2428. ============
  2429. */
  2430. static void Q3_SetHFOV( int entID, int data )
  2431. {
  2432. gentity_t *ent = &g_entities[entID];
  2433. if ( !ent )
  2434. {
  2435. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetHFOV: invalid entID %d\n", entID);
  2436. return;
  2437. }
  2438. if ( !ent->NPC )
  2439. {
  2440. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetHFOV: '%s' is not an NPC\n", ent->targetname );
  2441. return;
  2442. }
  2443. ent->NPC->stats.hfov = data;
  2444. }
  2445. /*
  2446. ============
  2447. Q3_SetWidth
  2448. Description :
  2449. Return type : static void
  2450. Argument : int entID
  2451. Argument : float data
  2452. ============
  2453. */
  2454. static void Q3_SetWidth( int entID, int data )
  2455. {
  2456. gentity_t *ent = &g_entities[entID];
  2457. if ( !ent )
  2458. {
  2459. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWidth: invalid entID %d\n", entID);
  2460. return;
  2461. }
  2462. if ( !ent->NPC )
  2463. {
  2464. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetWidth: '%s' is not an NPC\n", ent->targetname );
  2465. return;
  2466. }
  2467. ent->maxs[0] = ent->maxs[1] = data;
  2468. ent->mins[0] = ent->mins[1] = -data;
  2469. }
  2470. /*
  2471. ============
  2472. Q3_GetTimeScale
  2473. Description :
  2474. Return type : static DWORD
  2475. Argument : void
  2476. ============
  2477. */
  2478. // NEEDED???
  2479. /*static DWORD Q3_GetTimeScale( void )
  2480. {
  2481. //return Q3_TIME_SCALE;
  2482. return g_timescale->value;
  2483. }*/
  2484. /*
  2485. ============
  2486. Q3_SetTimeScale
  2487. Description :
  2488. Return type : static void
  2489. Argument : int entID
  2490. Argument : const char *data
  2491. ============
  2492. */
  2493. static void Q3_SetTimeScale( int entID, const char *data )
  2494. {
  2495. // if we're skipping the script DO NOT allow timescale to be set (skipping needs it at 100)
  2496. if ( g_skippingcin->integer )
  2497. {
  2498. return;
  2499. }
  2500. gi.cvar_set("timescale", data);
  2501. }
  2502. /*
  2503. ============
  2504. Q3_SetInvisible
  2505. Description :
  2506. Return type : static void
  2507. Argument : int entID
  2508. Argument : qboolean invisible
  2509. ============
  2510. */
  2511. static void Q3_SetInvisible( int entID, qboolean invisible )
  2512. {
  2513. gentity_t *self = &g_entities[entID];
  2514. if ( !self )
  2515. {
  2516. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetInvisible: invalid entID %d\n", entID);
  2517. return;
  2518. }
  2519. if ( invisible )
  2520. {
  2521. self->s.eFlags |= EF_NODRAW;
  2522. if ( self->client )
  2523. {
  2524. self->client->ps.eFlags |= EF_NODRAW;
  2525. }
  2526. self->contents = 0;
  2527. }
  2528. else
  2529. {
  2530. self->s.eFlags &= ~EF_NODRAW;
  2531. if ( self->client )
  2532. {
  2533. self->client->ps.eFlags &= ~EF_NODRAW;
  2534. }
  2535. }
  2536. }
  2537. /*
  2538. ============
  2539. Q3_SetVampire
  2540. Description :
  2541. Return type : static void
  2542. Argument : int entID
  2543. Argument : qboolean vampire
  2544. ============
  2545. */
  2546. static void Q3_SetVampire( int entID, qboolean vampire )
  2547. {
  2548. gentity_t *self = &g_entities[entID];
  2549. if ( !self || !self->client )
  2550. {
  2551. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetVampire: entID %d not a client\n", entID);
  2552. return;
  2553. }
  2554. if ( vampire )
  2555. {
  2556. self->client->ps.powerups[PW_DISINT_2] = Q3_INFINITE;
  2557. }
  2558. else
  2559. {
  2560. self->client->ps.powerups[PW_DISINT_2] = 0;
  2561. }
  2562. }
  2563. /*
  2564. ============
  2565. Q3_SetGreetAllies
  2566. Description :
  2567. Return type : static void
  2568. Argument : int entID
  2569. Argument : qboolean greet
  2570. ============
  2571. */
  2572. static void Q3_SetGreetAllies( int entID, qboolean greet )
  2573. {
  2574. gentity_t *self = &g_entities[entID];
  2575. if ( !self )
  2576. {
  2577. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetGreetAllies: invalid entID %d\n", entID);
  2578. return;
  2579. }
  2580. if ( !self->NPC )
  2581. {
  2582. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetGreetAllies: ent %s is not an NPC!\n", self->targetname );
  2583. return;
  2584. }
  2585. if ( greet )
  2586. {
  2587. self->NPC->aiFlags |= NPCAI_GREET_ALLIES;
  2588. }
  2589. else
  2590. {
  2591. self->NPC->aiFlags &= ~NPCAI_GREET_ALLIES;
  2592. }
  2593. }
  2594. /*
  2595. ============
  2596. Q3_SetViewTarget
  2597. Description :
  2598. Return type : static void
  2599. Argument : int entID
  2600. Argument : const char *name
  2601. ============
  2602. */
  2603. static void Q3_SetViewTarget (int entID, const char *name)
  2604. {
  2605. gentity_t *self = &g_entities[entID];
  2606. gentity_t *viewtarget = G_Find( NULL, FOFS(targetname), (char *) name);
  2607. vec3_t viewspot, selfspot, viewvec, viewangles;
  2608. if ( !self )
  2609. {
  2610. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetViewTarget: invalid entID %d\n", entID);
  2611. return;
  2612. }
  2613. if ( !self->client )
  2614. {
  2615. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetViewTarget: '%s' is not a player/NPC!\n", self->targetname );
  2616. return;
  2617. }
  2618. //FIXME: Exception handle here
  2619. if (viewtarget == NULL)
  2620. {
  2621. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetViewTarget: can't find ViewTarget: '%s'\n", name );
  2622. return;
  2623. }
  2624. //FIXME: should we set behavior to BS_FACE and keep facing this ent as it moves
  2625. //around for a script-specified length of time...?
  2626. VectorCopy ( self->currentOrigin, selfspot );
  2627. selfspot[2] += self->client->ps.viewheight;
  2628. if ( viewtarget->client && (!g_skippingcin || !g_skippingcin->integer ) )
  2629. {
  2630. VectorCopy ( viewtarget->client->renderInfo.eyePoint, viewspot );
  2631. }
  2632. else
  2633. {
  2634. VectorCopy ( viewtarget->currentOrigin, viewspot );
  2635. }
  2636. VectorSubtract( viewspot, selfspot, viewvec );
  2637. vectoangles( viewvec, viewangles );
  2638. Q3_SetDYaw( entID, viewangles[YAW] );
  2639. if ( !g_skippingcin || !g_skippingcin->integer )
  2640. {
  2641. Q3_SetDPitch( entID, viewangles[PITCH] );
  2642. }
  2643. }
  2644. /*
  2645. ============
  2646. Q3_SetWatchTarget
  2647. Description :
  2648. Return type : static void
  2649. Argument : int entID
  2650. Argument : const char *name
  2651. ============
  2652. */
  2653. static void Q3_SetWatchTarget (int entID, const char *name)
  2654. {
  2655. gentity_t *self = &g_entities[entID];
  2656. gentity_t *watchTarget = NULL;
  2657. if ( !self )
  2658. {
  2659. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWatchTarget: invalid entID %d\n", entID);
  2660. return;
  2661. }
  2662. if ( !self->NPC )
  2663. {
  2664. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetWatchTarget: '%s' is not an NPC!\n", self->targetname );
  2665. return;
  2666. }
  2667. if ( Q_stricmp( "NULL", name ) == 0 || Q_stricmp( "NONE", name ) == 0 || ( self->targetname && (Q_stricmp( self->targetname, name ) == 0) ) )
  2668. {//clearing watchTarget
  2669. self->NPC->watchTarget = NULL;
  2670. }
  2671. watchTarget = G_Find( NULL, FOFS(targetname), (char *) name);
  2672. if ( watchTarget == NULL )
  2673. {
  2674. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWatchTarget: can't find WatchTarget: '%s'\n", name );
  2675. return;
  2676. }
  2677. self->NPC->watchTarget = watchTarget;
  2678. }
  2679. void Q3_SetLoopSound(int entID, const char *name)
  2680. {
  2681. sfxHandle_t index;
  2682. gentity_t *self = &g_entities[entID];
  2683. if ( Q_stricmp( "NULL", name ) == 0 || Q_stricmp( "NONE", name )==0)
  2684. {
  2685. self->s.loopSound = 0;
  2686. return;
  2687. }
  2688. if ( self->s.eType == ET_MOVER )
  2689. {
  2690. index = cgi_S_RegisterSound( name );
  2691. }
  2692. else
  2693. {
  2694. index = G_SoundIndex( name );
  2695. }
  2696. if (index)
  2697. {
  2698. self->s.loopSound = index;
  2699. }
  2700. else
  2701. {
  2702. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLoopSound: can't find sound file: '%s'\n", name );
  2703. }
  2704. }
  2705. void Q3_SetICARUSFreeze( int entID, const char *name, qboolean freeze )
  2706. {
  2707. gentity_t *self = G_Find( NULL, FOFS(targetname), name );
  2708. if ( !self )
  2709. {//hmm, targetname failed, try script_targetname?
  2710. self = G_Find( NULL, FOFS(script_targetname), name );
  2711. }
  2712. if ( !self )
  2713. {
  2714. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetICARUSFreeze: invalid ent %s\n", name);
  2715. return;
  2716. }
  2717. if ( freeze )
  2718. {
  2719. self->svFlags |= SVF_ICARUS_FREEZE;
  2720. }
  2721. else
  2722. {
  2723. self->svFlags &= ~SVF_ICARUS_FREEZE;
  2724. }
  2725. }
  2726. /*
  2727. ============
  2728. Q3_SetViewEntity
  2729. Description :
  2730. Return type : static void
  2731. Argument : int entID
  2732. Argument : const char *name
  2733. ============
  2734. */
  2735. extern qboolean G_ClearViewEntity( gentity_t *ent );
  2736. extern void G_SetViewEntity( gentity_t *self, gentity_t *viewEntity );
  2737. void Q3_SetViewEntity(int entID, const char *name)
  2738. {
  2739. gentity_t *self = &g_entities[entID];
  2740. gentity_t *viewtarget = G_Find( NULL, FOFS(targetname), (char *) name);
  2741. if ( entID != 0 )
  2742. {//only valid on player
  2743. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetViewEntity: only valid on player\n", entID);
  2744. return;
  2745. }
  2746. if ( !self )
  2747. {
  2748. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetViewEntity: invalid entID %d\n", entID);
  2749. return;
  2750. }
  2751. if ( !self->client )
  2752. {
  2753. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetViewEntity: '%s' is not a player!\n", self->targetname );
  2754. return;
  2755. }
  2756. if ( !name )
  2757. {
  2758. G_ClearViewEntity( self );
  2759. return;
  2760. }
  2761. if ( viewtarget == NULL )
  2762. {
  2763. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetViewEntity: can't find ViewEntity: '%s'\n", name );
  2764. return;
  2765. }
  2766. G_SetViewEntity( self, viewtarget );
  2767. }
  2768. /*
  2769. ============
  2770. Q3_SetWeapon
  2771. Description :
  2772. Return type : static void
  2773. Argument : int entID
  2774. Argument : const char *wp_name
  2775. ============
  2776. */
  2777. extern gentity_t *TossClientItems( gentity_t *self );
  2778. void G_SetWeapon( gentity_t *self, int wp )
  2779. {
  2780. qboolean hadWeapon = qfalse;
  2781. if ( !self->client )
  2782. {
  2783. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetWeapon: '%s' is not a player/NPC!\n", self->targetname );
  2784. return;
  2785. }
  2786. if ( self->NPC )
  2787. {//since a script sets a weapon, we presume we don't want to auto-match the player's weapon anymore
  2788. self->NPC->aiFlags &= ~NPCAI_MATCHPLAYERWEAPON;
  2789. }
  2790. if(wp == WP_NONE)
  2791. {//no weapon
  2792. self->client->ps.weapon = WP_NONE;
  2793. G_RemoveWeaponModels( self );
  2794. if ( self->s.number < MAX_CLIENTS )
  2795. {//make sure the cgame-side knows this
  2796. CG_ChangeWeapon( wp );
  2797. }
  2798. return;
  2799. }
  2800. gitem_t *item = FindItemForWeapon( (weapon_t) wp);
  2801. RegisterItem( item ); //make sure the weapon is cached in case this runs at startup
  2802. if ( self->client->ps.stats[STAT_WEAPONS]&( 1 << wp ) )
  2803. {
  2804. hadWeapon = qtrue;
  2805. }
  2806. if ( self->NPC )
  2807. {//Should NPCs have only 1 weapon at a time?
  2808. self->client->ps.stats[STAT_WEAPONS] = ( 1 << wp );
  2809. self->client->ps.ammo[weaponData[wp].ammoIndex] = 999;
  2810. ChangeWeapon( self, wp );
  2811. self->client->ps.weapon = wp;
  2812. self->client->ps.weaponstate = WEAPON_READY;//WEAPON_RAISING;
  2813. G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/weapons/change.wav" ));
  2814. }
  2815. else
  2816. {
  2817. self->client->ps.stats[STAT_WEAPONS] |= ( 1 << wp );
  2818. self->client->ps.ammo[weaponData[wp].ammoIndex] = ammoData[weaponData[wp].ammoIndex].max;
  2819. G_AddEvent( self, EV_ITEM_PICKUP, (item - bg_itemlist) );
  2820. //force it to change
  2821. CG_ChangeWeapon( wp );
  2822. G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/weapons/change.wav" ));
  2823. }
  2824. G_RemoveWeaponModels( self );
  2825. if ( wp == WP_SABER )
  2826. {
  2827. if ( !hadWeapon )
  2828. {
  2829. WP_SaberInitBladeData( self );
  2830. }
  2831. WP_SaberAddG2SaberModels( self );
  2832. }
  2833. else
  2834. {
  2835. G_CreateG2AttachedWeaponModel( self, weaponData[wp].weaponMdl, self->handRBolt, 0 );
  2836. }
  2837. }
  2838. static void Q3_SetWeapon (int entID, const char *wp_name)
  2839. {
  2840. gentity_t *self = &g_entities[entID];
  2841. int wp = GetIDForString( WPTable, wp_name );
  2842. if ( !self )
  2843. {
  2844. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWeapon: invalid entID %d\n", entID);
  2845. return;
  2846. }
  2847. if ( !self->client )
  2848. {
  2849. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetWeapon: '%s' is not a player/NPC!\n", self->targetname );
  2850. return;
  2851. }
  2852. if ( self->NPC )
  2853. {//since a script sets a weapon, we presume we don't want to auto-match the player's weapon anymore
  2854. self->NPC->aiFlags &= ~NPCAI_MATCHPLAYERWEAPON;
  2855. }
  2856. if(!Q_stricmp("drop", wp_name))
  2857. {//no weapon, drop it
  2858. TossClientItems( self );
  2859. self->client->ps.weapon = WP_NONE;
  2860. G_RemoveWeaponModels( self );
  2861. return;
  2862. }
  2863. G_SetWeapon( self, wp );
  2864. }
  2865. /*
  2866. ============
  2867. Q3_SetItem
  2868. Description :
  2869. Return type : static void
  2870. Argument : int entID
  2871. Argument : const char *wp_name
  2872. ============
  2873. */
  2874. static void Q3_SetItem (int entID, const char *item_name)
  2875. {
  2876. gentity_t *self = &g_entities[entID];
  2877. int inv;
  2878. if ( !self )
  2879. {
  2880. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWeapon: invalid entID %d\n", entID);
  2881. return;
  2882. }
  2883. if ( !self->client )
  2884. {
  2885. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetWeapon: '%s' is not a player/NPC!\n", self->targetname );
  2886. return;
  2887. }
  2888. inv = GetIDForString( INVTable, item_name );
  2889. gitem_t *item = FindItemForInventory(inv);
  2890. RegisterItem( item ); //make sure the item is cached in case this runs at startup
  2891. // G_AddEvent( self, EV_ITEM_PICKUP, (item - bg_itemlist) );
  2892. // G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/weapons/change.wav" ));
  2893. self->client->ps.stats[STAT_ITEMS] |= (1<<item->giTag);
  2894. if( (inv == INV_ELECTROBINOCULARS) || (inv == INV_LIGHTAMP_GOGGLES) )
  2895. {
  2896. self->client->ps.inventory[inv] = 1;
  2897. return;
  2898. }
  2899. // else Bacta, seeker, sentry
  2900. if( self->client->ps.inventory[inv] < 5 )
  2901. {
  2902. self->client->ps.inventory[inv]++;
  2903. }
  2904. }
  2905. /*
  2906. ============
  2907. Q3_SetWalkSpeed
  2908. Description :
  2909. Return type : static void
  2910. Argument : int entID
  2911. Argument : int int_data
  2912. ============
  2913. */
  2914. static void Q3_SetWalkSpeed (int entID, int int_data)
  2915. {
  2916. gentity_t *self = &g_entities[entID];
  2917. if ( !self )
  2918. {
  2919. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWalkSpeed: invalid entID %d\n", entID);
  2920. return;
  2921. }
  2922. if ( !self->NPC )
  2923. {
  2924. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetWalkSpeed: '%s' is not an NPC!\n", self->targetname );
  2925. return;
  2926. }
  2927. if(int_data == 0)
  2928. {
  2929. self->NPC->stats.walkSpeed = self->client->ps.speed = 1;
  2930. }
  2931. self->NPC->stats.walkSpeed = self->client->ps.speed = int_data;
  2932. }
  2933. /*
  2934. ============
  2935. Q3_SetRunSpeed
  2936. Description :
  2937. Return type : static void
  2938. Argument : int entID
  2939. Argument : int int_data
  2940. ============
  2941. */
  2942. static void Q3_SetRunSpeed (int entID, int int_data)
  2943. {
  2944. gentity_t *self = &g_entities[entID];
  2945. if ( !self )
  2946. {
  2947. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRunSpeed: invalid entID %d\n", entID);
  2948. return;
  2949. }
  2950. if ( !self->NPC )
  2951. {
  2952. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetRunSpeed: '%s' is not an NPC!\n", self->targetname );
  2953. return;
  2954. }
  2955. if(int_data == 0)
  2956. {
  2957. self->NPC->stats.runSpeed = self->client->ps.speed = 1;
  2958. }
  2959. self->NPC->stats.runSpeed = self->client->ps.speed = int_data;
  2960. }
  2961. /*
  2962. ============
  2963. Q3_SetYawSpeed
  2964. Description :
  2965. Return type : static void
  2966. Argument : int entID
  2967. Argument : float float_data
  2968. ============
  2969. */
  2970. static void Q3_SetYawSpeed (int entID, float float_data)
  2971. {
  2972. gentity_t *self = &g_entities[entID];
  2973. if ( !self )
  2974. {
  2975. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetYawSpeed: invalid entID %d\n", entID);
  2976. return;
  2977. }
  2978. if ( !self->NPC )
  2979. {
  2980. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetYawSpeed: '%s' is not an NPC!\n", self->targetname );
  2981. return;
  2982. }
  2983. self->NPC->stats.yawSpeed = float_data;
  2984. }
  2985. /*
  2986. ============
  2987. Q3_SetAggression
  2988. Description :
  2989. Return type : static void
  2990. Argument : int entID
  2991. Argument : int int_data
  2992. ============
  2993. */
  2994. static void Q3_SetAggression(int entID, int int_data)
  2995. {
  2996. gentity_t *self = &g_entities[entID];
  2997. if ( !self )
  2998. {
  2999. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAggression: invalid entID %d\n", entID);
  3000. return;
  3001. }
  3002. if ( !self->NPC )
  3003. {
  3004. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetAggression: '%s' is not an NPC!\n", self->targetname );
  3005. return;
  3006. }
  3007. if(int_data < 1 || int_data > 5)
  3008. return;
  3009. self->NPC->stats.aggression = int_data;
  3010. }
  3011. /*
  3012. ============
  3013. Q3_SetAim
  3014. Description :
  3015. Return type : static void
  3016. Argument : int entID
  3017. Argument : int int_data
  3018. ============
  3019. */
  3020. static void Q3_SetAim(int entID, int int_data)
  3021. {
  3022. gentity_t *self = &g_entities[entID];
  3023. if ( !self )
  3024. {
  3025. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAim: invalid entID %d\n", entID);
  3026. return;
  3027. }
  3028. if ( !self->NPC )
  3029. {
  3030. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetAim: '%s' is not an NPC!\n", self->targetname );
  3031. return;
  3032. }
  3033. if(int_data < 1 || int_data > 5)
  3034. return;
  3035. self->NPC->stats.aim = int_data;
  3036. }
  3037. /*
  3038. ============
  3039. Q3_SetFriction
  3040. Description :
  3041. Return type : static void
  3042. Argument : int entID
  3043. Argument : int int_data
  3044. ============
  3045. */
  3046. static void Q3_SetFriction(int entID, int int_data)
  3047. {
  3048. gentity_t *self = &g_entities[entID];
  3049. if ( !self )
  3050. {
  3051. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetFriction: invalid entID %d\n", entID);
  3052. return;
  3053. }
  3054. if ( !self->client )
  3055. {
  3056. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetFriction: '%s' is not an NPC/player!\n", self->targetname );
  3057. return;
  3058. }
  3059. self->client->ps.friction = int_data;
  3060. }
  3061. /*
  3062. ============
  3063. Q3_SetGravity
  3064. Description :
  3065. Return type : static void
  3066. Argument : int entID
  3067. Argument : float float_data
  3068. ============
  3069. */
  3070. static void Q3_SetGravity(int entID, float float_data)
  3071. {
  3072. gentity_t *self = &g_entities[entID];
  3073. if ( !self )
  3074. {
  3075. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetGravity: invalid entID %d\n", entID);
  3076. return;
  3077. }
  3078. if ( !self->client )
  3079. {
  3080. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetGravity: '%s' is not an NPC/player!\n", self->targetname );
  3081. return;
  3082. }
  3083. //FIXME: what if we want to return them to normal global gravity?
  3084. self->svFlags |= SVF_CUSTOM_GRAVITY;
  3085. self->client->ps.gravity = float_data;
  3086. }
  3087. /*
  3088. ============
  3089. Q3_SetWait
  3090. Description :
  3091. Return type : static void
  3092. Argument : int entID
  3093. Argument : float float_data
  3094. ============
  3095. */
  3096. static void Q3_SetWait(int entID, float float_data)
  3097. {
  3098. gentity_t *self = &g_entities[entID];
  3099. if ( !self )
  3100. {
  3101. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWait: invalid entID %d\n", entID);
  3102. return;
  3103. }
  3104. self->wait = float_data;
  3105. }
  3106. static void Q3_SetShotSpacing(int entID, int int_data)
  3107. {
  3108. gentity_t *self = &g_entities[entID];
  3109. if ( !self )
  3110. {
  3111. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetShotSpacing: invalid entID %d\n", entID);
  3112. return;
  3113. }
  3114. if ( !self->NPC )
  3115. {
  3116. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetShotSpacing: '%s' is not an NPC!\n", self->targetname );
  3117. return;
  3118. }
  3119. self->NPC->aiFlags &= ~NPCAI_BURST_WEAPON;
  3120. self->NPC->burstSpacing = int_data;
  3121. }
  3122. /*
  3123. ============
  3124. Q3_SetFollowDist
  3125. Description :
  3126. Return type : static void
  3127. Argument : int entID
  3128. Argument : float float_data
  3129. ============
  3130. */
  3131. static void Q3_SetFollowDist(int entID, float float_data)
  3132. {
  3133. gentity_t *self = &g_entities[entID];
  3134. if ( !self )
  3135. {
  3136. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetFollowDist: invalid entID %d\n", entID);
  3137. return;
  3138. }
  3139. if ( !self->client || !self->NPC )
  3140. {
  3141. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetFollowDist: '%s' is not an NPC!\n", self->targetname );
  3142. return;
  3143. }
  3144. self->NPC->followDist = float_data;
  3145. }
  3146. /*
  3147. ============
  3148. Q3_SetScale
  3149. Description :
  3150. Return type : static void
  3151. Argument : int entID
  3152. Argument : float float_data
  3153. ============
  3154. */
  3155. static void Q3_SetScale(int entID, float float_data)
  3156. {
  3157. gentity_t *self = &g_entities[entID];
  3158. if ( !self )
  3159. {
  3160. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetScale: invalid entID %d\n", entID);
  3161. return;
  3162. }
  3163. self->s.scale = float_data;
  3164. }
  3165. /*
  3166. ============
  3167. Q3_SetRenderCullRadius
  3168. Description : allows NPCs to be drawn even when their origin is very far away from their model
  3169. Return type : static void
  3170. Argument : int entID
  3171. Argument : float float_data (the new radius for render culling)
  3172. ============
  3173. */
  3174. static void Q3_SetRenderCullRadius(int entID, float float_data)
  3175. {
  3176. gentity_t *self = &g_entities[entID];
  3177. if ( !self )
  3178. {
  3179. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRenderCullRadius: invalid entID %d\n", entID);
  3180. return;
  3181. }
  3182. self->s.radius = float_data;
  3183. }
  3184. /*
  3185. ============
  3186. Q3_SetCount
  3187. Description :
  3188. Return type : static void
  3189. Argument : int entID
  3190. Argument : const char *data
  3191. ============
  3192. */
  3193. static void Q3_SetCount(int entID, const char *data)
  3194. {
  3195. gentity_t *self = &g_entities[entID];
  3196. float val = 0.0f;
  3197. //FIXME: use FOFS() stuff here to make a generic entity field setting?
  3198. if ( !self )
  3199. {
  3200. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetCount: invalid entID %d\n", entID);
  3201. return;
  3202. }
  3203. if ( (val = Q3_CheckStringCounterIncrement( data )) )
  3204. {
  3205. self->count += (int)(val);
  3206. }
  3207. else
  3208. {
  3209. self->count = atoi((char *) data);
  3210. }
  3211. }
  3212. /*
  3213. ============
  3214. Q3_SetSquadName
  3215. Description :
  3216. Return type : static void
  3217. Argument : int entID
  3218. Argument : const char *squadname
  3219. ============
  3220. */
  3221. /*
  3222. static void Q3_SetSquadName (int entID, const char *squadname)
  3223. {
  3224. gentity_t *self = &g_entities[entID];
  3225. if ( !self )
  3226. {
  3227. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetSquadName: invalid entID %d\n", entID);
  3228. return;
  3229. }
  3230. if ( !self->client )
  3231. {
  3232. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetSquadName: '%s' is not an NPC/player!\n", self->targetname );
  3233. return;
  3234. }
  3235. if(!Q_stricmp("NULL", ((char *)squadname)))
  3236. {
  3237. self->client->squadname = NULL;
  3238. }
  3239. else
  3240. {
  3241. self->client->squadname = G_NewString(squadname);
  3242. }
  3243. }
  3244. */
  3245. /*
  3246. ============
  3247. Q3_SetTargetName
  3248. Description :
  3249. Return type : static void
  3250. Argument : int entID
  3251. Argument : const char *targetname
  3252. ============
  3253. */
  3254. static void Q3_SetTargetName (int entID, const char *targetname)
  3255. {
  3256. gentity_t *self = &g_entities[entID];
  3257. if ( !self )
  3258. {
  3259. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetTargetName: invalid entID %d\n", entID);
  3260. return;
  3261. }
  3262. if(!Q_stricmp("NULL", ((char *)targetname)))
  3263. {
  3264. self->targetname = NULL;
  3265. }
  3266. else
  3267. {
  3268. self->targetname = G_NewString( targetname );
  3269. }
  3270. }
  3271. /*
  3272. ============
  3273. Q3_SetTarget
  3274. Description :
  3275. Return type : static void
  3276. Argument : int entID
  3277. Argument : const char *target
  3278. ============
  3279. */
  3280. static void Q3_SetTarget (int entID, const char *target)
  3281. {
  3282. gentity_t *self = &g_entities[entID];
  3283. if ( !self )
  3284. {
  3285. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetTarget: invalid entID %d\n", entID);
  3286. return;
  3287. }
  3288. if(!Q_stricmp("NULL", ((char *)target)))
  3289. {
  3290. self->target = NULL;
  3291. }
  3292. else
  3293. {
  3294. self->target = G_NewString( target );
  3295. }
  3296. }
  3297. /*
  3298. ============
  3299. Q3_SetTarget2
  3300. Description :
  3301. Return type : static void
  3302. Argument : int entID
  3303. Argument : const char *target
  3304. ============
  3305. */
  3306. static void Q3_SetTarget2 (int entID, const char *target2)
  3307. {
  3308. gentity_t *self = &g_entities[entID];
  3309. if ( !self )
  3310. {
  3311. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetTarget2: invalid entID %d\n", entID);
  3312. return;
  3313. }
  3314. if(!Q_stricmp("NULL", ((char *)target2)))
  3315. {
  3316. self->target2 = NULL;
  3317. }
  3318. else
  3319. {
  3320. self->target2 = G_NewString( target2 );
  3321. }
  3322. }
  3323. /*
  3324. ============
  3325. Q3_SetRemoveTarget
  3326. Description :
  3327. Return type : static void
  3328. Argument : int entID
  3329. Argument : const char *target
  3330. ============
  3331. */
  3332. static void Q3_SetRemoveTarget (int entID, const char *target)
  3333. {
  3334. gentity_t *self = &g_entities[entID];
  3335. if ( !self )
  3336. {
  3337. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRemoveTarget: invalid entID %d\n", entID);
  3338. return;
  3339. }
  3340. if ( !self->NPC )
  3341. {
  3342. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetRemoveTarget: '%s' is not an NPC!\n", self->targetname );
  3343. return;
  3344. }
  3345. if( !Q_stricmp("NULL", ((char *)target)) )
  3346. {
  3347. self->target3 = NULL;
  3348. }
  3349. else
  3350. {
  3351. self->target3 = G_NewString( target );
  3352. }
  3353. }
  3354. /*
  3355. ============
  3356. Q3_SetPainTarget
  3357. Description :
  3358. Return type : void
  3359. Argument : int entID
  3360. Argument : const char *targetname
  3361. ============
  3362. */
  3363. static void Q3_SetPainTarget (int entID, const char *targetname)
  3364. {
  3365. gentity_t *self = &g_entities[entID];
  3366. if ( !self )
  3367. {
  3368. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetPainTarget: invalid entID %d\n", entID);
  3369. return;
  3370. }
  3371. if(Q_stricmp("NULL", ((char *)targetname)) == 0)
  3372. {
  3373. self->paintarget = NULL;
  3374. }
  3375. else
  3376. {
  3377. self->paintarget = G_NewString((char *)targetname);
  3378. }
  3379. }
  3380. static void Q3_SetMusicState( const char *dms )
  3381. {
  3382. int newDMS = GetIDForString( DMSTable, dms );
  3383. if ( newDMS != -1 )
  3384. {
  3385. level.dmState = newDMS;
  3386. }
  3387. }
  3388. static void Q3_SetForcePowerLevel ( int entID, int forcePower, int forceLevel )
  3389. {
  3390. if ( forcePower < FP_FIRST || forceLevel >= NUM_FORCE_POWERS )
  3391. {
  3392. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetForcePowerLevel: Force Power index %d out of range (%d-%d)\n", forcePower, FP_FIRST, (NUM_FORCE_POWERS-1) );
  3393. return;
  3394. }
  3395. if ( forceLevel < 0 || forceLevel >= NUM_FORCE_POWER_LEVELS )
  3396. {
  3397. if ( forcePower != FP_SABER_OFFENSE || forceLevel >= SS_NUM_SABER_STYLES )
  3398. {
  3399. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetForcePowerLevel: Force power setting %d out of range (0-3)\n", forceLevel );
  3400. return;
  3401. }
  3402. }
  3403. gentity_t *self = &g_entities[entID];
  3404. if ( !self )
  3405. {
  3406. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetForcePowerLevel: invalid entID %d\n", entID);
  3407. return;
  3408. }
  3409. if ( !self->client )
  3410. {
  3411. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetForcePowerLevel: ent %s is not a player or NPC\n", self->targetname );
  3412. return;
  3413. }
  3414. if ((forceLevel > self->client->ps.forcePowerLevel[forcePower]) && (entID==0) && (forceLevel > 0))
  3415. {
  3416. if (0)
  3417. {
  3418. if (!cg_updatedDataPadForcePower1.integer)
  3419. {
  3420. missionInfo_Updated = qtrue; // Activate flashing text
  3421. gi.cvar_set("cg_updatedDataPadForcePower1", va("%d",forcePower+1)); // The +1 is offset in the print routine. It ain't pretty, I know.
  3422. cg_updatedDataPadForcePower1.integer = forcePower+1;
  3423. }
  3424. else if (!cg_updatedDataPadForcePower2.integer)
  3425. {
  3426. missionInfo_Updated = qtrue; // Activate flashing text
  3427. gi.cvar_set("cg_updatedDataPadForcePower2", va("%d",forcePower+1)); // The +1 is offset in the print routine. It ain't pretty, I know.
  3428. cg_updatedDataPadForcePower2.integer = forcePower+1;
  3429. }
  3430. else if (!cg_updatedDataPadForcePower3.integer)
  3431. {
  3432. missionInfo_Updated = qtrue; // Activate flashing text
  3433. gi.cvar_set("cg_updatedDataPadForcePower3", va("%d",forcePower+1)); // The +1 is offset in the print routine. It ain't pretty, I know.
  3434. cg_updatedDataPadForcePower3.integer = forcePower+1;
  3435. }
  3436. }
  3437. }
  3438. self->client->ps.forcePowerLevel[forcePower] = forceLevel;
  3439. if ( forceLevel )
  3440. {
  3441. self->client->ps.forcePowersKnown |= ( 1 << forcePower );
  3442. }
  3443. else
  3444. {
  3445. self->client->ps.forcePowersKnown &= ~( 1 << forcePower );
  3446. }
  3447. }
  3448. extern qboolean G_InventorySelectable( int index,gentity_t *other);
  3449. static void Q3_GiveSecurityKey( int entID, char *keyname )
  3450. {
  3451. gentity_t *other = &g_entities[entID];
  3452. int i, original;
  3453. if ( !other )
  3454. {
  3455. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_GiveSecurityKey: invalid entID %d\n", entID);
  3456. return;
  3457. }
  3458. if ( !other->client )
  3459. {
  3460. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_GiveSecurityKey: ent %s is not a player or NPC\n", other->targetname );
  3461. return;
  3462. }
  3463. if ( !keyname || !keyname[0] || !Q_stricmp( "none", keyname ) || !Q_stricmp( "null", keyname ) )
  3464. {//remove the key
  3465. if ( other->message )
  3466. {//remove it
  3467. INV_SecurityKeyTake( other, other->message );
  3468. }
  3469. return;
  3470. }
  3471. other->client->ps.stats[STAT_ITEMS] |= (1<<INV_SECURITY_KEY);
  3472. //give the key
  3473. gi.SendServerCommand( NULL, "cp @SP_INGAME_YOU_TOOK_SECURITY_KEY" );
  3474. INV_SecurityKeyGive( other, keyname );
  3475. // Got a security key
  3476. // Set the inventory select, just in case it hasn't
  3477. original = cg.inventorySelect;
  3478. for ( i = 0 ; i < INV_MAX ; i++ )
  3479. {
  3480. if ((cg.inventorySelect < INV_ELECTROBINOCULARS) || (cg.inventorySelect >= INV_MAX))
  3481. {
  3482. cg.inventorySelect = (INV_MAX - 1);
  3483. }
  3484. if ( G_InventorySelectable( cg.inventorySelect,other ) )
  3485. {
  3486. return;
  3487. }
  3488. cg.inventorySelect++;
  3489. }
  3490. cg.inventorySelect = original;
  3491. }
  3492. /*
  3493. ============
  3494. Q3_SetParm
  3495. Description :
  3496. Return type : void
  3497. Argument : int entID
  3498. Argument : int parmNum
  3499. Argument : const char *parmValue
  3500. ============
  3501. */
  3502. void Q3_SetParm (int entID, int parmNum, const char *parmValue)
  3503. {
  3504. gentity_t *ent = &g_entities[entID];
  3505. float val;
  3506. if ( !ent )
  3507. {
  3508. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetParm: invalid entID %d\n", entID);
  3509. return;
  3510. }
  3511. if ( parmNum < 0 || parmNum >= MAX_PARMS )
  3512. {
  3513. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "SET_PARM: parmNum %d out of range!\n", parmNum );
  3514. return;
  3515. }
  3516. if( !ent->parms )
  3517. {
  3518. ent->parms = (parms_t *)G_Alloc( sizeof(parms_t) );
  3519. memset( ent->parms, 0, sizeof(parms_t) );
  3520. }
  3521. if ( (val = Q3_CheckStringCounterIncrement( parmValue )) )
  3522. {
  3523. val += atof( ent->parms->parm[parmNum] );
  3524. sprintf( ent->parms->parm[parmNum], "%f", val );
  3525. }
  3526. else
  3527. {//Just copy the string
  3528. //copy only 16 characters
  3529. strncpy( ent->parms->parm[parmNum], parmValue, sizeof(ent->parms->parm[0]) );
  3530. //set the last charcter to null in case we had to truncate their passed string
  3531. if ( ent->parms->parm[parmNum][sizeof(ent->parms->parm[0]) - 1] != 0 )
  3532. {//Tried to set a string that is too long
  3533. ent->parms->parm[parmNum][sizeof(ent->parms->parm[0]) - 1] = 0;
  3534. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "SET_PARM: parm%d string too long, truncated to '%s'!\n", parmNum, ent->parms->parm[parmNum] );
  3535. }
  3536. }
  3537. }
  3538. /*
  3539. =============
  3540. Q3_SetCaptureGoal
  3541. Sets the capture spot goal of an entity
  3542. =============
  3543. */
  3544. static void Q3_SetCaptureGoal( int entID, const char *name )
  3545. {
  3546. gentity_t *ent = &g_entities[entID];
  3547. gentity_t *goal = G_Find( NULL, FOFS(targetname), (char *) name);
  3548. if ( !ent )
  3549. {
  3550. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetCaptureGoal: invalid entID %d\n", entID);
  3551. return;
  3552. }
  3553. if ( !ent->NPC )
  3554. {
  3555. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetCaptureGoal: '%s' is not an NPC!\n", ent->targetname );
  3556. return;
  3557. }
  3558. //FIXME: Exception handle here
  3559. if (goal == NULL)
  3560. {
  3561. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetCaptureGoal: can't find CaptureGoal target: '%s'\n", name );
  3562. return;
  3563. }
  3564. if(ent->NPC)
  3565. {
  3566. ent->NPC->captureGoal = goal;
  3567. ent->NPC->goalEntity = goal;
  3568. ent->NPC->goalTime = level.time + 100000;
  3569. }
  3570. }
  3571. /*
  3572. =============
  3573. Q3_SetEvent
  3574. ?
  3575. =============
  3576. */
  3577. static void Q3_SetEvent( int entID, const char *event_name )
  3578. {
  3579. gentity_t *ent = &g_entities[entID];
  3580. // gentity_t *tent = NULL;
  3581. int event;
  3582. // vec3_t spot;
  3583. if ( !ent )
  3584. {
  3585. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetEvent: invalid entID %d\n", entID);
  3586. return;
  3587. }
  3588. event = GetIDForString( eventTable, event_name );
  3589. switch( event )
  3590. {
  3591. /*
  3592. case EV_DISINTEGRATE:
  3593. if( VectorCompare( ent->currentOrigin, vec3_origin ) )
  3594. {//Brush with no origin
  3595. VectorSubtract( ent->absmax, ent->absmin, spot );
  3596. VectorMA( ent->absmin, 0.5, spot, spot );
  3597. }
  3598. else
  3599. {
  3600. VectorCopy( ent->currentOrigin, spot );
  3601. spot[2] += ent->maxs[2]/2;
  3602. }
  3603. tent = G_TempEntity( spot, EV_DISINTEGRATION );
  3604. tent->s.eventParm = PW_REGEN;
  3605. tent->owner = ent;
  3606. break;
  3607. */
  3608. case EV_BAD:
  3609. default:
  3610. //Quake3Game()->DebugPrint( IGameInterface::WL_ERROR,"Q3_SetEvent: Invalid Event %d\n", event );
  3611. return;
  3612. break;
  3613. }
  3614. }
  3615. /*
  3616. ============
  3617. Q3_Use
  3618. Uses an entity
  3619. ============
  3620. */
  3621. /*static void Q3_Use( int entID, const char *target )
  3622. {
  3623. gentity_t *ent = &g_entities[entID];
  3624. if ( !ent )
  3625. {
  3626. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_Use: invalid entID %d\n", entID);
  3627. return;
  3628. }
  3629. if( !target || !target[0] )
  3630. {
  3631. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_Use: string is NULL!\n" );
  3632. return;
  3633. }
  3634. G_UseTargets2(ent, ent, target);
  3635. }*/
  3636. /*
  3637. ============
  3638. Q3_SetBehaviorSet
  3639. ?
  3640. ============
  3641. */
  3642. static qboolean Q3_SetBehaviorSet( int entID, int toSet, const char *scriptname)
  3643. {
  3644. gentity_t *ent = &g_entities[entID];
  3645. bSet_t bSet = BSET_INVALID;
  3646. if ( !ent )
  3647. {
  3648. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetBehaviorSet: invalid entID %d\n", entID);
  3649. return qfalse;
  3650. }
  3651. switch(toSet)
  3652. {
  3653. case SET_SPAWNSCRIPT:
  3654. bSet = BSET_SPAWN;
  3655. break;
  3656. case SET_USESCRIPT:
  3657. bSet = BSET_USE;
  3658. break;
  3659. case SET_AWAKESCRIPT:
  3660. bSet = BSET_AWAKE;
  3661. break;
  3662. case SET_ANGERSCRIPT:
  3663. bSet = BSET_ANGER;
  3664. break;
  3665. case SET_ATTACKSCRIPT:
  3666. bSet = BSET_ATTACK;
  3667. break;
  3668. case SET_VICTORYSCRIPT:
  3669. bSet = BSET_VICTORY;
  3670. break;
  3671. case SET_LOSTENEMYSCRIPT:
  3672. bSet = BSET_LOSTENEMY;
  3673. break;
  3674. case SET_PAINSCRIPT:
  3675. bSet = BSET_PAIN;
  3676. break;
  3677. case SET_FLEESCRIPT:
  3678. bSet = BSET_FLEE;
  3679. break;
  3680. case SET_DEATHSCRIPT:
  3681. bSet = BSET_DEATH;
  3682. break;
  3683. case SET_DELAYEDSCRIPT:
  3684. bSet = BSET_DELAYED;
  3685. break;
  3686. case SET_BLOCKEDSCRIPT:
  3687. bSet = BSET_BLOCKED;
  3688. break;
  3689. case SET_FFIRESCRIPT:
  3690. bSet = BSET_FFIRE;
  3691. break;
  3692. case SET_FFDEATHSCRIPT:
  3693. bSet = BSET_FFDEATH;
  3694. break;
  3695. case SET_MINDTRICKSCRIPT:
  3696. bSet = BSET_MINDTRICK;
  3697. break;
  3698. }
  3699. if(bSet < BSET_SPAWN || bSet >= NUM_BSETS)
  3700. {
  3701. return qfalse;
  3702. }
  3703. if(!Q_stricmp("NULL", scriptname))
  3704. {
  3705. if ( ent->behaviorSet[bSet] != NULL )
  3706. {
  3707. // gi.TagFree( ent->behaviorSet[bSet] );
  3708. }
  3709. ent->behaviorSet[bSet] = NULL;
  3710. //memset( &ent->behaviorSet[bSet], 0, sizeof(ent->behaviorSet[bSet]) );
  3711. }
  3712. else
  3713. {
  3714. if ( scriptname )
  3715. {
  3716. if ( ent->behaviorSet[bSet] != NULL )
  3717. {
  3718. // gi.TagFree( ent->behaviorSet[bSet] );
  3719. }
  3720. ent->behaviorSet[bSet] = G_NewString( (char *) scriptname ); //FIXME: This really isn't good...
  3721. }
  3722. //ent->behaviorSet[bSet] = scriptname;
  3723. //strncpy( (char *) &ent->behaviorSet[bSet], scriptname, MAX_BSET_LENGTH );
  3724. }
  3725. return qtrue;
  3726. }
  3727. /*
  3728. ============
  3729. Q3_SetDelayScriptTime
  3730. ?
  3731. ============
  3732. */
  3733. static void Q3_SetDelayScriptTime(int entID, int delayTime)
  3734. {
  3735. gentity_t *ent = &g_entities[entID];
  3736. if ( !ent )
  3737. {
  3738. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDelayScriptTime: invalid entID %d\n", entID);
  3739. return;
  3740. }
  3741. ent->delayScriptTime = level.time + delayTime;
  3742. }
  3743. /*
  3744. ============
  3745. Q3_SetIgnorePain
  3746. ?
  3747. ============
  3748. */
  3749. static void Q3_SetIgnorePain( int entID, qboolean data)
  3750. {
  3751. gentity_t *ent = &g_entities[entID];
  3752. if ( !ent )
  3753. {
  3754. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetIgnorePain: invalid entID %d\n", entID);
  3755. return;
  3756. }
  3757. if ( !ent->NPC )
  3758. {
  3759. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetIgnorePain: '%s' is not an NPC!\n", ent->targetname );
  3760. return;
  3761. }
  3762. ent->NPC->ignorePain = data;
  3763. }
  3764. /*
  3765. ============
  3766. Q3_SetIgnoreEnemies
  3767. ?
  3768. ============
  3769. */
  3770. static void Q3_SetIgnoreEnemies( int entID, qboolean data)
  3771. {
  3772. gentity_t *ent = &g_entities[entID];
  3773. if ( !ent )
  3774. {
  3775. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetIgnoreEnemies: invalid entID %d\n", entID);
  3776. return;
  3777. }
  3778. if ( !ent->NPC )
  3779. {
  3780. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetIgnoreEnemies: '%s' is not an NPC!\n", ent->targetname );
  3781. return;
  3782. }
  3783. if(data)
  3784. {
  3785. ent->svFlags |= SVF_IGNORE_ENEMIES;
  3786. }
  3787. else
  3788. {
  3789. ent->svFlags &= ~SVF_IGNORE_ENEMIES;
  3790. }
  3791. }
  3792. /*
  3793. ============
  3794. Q3_SetIgnoreAlerts
  3795. ?
  3796. ============
  3797. */
  3798. static void Q3_SetIgnoreAlerts( int entID, qboolean data)
  3799. {
  3800. gentity_t *ent = &g_entities[entID];
  3801. if ( !ent )
  3802. {
  3803. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetIgnoreAlerts: invalid entID %d\n", entID);
  3804. return;
  3805. }
  3806. if ( !ent->NPC )
  3807. {
  3808. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetIgnoreAlerts: '%s' is not an NPC!\n", ent->targetname );
  3809. return;
  3810. }
  3811. if(data)
  3812. {
  3813. ent->NPC->scriptFlags |= SCF_IGNORE_ALERTS;
  3814. }
  3815. else
  3816. {
  3817. ent->NPC->scriptFlags &= ~SCF_IGNORE_ALERTS;
  3818. }
  3819. }
  3820. /*
  3821. ============
  3822. Q3_SetNoTarget
  3823. ?
  3824. ============
  3825. */
  3826. static void Q3_SetNoTarget( int entID, qboolean data)
  3827. {
  3828. gentity_t *ent = &g_entities[entID];
  3829. if ( !ent )
  3830. {
  3831. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoTarget: invalid entID %d\n", entID);
  3832. return;
  3833. }
  3834. if(data)
  3835. ent->flags |= FL_NOTARGET;
  3836. else
  3837. ent->flags &= ~FL_NOTARGET;
  3838. }
  3839. /*
  3840. ============
  3841. Q3_SetDontShoot
  3842. ?
  3843. ============
  3844. */
  3845. static void Q3_SetDontShoot( int entID, qboolean add)
  3846. {
  3847. gentity_t *ent = &g_entities[entID];
  3848. if ( !ent )
  3849. {
  3850. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDontShoot: invalid entID %d\n", entID);
  3851. return;
  3852. }
  3853. if(add)
  3854. {
  3855. ent->flags |= FL_DONT_SHOOT;
  3856. }
  3857. else
  3858. {
  3859. ent->flags &= ~FL_DONT_SHOOT;
  3860. }
  3861. }
  3862. /*
  3863. ============
  3864. Q3_SetDontFire
  3865. ?
  3866. ============
  3867. */
  3868. static void Q3_SetDontFire( int entID, qboolean add)
  3869. {
  3870. gentity_t *ent = &g_entities[entID];
  3871. if ( !ent )
  3872. {
  3873. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDontFire: invalid entID %d\n", entID);
  3874. return;
  3875. }
  3876. if ( !ent->NPC )
  3877. {
  3878. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetDontFire: '%s' is not an NPC!\n", ent->targetname );
  3879. return;
  3880. }
  3881. if(add)
  3882. {
  3883. ent->NPC->scriptFlags |= SCF_DONT_FIRE;
  3884. }
  3885. else
  3886. {
  3887. ent->NPC->scriptFlags &= ~SCF_DONT_FIRE;
  3888. }
  3889. }
  3890. /*
  3891. ============
  3892. Q3_SetFireWeapon
  3893. ?
  3894. ============
  3895. */
  3896. static void Q3_SetFireWeapon(int entID, qboolean add)
  3897. {
  3898. gentity_t *ent = &g_entities[entID];
  3899. if ( !ent )
  3900. {
  3901. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_FireWeapon: invalid entID %d\n", entID);
  3902. return;
  3903. }
  3904. if ( !ent->NPC )
  3905. {
  3906. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetFireWeapon: '%s' is not an NPC!\n", ent->targetname );
  3907. return;
  3908. }
  3909. if(add)
  3910. {
  3911. ent->NPC->scriptFlags |= SCF_FIRE_WEAPON;
  3912. }
  3913. else
  3914. {
  3915. ent->NPC->scriptFlags &= ~SCF_FIRE_WEAPON;
  3916. }
  3917. }
  3918. /*
  3919. ============
  3920. Q3_SetFireWeaponNoAnim
  3921. ?
  3922. ============
  3923. */
  3924. static void Q3_SetFireWeaponNoAnim(int entID, qboolean add)
  3925. {
  3926. gentity_t *ent = &g_entities[entID];
  3927. if ( !ent )
  3928. {
  3929. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_FireWeaponNoAnim: invalid entID %d\n", entID);
  3930. return;
  3931. }
  3932. if ( !ent->NPC )
  3933. {
  3934. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetFireWeaponNoAnim: '%s' is not an NPC!\n", ent->targetname );
  3935. return;
  3936. }
  3937. if(add)
  3938. {
  3939. ent->NPC->scriptFlags |= SCF_FIRE_WEAPON_NO_ANIM;
  3940. }
  3941. else
  3942. {
  3943. ent->NPC->scriptFlags &= ~SCF_FIRE_WEAPON_NO_ANIM;
  3944. }
  3945. }
  3946. /*
  3947. ============
  3948. Q3_SetSafeRemove
  3949. If true, NPC will remove itself once player is not in PVS
  3950. ============
  3951. */
  3952. static void Q3_SetSafeRemove(int entID, qboolean add)
  3953. {
  3954. gentity_t *ent = &g_entities[entID];
  3955. if ( !ent )
  3956. {
  3957. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetSafeRemove: invalid entID %d\n", entID);
  3958. return;
  3959. }
  3960. if ( !ent->NPC )
  3961. {
  3962. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetSafeRemove: '%s' is not an NPC!\n", ent->targetname );
  3963. return;
  3964. }
  3965. if(add)
  3966. {
  3967. ent->NPC->scriptFlags |= SCF_SAFE_REMOVE;
  3968. }
  3969. else
  3970. {
  3971. ent->NPC->scriptFlags &= ~SCF_SAFE_REMOVE;
  3972. }
  3973. }
  3974. /*
  3975. ============
  3976. Q3_SetBobaJetPack
  3977. Turn on/off Boba's jet pack
  3978. ============
  3979. */
  3980. static void Q3_SetBobaJetPack(int entID, qboolean add)
  3981. {
  3982. gentity_t *ent = &g_entities[entID];
  3983. if ( !ent )
  3984. {
  3985. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetBobaJetPack: invalid entID %d\n", entID);
  3986. return;
  3987. }
  3988. if ( !ent->NPC )
  3989. {
  3990. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetBobaJetPack: '%s' is not an NPC!\n", ent->targetname );
  3991. return;
  3992. }
  3993. // make sure we this is Boba Fett
  3994. if ( ent->client && ent->client->NPC_class != CLASS_BOBAFETT )
  3995. {
  3996. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetBobaJetPack: '%s' is not Boba Fett!\n", ent->targetname );
  3997. return;
  3998. }
  3999. if(add)
  4000. {
  4001. if ( ent->genericBolt1 != -1 )
  4002. {
  4003. G_PlayEffect( G_EffectIndex( "boba/jetSP" ), ent->playerModel, ent->genericBolt1, ent->s.number, ent->currentOrigin, qtrue, qtrue );
  4004. }
  4005. if ( ent->genericBolt2 != -1 )
  4006. {
  4007. G_PlayEffect( G_EffectIndex( "boba/jetSP" ), ent->playerModel, ent->genericBolt2, ent->s.number, ent->currentOrigin, qtrue, qtrue );
  4008. }
  4009. //take-off sound
  4010. G_SoundOnEnt( ent, CHAN_ITEM, "sound/chars/boba/bf_blast-off.wav" );
  4011. //jet loop sound
  4012. ent->s.loopSound = G_SoundIndex( "sound/chars/boba/bf_jetpack_lp.wav" );
  4013. }
  4014. else
  4015. {
  4016. if ( ent->genericBolt1 != -1 )
  4017. {
  4018. G_StopEffect( "boba/jetSP", ent->playerModel, ent->genericBolt1, ent->s.number );
  4019. }
  4020. if ( ent->genericBolt2 != -1 )
  4021. {
  4022. G_StopEffect( "boba/jetSP", ent->playerModel, ent->genericBolt2, ent->s.number );
  4023. }
  4024. //stop jet loop sound
  4025. ent->s.loopSound = 0;
  4026. G_SoundOnEnt( ent, CHAN_ITEM, "sound/chars/boba/bf_land.wav" );
  4027. }
  4028. }
  4029. /*
  4030. ============
  4031. Q3_SetInactive
  4032. ?
  4033. ============
  4034. */
  4035. static void Q3_SetInactive(int entID, qboolean add)
  4036. {
  4037. gentity_t *ent = &g_entities[entID];
  4038. if ( !ent )
  4039. {
  4040. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetInactive: invalid entID %d\n", entID);
  4041. return;
  4042. }
  4043. if(add)
  4044. {
  4045. ent->svFlags |= SVF_INACTIVE;
  4046. }
  4047. else
  4048. {
  4049. ent->svFlags &= ~SVF_INACTIVE;
  4050. }
  4051. }
  4052. /*
  4053. ============
  4054. Q3_SetFuncUsableVisible
  4055. ?
  4056. ============
  4057. */
  4058. static void Q3_SetFuncUsableVisible(int entID, qboolean visible )
  4059. {
  4060. gentity_t *ent = &g_entities[entID];
  4061. if ( !ent )
  4062. {
  4063. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetFuncUsableVisible: invalid entID %d\n", entID);
  4064. return;
  4065. }
  4066. // Yeah, I know that this doesn't even do half of what the func_usable use code does, but if I've got two things on top of each other...and only
  4067. // one is visible at a time....and neither can ever be used......and finally, the shader on it has the shader_anim stuff going on....It doesn't seem
  4068. // like I can easily use the other version without nasty side effects.
  4069. if( visible )
  4070. {
  4071. ent->svFlags &= ~SVF_NOCLIENT;
  4072. ent->s.eFlags &= ~EF_NODRAW;
  4073. }
  4074. else
  4075. {
  4076. ent->svFlags |= SVF_NOCLIENT;
  4077. ent->s.eFlags |= EF_NODRAW;
  4078. }
  4079. }
  4080. /*
  4081. ============
  4082. Q3_SetLockedEnemy
  4083. ?
  4084. ============
  4085. */
  4086. static void Q3_SetLockedEnemy ( int entID, qboolean locked)
  4087. {
  4088. gentity_t *ent = &g_entities[entID];
  4089. if ( !ent )
  4090. {
  4091. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLockedEnemy: invalid entID %d\n", entID);
  4092. return;
  4093. }
  4094. if ( !ent->NPC )
  4095. {
  4096. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetLockedEnemy: '%s' is not an NPC!\n", ent->targetname );
  4097. return;
  4098. }
  4099. //FIXME: make an NPCAI_FLAG
  4100. if(locked)
  4101. {
  4102. ent->svFlags |= SVF_LOCKEDENEMY;
  4103. }
  4104. else
  4105. {
  4106. ent->svFlags &= ~SVF_LOCKEDENEMY;
  4107. }
  4108. }
  4109. char cinematicSkipScript[64];
  4110. /*
  4111. ============
  4112. Q3_SetCinematicSkipScript
  4113. ============
  4114. */
  4115. static void Q3_SetCinematicSkipScript( char *scriptname )
  4116. {
  4117. if(Q_stricmp("none", scriptname) == 0 || Q_stricmp("NULL", scriptname) == 0)
  4118. {
  4119. cinematicSkipScript[0] = 0;
  4120. }
  4121. else
  4122. {
  4123. Q_strncpyz(cinematicSkipScript,scriptname,sizeof(cinematicSkipScript));
  4124. }
  4125. }
  4126. /*
  4127. ============
  4128. Q3_SetNoMindTrick
  4129. ?
  4130. ============
  4131. */
  4132. static void Q3_SetNoMindTrick( int entID, qboolean add)
  4133. {
  4134. gentity_t *ent = &g_entities[entID];
  4135. if ( !ent )
  4136. {
  4137. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoMindTrick: invalid entID %d\n", entID);
  4138. return;
  4139. }
  4140. if ( !ent->NPC )
  4141. {
  4142. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNoMindTrick: '%s' is not an NPC!\n", ent->targetname );
  4143. return;
  4144. }
  4145. if(add)
  4146. {
  4147. ent->NPC->scriptFlags |= SCF_NO_MIND_TRICK;
  4148. ent->NPC->confusionTime = 0;
  4149. if ( ent->ghoul2.size() && ent->headBolt != -1 )
  4150. {
  4151. G_StopEffect("force/confusion", ent->playerModel, ent->headBolt, ent->s.number );
  4152. }
  4153. }
  4154. else
  4155. {
  4156. ent->NPC->scriptFlags &= ~SCF_NO_MIND_TRICK;
  4157. }
  4158. }
  4159. /*
  4160. ============
  4161. Q3_SetCrouched
  4162. ?
  4163. ============
  4164. */
  4165. static void Q3_SetCrouched( int entID, qboolean add)
  4166. {
  4167. gentity_t *ent = &g_entities[entID];
  4168. if ( !ent )
  4169. {
  4170. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetCrouched: invalid entID %d\n", entID);
  4171. return;
  4172. }
  4173. if ( !ent->NPC )
  4174. {
  4175. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetCrouched: '%s' is not an NPC!\n", ent->targetname );
  4176. return;
  4177. }
  4178. if(add)
  4179. {
  4180. ent->NPC->scriptFlags |= SCF_CROUCHED;
  4181. }
  4182. else
  4183. {
  4184. ent->NPC->scriptFlags &= ~SCF_CROUCHED;
  4185. }
  4186. }
  4187. /*
  4188. ============
  4189. Q3_SetWalking
  4190. ?
  4191. ============
  4192. */
  4193. static void Q3_SetWalking( int entID, qboolean add)
  4194. {
  4195. gentity_t *ent = &g_entities[entID];
  4196. if ( !ent )
  4197. {
  4198. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetWalking: invalid entID %d\n", entID);
  4199. return;
  4200. }
  4201. if ( !ent->NPC )
  4202. {
  4203. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetWalking: '%s' is not an NPC!\n", ent->targetname );
  4204. return;
  4205. }
  4206. if(add)
  4207. {
  4208. ent->NPC->scriptFlags |= SCF_WALKING;
  4209. }
  4210. else
  4211. {
  4212. ent->NPC->scriptFlags &= ~SCF_WALKING;
  4213. }
  4214. }
  4215. /*
  4216. ============
  4217. Q3_SetRunning
  4218. ?
  4219. ============
  4220. */
  4221. static void Q3_SetRunning( int entID, qboolean add)
  4222. {
  4223. gentity_t *ent = &g_entities[entID];
  4224. if ( !ent )
  4225. {
  4226. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRunning: invalid entID %d\n", entID);
  4227. return;
  4228. }
  4229. if ( !ent->NPC )
  4230. {
  4231. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetRunning: '%s' is not an NPC!\n", ent->targetname );
  4232. return;
  4233. }
  4234. if(add)
  4235. {
  4236. ent->NPC->scriptFlags |= SCF_RUNNING;
  4237. }
  4238. else
  4239. {
  4240. ent->NPC->scriptFlags &= ~SCF_RUNNING;
  4241. }
  4242. }
  4243. /*
  4244. ============
  4245. Q3_SetForcedMarch
  4246. ?
  4247. ============
  4248. */
  4249. static void Q3_SetForcedMarch( int entID, qboolean add)
  4250. {
  4251. gentity_t *ent = &g_entities[entID];
  4252. if ( !ent )
  4253. {
  4254. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetForcedMarch: invalid entID %d\n", entID);
  4255. return;
  4256. }
  4257. if ( !ent->NPC )
  4258. {
  4259. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetForcedMarch: '%s' is not an NPC!\n", ent->targetname );
  4260. return;
  4261. }
  4262. if(add)
  4263. {
  4264. ent->NPC->scriptFlags |= SCF_FORCED_MARCH;
  4265. }
  4266. else
  4267. {
  4268. ent->NPC->scriptFlags &= ~SCF_FORCED_MARCH;
  4269. }
  4270. }
  4271. /*
  4272. ============
  4273. Q3_SetChaseEnemies
  4274. indicates whether the npc should chase after an enemy
  4275. ============
  4276. */
  4277. static void Q3_SetChaseEnemies( int entID, qboolean add)
  4278. {
  4279. gentity_t *ent = &g_entities[entID];
  4280. if ( !ent )
  4281. {
  4282. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetChaseEnemies: invalid entID %d\n", entID);
  4283. return;
  4284. }
  4285. if ( !ent->NPC )
  4286. {
  4287. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetChaseEnemies: '%s' is not an NPC!\n", ent->targetname );
  4288. return;
  4289. }
  4290. if(add)
  4291. {
  4292. ent->NPC->scriptFlags |= SCF_CHASE_ENEMIES;
  4293. }
  4294. else
  4295. {
  4296. ent->NPC->scriptFlags &= ~SCF_CHASE_ENEMIES;
  4297. }
  4298. }
  4299. /*
  4300. ============
  4301. Q3_SetLookForEnemies
  4302. if set npc will be on the look out for potential enemies
  4303. if not set, npc will ignore enemies
  4304. ============
  4305. */
  4306. static void Q3_SetLookForEnemies( int entID, qboolean add)
  4307. {
  4308. gentity_t *ent = &g_entities[entID];
  4309. if ( !ent )
  4310. {
  4311. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLookForEnemies: invalid entID %d\n", entID);
  4312. return;
  4313. }
  4314. if ( !ent->NPC )
  4315. {
  4316. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetLookForEnemies: '%s' is not an NPC!\n", ent->targetname );
  4317. return;
  4318. }
  4319. if(add)
  4320. {
  4321. ent->NPC->scriptFlags |= SCF_LOOK_FOR_ENEMIES;
  4322. }
  4323. else
  4324. {
  4325. ent->NPC->scriptFlags &= ~SCF_LOOK_FOR_ENEMIES;
  4326. }
  4327. }
  4328. /*
  4329. ============
  4330. Q3_SetFaceMoveDir
  4331. ============
  4332. */
  4333. static void Q3_SetFaceMoveDir( int entID, qboolean add)
  4334. {
  4335. gentity_t *ent = &g_entities[entID];
  4336. if ( !ent )
  4337. {
  4338. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetFaceMoveDir: invalid entID %d\n", entID);
  4339. return;
  4340. }
  4341. if ( !ent->NPC )
  4342. {
  4343. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetFaceMoveDir: '%s' is not an NPC!\n", ent->targetname );
  4344. return;
  4345. }
  4346. if(add)
  4347. {
  4348. ent->NPC->scriptFlags |= SCF_FACE_MOVE_DIR;
  4349. }
  4350. else
  4351. {
  4352. ent->NPC->scriptFlags &= ~SCF_FACE_MOVE_DIR;
  4353. }
  4354. }
  4355. /*
  4356. ============
  4357. Q3_SetAltFire
  4358. ?
  4359. ============
  4360. */
  4361. static void Q3_SetAltFire( int entID, qboolean add)
  4362. {
  4363. gentity_t *ent = &g_entities[entID];
  4364. if ( !ent )
  4365. {
  4366. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAltFire: invalid entID %d\n", entID);
  4367. return;
  4368. }
  4369. if ( !ent->NPC )
  4370. {
  4371. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetAltFire: '%s' is not an NPC!\n", ent->targetname );
  4372. return;
  4373. }
  4374. if(add)
  4375. {
  4376. ent->NPC->scriptFlags |= SCF_ALT_FIRE;
  4377. }
  4378. else
  4379. {
  4380. ent->NPC->scriptFlags &= ~SCF_ALT_FIRE;
  4381. }
  4382. ChangeWeapon( ent, ent->client->ps.weapon );
  4383. }
  4384. /*
  4385. ============
  4386. Q3_SetDontFlee
  4387. ?
  4388. ============
  4389. */
  4390. static void Q3_SetDontFlee( int entID, qboolean add)
  4391. {
  4392. gentity_t *ent = &g_entities[entID];
  4393. if ( !ent )
  4394. {
  4395. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDontFlee: invalid entID %d\n", entID);
  4396. return;
  4397. }
  4398. if ( !ent->NPC )
  4399. {
  4400. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetDontFlee: '%s' is not an NPC!\n", ent->targetname );
  4401. return;
  4402. }
  4403. if(add)
  4404. {
  4405. ent->NPC->scriptFlags |= SCF_DONT_FLEE;
  4406. }
  4407. else
  4408. {
  4409. ent->NPC->scriptFlags &= ~SCF_DONT_FLEE;
  4410. }
  4411. }
  4412. /*
  4413. ============
  4414. Q3_SetNoResponse
  4415. ?
  4416. ============
  4417. */
  4418. static void Q3_SetNoResponse( int entID, qboolean add)
  4419. {
  4420. gentity_t *ent = &g_entities[entID];
  4421. if ( !ent )
  4422. {
  4423. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoResponse: invalid entID %d\n", entID);
  4424. return;
  4425. }
  4426. if ( !ent->NPC )
  4427. {
  4428. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNoResponse: '%s' is not an NPC!\n", ent->targetname );
  4429. return;
  4430. }
  4431. if(add)
  4432. {
  4433. ent->NPC->scriptFlags |= SCF_NO_RESPONSE;
  4434. }
  4435. else
  4436. {
  4437. ent->NPC->scriptFlags &= ~SCF_NO_RESPONSE;
  4438. }
  4439. }
  4440. /*
  4441. ============
  4442. Q3_SetCombatTalk
  4443. ?
  4444. ============
  4445. */
  4446. static void Q3_SetCombatTalk( int entID, qboolean add)
  4447. {
  4448. gentity_t *ent = &g_entities[entID];
  4449. if ( !ent )
  4450. {
  4451. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetCombatTalk: invalid entID %d\n", entID);
  4452. return;
  4453. }
  4454. if ( !ent->NPC )
  4455. {
  4456. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetCombatTalk: '%s' is not an NPC!\n", ent->targetname );
  4457. return;
  4458. }
  4459. if ( add )
  4460. {
  4461. ent->NPC->scriptFlags |= SCF_NO_COMBAT_TALK;
  4462. }
  4463. else
  4464. {
  4465. ent->NPC->scriptFlags &= ~SCF_NO_COMBAT_TALK;
  4466. }
  4467. }
  4468. /*
  4469. ============
  4470. Q3_SetAlertTalk
  4471. ?
  4472. ============
  4473. */
  4474. static void Q3_SetAlertTalk( int entID, qboolean add)
  4475. {
  4476. gentity_t *ent = &g_entities[entID];
  4477. if ( !ent )
  4478. {
  4479. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAlertTalk: invalid entID %d\n", entID);
  4480. return;
  4481. }
  4482. if ( !ent->NPC )
  4483. {
  4484. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetAlertTalk: '%s' is not an NPC!\n", ent->targetname );
  4485. return;
  4486. }
  4487. if ( add )
  4488. {
  4489. ent->NPC->scriptFlags |= SCF_NO_ALERT_TALK;
  4490. }
  4491. else
  4492. {
  4493. ent->NPC->scriptFlags &= ~SCF_NO_ALERT_TALK;
  4494. }
  4495. }
  4496. /*
  4497. ============
  4498. Q3_SetUseCpNearest
  4499. ?
  4500. ============
  4501. */
  4502. static void Q3_SetUseCpNearest( int entID, qboolean add)
  4503. {
  4504. gentity_t *ent = &g_entities[entID];
  4505. if ( !ent )
  4506. {
  4507. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetUseCpNearest: invalid entID %d\n", entID);
  4508. return;
  4509. }
  4510. if ( !ent->NPC )
  4511. {
  4512. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetUseCpNearest: '%s' is not an NPC!\n", ent->targetname );
  4513. return;
  4514. }
  4515. if ( add )
  4516. {
  4517. ent->NPC->scriptFlags |= SCF_USE_CP_NEAREST;
  4518. }
  4519. else
  4520. {
  4521. ent->NPC->scriptFlags &= ~SCF_USE_CP_NEAREST;
  4522. }
  4523. }
  4524. /*
  4525. ============
  4526. Q3_SetNoForce
  4527. ?
  4528. ============
  4529. */
  4530. static void Q3_SetNoForce( int entID, qboolean add)
  4531. {
  4532. gentity_t *ent = &g_entities[entID];
  4533. if ( !ent )
  4534. {
  4535. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoForce: invalid entID %d\n", entID);
  4536. return;
  4537. }
  4538. if ( !ent->NPC )
  4539. {
  4540. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNoForce: '%s' is not an NPC!\n", ent->targetname );
  4541. return;
  4542. }
  4543. if ( add )
  4544. {
  4545. ent->NPC->scriptFlags |= SCF_NO_FORCE;
  4546. }
  4547. else
  4548. {
  4549. ent->NPC->scriptFlags &= ~SCF_NO_FORCE;
  4550. }
  4551. }
  4552. /*
  4553. ============
  4554. Q3_SetNoAcrobatics
  4555. ?
  4556. ============
  4557. */
  4558. static void Q3_SetNoAcrobatics( int entID, qboolean add)
  4559. {
  4560. gentity_t *ent = &g_entities[entID];
  4561. if ( !ent )
  4562. {
  4563. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoAcrobatics: invalid entID %d\n", entID);
  4564. return;
  4565. }
  4566. if ( !ent->NPC )
  4567. {
  4568. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNoAcrobatics: '%s' is not an NPC!\n", ent->targetname );
  4569. return;
  4570. }
  4571. if ( add )
  4572. {
  4573. ent->NPC->scriptFlags |= SCF_NO_ACROBATICS;
  4574. }
  4575. else
  4576. {
  4577. ent->NPC->scriptFlags &= ~SCF_NO_ACROBATICS;
  4578. }
  4579. }
  4580. /*
  4581. ============
  4582. Q3_SetUseSubtitles
  4583. ?
  4584. ============
  4585. */
  4586. static void Q3_SetUseSubtitles( int entID, qboolean add)
  4587. {
  4588. gentity_t *ent = &g_entities[entID];
  4589. if ( !ent )
  4590. {
  4591. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetUseSubtitles: invalid entID %d\n", entID);
  4592. return;
  4593. }
  4594. if ( !ent->NPC )
  4595. {
  4596. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetUseSubtitles: '%s' is not an NPC!\n", ent->targetname );
  4597. return;
  4598. }
  4599. if ( add )
  4600. {
  4601. ent->NPC->scriptFlags |= SCF_USE_SUBTITLES;
  4602. }
  4603. else
  4604. {
  4605. ent->NPC->scriptFlags &= ~SCF_USE_SUBTITLES;
  4606. }
  4607. }
  4608. /*
  4609. ============
  4610. Q3_SetNoFallToDeath
  4611. ?
  4612. ============
  4613. */
  4614. static void Q3_SetNoFallToDeath( int entID, qboolean add)
  4615. {
  4616. gentity_t *ent = &g_entities[entID];
  4617. if ( !ent )
  4618. {
  4619. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoFallToDeath: invalid entID %d\n", entID);
  4620. return;
  4621. }
  4622. if ( !ent->NPC )
  4623. {
  4624. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNoFallToDeath: '%s' is not an NPC!\n", ent->targetname );
  4625. return;
  4626. }
  4627. if ( add )
  4628. {
  4629. ent->NPC->scriptFlags |= SCF_NO_FALLTODEATH;
  4630. }
  4631. else
  4632. {
  4633. ent->NPC->scriptFlags &= ~SCF_NO_FALLTODEATH;
  4634. }
  4635. }
  4636. /*
  4637. ============
  4638. Q3_SetDismemberable
  4639. ?
  4640. ============
  4641. */
  4642. static void Q3_SetDismemberable( int entID, qboolean dismemberable)
  4643. {
  4644. gentity_t *ent = &g_entities[entID];
  4645. if ( !ent )
  4646. {
  4647. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDismemberable: invalid entID %d\n", entID);
  4648. return;
  4649. }
  4650. if ( !ent->client )
  4651. {
  4652. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetDismemberable: '%s' is not an client!\n", ent->targetname );
  4653. return;
  4654. }
  4655. ent->client->dismembered = !dismemberable;
  4656. }
  4657. /*
  4658. ============
  4659. Q3_SetMoreLight
  4660. ?
  4661. ============
  4662. */
  4663. static void Q3_SetMoreLight( int entID, qboolean add )
  4664. {
  4665. gentity_t *ent = &g_entities[entID];
  4666. if ( !ent )
  4667. {
  4668. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetMoreLight: invalid entID %d\n", entID);
  4669. return;
  4670. }
  4671. if ( !ent->NPC )
  4672. {
  4673. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetMoreLight: '%s' is not an NPC!\n", ent->targetname );
  4674. return;
  4675. }
  4676. if ( add )
  4677. {
  4678. ent->NPC->scriptFlags |= SCF_MORELIGHT;
  4679. }
  4680. else
  4681. {
  4682. ent->NPC->scriptFlags &= ~SCF_MORELIGHT;
  4683. }
  4684. }
  4685. /*
  4686. ============
  4687. Q3_SetUndying
  4688. ?
  4689. ============
  4690. */
  4691. static void Q3_SetUndying( int entID, qboolean undying)
  4692. {
  4693. gentity_t *ent = &g_entities[entID];
  4694. if ( !ent )
  4695. {
  4696. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetUndying: invalid entID %d\n", entID);
  4697. return;
  4698. }
  4699. if(undying)
  4700. {
  4701. ent->flags |= FL_UNDYING;
  4702. }
  4703. else
  4704. {
  4705. ent->flags &= ~FL_UNDYING;
  4706. }
  4707. }
  4708. /*
  4709. ============
  4710. Q3_SetInvincible
  4711. ?
  4712. ============
  4713. */
  4714. static void Q3_SetInvincible( int entID, qboolean invincible)
  4715. {
  4716. gentity_t *ent = &g_entities[entID];
  4717. if ( !ent )
  4718. {
  4719. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetInvincible: invalid entID %d\n", entID);
  4720. return;
  4721. }
  4722. if ( !Q_stricmp( "func_breakable", ent->classname ) )
  4723. {
  4724. if ( invincible )
  4725. {
  4726. ent->spawnflags |= 1;
  4727. }
  4728. else
  4729. {
  4730. ent->spawnflags &= ~1;
  4731. }
  4732. return;
  4733. }
  4734. if ( invincible )
  4735. {
  4736. ent->flags |= FL_GODMODE;
  4737. }
  4738. else
  4739. {
  4740. ent->flags &= ~FL_GODMODE;
  4741. }
  4742. }
  4743. /*
  4744. ============
  4745. Q3_SetForceInvincible
  4746. Description :
  4747. Return type : static void
  4748. Argument : int entID
  4749. Argument : qboolean forceInv
  4750. ============
  4751. */
  4752. static void Q3_SetForceInvincible( int entID, qboolean forceInv )
  4753. {
  4754. gentity_t *self = &g_entities[entID];
  4755. if ( !self || !self->client )
  4756. {
  4757. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetForceInvincible: entID %d not a client\n", entID);
  4758. return;
  4759. }
  4760. Q3_SetInvincible( entID, forceInv );
  4761. if ( forceInv )
  4762. {
  4763. self->client->ps.powerups[PW_INVINCIBLE] = Q3_INFINITE;
  4764. }
  4765. else
  4766. {
  4767. self->client->ps.powerups[PW_INVINCIBLE] = 0;
  4768. }
  4769. }
  4770. /*
  4771. ============
  4772. Q3_SetNoAvoid
  4773. ?
  4774. ============
  4775. */
  4776. static void Q3_SetNoAvoid( int entID, qboolean noAvoid)
  4777. {
  4778. gentity_t *ent = &g_entities[entID];
  4779. if ( !ent )
  4780. {
  4781. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoAvoid: invalid entID %d\n", entID);
  4782. return;
  4783. }
  4784. if ( !ent->NPC )
  4785. {
  4786. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetNoAvoid: '%s' is not an NPC!\n", ent->targetname );
  4787. return;
  4788. }
  4789. if(noAvoid)
  4790. {
  4791. ent->NPC->aiFlags |= NPCAI_NO_COLL_AVOID;
  4792. }
  4793. else
  4794. {
  4795. ent->NPC->aiFlags &= ~NPCAI_NO_COLL_AVOID;
  4796. }
  4797. }
  4798. /*
  4799. ============
  4800. SolidifyOwner
  4801. Description :
  4802. Return type : void
  4803. Argument : gentity_t *self
  4804. ============
  4805. */
  4806. void SolidifyOwner( gentity_t *self )
  4807. {
  4808. self->nextthink = level.time + FRAMETIME;
  4809. self->e_ThinkFunc = thinkF_G_FreeEntity;
  4810. if ( !self->owner || !self->owner->inuse )
  4811. {
  4812. return;
  4813. }
  4814. int oldContents = self->owner->contents;
  4815. self->owner->contents = CONTENTS_BODY;
  4816. if ( SpotWouldTelefrag2( self->owner, self->owner->currentOrigin ) )
  4817. {
  4818. self->owner->contents = oldContents;
  4819. self->e_ThinkFunc = thinkF_SolidifyOwner;
  4820. }
  4821. else
  4822. {
  4823. if ( self->owner->NPC && !(self->owner->spawnflags & SFB_NOTSOLID) )
  4824. {
  4825. self->owner->clipmask |= CONTENTS_BODY;
  4826. }
  4827. Q3_TaskIDComplete( self->owner, TID_RESIZE );
  4828. }
  4829. }
  4830. /*
  4831. ============
  4832. Q3_SetSolid
  4833. ?
  4834. ============
  4835. */
  4836. static qboolean Q3_SetSolid( int entID, qboolean solid)
  4837. {
  4838. gentity_t *ent = &g_entities[entID];
  4839. if ( !ent )
  4840. {
  4841. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetSolid: invalid entID %d\n", entID);
  4842. return qtrue;
  4843. }
  4844. if ( solid )
  4845. {//FIXME: Presumption
  4846. int oldContents = ent->contents;
  4847. ent->contents = CONTENTS_BODY;
  4848. if ( SpotWouldTelefrag2( ent, ent->currentOrigin ) )
  4849. {
  4850. gentity_t *solidifier = G_Spawn();
  4851. solidifier->owner = ent;
  4852. solidifier->e_ThinkFunc = thinkF_SolidifyOwner;
  4853. solidifier->nextthink = level.time + FRAMETIME;
  4854. ent->contents = oldContents;
  4855. return qfalse;
  4856. }
  4857. ent->clipmask |= CONTENTS_BODY;
  4858. }
  4859. else
  4860. {//FIXME: Presumption
  4861. if ( ent->s.eFlags & EF_NODRAW )
  4862. {//We're invisible too, so set contents to none
  4863. ent->contents = 0;
  4864. }
  4865. else
  4866. {
  4867. ent->contents = CONTENTS_CORPSE;
  4868. }
  4869. if ( ent->NPC )
  4870. {
  4871. if(!(ent->spawnflags & SFB_NOTSOLID))
  4872. {
  4873. ent->clipmask &= ~CONTENTS_BODY;
  4874. }
  4875. }
  4876. }
  4877. return qtrue;
  4878. }
  4879. /*
  4880. ============
  4881. Q3_SetLean
  4882. ?
  4883. ============
  4884. */
  4885. #define LEAN_NONE 0
  4886. #define LEAN_RIGHT 1
  4887. #define LEAN_LEFT 2
  4888. static void Q3_SetLean( int entID, int lean)
  4889. {
  4890. gentity_t *ent = &g_entities[entID];
  4891. if ( !ent )
  4892. {
  4893. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLean: invalid entID %d\n", entID);
  4894. return;
  4895. }
  4896. if ( !ent->NPC )
  4897. {
  4898. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetLean: '%s' is not an NPC!\n", ent->targetname );
  4899. return;
  4900. }
  4901. if(lean == LEAN_RIGHT)
  4902. {
  4903. ent->NPC->scriptFlags |= SCF_LEAN_RIGHT;
  4904. ent->NPC->scriptFlags &= ~SCF_LEAN_LEFT;
  4905. }
  4906. else if(lean == LEAN_LEFT)
  4907. {
  4908. ent->NPC->scriptFlags |= SCF_LEAN_LEFT;
  4909. ent->NPC->scriptFlags &= ~SCF_LEAN_RIGHT;
  4910. }
  4911. else
  4912. {
  4913. ent->NPC->scriptFlags &= ~SCF_LEAN_LEFT;
  4914. ent->NPC->scriptFlags &= ~SCF_LEAN_RIGHT;
  4915. }
  4916. }
  4917. /*
  4918. ============
  4919. Q3_SetForwardMove
  4920. ?
  4921. ============
  4922. */
  4923. static void Q3_SetForwardMove( int entID, int fmoveVal)
  4924. {
  4925. gentity_t *ent = &g_entities[entID];
  4926. if ( !ent )
  4927. {
  4928. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetForwardMove: invalid entID %d\n", entID);
  4929. return;
  4930. }
  4931. if ( !ent->client )
  4932. {
  4933. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetForwardMove: '%s' is not an NPC/player!\n", ent->targetname );
  4934. return;
  4935. }
  4936. ent->client->forced_forwardmove = fmoveVal;
  4937. }
  4938. /*
  4939. ============
  4940. Q3_SetRightMove
  4941. ?
  4942. ============
  4943. */
  4944. static void Q3_SetRightMove( int entID, int rmoveVal)
  4945. {
  4946. gentity_t *ent = &g_entities[entID];
  4947. if ( !ent )
  4948. {
  4949. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRightMove: invalid entID %d\n", entID);
  4950. return;
  4951. }
  4952. if ( !ent->client )
  4953. {
  4954. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetRightMove: '%s' is not an NPC/player!\n", ent->targetname );
  4955. return;
  4956. }
  4957. ent->client->forced_rightmove = rmoveVal;
  4958. }
  4959. /*
  4960. ============
  4961. Q3_SetLockAngle
  4962. ?
  4963. ============
  4964. */
  4965. static void Q3_SetLockAngle( int entID, const char *lockAngle)
  4966. {
  4967. gentity_t *ent = &g_entities[entID];
  4968. if ( !ent )
  4969. {
  4970. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLockAngle: invalid entID %d\n", entID);
  4971. return;
  4972. }
  4973. if ( !ent->client )
  4974. {
  4975. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetLockAngle: '%s' is not an NPC/player!\n", ent->targetname );
  4976. return;
  4977. }
  4978. if(Q_stricmp("off", lockAngle) == 0)
  4979. {//free it
  4980. ent->client->renderInfo.renderFlags &= ~RF_LOCKEDANGLE;
  4981. }
  4982. else
  4983. {
  4984. ent->client->renderInfo.renderFlags |= RF_LOCKEDANGLE;
  4985. if(Q_stricmp("auto", lockAngle) == 0)
  4986. {//use current yaw
  4987. if( ent->NPC ) // I need this to work on NPCs, so their locked value
  4988. {
  4989. ent->NPC->lockedDesiredYaw = NPC->client->ps.viewangles[YAW]; // could also set s.angles[1] and desiredYaw to this value...
  4990. }
  4991. else
  4992. {
  4993. ent->client->renderInfo.lockYaw = ent->client->ps.viewangles[YAW];
  4994. }
  4995. }
  4996. else
  4997. {//specified yaw
  4998. if( ent->NPC ) // I need this to work on NPCs, so their locked value
  4999. {
  5000. ent->NPC->lockedDesiredYaw = atof((char *)lockAngle); // could also set s.angles[1] and desiredYaw to this value...
  5001. }
  5002. else
  5003. {
  5004. ent->client->renderInfo.lockYaw = atof((char *)lockAngle);
  5005. }
  5006. }
  5007. }
  5008. }
  5009. /*
  5010. ============
  5011. Q3_CameraGroup
  5012. ?
  5013. ============
  5014. */
  5015. static void Q3_CameraGroup( int entID, char *camG)
  5016. {
  5017. gentity_t *ent = &g_entities[entID];
  5018. if ( !ent )
  5019. {
  5020. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_CameraGroup: invalid entID %d\n", entID);
  5021. return;
  5022. }
  5023. ent->cameraGroup = G_NewString(camG);
  5024. }
  5025. extern camera_t client_camera;
  5026. /*
  5027. ============
  5028. Q3_CameraGroupZOfs
  5029. ?
  5030. ============
  5031. */
  5032. static void Q3_CameraGroupZOfs( float camGZOfs )
  5033. {
  5034. client_camera.cameraGroupZOfs = camGZOfs;
  5035. }
  5036. /*
  5037. ============
  5038. Q3_CameraGroup
  5039. ?
  5040. ============
  5041. */
  5042. static void Q3_CameraGroupTag( char *camGTag )
  5043. {
  5044. Q_strncpyz( client_camera.cameraGroupTag, camGTag, sizeof(client_camera.cameraGroupTag) );
  5045. }
  5046. /*
  5047. ============
  5048. Q3_RemoveRHandModel
  5049. ============
  5050. */
  5051. static void Q3_RemoveRHandModel( int entID, char *addModel)
  5052. {
  5053. gentity_t *ent = &g_entities[entID];
  5054. if ( ent->cinematicModel >= 0 )
  5055. {
  5056. gi.G2API_RemoveGhoul2Model(ent->ghoul2,ent->cinematicModel);
  5057. }
  5058. }
  5059. /*
  5060. ============
  5061. Q3_AddRHandModel
  5062. ============
  5063. */
  5064. static void Q3_AddRHandModel( int entID, char *addModel)
  5065. {
  5066. gentity_t *ent = &g_entities[entID];
  5067. ent->cinematicModel = gi.G2API_InitGhoul2Model(ent->ghoul2, addModel, G_ModelIndex( addModel ));
  5068. if ( ent->cinematicModel != -1 )
  5069. {
  5070. // attach it to the hand
  5071. gi.G2API_AttachG2Model(&ent->ghoul2[ent->cinematicModel], &ent->ghoul2[ent->playerModel],
  5072. ent->handRBolt, ent->playerModel);
  5073. }
  5074. }
  5075. /*
  5076. ============
  5077. Q3_AddLHandModel
  5078. ============
  5079. */
  5080. static void Q3_AddLHandModel( int entID, char *addModel)
  5081. {
  5082. gentity_t *ent = &g_entities[entID];
  5083. ent->cinematicModel = gi.G2API_InitGhoul2Model(ent->ghoul2, addModel, G_ModelIndex( addModel ));
  5084. if ( ent->cinematicModel != -1 )
  5085. {
  5086. // attach it to the hand
  5087. gi.G2API_AttachG2Model(&ent->ghoul2[ent->cinematicModel], &ent->ghoul2[ent->playerModel],
  5088. ent->handLBolt, ent->playerModel);
  5089. }
  5090. }
  5091. /*
  5092. ============
  5093. Q3_RemoveLHandModel
  5094. ============
  5095. */
  5096. static void Q3_RemoveLHandModel( int entID, char *addModel)
  5097. {
  5098. gentity_t *ent = &g_entities[entID];
  5099. if ( ent->cinematicModel >= 0 )
  5100. {
  5101. gi.G2API_RemoveGhoul2Model(ent->ghoul2, ent->cinematicModel);
  5102. }
  5103. }
  5104. /*
  5105. ============
  5106. Q3_LookTarget
  5107. ?
  5108. ============
  5109. */
  5110. static void Q3_LookTarget( int entID, char *targetName)
  5111. {
  5112. gentity_t *ent = &g_entities[entID];
  5113. if ( !ent )
  5114. {
  5115. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_LookTarget: invalid entID %d\n", entID);
  5116. return;
  5117. }
  5118. if ( !ent->client )
  5119. {
  5120. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_LookTarget: '%s' is not an NPC/player!\n", ent->targetname );
  5121. return;
  5122. }
  5123. if(Q_stricmp("none", targetName) == 0 || Q_stricmp("NULL", targetName) == 0)
  5124. {//clearing look target
  5125. NPC_ClearLookTarget( ent );
  5126. return;
  5127. }
  5128. gentity_t *targ = G_Find(NULL, FOFS(targetname), targetName);
  5129. if(!targ)
  5130. {
  5131. targ = G_Find(NULL, FOFS(script_targetname), targetName);
  5132. if (!targ)
  5133. {
  5134. targ = G_Find(NULL, FOFS(NPC_targetname), targetName);
  5135. if (!targ)
  5136. {
  5137. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_LookTarget: Can't find ent %s\n", targetName );
  5138. return;
  5139. }
  5140. }
  5141. }
  5142. NPC_SetLookTarget( ent, targ->s.number, 0 );
  5143. }
  5144. /*
  5145. ============
  5146. Q3_Face
  5147. ?
  5148. ============
  5149. */
  5150. static void Q3_Face( int entID,int expression, float holdtime)
  5151. {
  5152. gentity_t *ent = &g_entities[entID];
  5153. if ( !ent )
  5154. {
  5155. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_Face: invalid entID %d\n", entID);
  5156. return;
  5157. }
  5158. if ( !ent->client )
  5159. {
  5160. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_Face: '%s' is not an NPC/player!\n", ent->targetname );
  5161. return;
  5162. }
  5163. //FIXME: change to milliseconds to be consistant!
  5164. holdtime *= 1000;
  5165. switch(expression)
  5166. {
  5167. case SET_FACEEYESCLOSED:
  5168. ent->client->facial_blink = 1;
  5169. break;
  5170. case SET_FACEEYESOPENED:
  5171. ent->client->facial_blink = -1;
  5172. break;
  5173. case SET_FACEBLINK:
  5174. ent->client->facial_timer = -(level.time + holdtime);
  5175. break;
  5176. case SET_FACEAUX:
  5177. ent->client->facial_timer = -(level.time + holdtime);
  5178. ent->client->facial_anim = FACE_ALERT;
  5179. break;
  5180. case SET_FACEBLINKFROWN:
  5181. ent->client->facial_blink = -(level.time + holdtime);
  5182. //fall through
  5183. case SET_FACEFROWN:
  5184. ent->client->facial_timer = -(level.time + holdtime);
  5185. ent->client->facial_anim = FACE_FROWN;
  5186. break;
  5187. case SET_FACENORMAL:
  5188. ent->client->facial_timer = level.time + Q_flrand(6000.0, 10000.0);
  5189. ent->client->facial_blink = level.time + Q_flrand(3000.0, 5000.0);
  5190. break;
  5191. }
  5192. }
  5193. /*
  5194. ============
  5195. Q3_SetPlayerUsable
  5196. Description :
  5197. Return type : void
  5198. Argument : int entID
  5199. Argument : qboolean usable
  5200. ============
  5201. */
  5202. static void Q3_SetPlayerUsable( int entID, qboolean usable )
  5203. {
  5204. gentity_t *ent = &g_entities[entID];
  5205. if ( !ent )
  5206. {
  5207. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetPlayerUsable: invalid entID %d\n", entID);
  5208. return;
  5209. }
  5210. if(usable)
  5211. {
  5212. ent->svFlags |= SVF_PLAYER_USABLE;
  5213. }
  5214. else
  5215. {
  5216. ent->svFlags &= ~SVF_PLAYER_USABLE;
  5217. }
  5218. }
  5219. /*
  5220. ============
  5221. Q3_SetDisableShaderAnims
  5222. Description :
  5223. Return type : static void
  5224. Argument : int entID
  5225. Argument : int disabled
  5226. ============
  5227. */
  5228. static void Q3_SetDisableShaderAnims( int entID, int disabled )
  5229. {
  5230. gentity_t *ent = &g_entities[entID];
  5231. if ( !ent )
  5232. {
  5233. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetDisableShaderAnims: invalid entID %d\n", entID);
  5234. return;
  5235. }
  5236. if ( disabled )
  5237. {
  5238. ent->s.eFlags |= EF_DISABLE_SHADER_ANIM;
  5239. }
  5240. else
  5241. {
  5242. ent->s.eFlags &= ~EF_DISABLE_SHADER_ANIM;
  5243. }
  5244. }
  5245. /*
  5246. ============
  5247. Q3_SetShaderAnim
  5248. Description :
  5249. Return type : static void
  5250. Argument : int entID
  5251. Argument : int disabled
  5252. ============
  5253. */
  5254. static void Q3_SetShaderAnim( int entID, int disabled )
  5255. {
  5256. gentity_t *ent = &g_entities[entID];
  5257. if ( !ent )
  5258. {
  5259. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetShaderAnim: invalid entID %d\n", entID);
  5260. return;
  5261. }
  5262. if ( disabled )
  5263. {
  5264. ent->s.eFlags |= EF_SHADER_ANIM;
  5265. }
  5266. else
  5267. {
  5268. ent->s.eFlags &= ~EF_SHADER_ANIM;
  5269. }
  5270. }
  5271. void Q3_SetBroadcast( int entID, qboolean broadcast )
  5272. {
  5273. gentity_t *ent = &g_entities[entID];
  5274. if ( broadcast )
  5275. {
  5276. ent->svFlags |= SVF_BROADCAST;
  5277. }
  5278. else
  5279. {
  5280. ent->svFlags &= ~SVF_BROADCAST;
  5281. }
  5282. }
  5283. void Q3_SetForcePower( int entID, int forcePower, qboolean powerOn )
  5284. {
  5285. gentity_t *ent = &g_entities[entID];
  5286. if ( !ent )
  5287. {
  5288. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetForcePower: invalid entID %d\n", entID);
  5289. return;
  5290. }
  5291. if ( !ent->client )
  5292. {
  5293. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetForcePower: ent # %d not a client!\n", entID );
  5294. return;
  5295. }
  5296. if ( powerOn )
  5297. {
  5298. ent->client->ps.forcePowersForced |= (1<<forcePower);
  5299. }
  5300. else
  5301. {
  5302. ent->client->ps.forcePowersForced &= ~(1<<forcePower);
  5303. }
  5304. }
  5305. /*
  5306. ============
  5307. Q3_SetStartFrame
  5308. Description :
  5309. Return type : static void
  5310. Argument : int entID
  5311. Argument : int startFrame
  5312. ============
  5313. */
  5314. static void Q3_SetStartFrame( int entID, int startFrame )
  5315. {
  5316. gentity_t *ent = &g_entities[entID];
  5317. if ( !ent )
  5318. {
  5319. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetStartFrame: invalid entID %d\n", entID);
  5320. return;
  5321. }
  5322. if ( ent->client )
  5323. {
  5324. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLoopAnim: command not valid on players/NPCs!\n" );
  5325. return;
  5326. }
  5327. if ( startFrame >= 0 )
  5328. {
  5329. ent->s.frame = startFrame;
  5330. ent->startFrame = startFrame;
  5331. }
  5332. }
  5333. /*
  5334. ============
  5335. Q3_SetEndFrame
  5336. Description :
  5337. Return type : static void
  5338. Argument : int entID
  5339. Argument : int endFrame
  5340. ============
  5341. */
  5342. static void Q3_SetEndFrame( int entID, int endFrame )
  5343. {
  5344. gentity_t *ent = &g_entities[entID];
  5345. if ( !ent )
  5346. {
  5347. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetEndFrame: invalid entID %d\n", entID);
  5348. return;
  5349. }
  5350. if ( ent->client )
  5351. {
  5352. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetEndFrame: command not valid on players/NPCs!\n" );
  5353. return;
  5354. }
  5355. if ( endFrame >= 0 )
  5356. {
  5357. ent->endFrame = endFrame;
  5358. }
  5359. }
  5360. /*
  5361. ============
  5362. Q3_SetAnimFrame
  5363. Description :
  5364. Return type : static void
  5365. Argument : int entID
  5366. Argument : int startFrame
  5367. ============
  5368. */
  5369. static void Q3_SetAnimFrame( int entID, int animFrame )
  5370. {
  5371. gentity_t *ent = &g_entities[entID];
  5372. if ( !ent )
  5373. {
  5374. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAnimFrame: invalid entID %d\n", entID);
  5375. return;
  5376. }
  5377. if ( ent->client )
  5378. {
  5379. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAnimFrame: command not valid on players/NPCs!\n" );
  5380. return;
  5381. }
  5382. if ( animFrame >= ent->endFrame )
  5383. {
  5384. ent->s.frame = ent->endFrame;
  5385. }
  5386. else if ( animFrame >= ent->startFrame )
  5387. {
  5388. ent->s.frame = animFrame;
  5389. }
  5390. else
  5391. {
  5392. // FIXME/NOTE: Set s.frame anyway??
  5393. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetAnimFrame: value must be valid number between StartFrame and EndFrame.\n" );
  5394. return;
  5395. }
  5396. }
  5397. void InflateOwner( gentity_t *self )
  5398. {
  5399. self->nextthink = level.time + FRAMETIME;
  5400. self->e_ThinkFunc = thinkF_G_FreeEntity;
  5401. if ( !self->owner || !self->owner->inuse )
  5402. {
  5403. return;
  5404. }
  5405. trace_t trace;
  5406. gi.trace( &trace, self->currentOrigin, self->mins, self->maxs, self->currentOrigin, self->owner->s.number, self->owner->clipmask&~(CONTENTS_SOLID|CONTENTS_MONSTERCLIP) );
  5407. if ( trace.allsolid || trace.startsolid )
  5408. {
  5409. self->e_ThinkFunc = thinkF_InflateOwner;
  5410. return;
  5411. }
  5412. if ( Q3_TaskIDPending( self->owner, TID_RESIZE ) )
  5413. {
  5414. Q3_TaskIDComplete( self->owner, TID_RESIZE );
  5415. VectorCopy( self->mins, self->owner->mins );
  5416. VectorCopy( self->maxs, self->owner->maxs );
  5417. gi.linkentity( self->owner );
  5418. }
  5419. }
  5420. /*
  5421. ============
  5422. Q3_SetLoopAnim
  5423. Description :
  5424. Return type : void
  5425. Argument : int entID
  5426. Argument : qboolean loopAnim
  5427. ============
  5428. */
  5429. static void Q3_SetLoopAnim( int entID, qboolean loopAnim )
  5430. {
  5431. gentity_t *ent = &g_entities[entID];
  5432. if ( !ent )
  5433. {
  5434. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLoopAnim: invalid entID %d\n", entID);
  5435. return;
  5436. }
  5437. if ( ent->client )
  5438. {
  5439. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetLoopAnim: command not valid on players/NPCs!\n" );
  5440. return;
  5441. }
  5442. ent->loopAnim = loopAnim;
  5443. }
  5444. /*
  5445. ============
  5446. Q3_SetShields
  5447. Description :
  5448. Return type : void
  5449. Argument : int entID
  5450. Argument : qboolean shields
  5451. ============
  5452. */
  5453. static void Q3_SetShields( int entID, qboolean shields )
  5454. {
  5455. gentity_t *ent = &g_entities[entID];
  5456. if ( !ent )
  5457. {
  5458. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetShields: invalid entID %d\n", entID);
  5459. return;
  5460. }
  5461. if ( !ent->NPC )
  5462. {
  5463. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetShields: '%s' is not an NPC!\n", ent->targetname );
  5464. return;
  5465. }
  5466. if ( shields )
  5467. {
  5468. ent->NPC->aiFlags |= NPCAI_SHIELDS;
  5469. }
  5470. else
  5471. {
  5472. ent->NPC->aiFlags &= ~NPCAI_SHIELDS;
  5473. }
  5474. }
  5475. /*
  5476. ============
  5477. Q3_SetSaberActive
  5478. Description :
  5479. Return type : void
  5480. Argument : int entID
  5481. Argument : qboolean shields
  5482. ============
  5483. */
  5484. static void Q3_SetSaberActive( int entID, qboolean active )
  5485. {
  5486. gentity_t *ent = &g_entities[entID];
  5487. if ( !ent )
  5488. {
  5489. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetSaberActive: invalid entID %d\n", entID);
  5490. return;
  5491. }
  5492. if ( !ent->client )
  5493. {
  5494. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetSaberActive: '%s' is not an player/NPC!\n", ent->targetname );
  5495. return;
  5496. }
  5497. if ( ent->client->ps.weapon != WP_SABER )
  5498. {
  5499. if ( (ent->client->ps.stats[STAT_WEAPONS]&(1<<WP_SABER)) )
  5500. {//change to it right now
  5501. if ( ent->NPC )
  5502. {
  5503. ChangeWeapon( ent, WP_SABER );
  5504. }
  5505. else
  5506. {
  5507. gitem_t *item = FindItemForWeapon( WP_SABER );
  5508. RegisterItem( item ); //make sure the weapon is cached in case this runs at startup
  5509. G_AddEvent( ent, EV_ITEM_PICKUP, (item - bg_itemlist) );
  5510. CG_ChangeWeapon( WP_SABER );
  5511. }
  5512. ent->client->ps.weapon = WP_SABER;
  5513. ent->client->ps.weaponstate = WEAPON_READY;
  5514. G_AddEvent( ent, EV_GENERAL_SOUND, G_SoundIndex( "sound/weapons/change.wav" ));
  5515. }
  5516. else
  5517. {
  5518. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetSaberActive: '%s' is not using a saber!\n", ent->targetname );
  5519. return;
  5520. }
  5521. }
  5522. if ( active )
  5523. {
  5524. ent->client->ps.SaberActivate();
  5525. }
  5526. else
  5527. {
  5528. ent->client->ps.SaberDeactivate();
  5529. }
  5530. }
  5531. /*
  5532. ============
  5533. Name: Q3_SetSaberBladeActive
  5534. Description: Make a specific blade of a specific Saber active or inactive.
  5535. Created: 10/02/02 by Aurelio Reis, Modified: 10/02/02 by Aurelio Reis
  5536. [in] int entID The ID of the Entity to modify.
  5537. [in] int iSaber Which Saber to modify.
  5538. [in] int iBlade Which blade to modify (0 - (NUM_BLADES - 1)).
  5539. [in] bool bActive Whether to make it active (default true) or inactive (false).
  5540. [return] void
  5541. ============
  5542. */
  5543. static void Q3_SetSaberBladeActive( int entID, int iSaber, int iBlade, qboolean bActive = qtrue )
  5544. {
  5545. gentity_t *ent = &g_entities[entID];
  5546. if ( !ent )
  5547. {
  5548. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetSaberBladeActive: invalid entID %d\n", entID);
  5549. return;
  5550. }
  5551. if ( !ent->client )
  5552. {
  5553. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetSaberBladeActive: '%s' is not an player/NPC!\n", ent->targetname );
  5554. return;
  5555. }
  5556. if ( ent->client->ps.weapon != WP_SABER )
  5557. {
  5558. if ( (ent->client->ps.stats[STAT_WEAPONS]&(1<<WP_SABER)) )
  5559. {//change to it right now
  5560. if ( ent->NPC )
  5561. {
  5562. ChangeWeapon( ent, WP_SABER );
  5563. }
  5564. else
  5565. {
  5566. gitem_t *item = FindItemForWeapon( WP_SABER );
  5567. RegisterItem( item ); //make sure the weapon is cached in case this runs at startup
  5568. G_AddEvent( ent, EV_ITEM_PICKUP, (item - bg_itemlist) );
  5569. CG_ChangeWeapon( WP_SABER );
  5570. }
  5571. ent->client->ps.weapon = WP_SABER;
  5572. ent->client->ps.weaponstate = WEAPON_READY;
  5573. G_AddEvent( ent, EV_GENERAL_SOUND, G_SoundIndex( "sound/weapons/change.wav" ));
  5574. }
  5575. else
  5576. {
  5577. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_SetSaberBladeActive: '%s' is not using a saber!\n", ent->targetname );
  5578. return;
  5579. }
  5580. }
  5581. // Activate the Blade.
  5582. ent->client->ps.SaberBladeActivate( iSaber, iBlade, bActive );
  5583. }
  5584. /*
  5585. ============
  5586. Q3_SetNoKnockback
  5587. Description :
  5588. Return type : void
  5589. Argument : int entID
  5590. Argument : qboolean noKnockback
  5591. ============
  5592. */
  5593. static void Q3_SetNoKnockback( int entID, qboolean noKnockback )
  5594. {
  5595. gentity_t *ent = &g_entities[entID];
  5596. if ( !ent )
  5597. {
  5598. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoKnockback: invalid entID %d\n", entID);
  5599. return;
  5600. }
  5601. if ( noKnockback )
  5602. {
  5603. ent->flags |= FL_NO_KNOCKBACK;
  5604. }
  5605. else
  5606. {
  5607. ent->flags &= ~FL_NO_KNOCKBACK;
  5608. }
  5609. }
  5610. /*
  5611. ============
  5612. Q3_SetCleanDamagingEnts
  5613. Description :
  5614. Return type : void
  5615. ============
  5616. */
  5617. static void Q3_SetCleanDamagingEnts( void )
  5618. {
  5619. gentity_t *ent = NULL;
  5620. for ( int i = 0; i < ENTITYNUM_WORLD; i++ )
  5621. {
  5622. if ( !PInUse( i ))
  5623. {
  5624. continue;
  5625. }
  5626. ent = &g_entities[i];
  5627. if ( ent )
  5628. {
  5629. if ( !ent->client && ( ent->s.weapon == WP_DET_PACK || ent->s.weapon == WP_TRIP_MINE || ent->s.weapon == WP_THERMAL ))
  5630. {
  5631. // check for a client, otherwise we could remove someone holding this weapon
  5632. G_FreeEntity( ent );
  5633. }
  5634. else if ( ent->s.weapon == WP_TURRET && ent->activator && ent->activator->s.number == 0 && !Q_stricmp( "PAS", ent->classname ))
  5635. {
  5636. // is a player owner personal assault sentry gun.
  5637. G_FreeEntity( ent );
  5638. }
  5639. else if ( ent->client && ent->client->NPC_class == CLASS_SEEKER )
  5640. {
  5641. // they blow up when they run out of ammo, so this may as well just do the same.
  5642. G_Damage( ent, ent, ent, NULL, NULL, 999, 0, MOD_UNKNOWN );
  5643. }
  5644. }
  5645. }
  5646. }
  5647. /*
  5648. ============
  5649. Q3_SetInterface
  5650. Description :
  5651. Return type : void
  5652. Argument : int entID
  5653. Argument : const char *data
  5654. ============
  5655. */
  5656. static void Q3_SetInterface( int entID, const char *data )
  5657. {
  5658. gi.cvar_set("cg_drawStatus", data);
  5659. }
  5660. /*
  5661. ============
  5662. Q3_SetLocation
  5663. Description :
  5664. Return type : qboolean
  5665. Argument : int entID
  5666. Argument : const char *location
  5667. ============
  5668. */
  5669. static qboolean Q3_SetLocation( int entID, const char *location )
  5670. {
  5671. gentity_t *ent = &g_entities[entID];
  5672. char *currentLoc;
  5673. if ( !ent )
  5674. {
  5675. return qtrue;
  5676. }
  5677. currentLoc = G_GetLocationForEnt( ent );
  5678. if ( currentLoc && currentLoc[0] && Q_stricmp( location, currentLoc ) == 0 )
  5679. {
  5680. return qtrue;
  5681. }
  5682. ent->message = G_NewString( location );
  5683. return qfalse;
  5684. }
  5685. /*
  5686. ============
  5687. Q3_SetPlayerLocked
  5688. Description :
  5689. Return type : void
  5690. Argument : int entID
  5691. Argument : qboolean locked
  5692. ============
  5693. */
  5694. qboolean player_locked = qfalse;
  5695. static void Q3_SetPlayerLocked( int entID, qboolean locked )
  5696. {
  5697. gentity_t *ent = &g_entities[0];
  5698. player_locked = locked;
  5699. if ( ent && ent->client )
  5700. {//stop him too
  5701. VectorClear(ent->client->ps.velocity);
  5702. }
  5703. }
  5704. /*
  5705. ============
  5706. Q3_SetLockPlayerWeapons
  5707. Description :
  5708. Return type : void
  5709. Argument : int entID
  5710. Argument : qboolean locked
  5711. ============
  5712. */
  5713. static void Q3_SetLockPlayerWeapons( int entID, qboolean locked )
  5714. {
  5715. gentity_t *ent = &g_entities[0];
  5716. ent->flags &= ~FL_LOCK_PLAYER_WEAPONS;
  5717. if( locked )
  5718. {
  5719. ent->flags |= FL_LOCK_PLAYER_WEAPONS;
  5720. }
  5721. }
  5722. /*
  5723. ============
  5724. Q3_SetNoImpactDamage
  5725. Description :
  5726. Return type : void
  5727. Argument : int entID
  5728. Argument : qboolean locked
  5729. ============
  5730. */
  5731. static void Q3_SetNoImpactDamage( int entID, qboolean noImp )
  5732. {
  5733. gentity_t *ent = &g_entities[entID];
  5734. if ( !ent )
  5735. {
  5736. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetNoImpactDamage: invalid entID %d\n", entID);
  5737. return;
  5738. }
  5739. ent->flags &= ~FL_NO_IMPACT_DMG;
  5740. if( noImp )
  5741. {
  5742. ent->flags |= FL_NO_IMPACT_DMG;
  5743. }
  5744. }
  5745. extern void CG_CameraAutoAim( const char *name );
  5746. extern void CG_CameraAutoTrack( const char *name );
  5747. /*
  5748. ============
  5749. Q3_SetVar
  5750. Description :
  5751. Return type : static void
  5752. Argument : int taskID
  5753. Argument : int entID
  5754. Argument : const char *type_name
  5755. Argument : const char *data
  5756. ============
  5757. */
  5758. /*void SetVar( int taskID, int entID, const char *type_name, const char *data )
  5759. {
  5760. int vret = Q3_VariableDeclared( type_name ) ;
  5761. float float_data;
  5762. float val = 0.0f;
  5763. if ( vret != VTYPE_NONE )
  5764. {
  5765. switch ( vret )
  5766. {
  5767. case VTYPE_FLOAT:
  5768. //Check to see if increment command
  5769. if ( (val = Q3_CheckStringCounterIncrement( data )) )
  5770. {
  5771. Q3_GetFloatVariable( type_name, &float_data );
  5772. float_data += val;
  5773. }
  5774. else
  5775. {
  5776. float_data = atof((char *) data);
  5777. }
  5778. Q3_SetFloatVariable( type_name, float_data );
  5779. break;
  5780. case VTYPE_STRING:
  5781. Q3_SetStringVariable( type_name, data );
  5782. break;
  5783. case VTYPE_VECTOR:
  5784. Q3_SetVectorVariable( type_name, (char *) data );
  5785. break;
  5786. }
  5787. return;
  5788. }
  5789. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "%s variable or field not found!\n", type_name );
  5790. }*/
  5791. /*
  5792. ============
  5793. Q3_RemoveEnt
  5794. Description :
  5795. Return type : void
  5796. Argument : gentity_t *victim
  5797. ============
  5798. */
  5799. static void Q3_RemoveEnt( gentity_t *victim )
  5800. {
  5801. if (!victim || !victim->inuse)
  5802. {
  5803. return;
  5804. }
  5805. if( victim->client )
  5806. {
  5807. if ( victim->client->NPC_class == CLASS_VEHICLE )
  5808. {//eject everyone out of a vehicle that's about to remove itself
  5809. Vehicle_t *pVeh = victim->m_pVehicle;
  5810. if ( pVeh && pVeh->m_pVehicleInfo )
  5811. {
  5812. pVeh->m_pVehicleInfo->EjectAll( pVeh );
  5813. }
  5814. }
  5815. //ClientDisconnect(ent);
  5816. victim->s.eFlags |= EF_NODRAW;
  5817. victim->svFlags &= ~SVF_NPC;
  5818. victim->s.eType = ET_INVISIBLE;
  5819. victim->contents = 0;
  5820. victim->health = 0;
  5821. victim->targetname = NULL;
  5822. if ( victim->NPC && victim->NPC->tempGoal != NULL )
  5823. {
  5824. G_FreeEntity( victim->NPC->tempGoal );
  5825. victim->NPC->tempGoal = NULL;
  5826. }
  5827. if ( victim->client->ps.saberEntityNum != ENTITYNUM_NONE && victim->client->ps.saberEntityNum > 0 )
  5828. {
  5829. if ( g_entities[victim->client->ps.saberEntityNum].inuse )
  5830. {
  5831. G_FreeEntity( &g_entities[victim->client->ps.saberEntityNum] );
  5832. }
  5833. victim->client->ps.saberEntityNum = ENTITYNUM_NONE;
  5834. }
  5835. //Disappear in half a second
  5836. victim->e_ThinkFunc = thinkF_G_FreeEntity;
  5837. victim->nextthink = level.time + 500;
  5838. return;
  5839. }
  5840. else
  5841. {
  5842. victim->e_ThinkFunc = thinkF_G_FreeEntity;
  5843. victim->nextthink = level.time + 100;
  5844. }
  5845. }
  5846. /*
  5847. ============
  5848. MakeOwnerInvis
  5849. Description :
  5850. Return type : void
  5851. Argument : gentity_t *self
  5852. ============
  5853. */
  5854. void MakeOwnerInvis(gentity_t *self)
  5855. {
  5856. if(self->owner && self->owner->client)
  5857. {
  5858. self->owner->client->ps.powerups[PW_CLOAKED] = level.time + 500;
  5859. }
  5860. //HACKHGACLHACK!! - MCG
  5861. self->e_ThinkFunc = thinkF_RemoveOwner;
  5862. self->nextthink = level.time + 400;
  5863. }
  5864. /*
  5865. ============
  5866. MakeOwnerEnergy
  5867. Description :
  5868. Return type : void
  5869. Argument : gentity_t *self
  5870. ============
  5871. */
  5872. void MakeOwnerEnergy(gentity_t *self)
  5873. {
  5874. if(self->owner && self->owner->client)
  5875. {
  5876. // self->owner->client->ps.powerups[PW_QUAD] = level.time + 1000;
  5877. }
  5878. G_FreeEntity(self);
  5879. }
  5880. // NOTE! RemoveOwner() is a function used within the entity (a pointer to the function is
  5881. // contained). This leads to a "funny" predicament: why is RemoveOwner() here???
  5882. // NOTE NOTE! This is also true of Q3_Remove, which should be eliminated as soon as possible.
  5883. /*
  5884. ============
  5885. Q3_Remove
  5886. Description :
  5887. Return type : void
  5888. Argument : int entID
  5889. Argument : const char *name
  5890. ============
  5891. */
  5892. static void Q3_Remove( int entID, const char *name )
  5893. {
  5894. gentity_t *ent = &g_entities[entID];
  5895. gentity_t *victim = NULL;
  5896. if( !Q_stricmp( "self", name ) )
  5897. {
  5898. victim = ent;
  5899. if ( !victim )
  5900. {
  5901. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_Remove: can't find %s\n", name );
  5902. return;
  5903. }
  5904. Q3_RemoveEnt( victim );
  5905. }
  5906. else if( !Q_stricmp( "enemy", name ) )
  5907. {
  5908. victim = ent->enemy;
  5909. if ( !victim )
  5910. {
  5911. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_Remove: can't find %s\n", name );
  5912. return;
  5913. }
  5914. Q3_RemoveEnt( victim );
  5915. }
  5916. else
  5917. {
  5918. victim = G_Find( NULL, FOFS(targetname), (char *) name );
  5919. if ( !victim )
  5920. {
  5921. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_Remove: can't find %s\n", name );
  5922. return;
  5923. }
  5924. while ( victim )
  5925. {
  5926. Q3_RemoveEnt( victim );
  5927. victim = G_Find( victim, FOFS(targetname), (char *) name );
  5928. }
  5929. }
  5930. }
  5931. /*
  5932. ============
  5933. RemoveOwner
  5934. Description :
  5935. Return type : void
  5936. Argument : gentity_t *self
  5937. ============
  5938. */
  5939. void RemoveOwner (gentity_t *self)
  5940. {
  5941. if ( self->owner && self->owner->inuse )
  5942. {//I have an owner and they heavn't been freed yet
  5943. Q3_Remove( self->owner->s.number, "self" );
  5944. }
  5945. G_FreeEntity( self );
  5946. }
  5947. void Q3_DismemberLimb( int entID, char *hitLocName )
  5948. {
  5949. gentity_t *self = &g_entities[entID];
  5950. int hitLoc = GetIDForString( HLTable, hitLocName );
  5951. vec3_t point;
  5952. if ( !self )
  5953. {
  5954. Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_DismemberLimb: invalid entID %d\n", entID);
  5955. return;
  5956. }
  5957. if ( !self->client )
  5958. {
  5959. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_DismemberLimb: '%s' is not a player/NPC!\n", self->targetname );
  5960. return;
  5961. }
  5962. if ( !self->ghoul2.size() )
  5963. {
  5964. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_DismemberLimb: '%s' is not a ghoul model!\n", self->targetname );
  5965. return;
  5966. }
  5967. if ( hitLoc <= HL_NONE || hitLoc >= HL_MAX )
  5968. {
  5969. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "Q3_DismemberLimb: '%s' is not a valid hit location!\n", hitLocName );
  5970. return;
  5971. }
  5972. switch ( hitLoc )
  5973. {
  5974. case HL_FOOT_RT:
  5975. VectorCopy( self->client->renderInfo.footRPoint, point );
  5976. break;
  5977. case HL_FOOT_LT:
  5978. VectorCopy( self->client->renderInfo.footLPoint, point );
  5979. break;
  5980. case HL_LEG_RT:
  5981. G_GetBoltPosition( self, self->kneeRBolt, point );
  5982. break;
  5983. case HL_LEG_LT:
  5984. G_GetBoltPosition( self, self->kneeLBolt, point );
  5985. break;
  5986. case HL_ARM_RT:
  5987. case HL_CHEST_RT:
  5988. case HL_BACK_LT:
  5989. G_GetBoltPosition( self, self->elbowRBolt, point );
  5990. break;
  5991. case HL_ARM_LT:
  5992. case HL_CHEST_LT:
  5993. case HL_BACK_RT:
  5994. G_GetBoltPosition( self, self->elbowLBolt, point );
  5995. break;
  5996. case HL_WAIST:
  5997. case HL_BACK:
  5998. case HL_CHEST:
  5999. VectorCopy( self->client->renderInfo.torsoPoint, point );
  6000. break;
  6001. case HL_HAND_RT:
  6002. VectorCopy( self->client->renderInfo.handRPoint, point );
  6003. break;
  6004. case HL_HAND_LT:
  6005. VectorCopy( self->client->renderInfo.handLPoint, point );
  6006. break;
  6007. case HL_HEAD:
  6008. VectorCopy( self->client->renderInfo.headPoint, point );
  6009. break;
  6010. case HL_GENERIC1:
  6011. case HL_GENERIC2:
  6012. case HL_GENERIC3:
  6013. case HL_GENERIC4:
  6014. case HL_GENERIC5:
  6015. case HL_GENERIC6:
  6016. VectorCopy( self->currentOrigin, point );
  6017. break;
  6018. }
  6019. G_DoDismemberment( self, point, MOD_SABER, 1000, hitLoc, qtrue );
  6020. }
  6021. /*
  6022. -------------------------
  6023. VariableDeclared
  6024. -------------------------
  6025. */
  6026. int CQuake3GameInterface::VariableDeclared( const char *name )
  6027. {
  6028. //Check the strings
  6029. varString_m::iterator vsi = m_varStrings.find( name );
  6030. if ( vsi != m_varStrings.end() )
  6031. return VTYPE_STRING;
  6032. //Check the floats
  6033. varFloat_m::iterator vfi = m_varFloats.find( name );
  6034. if ( vfi != m_varFloats.end() )
  6035. return VTYPE_FLOAT;
  6036. //Check the vectors
  6037. varString_m::iterator vvi = m_varVectors.find( name );
  6038. if ( vvi != m_varVectors.end() )
  6039. return VTYPE_VECTOR;
  6040. return VTYPE_NONE;
  6041. }
  6042. /*
  6043. -------------------------
  6044. SetVar
  6045. -------------------------
  6046. */
  6047. void CQuake3GameInterface::SetVar( int taskID, int entID, const char *type_name, const char *data )
  6048. {
  6049. int vret = VariableDeclared( type_name ) ;
  6050. float float_data;
  6051. float val = 0.0f;
  6052. int favre=0;
  6053. if( Q_stricmp( type_name, "path_enemies_dead" )==0 )
  6054. {
  6055. favre=4;
  6056. }
  6057. if( Q_stricmp( type_name, "path_door_open" )==0 )
  6058. {
  6059. favre = 4;
  6060. }
  6061. if ( vret != VTYPE_NONE )
  6062. {
  6063. switch ( vret )
  6064. {
  6065. case VTYPE_FLOAT:
  6066. //Check to see if increment command
  6067. if ( (val = Q3_CheckStringCounterIncrement( data )) )
  6068. {
  6069. GetFloatVariable( type_name, &float_data );
  6070. float_data += val;
  6071. }
  6072. else
  6073. {
  6074. float_data = atof((char *) data);
  6075. }
  6076. SetFloatVariable( type_name, float_data );
  6077. break;
  6078. case VTYPE_STRING:
  6079. SetStringVariable( type_name, data );
  6080. break;
  6081. case VTYPE_VECTOR:
  6082. SetVectorVariable( type_name, (char *) data );
  6083. break;
  6084. }
  6085. return;
  6086. }
  6087. DebugPrint( WL_ERROR, "%s variable or field not found!\n", type_name );
  6088. }
  6089. /*
  6090. -------------------------
  6091. GetFloatVariable
  6092. -------------------------
  6093. */
  6094. int CQuake3GameInterface::GetFloatVariable( const char *name, float *value )
  6095. {
  6096. //Check the floats
  6097. varFloat_m::iterator vfi = m_varFloats.find( name );
  6098. if ( vfi != m_varFloats.end() )
  6099. {
  6100. *value = (*vfi).second;
  6101. return true;
  6102. }
  6103. return false;
  6104. }
  6105. /*
  6106. -------------------------
  6107. GetStringVariable
  6108. -------------------------
  6109. */
  6110. int CQuake3GameInterface::GetStringVariable( const char *name, const char **value )
  6111. {
  6112. //Check the strings
  6113. varString_m::iterator vsi = m_varStrings.find( name );
  6114. if ( vsi != m_varStrings.end() )
  6115. {
  6116. *value = (const char *) ((*vsi).second).c_str();
  6117. return true;
  6118. }
  6119. return false;
  6120. }
  6121. /*
  6122. -------------------------
  6123. GetVectorVariable
  6124. -------------------------
  6125. */
  6126. int CQuake3GameInterface::GetVectorVariable( const char *name, vec3_t value )
  6127. {
  6128. //Check the strings
  6129. varString_m::iterator vvi = m_varVectors.find( name );
  6130. if ( vvi != m_varVectors.end() )
  6131. {
  6132. const char *str = ((*vvi).second).c_str();
  6133. sscanf( str, "%f %f %f", &value[0], &value[1], &value[2] );
  6134. return true;
  6135. }
  6136. return false;
  6137. }
  6138. /*
  6139. -------------------------
  6140. InitVariables
  6141. -------------------------
  6142. */
  6143. void CQuake3GameInterface::InitVariables( void )
  6144. {
  6145. m_varStrings.clear();
  6146. m_varFloats.clear();
  6147. m_varVectors.clear();
  6148. if ( m_numVariables > 0 )
  6149. DebugPrint( WL_WARNING, "%d residual variables found!\n", m_numVariables );
  6150. m_numVariables = 0;
  6151. }
  6152. /*
  6153. -------------------------
  6154. SetVariable_Float
  6155. -------------------------
  6156. */
  6157. int CQuake3GameInterface::SetFloatVariable( const char *name, float value )
  6158. {
  6159. //Check the floats
  6160. varFloat_m::iterator vfi = m_varFloats.find( name );
  6161. if ( vfi == m_varFloats.end() )
  6162. return VTYPE_FLOAT;
  6163. (*vfi).second = value;
  6164. return true;
  6165. }
  6166. /*
  6167. -------------------------
  6168. SetVariable_String
  6169. -------------------------
  6170. */
  6171. int CQuake3GameInterface::SetStringVariable( const char *name, const char *value )
  6172. {
  6173. //Check the strings
  6174. varString_m::iterator vsi = m_varStrings.find( name );
  6175. if ( vsi == m_varStrings.end() )
  6176. return false;
  6177. (*vsi).second = value;
  6178. return true;
  6179. }
  6180. /*
  6181. -------------------------
  6182. SetVariable_Vector
  6183. -------------------------
  6184. */
  6185. int CQuake3GameInterface::SetVectorVariable( const char *name, const char *value )
  6186. {
  6187. //Check the strings
  6188. varString_m::iterator vvi = m_varVectors.find( name );
  6189. if ( vvi == m_varVectors.end() )
  6190. return false;
  6191. (*vvi).second = value;
  6192. return true;
  6193. }
  6194. /*
  6195. -------------------------
  6196. VariableSaveFloats
  6197. -------------------------
  6198. */
  6199. void CQuake3GameInterface::VariableSaveFloats( varFloat_m &fmap )
  6200. {
  6201. int numFloats = fmap.size();
  6202. gi.AppendToSaveGame( 'FVAR', &numFloats, sizeof( numFloats ) );
  6203. varFloat_m::iterator vfi;
  6204. STL_ITERATE( vfi, fmap )
  6205. {
  6206. //Save out the map id
  6207. int idSize = strlen( ((*vfi).first).c_str() );
  6208. //Save out the real data
  6209. gi.AppendToSaveGame( 'FIDL', &idSize, sizeof( idSize ) );
  6210. gi.AppendToSaveGame( 'FIDS', (void *) ((*vfi).first).c_str(), idSize );
  6211. //Save out the float value
  6212. gi.AppendToSaveGame( 'FVAL', &((*vfi).second), sizeof( float ) );
  6213. }
  6214. }
  6215. /*
  6216. -------------------------
  6217. VariableSaveStrings
  6218. -------------------------
  6219. */
  6220. void CQuake3GameInterface::VariableSaveStrings( varString_m &smap )
  6221. {
  6222. int numStrings = smap.size();
  6223. gi.AppendToSaveGame( 'SVAR', &numStrings, sizeof( numStrings ) );
  6224. varString_m::iterator vsi;
  6225. STL_ITERATE( vsi, smap )
  6226. {
  6227. //Save out the map id
  6228. int idSize = strlen( ((*vsi).first).c_str() );
  6229. //Save out the real data
  6230. gi.AppendToSaveGame( 'SIDL', &idSize, sizeof( idSize ) );
  6231. gi.AppendToSaveGame( 'SIDS', (void *) ((*vsi).first).c_str(), idSize );
  6232. //Save out the string value
  6233. idSize = strlen( ((*vsi).second).c_str() );
  6234. gi.AppendToSaveGame( 'SVSZ', &idSize, sizeof( idSize ) );
  6235. gi.AppendToSaveGame( 'SVAL', (void *) ((*vsi).second).c_str(), idSize );
  6236. }
  6237. }
  6238. /*
  6239. -------------------------
  6240. VariableSave
  6241. -------------------------
  6242. */
  6243. int CQuake3GameInterface::VariableSave( void )
  6244. {
  6245. VariableSaveFloats( m_varFloats );
  6246. VariableSaveStrings( m_varStrings );
  6247. VariableSaveStrings( m_varVectors);
  6248. return qtrue;
  6249. }
  6250. /*
  6251. -------------------------
  6252. VariableLoadFloats
  6253. -------------------------
  6254. */
  6255. void CQuake3GameInterface::VariableLoadFloats( varFloat_m &fmap )
  6256. {
  6257. int numFloats;
  6258. char tempBuffer[1024];
  6259. gi.ReadFromSaveGame( 'FVAR', &numFloats, sizeof( numFloats ) );
  6260. for ( int i = 0; i < numFloats; i++ )
  6261. {
  6262. int idSize;
  6263. gi.ReadFromSaveGame( 'FIDL', &idSize, sizeof( idSize ) );
  6264. gi.ReadFromSaveGame( 'FIDS', &tempBuffer, idSize );
  6265. tempBuffer[ idSize ] = 0;
  6266. float val;
  6267. gi.ReadFromSaveGame( 'FVAL', &val, sizeof( float ) );
  6268. DeclareVariable( TK_FLOAT, (const char *) &tempBuffer );
  6269. SetFloatVariable( (const char *) &tempBuffer, val );
  6270. }
  6271. }
  6272. /*
  6273. -------------------------
  6274. VariableLoadStrings
  6275. -------------------------
  6276. */
  6277. void CQuake3GameInterface::VariableLoadStrings( int type, varString_m &fmap )
  6278. {
  6279. int numFloats;
  6280. char tempBuffer[1024];
  6281. char tempBuffer2[1024];
  6282. gi.ReadFromSaveGame( 'SVAR', &numFloats, sizeof( numFloats ) );
  6283. for ( int i = 0; i < numFloats; i++ )
  6284. {
  6285. int idSize;
  6286. gi.ReadFromSaveGame( 'SIDL', &idSize, sizeof( idSize ) );
  6287. gi.ReadFromSaveGame( 'SIDS', &tempBuffer, idSize );
  6288. tempBuffer[ idSize ] = 0;
  6289. gi.ReadFromSaveGame( 'SVSZ', &idSize, sizeof( idSize ) );
  6290. gi.ReadFromSaveGame( 'SVAL', &tempBuffer2, idSize );
  6291. tempBuffer2[ idSize ] = 0;
  6292. switch ( type )
  6293. {
  6294. case TK_STRING:
  6295. DeclareVariable( TK_STRING, (const char *) &tempBuffer );
  6296. SetStringVariable( (const char *) &tempBuffer, (const char *) &tempBuffer2 );
  6297. break;
  6298. case TK_VECTOR:
  6299. DeclareVariable( TK_VECTOR, (const char *) &tempBuffer );
  6300. SetVectorVariable( (const char *) &tempBuffer, (const char *) &tempBuffer2 );
  6301. break;
  6302. }
  6303. }
  6304. }
  6305. /*
  6306. -------------------------
  6307. VariableLoad
  6308. -------------------------
  6309. */
  6310. int CQuake3GameInterface::VariableLoad( void )
  6311. {
  6312. InitVariables();
  6313. VariableLoadFloats( m_varFloats );
  6314. VariableLoadStrings( TK_STRING, m_varStrings );
  6315. VariableLoadStrings( TK_VECTOR, m_varVectors);
  6316. return qfalse;
  6317. }
  6318. // Static Singleton Instance.
  6319. CQuake3GameInterface *CQuake3GameInterface::m_pInstance = NULL;
  6320. // Destructor.
  6321. IGameInterface::~IGameInterface() {}
  6322. int IGameInterface::s_IcarusFlavorsNeeded = 1;
  6323. // Get this Interface Instance.
  6324. IGameInterface *IGameInterface::GetGame( int flavor )
  6325. {
  6326. // If no instance exists, create one...
  6327. if ( !CQuake3GameInterface::m_pInstance )
  6328. {
  6329. CQuake3GameInterface::m_pInstance = new CQuake3GameInterface();
  6330. }
  6331. return CQuake3GameInterface::m_pInstance;
  6332. }
  6333. // Destroy the game Instance.
  6334. void IGameInterface::Destroy()
  6335. {
  6336. if ( CQuake3GameInterface::m_pInstance )
  6337. {
  6338. delete CQuake3GameInterface::m_pInstance;
  6339. CQuake3GameInterface::m_pInstance = NULL;
  6340. }
  6341. }
  6342. // Constructor.
  6343. CQuake3GameInterface::CQuake3GameInterface() : IGameInterface()
  6344. {
  6345. m_ScriptList.clear();
  6346. m_EntityList.clear();
  6347. m_numVariables = 0;
  6348. m_entFilter = -1;
  6349. gclient_t* client = &level.clients[0];
  6350. memset(&client->sess, 0, sizeof(client->sess));
  6351. }
  6352. // Destructor.
  6353. CQuake3GameInterface::~CQuake3GameInterface()
  6354. {
  6355. scriptlist_t::iterator iterScript;
  6356. entitylist_t::iterator iterEntity;
  6357. gentity_t *ent = &g_entities[0];
  6358. // Release all entities Icarus resources.
  6359. for ( int i = 0; i < globals.num_entities; i++, ent++ )
  6360. {
  6361. if ( !ent->inuse )
  6362. continue;
  6363. FreeEntity( ent );
  6364. }
  6365. // Clear out all precached script's.
  6366. for ( iterScript = m_ScriptList.begin(); iterScript != m_ScriptList.end(); iterScript++ )
  6367. {
  6368. Free( (*iterScript).second->buffer );
  6369. delete (*iterScript).second;
  6370. }
  6371. m_ScriptList.clear();
  6372. m_EntityList.clear();
  6373. }
  6374. // Initialize an Entity by ID.
  6375. bool CQuake3GameInterface::InitEntity( gentity_t *pEntity )
  6376. {
  6377. //Make sure this is a fresh entity.
  6378. assert( pEntity->m_iIcarusID == IIcarusInterface::ICARUS_INVALID );
  6379. if ( pEntity->m_iIcarusID != IIcarusInterface::ICARUS_INVALID )
  6380. return false;
  6381. // Get an Icarus ID.
  6382. pEntity->m_iIcarusID = IIcarusInterface::GetIcarus()->GetIcarusID( pEntity->s.number );
  6383. // Initialize all taskIDs to -1
  6384. memset( &pEntity->taskID, -1, sizeof( pEntity->taskID ) );
  6385. // Add this entity to a map of valid associated entity's for quick retrieval later.
  6386. AssociateEntity( pEntity );
  6387. //Precache all the entity's scripts.
  6388. PrecacheEntity( pEntity );
  6389. return false;
  6390. }
  6391. // Free an Entity by ID.
  6392. void CQuake3GameInterface::FreeEntity( gentity_t *pEntity )
  6393. {
  6394. //Make sure the entity is valid
  6395. if ( pEntity->m_iIcarusID == IIcarusInterface::ICARUS_INVALID )
  6396. return;
  6397. // Remove the Entity from the Entity map so that when their g_entity index is reused,
  6398. // ICARUS doesn't try to affect the new (incorrect) pEntity.
  6399. if VALIDSTRING( pEntity->script_targetname )
  6400. {
  6401. char temp[1024];
  6402. strncpy( (char *) temp, pEntity->script_targetname, 1023 );
  6403. temp[ 1023 ] = 0;
  6404. entitylist_t::iterator it = m_EntityList.find( strupr(temp) );
  6405. if (it != m_EntityList.end())
  6406. {
  6407. m_EntityList.erase(it);
  6408. }
  6409. }
  6410. // Delete the Icarus ID, but lets not construct icarus to do it
  6411. if (IIcarusInterface::GetIcarus(0,false))
  6412. {
  6413. IIcarusInterface::GetIcarus()->DeleteIcarusID( pEntity->m_iIcarusID );
  6414. }
  6415. }
  6416. // Determines whether or not a Game Element needs ICARUS information.
  6417. bool CQuake3GameInterface::ValidEntity( gentity_t *pEntity )
  6418. {
  6419. int i;
  6420. // Targeted by a script.
  6421. if ( pEntity->script_targetname && pEntity->script_targetname[0] )
  6422. return true;
  6423. // Potentially able to call a script.
  6424. for ( i = 0; i < NUM_BSETS; i++ )
  6425. {
  6426. if VALIDSTRING( pEntity->behaviorSet[i] )
  6427. {
  6428. //Com_Printf( "WARNING: Entity %d (%s) has behaviorSet but no script_targetname -- using targetname\n", pEntity->s.number, pEntity->targetname );
  6429. pEntity->script_targetname = G_NewString(pEntity->targetname);
  6430. return true;
  6431. }
  6432. }
  6433. return false;
  6434. }
  6435. // Associate the entity's id and name so that it can be referenced later.
  6436. void CQuake3GameInterface::AssociateEntity( gentity_t *pEntity )
  6437. {
  6438. char temp[1024];
  6439. if ( VALIDSTRING( pEntity->script_targetname ) == false )
  6440. return;
  6441. strncpy( (char *) temp, pEntity->script_targetname, 1023 );
  6442. temp[ 1023 ] = 0;
  6443. m_EntityList[ strupr( (char *) temp ) ] = pEntity->s.number;
  6444. }
  6445. // Make a valid script name.
  6446. int CQuake3GameInterface::MakeValidScriptName( char **strScriptName )
  6447. {
  6448. if ( !Q_stricmp( *strScriptName, "NULL" ) || !Q_stricmp( *strScriptName, "default" ) )
  6449. return 0;
  6450. // ensure "scripts" (Q3_SCRIPT_DIR), which will be missing if this was called recursively...
  6451. // MAX_FILENAME_LENGTH should really be MAX_QPATH (and 64 bytes instead of 1024), but this fits the rest of the code
  6452. char sFilename[MAX_FILENAME_LENGTH];
  6453. if ( !Q_stricmpn( *strScriptName, Q3_SCRIPT_DIR, strlen( Q3_SCRIPT_DIR ) ) )
  6454. {
  6455. Q_strncpyz( sFilename, *strScriptName, sizeof( sFilename ) );
  6456. }
  6457. else
  6458. {
  6459. Q_strncpyz( sFilename, va( "%s/%s", Q3_SCRIPT_DIR, *strScriptName ), sizeof( sFilename ) );
  6460. }
  6461. return 1;
  6462. }
  6463. // First looks to see if a script has already been loaded, if so, return SCRIPT_ALREADYREGISTERED. If a script has
  6464. // NOT been already cached, that script is loaded and the return is SCRIPT_REGISTERED. If a script could not
  6465. // be found cached and could not be loaded we return SCRIPT_COULDNOTREGISTER.
  6466. int CQuake3GameInterface::RegisterScript( const char *strFileName, void **ppBuf, int &iLength )
  6467. {
  6468. // If the file name is invalid, leave.
  6469. if ( !strFileName || strFileName[0] == '\0' || !Q_stricmp( strFileName, "NULL" ) || !Q_stricmp( strFileName, "default" ) )
  6470. return SCRIPT_COULDNOTREGISTER;
  6471. // Ensure "scripts" (Q3_SCRIPT_DIR), which will be missing if this was called recursively...
  6472. // MAX_FILENAME_LENGTH should really be MAX_QPATH (and 64 bytes instead of 1024), but this fits the rest of the code
  6473. char sFilename[MAX_FILENAME_LENGTH];
  6474. if ( !Q_stricmpn( strFileName, Q3_SCRIPT_DIR, strlen( Q3_SCRIPT_DIR ) ) )
  6475. {
  6476. Q_strncpyz( sFilename, strFileName, sizeof( sFilename ) );
  6477. }
  6478. else
  6479. {
  6480. Q_strncpyz( sFilename, va( "%s/%s", Q3_SCRIPT_DIR, strFileName ), sizeof( sFilename ) );
  6481. }
  6482. scriptlist_t::iterator ei;
  6483. pscript_t *pscript;
  6484. // Make sure this isn't already cached
  6485. ei = m_ScriptList.find( strFileName );
  6486. // If we found the script (didn't get to the end of the list), return true.
  6487. if ( ei != m_ScriptList.end() )
  6488. {
  6489. // Send back the script buffer info.
  6490. (*ppBuf) = (*ei).second->buffer;
  6491. iLength = (*ei).second->length;
  6492. return SCRIPT_ALREADYREGISTERED;
  6493. }
  6494. // Prepare the name with the extension.
  6495. char newname[MAX_FILENAME_LENGTH];
  6496. sprintf((char *) newname, "%s%s", sFilename, IBI_EXT );
  6497. qboolean qbIgnoreFileRead = qfalse;
  6498. // NOTENOTE: For the moment I've taken this back out, to avoid doubling the number of fopen()'s per file.
  6499. /*#if 0//#ifndef FINAL_BUILD
  6500. // small update here, if called during interrogate, don't let gi.FS_ReadFile() complain because it can't
  6501. // find stuff like BS_RUN_AND_SHOOT as scriptname... During FINALBUILD the message won't appear anyway, hence
  6502. // the ifndef, this just cuts down on internal error reports while testing release mode...
  6503. //
  6504. if (bCalledDuringInterrogate)
  6505. {
  6506. fileHandle_t file;
  6507. gi.FS_FOpenFile( newname, &file, FS_READ );
  6508. if ( file == NULL )
  6509. {
  6510. qbIgnoreFileRead = qtrue; // warn disk code further down not to try FS_ReadFile()
  6511. }
  6512. else
  6513. {
  6514. gi.FS_FCloseFile( file );
  6515. }
  6516. }
  6517. #endif*/
  6518. // Read the Script File into the Buffer.
  6519. char *pBuf = NULL;
  6520. iLength = qbIgnoreFileRead ? -1 : gi.FS_ReadFile( newname, (void **) &pBuf );
  6521. if ( iLength <= 0 )
  6522. {
  6523. // File not found, but keep quiet during interrogate stage, because of stuff like BS_RUN_AND_SHOOT as scriptname
  6524. //
  6525. /* if (!bCalledDuringInterrogate)
  6526. {
  6527. Com_Printf(S_COLOR_RED"Could not open file '%s'\n", newname );
  6528. }*/
  6529. return SCRIPT_COULDNOTREGISTER;
  6530. }
  6531. // Allocate a new pscript (Script Buffer).
  6532. pscript = new pscript_t;
  6533. // Allocate a buffer of the size we need then mem copy over the buffer.
  6534. pscript->buffer = (char *)Malloc( iLength );
  6535. memcpy( pscript->buffer, pBuf, iLength );
  6536. pscript->length = iLength;
  6537. // We (mem)copied the data over so release the original buffer.
  6538. gi.FS_FreeFile( pBuf );
  6539. // Keep track of the buffer still.
  6540. (*ppBuf) = pscript->buffer;
  6541. // Add the Script Buffer to the STL map.
  6542. m_ScriptList[strFileName] = pscript;
  6543. return SCRIPT_REGISTERED;
  6544. }
  6545. // Precache all the resources needed by a Script and it's Entity (or vice-versa).
  6546. int CQuake3GameInterface::PrecacheEntity( gentity_t *pEntity )
  6547. {
  6548. extern stringID_table_t BSTable[];
  6549. int i;
  6550. for ( i = 0; i < NUM_BSETS; i++ )
  6551. {
  6552. if ( pEntity->behaviorSet[i] == NULL )
  6553. continue;
  6554. if ( GetIDForString( BSTable, pEntity->behaviorSet[i] ) == -1 )
  6555. {//not a behavior set
  6556. char *pBuf = NULL;
  6557. int iLength = 0;
  6558. // Try to register this script.
  6559. if ( RegisterScript( pEntity->behaviorSet[i], (void **) &pBuf, iLength ) != SCRIPT_COULDNOTREGISTER )
  6560. {
  6561. assert( pBuf );
  6562. assert( iLength );
  6563. if ( pBuf != NULL && iLength > 0 )
  6564. // Tell Icarus to precache the script data.
  6565. IIcarusInterface::GetIcarus()->Precache( pBuf, iLength );
  6566. }
  6567. else
  6568. // otherwise try the next guy, maybe It will work.
  6569. continue;
  6570. }
  6571. }
  6572. return 0;
  6573. }
  6574. // Run the script.
  6575. void CQuake3GameInterface::RunScript( const gentity_t *pEntity, const char *strScriptName )
  6576. {
  6577. char *pBuf = NULL;
  6578. int iLength = 0;
  6579. switch( RegisterScript( strScriptName, (void **) &pBuf, iLength ) )
  6580. {
  6581. // If could not be loaded, leave!
  6582. case SCRIPT_COULDNOTREGISTER:
  6583. DebugPrint( WL_WARNING, "RunScript: Script was not found and could not be loaded!!! %s\n", strScriptName);
  6584. return;
  6585. // We loaded the script and registered it, so run it!
  6586. case SCRIPT_REGISTERED:
  6587. case SCRIPT_ALREADYREGISTERED:
  6588. assert( pBuf );
  6589. assert( iLength );
  6590. if ( IIcarusInterface::GetIcarus()->Run( pEntity->m_iIcarusID, pBuf, iLength ) != IIcarusInterface::ICARUS_INVALID )
  6591. DebugPrint( WL_VERBOSE, "%d Script %s executed by %s %s\n", level.time, (char *) strScriptName, pEntity->classname, pEntity->targetname );
  6592. return;
  6593. }
  6594. }
  6595. void CQuake3GameInterface::Svcmd( void )
  6596. {
  6597. char *cmd = gi.argv( 1 );
  6598. if ( Q_stricmp( cmd, "log" ) == 0 )
  6599. {
  6600. g_ICARUSDebug->integer = WL_DEBUG;
  6601. if ( VALIDSTRING( gi.argv( 2 ) ) )
  6602. {
  6603. gentity_t *ent = G_Find( NULL, FOFS( script_targetname ), gi.argv(2) );
  6604. if ( ent == NULL )
  6605. {
  6606. Com_Printf( "Entity \"%s\" not found!\n", gi.argv(2) );
  6607. return;
  6608. }
  6609. //Start logging
  6610. Com_Printf("Logging ICARUS info for entity %s\n", gi.argv(2) );
  6611. m_entFilter = ( ent->s.number == m_entFilter ) ? -1 : ent->s.number;
  6612. }
  6613. Com_Printf("Logging ICARUS info for all entities\n");
  6614. }
  6615. }
  6616. // Get the current Game flavor.
  6617. int CQuake3GameInterface::GetFlavor()
  6618. {
  6619. return 0;
  6620. }
  6621. // Reads in a file and attaches the script directory properly.
  6622. int CQuake3GameInterface::LoadFile( const char *name, void **buf )
  6623. {
  6624. int iLength = 0;
  6625. // Register the Script (or retrieve it).
  6626. RegisterScript( name, buf, iLength );
  6627. return iLength;
  6628. }
  6629. // Prints a message in the center of the screen.
  6630. void CQuake3GameInterface::CenterPrint( const char *format, ... )
  6631. {
  6632. va_list argptr;
  6633. char text[1024];
  6634. va_start (argptr, format);
  6635. vsprintf (text, format, argptr);
  6636. va_end (argptr);
  6637. // FIXME: added '!' so you can print something that's hasn't been precached, '@' searches only for precache text
  6638. // this is just a TEMPORARY placeholder until objectives are in!!! -- dmv 11/26/01
  6639. if ((text[0] == '@') || text[0] == '!') // It's a key
  6640. {
  6641. if( text[0] == '!')
  6642. {
  6643. gi.SendServerCommand( NULL, "cp \"%s\"", (text+1) );
  6644. return;
  6645. }
  6646. gi.SendServerCommand( NULL, "cp \"%s\"", text );
  6647. }
  6648. DebugPrint( WL_VERBOSE, "%s\n", text); // Just a developers note
  6649. }
  6650. // Print a debug message.
  6651. void CQuake3GameInterface::DebugPrint( e_DebugPrintLevel level, const char *format, ... )
  6652. {
  6653. //Don't print messages they don't want to see
  6654. if ( g_ICARUSDebug->integer < level )
  6655. return;
  6656. va_list argptr;
  6657. char text[1024];
  6658. va_start (argptr, format);
  6659. vsprintf (text, format, argptr);
  6660. va_end (argptr);
  6661. //Add the color formatting
  6662. switch ( level )
  6663. {
  6664. case WL_ERROR:
  6665. Com_Printf ( S_COLOR_RED"ERROR: %s", text );
  6666. break;
  6667. case WL_WARNING:
  6668. Com_Printf ( S_COLOR_YELLOW"WARNING: %s", text );
  6669. break;
  6670. case WL_DEBUG:
  6671. {
  6672. int entNum;
  6673. char *buffer;
  6674. sscanf( text, "%d", &entNum );
  6675. if ( ( m_entFilter >= 0 ) && ( m_entFilter != entNum ) )
  6676. return;
  6677. buffer = (char *) text;
  6678. buffer += 5;
  6679. if ( ( entNum < 0 ) || ( entNum > MAX_GENTITIES ) )
  6680. entNum = 0;
  6681. Com_Printf ( S_COLOR_BLUE"DEBUG: %s(%d): %s\n", g_entities[entNum].script_targetname, entNum, buffer );
  6682. break;
  6683. }
  6684. default:
  6685. case WL_VERBOSE:
  6686. Com_Printf ( S_COLOR_GREEN"INFO: %s", text );
  6687. break;
  6688. }
  6689. }
  6690. //Gets the current time
  6691. unsigned int CQuake3GameInterface::GetTime( void )
  6692. {
  6693. return level.time;
  6694. }
  6695. // DWORD CQuake3GameInterface::GetTimeScale(void ) {}
  6696. // NOTE: This extern does not really fit here, fix later please...
  6697. extern void G_SoundBroadcast( gentity_t *ent, int soundIndex );
  6698. // Plays a sound from an entity.
  6699. int CQuake3GameInterface::PlaySound( int taskID, int entID, const char *name, const char *channel )
  6700. {
  6701. gentity_t *ent = &g_entities[entID];
  6702. char finalName[MAX_QPATH];
  6703. soundChannel_t voice_chan = CHAN_VOICE; // set a default so the compiler doesn't bitch
  6704. qboolean type_voice = qfalse;
  6705. Q_strncpyz( finalName, name, MAX_QPATH, 0 );
  6706. strlwr(finalName);
  6707. G_AddSexToPlayerString( finalName, qtrue );
  6708. COM_StripExtension( (const char *)finalName, finalName );
  6709. int soundHandle = G_SoundIndex( (char *) finalName );
  6710. bool bBroadcast = false;
  6711. if ( ( stricmp( channel, "CHAN_ANNOUNCER" ) == 0 ) || (ent->classname && Q_stricmp("target_scriptrunner", ent->classname ) == 0) ) {
  6712. bBroadcast = true;
  6713. }
  6714. // moved here from further down so I can easily check channel-type without code dup...
  6715. //
  6716. if ( stricmp( channel, "CHAN_VOICE" ) == 0 )
  6717. {
  6718. voice_chan = CHAN_VOICE;
  6719. type_voice = qtrue;
  6720. }
  6721. else if ( stricmp( channel, "CHAN_VOICE_ATTEN" ) == 0 )
  6722. {
  6723. voice_chan = CHAN_VOICE_ATTEN;
  6724. type_voice = qtrue;
  6725. }
  6726. else if ( stricmp( channel, "CHAN_VOICE_GLOBAL" ) == 0 ) // this should broadcast to everyone, put only casue animation on G_SoundOnEnt...
  6727. {
  6728. voice_chan = CHAN_VOICE_GLOBAL;
  6729. type_voice = qtrue;
  6730. bBroadcast = true;
  6731. }
  6732. // if we're in-camera, check for skipping cinematic and ifso, no subtitle print (since screen is not being
  6733. // updated anyway during skipping). This stops leftover subtitles being left onscreen after unskipping.
  6734. //
  6735. if (!in_camera ||
  6736. (!g_skippingcin || !g_skippingcin->integer)
  6737. ) // paranoia towards project end <g>
  6738. {
  6739. // Text on
  6740. // certain NPC's we always want to use subtitles regardless of subtitle setting
  6741. if (g_subtitles->integer == 1 || (ent->NPC && (ent->NPC->scriptFlags & SCF_USE_SUBTITLES) ) ) // Show all text
  6742. {
  6743. if ( in_camera) // Cinematic
  6744. {
  6745. gi.SendServerCommand( NULL, "ct \"%s\" %i", finalName, soundHandle );
  6746. }
  6747. else //if (precacheWav[i].speaker==SP_NONE) // lower screen text
  6748. {
  6749. gentity_t *ent2 = &g_entities[0];
  6750. // the numbers in here were either the original ones Bob entered (350), or one arrived at from checking the distance Chell stands at in stasis2 by the computer core that was submitted as a bug report...
  6751. //
  6752. if (bBroadcast || (DistanceSquared(ent->currentOrigin, ent2->currentOrigin) < ((voice_chan == CHAN_VOICE_ATTEN)?(350 * 350):(1200 * 1200)) ) )
  6753. {
  6754. gi.SendServerCommand( NULL, "ct \"%s\" %i", finalName, soundHandle );
  6755. }
  6756. }
  6757. }
  6758. // Cinematic only
  6759. else if (g_subtitles->integer == 2) // Show only talking head text and CINEMATIC
  6760. {
  6761. if ( in_camera) // Cinematic text
  6762. {
  6763. gi.SendServerCommand( NULL, "ct \"%s\" %i", finalName, soundHandle);
  6764. }
  6765. }
  6766. }
  6767. if ( type_voice )
  6768. {
  6769. if ( g_timescale->value > 1.0f )
  6770. {//Skip the damn sound!
  6771. return qtrue;
  6772. }
  6773. else
  6774. {
  6775. //This the voice channel
  6776. G_SoundOnEnt( ent, voice_chan, ((char *) finalName) );
  6777. }
  6778. //Remember we're waiting for this
  6779. Q3_TaskIDSet( ent, TID_CHAN_VOICE, taskID );
  6780. //do not task_return complete
  6781. // if( voice_chan == CHAN_VOICE_GLOBAL )
  6782. // {
  6783. // G_SoundBroadcast( ent, soundHandle );
  6784. // }
  6785. return qfalse;
  6786. }
  6787. if ( bBroadcast )
  6788. {//Broadcast the sound
  6789. G_SoundBroadcast( ent, soundHandle );
  6790. }
  6791. else
  6792. {
  6793. G_Sound( ent, soundHandle );
  6794. }
  6795. return qtrue;
  6796. }
  6797. // Lerps the origin and angles of an entity to the destination values.
  6798. void CQuake3GameInterface::Lerp2Pos( int taskID, int entID, vec3_t origin, vec3_t angles, float duration )
  6799. {
  6800. gentity_t *ent = &g_entities[entID];
  6801. vec3_t ang;
  6802. int i;
  6803. if(!ent)
  6804. {
  6805. DebugPrint( WL_WARNING, "Lerp2Pos: invalid entID %d\n", entID);
  6806. return;
  6807. }
  6808. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  6809. {
  6810. DebugPrint( WL_ERROR, "Lerp2Pos: ent %d is NOT a mover!\n", entID);
  6811. return;
  6812. }
  6813. if ( ent->s.eType != ET_MOVER )
  6814. {
  6815. ent->s.eType = ET_MOVER;
  6816. }
  6817. //Don't allow a zero duration
  6818. if ( duration == 0 )
  6819. duration = 1;
  6820. //
  6821. // Movement
  6822. moverState_t moverState = ent->moverState;
  6823. if ( moverState == MOVER_POS1 || moverState == MOVER_2TO1 )
  6824. {
  6825. VectorCopy( ent->currentOrigin, ent->pos1 );
  6826. VectorCopy( origin, ent->pos2 );
  6827. if ( moverState == MOVER_POS1 )
  6828. {//open the portal
  6829. if ( ent->svFlags & SVF_MOVER_ADJ_AREA_PORTALS )
  6830. {
  6831. gi.AdjustAreaPortalState( ent, qtrue );
  6832. }
  6833. }
  6834. moverState = MOVER_1TO2;
  6835. }
  6836. else /*if ( moverState == MOVER_POS2 || moverState == MOVER_1TO2 )*/
  6837. {
  6838. VectorCopy( ent->currentOrigin, ent->pos2 );
  6839. VectorCopy( origin, ent->pos1 );
  6840. moverState = MOVER_2TO1;
  6841. }
  6842. InitMoverTrData( ent );
  6843. ent->s.pos.trDuration = duration;
  6844. // start it going
  6845. MatchTeam( ent, moverState, level.time );
  6846. //SetMoverState( ent, moverState, level.time );
  6847. //Only do the angles if specified
  6848. if ( angles != NULL )
  6849. {
  6850. //
  6851. // Rotation
  6852. for ( i = 0; i < 3; i++ )
  6853. {
  6854. ang[i] = AngleDelta( angles[i], ent->currentAngles[i] );
  6855. ent->s.apos.trDelta[i] = ( ang[i] / ( duration * 0.001f ) );
  6856. }
  6857. VectorCopy( ent->currentAngles, ent->s.apos.trBase );
  6858. if ( ent->alt_fire )
  6859. {
  6860. ent->s.apos.trType = TR_LINEAR_STOP;
  6861. }
  6862. else
  6863. {
  6864. ent->s.apos.trType = TR_NONLINEAR_STOP;
  6865. }
  6866. ent->s.apos.trDuration = duration;
  6867. ent->s.apos.trTime = level.time;
  6868. ent->e_ReachedFunc = reachedF_moveAndRotateCallback;
  6869. Q3_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
  6870. }
  6871. else
  6872. {
  6873. //Setup the last bits of information
  6874. ent->e_ReachedFunc = reachedF_moverCallback;
  6875. }
  6876. if ( ent->damage )
  6877. {
  6878. ent->e_BlockedFunc = blockedF_Blocked_Mover;
  6879. }
  6880. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  6881. // starting sound
  6882. G_PlayDoorLoopSound( ent );
  6883. G_PlayDoorSound( ent, BMS_START ); //??
  6884. gi.linkentity( ent );
  6885. }
  6886. // void CQuake3GameInterface::Lerp2Origin( int taskID, int entID, vec3_t origin, float duration ) {}
  6887. // Lerps the angles to the destination value.
  6888. void CQuake3GameInterface::Lerp2Angles( int taskID, int entID, vec3_t angles, float duration )
  6889. {
  6890. gentity_t *ent = &g_entities[entID];
  6891. vec3_t ang;
  6892. int i;
  6893. if(!ent)
  6894. {
  6895. DebugPrint( WL_WARNING, "Lerp2Angles: invalid entID %d\n", entID);
  6896. return;
  6897. }
  6898. if ( ent->client || ent->NPC || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
  6899. {
  6900. DebugPrint( WL_ERROR, "Lerp2Angles: ent %d is NOT a mover!\n", entID);
  6901. return;
  6902. }
  6903. //If we want an instant move, don't send 0...
  6904. ent->s.apos.trDuration = (duration>0) ? duration : 1;
  6905. for ( i = 0; i < 3; i++ )
  6906. {
  6907. ang [i] = AngleSubtract( angles[i], ent->currentAngles[i]);
  6908. ent->s.apos.trDelta[i] = ( ang[i] / ( ent->s.apos.trDuration * 0.001f ) );
  6909. }
  6910. VectorCopy( ent->currentAngles, ent->s.apos.trBase );
  6911. if ( ent->alt_fire )
  6912. {
  6913. ent->s.apos.trType = TR_LINEAR_STOP;
  6914. }
  6915. else
  6916. {
  6917. ent->s.apos.trType = TR_NONLINEAR_STOP;
  6918. }
  6919. ent->s.apos.trTime = level.time;
  6920. Q3_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
  6921. //ent->e_ReachedFunc = reachedF_NULL;
  6922. ent->e_ThinkFunc = thinkF_anglerCallback;
  6923. ent->nextthink = level.time + duration;
  6924. // starting sound
  6925. G_PlayDoorLoopSound( ent );
  6926. G_PlayDoorSound( ent, BMS_START ); //??
  6927. gi.linkentity( ent );
  6928. }
  6929. // Gets the value of a tag by the give name.
  6930. int CQuake3GameInterface::GetTag( int entID, const char *name, int lookup, vec3_t info )
  6931. {
  6932. gentity_t *ent = &g_entities[ entID ];
  6933. VALIDATEB( ent );
  6934. switch ( lookup )
  6935. {
  6936. case TYPE_ORIGIN:
  6937. //return TAG_GetOrigin( ent->targetname, name, info );
  6938. return TAG_GetOrigin( ent->ownername, name, info );
  6939. break;
  6940. case TYPE_ANGLES:
  6941. //return TAG_GetAngles( ent->targetname, name, info );
  6942. return TAG_GetAngles( ent->ownername, name, info );
  6943. break;
  6944. }
  6945. return false;
  6946. }
  6947. // void CQuake3GameInterface::Lerp2Start( int taskID, int entID, float duration ) {}
  6948. // void CQuake3GameInterface::Lerp2End( int taskID, int entID, float duration ) {}
  6949. void CQuake3GameInterface::Set( int taskID, int entID, const char *type_name, const char *data )
  6950. {
  6951. gentity_t *ent = &g_entities[entID];
  6952. float float_data;
  6953. int int_data, toSet;
  6954. vec3_t vector_data;
  6955. //Set this for callbacks
  6956. toSet = GetIDForString( setTable, type_name );
  6957. //TODO: Throw in a showscript command that will list each command and what they're doing...
  6958. // maybe as simple as printing that line of the script to the console preceeded by the person's name?
  6959. // showscript can take any number of targetnames or "all"? Groupname?
  6960. switch ( toSet )
  6961. {
  6962. case SET_ORIGIN:
  6963. sscanf( data, "%f %f %f", &vector_data[0], &vector_data[1], &vector_data[2] );
  6964. G_SetOrigin( ent, vector_data );
  6965. if ( Q_strncmp( "NPC_", ent->classname, 4 ) == 0 )
  6966. {//hack for moving spawners
  6967. VectorCopy( vector_data, ent->s.origin);
  6968. }
  6969. if ( ent->client )
  6970. {//clear jump start positions so we don't take damage when we land...
  6971. ent->client->ps.jumpZStart = ent->client->ps.forceJumpZStart = vector_data[2];
  6972. }
  6973. gi.linkentity( ent );
  6974. break;
  6975. case SET_TELEPORT_DEST:
  6976. sscanf( data, "%f %f %f", &vector_data[0], &vector_data[1], &vector_data[2] );
  6977. if ( !Q3_SetTeleportDest( entID, vector_data ) )
  6978. {
  6979. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  6980. return;
  6981. }
  6982. break;
  6983. case SET_COPY_ORIGIN:
  6984. Q3_SetCopyOrigin( entID, (char *) data );
  6985. break;
  6986. case SET_ANGLES:
  6987. //Q3_SetAngles( entID, *(vec3_t *) data);
  6988. sscanf( data, "%f %f %f", &vector_data[0], &vector_data[1], &vector_data[2] );
  6989. Q3_SetAngles( entID, vector_data);
  6990. break;
  6991. case SET_XVELOCITY:
  6992. float_data = atof((char *) data);
  6993. Q3_SetVelocity( entID, 0, float_data);
  6994. break;
  6995. case SET_YVELOCITY:
  6996. float_data = atof((char *) data);
  6997. Q3_SetVelocity( entID, 1, float_data);
  6998. break;
  6999. case SET_ZVELOCITY:
  7000. float_data = atof((char *) data);
  7001. Q3_SetVelocity( entID, 2, float_data);
  7002. break;
  7003. case SET_Z_OFFSET:
  7004. float_data = atof((char *) data);
  7005. Q3_SetOriginOffset( entID, 2, float_data);
  7006. break;
  7007. case SET_ENEMY:
  7008. Q3_SetEnemy( entID, (char *) data );
  7009. break;
  7010. case SET_LEADER:
  7011. Q3_SetLeader( entID, (char *) data );
  7012. break;
  7013. case SET_NAVGOAL:
  7014. if ( Q3_SetNavGoal( entID, (char *) data ) )
  7015. {
  7016. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  7017. return; //Don't call it back
  7018. }
  7019. break;
  7020. case SET_ANIM_UPPER:
  7021. if ( Q3_SetAnimUpper( entID, (char *) data ) )
  7022. {
  7023. Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the top
  7024. Q3_TaskIDSet( ent, TID_ANIM_UPPER, taskID );
  7025. return; //Don't call it back
  7026. }
  7027. break;
  7028. case SET_ANIM_LOWER:
  7029. if ( Q3_SetAnimLower( entID, (char *) data ) )
  7030. {
  7031. Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the bottom
  7032. Q3_TaskIDSet( ent, TID_ANIM_LOWER, taskID );
  7033. return; //Don't call it back
  7034. }
  7035. break;
  7036. case SET_ANIM_BOTH:
  7037. {
  7038. int both = 0;
  7039. if ( Q3_SetAnimUpper( entID, (char *) data ) )
  7040. {
  7041. Q3_TaskIDSet( ent, TID_ANIM_UPPER, taskID );
  7042. both++;
  7043. }
  7044. else
  7045. {
  7046. DebugPrint( WL_ERROR, "SetAnimUpper: %s does not have anim %s!\n", ent->targetname, (char *)data );
  7047. }
  7048. if ( Q3_SetAnimLower( entID, (char *) data ) )
  7049. {
  7050. Q3_TaskIDSet( ent, TID_ANIM_LOWER, taskID );
  7051. both++;
  7052. }
  7053. else
  7054. {
  7055. DebugPrint( WL_ERROR, "SetAnimLower: %s does not have anim %s!\n", ent->targetname, (char *)data );
  7056. }
  7057. if ( both >= 2 )
  7058. {
  7059. Q3_TaskIDSet( ent, TID_ANIM_BOTH, taskID );
  7060. }
  7061. if ( both )
  7062. {
  7063. return; //Don't call it back
  7064. }
  7065. }
  7066. break;
  7067. case SET_ANIM_HOLDTIME_LOWER:
  7068. int_data = atoi((char *) data);
  7069. Q3_SetAnimHoldTime( entID, int_data, qtrue );
  7070. Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the bottom
  7071. Q3_TaskIDSet( ent, TID_ANIM_LOWER, taskID );
  7072. return; //Don't call it back
  7073. break;
  7074. case SET_ANIM_HOLDTIME_UPPER:
  7075. int_data = atoi((char *) data);
  7076. Q3_SetAnimHoldTime( entID, int_data, qfalse );
  7077. Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the top
  7078. Q3_TaskIDSet( ent, TID_ANIM_UPPER, taskID );
  7079. return; //Don't call it back
  7080. break;
  7081. case SET_ANIM_HOLDTIME_BOTH:
  7082. int_data = atoi((char *) data);
  7083. Q3_SetAnimHoldTime( entID, int_data, qfalse );
  7084. Q3_SetAnimHoldTime( entID, int_data, qtrue );
  7085. Q3_TaskIDSet( ent, TID_ANIM_BOTH, taskID );
  7086. Q3_TaskIDSet( ent, TID_ANIM_UPPER, taskID );
  7087. Q3_TaskIDSet( ent, TID_ANIM_LOWER, taskID );
  7088. return; //Don't call it back
  7089. break;
  7090. case SET_PLAYER_TEAM:
  7091. Q3_SetPlayerTeam( entID, (char *) data );
  7092. break;
  7093. case SET_ENEMY_TEAM:
  7094. Q3_SetEnemyTeam( entID, (char *) data );
  7095. break;
  7096. case SET_HEALTH:
  7097. int_data = atoi((char *) data);
  7098. Q3_SetHealth( entID, int_data );
  7099. break;
  7100. case SET_ARMOR:
  7101. int_data = atoi((char *) data);
  7102. Q3_SetArmor( entID, int_data );
  7103. break;
  7104. case SET_BEHAVIOR_STATE:
  7105. if( !Q3_SetBState( entID, (char *) data ) )
  7106. {
  7107. Q3_TaskIDSet( ent, TID_BSTATE, taskID );
  7108. return;//don't complete
  7109. }
  7110. break;
  7111. case SET_DEFAULT_BSTATE:
  7112. Q3_SetDefaultBState( entID, (char *) data );
  7113. break;
  7114. case SET_TEMP_BSTATE:
  7115. if( !Q3_SetTempBState( entID, (char *) data ) )
  7116. {
  7117. Q3_TaskIDSet( ent, TID_BSTATE, taskID );
  7118. return;//don't complete
  7119. }
  7120. break;
  7121. case SET_CAPTURE:
  7122. Q3_SetCaptureGoal( entID, (char *) data );
  7123. break;
  7124. case SET_DPITCH://FIXME: make these set tempBehavior to BS_FACE and await completion? Or set lockedDesiredPitch/Yaw and aimTime?
  7125. float_data = atof((char *) data);
  7126. Q3_SetDPitch( entID, float_data );
  7127. Q3_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
  7128. return;
  7129. break;
  7130. case SET_DYAW:
  7131. float_data = atof((char *) data);
  7132. Q3_SetDYaw( entID, float_data );
  7133. Q3_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
  7134. return;
  7135. break;
  7136. case SET_EVENT:
  7137. Q3_SetEvent( entID, (char *) data );
  7138. break;
  7139. case SET_VIEWTARGET:
  7140. Q3_SetViewTarget( entID, (char *) data );
  7141. Q3_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
  7142. return;
  7143. break;
  7144. case SET_WATCHTARGET:
  7145. Q3_SetWatchTarget( entID, (char *) data );
  7146. break;
  7147. case SET_VIEWENTITY:
  7148. Q3_SetViewEntity( entID, (char *) data );
  7149. break;
  7150. case SET_LOOPSOUND:
  7151. Q3_SetLoopSound( entID, (char *) data );
  7152. break;
  7153. case SET_ICARUS_FREEZE:
  7154. case SET_ICARUS_UNFREEZE:
  7155. Q3_SetICARUSFreeze( entID, (char *) data, (toSet==SET_ICARUS_FREEZE) );
  7156. break;
  7157. case SET_WEAPON:
  7158. Q3_SetWeapon ( entID, (char *) data);
  7159. break;
  7160. case SET_ITEM:
  7161. Q3_SetItem ( entID, (char *) data);
  7162. break;
  7163. case SET_WALKSPEED:
  7164. int_data = atoi((char *) data);
  7165. Q3_SetWalkSpeed ( entID, int_data);
  7166. break;
  7167. case SET_RUNSPEED:
  7168. int_data = atoi((char *) data);
  7169. Q3_SetRunSpeed ( entID, int_data);
  7170. break;
  7171. case SET_WIDTH:
  7172. int_data = atoi((char *) data);
  7173. Q3_SetWidth( entID, int_data );
  7174. return;
  7175. break;
  7176. case SET_YAWSPEED:
  7177. float_data = atof((char *) data);
  7178. Q3_SetYawSpeed ( entID, float_data);
  7179. break;
  7180. case SET_AGGRESSION:
  7181. int_data = atoi((char *) data);
  7182. Q3_SetAggression ( entID, int_data);
  7183. break;
  7184. case SET_AIM:
  7185. int_data = atoi((char *) data);
  7186. Q3_SetAim ( entID, int_data);
  7187. break;
  7188. case SET_FRICTION:
  7189. int_data = atoi((char *) data);
  7190. Q3_SetFriction ( entID, int_data);
  7191. break;
  7192. case SET_GRAVITY:
  7193. float_data = atof((char *) data);
  7194. Q3_SetGravity ( entID, float_data);
  7195. break;
  7196. case SET_WAIT:
  7197. float_data = atof((char *) data);
  7198. Q3_SetWait( entID, float_data);
  7199. break;
  7200. case SET_FOLLOWDIST:
  7201. float_data = atof((char *) data);
  7202. Q3_SetFollowDist( entID, float_data);
  7203. break;
  7204. case SET_SCALE:
  7205. float_data = atof((char *) data);
  7206. Q3_SetScale( entID, float_data);
  7207. break;
  7208. case SET_RENDER_CULL_RADIUS:
  7209. float_data = atof((char *) data);
  7210. Q3_SetRenderCullRadius(entID, float_data);
  7211. break;
  7212. case SET_COUNT:
  7213. Q3_SetCount( entID, (char *) data);
  7214. break;
  7215. case SET_SHOT_SPACING:
  7216. int_data = atoi((char *) data);
  7217. Q3_SetShotSpacing( entID, int_data );
  7218. break;
  7219. case SET_IGNOREPAIN:
  7220. if(!stricmp("true", ((char *)data)))
  7221. Q3_SetIgnorePain( entID, qtrue);
  7222. else if(!stricmp("false", ((char *)data)))
  7223. Q3_SetIgnorePain( entID, qfalse);
  7224. break;
  7225. case SET_IGNOREENEMIES:
  7226. if(!stricmp("true", ((char *)data)))
  7227. Q3_SetIgnoreEnemies( entID, qtrue);
  7228. else if(!stricmp("false", ((char *)data)))
  7229. Q3_SetIgnoreEnemies( entID, qfalse);
  7230. break;
  7231. case SET_IGNOREALERTS:
  7232. if(!stricmp("true", ((char *)data)))
  7233. Q3_SetIgnoreAlerts( entID, qtrue);
  7234. else if(!stricmp("false", ((char *)data)))
  7235. Q3_SetIgnoreAlerts( entID, qfalse);
  7236. break;
  7237. case SET_DONTSHOOT:
  7238. if(!stricmp("true", ((char *)data)))
  7239. Q3_SetDontShoot( entID, qtrue);
  7240. else if(!stricmp("false", ((char *)data)))
  7241. Q3_SetDontShoot( entID, qfalse);
  7242. break;
  7243. case SET_DONTFIRE:
  7244. if(!stricmp("true", ((char *)data)))
  7245. Q3_SetDontFire( entID, qtrue);
  7246. else if(!stricmp("false", ((char *)data)))
  7247. Q3_SetDontFire( entID, qfalse);
  7248. break;
  7249. case SET_LOCKED_ENEMY:
  7250. if(!stricmp("true", ((char *)data)))
  7251. Q3_SetLockedEnemy( entID, qtrue);
  7252. else if(!stricmp("false", ((char *)data)))
  7253. Q3_SetLockedEnemy( entID, qfalse);
  7254. break;
  7255. case SET_NOTARGET:
  7256. if(!stricmp("true", ((char *)data)))
  7257. Q3_SetNoTarget( entID, qtrue);
  7258. else if(!stricmp("false", ((char *)data)))
  7259. Q3_SetNoTarget( entID, qfalse);
  7260. break;
  7261. case SET_LEAN:
  7262. if(!stricmp("right", ((char *)data)))
  7263. Q3_SetLean( entID, LEAN_RIGHT);
  7264. else if(!stricmp("left", ((char *)data)))
  7265. Q3_SetLean( entID, LEAN_LEFT);
  7266. else
  7267. Q3_SetLean( entID, LEAN_NONE);
  7268. break;
  7269. case SET_SHOOTDIST:
  7270. float_data = atof((char *) data);
  7271. Q3_SetShootDist( entID, float_data );
  7272. break;
  7273. case SET_TIMESCALE:
  7274. Q3_SetTimeScale( entID, (char *) data );
  7275. break;
  7276. case SET_VISRANGE:
  7277. float_data = atof((char *) data);
  7278. Q3_SetVisrange( entID, float_data );
  7279. break;
  7280. case SET_EARSHOT:
  7281. float_data = atof((char *) data);
  7282. Q3_SetEarshot( entID, float_data );
  7283. break;
  7284. case SET_VIGILANCE:
  7285. float_data = atof((char *) data);
  7286. Q3_SetVigilance( entID, float_data );
  7287. break;
  7288. case SET_VFOV:
  7289. int_data = atoi((char *) data);
  7290. Q3_SetVFOV( entID, int_data );
  7291. break;
  7292. case SET_HFOV:
  7293. int_data = atoi((char *) data);
  7294. Q3_SetHFOV( entID, int_data );
  7295. break;
  7296. case SET_TARGETNAME:
  7297. Q3_SetTargetName( entID, (char *) data );
  7298. break;
  7299. case SET_TARGET:
  7300. Q3_SetTarget( entID, (char *) data );
  7301. break;
  7302. case SET_TARGET2:
  7303. Q3_SetTarget2( entID, (char *) data );
  7304. break;
  7305. case SET_LOCATION:
  7306. if ( !Q3_SetLocation( entID, (char *) data ) )
  7307. {
  7308. Q3_TaskIDSet( ent, TID_LOCATION, taskID );
  7309. return;
  7310. }
  7311. break;
  7312. case SET_PAINTARGET:
  7313. Q3_SetPainTarget( entID, (char *) data );
  7314. break;
  7315. case SET_DEFEND_TARGET:
  7316. DebugPrint( WL_WARNING, "SetDefendTarget unimplemented\n", entID );
  7317. //Q3_SetEnemy( entID, (char *) data);
  7318. break;
  7319. case SET_PARM1:
  7320. case SET_PARM2:
  7321. case SET_PARM3:
  7322. case SET_PARM4:
  7323. case SET_PARM5:
  7324. case SET_PARM6:
  7325. case SET_PARM7:
  7326. case SET_PARM8:
  7327. case SET_PARM9:
  7328. case SET_PARM10:
  7329. case SET_PARM11:
  7330. case SET_PARM12:
  7331. case SET_PARM13:
  7332. case SET_PARM14:
  7333. case SET_PARM15:
  7334. case SET_PARM16:
  7335. Q3_SetParm( entID, (toSet-SET_PARM1), (char *) data );
  7336. break;
  7337. case SET_SPAWNSCRIPT:
  7338. case SET_USESCRIPT:
  7339. case SET_AWAKESCRIPT:
  7340. case SET_ANGERSCRIPT:
  7341. case SET_ATTACKSCRIPT:
  7342. case SET_VICTORYSCRIPT:
  7343. case SET_PAINSCRIPT:
  7344. case SET_FLEESCRIPT:
  7345. case SET_DEATHSCRIPT:
  7346. case SET_DELAYEDSCRIPT:
  7347. case SET_BLOCKEDSCRIPT:
  7348. case SET_FFIRESCRIPT:
  7349. case SET_FFDEATHSCRIPT:
  7350. case SET_MINDTRICKSCRIPT:
  7351. if( !Q3_SetBehaviorSet(entID, toSet, (char *) data) )
  7352. DebugPrint( WL_ERROR, "SetBehaviorSet: Invalid bSet %s\n", type_name );
  7353. break;
  7354. case SET_NO_MINDTRICK:
  7355. if(!stricmp("true", ((char *)data)))
  7356. Q3_SetNoMindTrick( entID, qtrue);
  7357. else
  7358. Q3_SetNoMindTrick( entID, qfalse);
  7359. break;
  7360. case SET_CINEMATIC_SKIPSCRIPT :
  7361. Q3_SetCinematicSkipScript((char *) data);
  7362. break;
  7363. case SET_RAILCENTERTRACKLOCKED :
  7364. Rail_LockCenterOfTrack((char *) data);
  7365. break;
  7366. case SET_RAILCENTERTRACKUNLOCKED :
  7367. Rail_UnLockCenterOfTrack((char *) data);
  7368. break;
  7369. case SET_DELAYSCRIPTTIME:
  7370. int_data = atoi((char *) data);
  7371. Q3_SetDelayScriptTime( entID, int_data );
  7372. break;
  7373. case SET_CROUCHED:
  7374. if(!stricmp("true", ((char *)data)))
  7375. Q3_SetCrouched( entID, qtrue);
  7376. else
  7377. Q3_SetCrouched( entID, qfalse);
  7378. break;
  7379. case SET_WALKING:
  7380. if(!stricmp("true", ((char *)data)))
  7381. Q3_SetWalking( entID, qtrue);
  7382. else
  7383. Q3_SetWalking( entID, qfalse);
  7384. break;
  7385. case SET_RUNNING:
  7386. if(!stricmp("true", ((char *)data)))
  7387. Q3_SetRunning( entID, qtrue);
  7388. else
  7389. Q3_SetRunning( entID, qfalse);
  7390. break;
  7391. case SET_CHASE_ENEMIES:
  7392. if(!stricmp("true", ((char *)data)))
  7393. Q3_SetChaseEnemies( entID, qtrue);
  7394. else
  7395. Q3_SetChaseEnemies( entID, qfalse);
  7396. break;
  7397. case SET_LOOK_FOR_ENEMIES:
  7398. if(!stricmp("true", ((char *)data)))
  7399. Q3_SetLookForEnemies( entID, qtrue);
  7400. else
  7401. Q3_SetLookForEnemies( entID, qfalse);
  7402. break;
  7403. case SET_FACE_MOVE_DIR:
  7404. if(!stricmp("true", ((char *)data)))
  7405. Q3_SetFaceMoveDir( entID, qtrue);
  7406. else
  7407. Q3_SetFaceMoveDir( entID, qfalse);
  7408. break;
  7409. case SET_ALT_FIRE:
  7410. if(!stricmp("true", ((char *)data)))
  7411. Q3_SetAltFire( entID, qtrue);
  7412. else
  7413. Q3_SetAltFire( entID, qfalse);
  7414. break;
  7415. case SET_DONT_FLEE:
  7416. if(!stricmp("true", ((char *)data)))
  7417. Q3_SetDontFlee( entID, qtrue);
  7418. else
  7419. Q3_SetDontFlee( entID, qfalse);
  7420. break;
  7421. case SET_FORCED_MARCH:
  7422. if(!stricmp("true", ((char *)data)))
  7423. Q3_SetForcedMarch( entID, qtrue);
  7424. else
  7425. Q3_SetForcedMarch( entID, qfalse);
  7426. break;
  7427. case SET_NO_RESPONSE:
  7428. if(!stricmp("true", ((char *)data)))
  7429. Q3_SetNoResponse( entID, qtrue);
  7430. else
  7431. Q3_SetNoResponse( entID, qfalse);
  7432. break;
  7433. case SET_NO_COMBAT_TALK:
  7434. if(!stricmp("true", ((char *)data)))
  7435. Q3_SetCombatTalk( entID, qtrue);
  7436. else
  7437. Q3_SetCombatTalk( entID, qfalse);
  7438. break;
  7439. case SET_NO_ALERT_TALK:
  7440. if(!stricmp("true", ((char *)data)))
  7441. Q3_SetAlertTalk( entID, qtrue);
  7442. else
  7443. Q3_SetAlertTalk( entID, qfalse);
  7444. break;
  7445. case SET_USE_CP_NEAREST:
  7446. if(!stricmp("true", ((char *)data)))
  7447. Q3_SetUseCpNearest( entID, qtrue);
  7448. else
  7449. Q3_SetUseCpNearest( entID, qfalse);
  7450. break;
  7451. case SET_NO_FORCE:
  7452. if(!stricmp("true", ((char *)data)))
  7453. Q3_SetNoForce( entID, qtrue);
  7454. else
  7455. Q3_SetNoForce( entID, qfalse);
  7456. break;
  7457. case SET_NO_ACROBATICS:
  7458. if(!stricmp("true", ((char *)data)))
  7459. Q3_SetNoAcrobatics( entID, qtrue);
  7460. else
  7461. Q3_SetNoAcrobatics( entID, qfalse);
  7462. break;
  7463. case SET_USE_SUBTITLES:
  7464. if(!stricmp("true", ((char *)data)))
  7465. Q3_SetUseSubtitles( entID, qtrue);
  7466. else
  7467. Q3_SetUseSubtitles( entID, qfalse);
  7468. break;
  7469. case SET_NO_FALLTODEATH:
  7470. if(!stricmp("true", ((char *)data)))
  7471. Q3_SetNoFallToDeath( entID, qtrue);
  7472. else
  7473. Q3_SetNoFallToDeath( entID, qfalse);
  7474. break;
  7475. case SET_DISMEMBERABLE:
  7476. if(!stricmp("true", ((char *)data)))
  7477. Q3_SetDismemberable( entID, qtrue);
  7478. else
  7479. Q3_SetDismemberable( entID, qfalse);
  7480. break;
  7481. case SET_MORELIGHT:
  7482. if(!stricmp("true", ((char *)data)))
  7483. Q3_SetMoreLight( entID, qtrue);
  7484. else
  7485. Q3_SetMoreLight( entID, qfalse);
  7486. break;
  7487. case SET_TREASONED:
  7488. DebugPrint( WL_VERBOSE, "SET_TREASONED is disabled, do not use\n" );
  7489. /*
  7490. G_TeamRetaliation( NULL, &g_entities[0], qfalse );
  7491. ffireLevel = FFIRE_LEVEL_RETALIATION;
  7492. */
  7493. break;
  7494. case SET_UNDYING:
  7495. if(!stricmp("true", ((char *)data)))
  7496. Q3_SetUndying( entID, qtrue);
  7497. else
  7498. Q3_SetUndying( entID, qfalse);
  7499. break;
  7500. case SET_INVINCIBLE:
  7501. if(!stricmp("true", ((char *)data)))
  7502. Q3_SetInvincible( entID, qtrue);
  7503. else
  7504. Q3_SetInvincible( entID, qfalse);
  7505. break;
  7506. case SET_NOAVOID:
  7507. if(!stricmp("true", ((char *)data)))
  7508. Q3_SetNoAvoid( entID, qtrue);
  7509. else
  7510. Q3_SetNoAvoid( entID, qfalse);
  7511. break;
  7512. case SET_SOLID:
  7513. if(!stricmp("true", ((char *)data)))
  7514. {
  7515. if ( !Q3_SetSolid( entID, qtrue) )
  7516. {
  7517. Q3_TaskIDSet( ent, TID_RESIZE, taskID );
  7518. return;
  7519. }
  7520. }
  7521. else
  7522. {
  7523. Q3_SetSolid( entID, qfalse);
  7524. }
  7525. break;
  7526. case SET_INVISIBLE:
  7527. if( !stricmp("true", ((char *)data)) )
  7528. Q3_SetInvisible( entID, qtrue );
  7529. else
  7530. Q3_SetInvisible( entID, qfalse );
  7531. break;
  7532. case SET_VAMPIRE:
  7533. if( !stricmp("true", ((char *)data)) )
  7534. Q3_SetVampire( entID, qtrue );
  7535. else
  7536. Q3_SetVampire( entID, qfalse );
  7537. break;
  7538. case SET_FORCE_INVINCIBLE:
  7539. if( !stricmp("true", ((char *)data)) )
  7540. Q3_SetForceInvincible( entID, qtrue );
  7541. else
  7542. Q3_SetForceInvincible( entID, qfalse );
  7543. break;
  7544. case SET_GREET_ALLIES:
  7545. if( !stricmp("true", ((char *)data)) )
  7546. Q3_SetGreetAllies( entID, qtrue );
  7547. else
  7548. Q3_SetGreetAllies( entID, qfalse );
  7549. break;
  7550. case SET_PLAYER_LOCKED:
  7551. if( !stricmp("true", ((char *)data)) )
  7552. Q3_SetPlayerLocked( entID, qtrue );
  7553. else
  7554. Q3_SetPlayerLocked( entID, qfalse );
  7555. break;
  7556. case SET_LOCK_PLAYER_WEAPONS:
  7557. if( !stricmp("true", ((char *)data)) )
  7558. Q3_SetLockPlayerWeapons( entID, qtrue );
  7559. else
  7560. Q3_SetLockPlayerWeapons( entID, qfalse );
  7561. break;
  7562. case SET_NO_IMPACT_DAMAGE:
  7563. if( !stricmp("true", ((char *)data)) )
  7564. Q3_SetNoImpactDamage( entID, qtrue );
  7565. else
  7566. Q3_SetNoImpactDamage( entID, qfalse );
  7567. break;
  7568. case SET_FORWARDMOVE:
  7569. int_data = atoi((char *) data);
  7570. Q3_SetForwardMove( entID, int_data);
  7571. break;
  7572. case SET_RIGHTMOVE:
  7573. int_data = atoi((char *) data);
  7574. Q3_SetRightMove( entID, int_data);
  7575. break;
  7576. case SET_LOCKYAW:
  7577. Q3_SetLockAngle( entID, data);
  7578. break;
  7579. case SET_CAMERA_GROUP:
  7580. Q3_CameraGroup(entID, (char *)data);
  7581. break;
  7582. case SET_CAMERA_GROUP_Z_OFS:
  7583. float_data = atof((char *) data);
  7584. Q3_CameraGroupZOfs( float_data );
  7585. break;
  7586. case SET_CAMERA_GROUP_TAG:
  7587. Q3_CameraGroupTag( (char *)data );
  7588. break;
  7589. //FIXME: put these into camera commands
  7590. case SET_LOOK_TARGET:
  7591. Q3_LookTarget(entID, (char *)data);
  7592. break;
  7593. case SET_ADDRHANDBOLT_MODEL:
  7594. Q3_AddRHandModel(entID, (char *)data);
  7595. break;
  7596. case SET_REMOVERHANDBOLT_MODEL:
  7597. Q3_RemoveRHandModel(entID, (char *)data);
  7598. break;
  7599. case SET_ADDLHANDBOLT_MODEL:
  7600. Q3_AddLHandModel(entID, (char *)data);
  7601. break;
  7602. case SET_REMOVELHANDBOLT_MODEL:
  7603. Q3_RemoveLHandModel(entID, (char *)data);
  7604. break;
  7605. case SET_FACEEYESCLOSED:
  7606. case SET_FACEEYESOPENED:
  7607. case SET_FACEAUX:
  7608. case SET_FACEBLINK:
  7609. case SET_FACEBLINKFROWN:
  7610. case SET_FACEFROWN:
  7611. case SET_FACENORMAL:
  7612. float_data = atof((char *) data);
  7613. Q3_Face(entID, toSet, float_data);
  7614. break;
  7615. case SET_SCROLLTEXT:
  7616. Q3_ScrollText( (char *)data );
  7617. break;
  7618. case SET_LCARSTEXT:
  7619. Q3_LCARSText( (char *)data );
  7620. break;
  7621. case SET_CENTERTEXT:
  7622. CenterPrint( (char *)data );
  7623. break;
  7624. case SET_CAPTIONTEXTCOLOR:
  7625. Q3_SetCaptionTextColor ( (char *)data );
  7626. break;
  7627. case SET_CENTERTEXTCOLOR:
  7628. Q3_SetCenterTextColor ( (char *)data );
  7629. break;
  7630. case SET_SCROLLTEXTCOLOR:
  7631. Q3_SetScrollTextColor ( (char *)data );
  7632. break;
  7633. case SET_PLAYER_USABLE:
  7634. if(!stricmp("true", ((char *)data)))
  7635. {
  7636. Q3_SetPlayerUsable(entID, qtrue);
  7637. }
  7638. else
  7639. {
  7640. Q3_SetPlayerUsable(entID, qfalse);
  7641. }
  7642. break;
  7643. case SET_STARTFRAME:
  7644. int_data = atoi((char *) data);
  7645. Q3_SetStartFrame(entID, int_data);
  7646. break;
  7647. case SET_ENDFRAME:
  7648. int_data = atoi((char *) data);
  7649. Q3_SetEndFrame(entID, int_data);
  7650. Q3_TaskIDSet( ent, TID_ANIM_BOTH, taskID );
  7651. return;
  7652. break;
  7653. case SET_ANIMFRAME:
  7654. int_data = atoi((char *) data);
  7655. Q3_SetAnimFrame(entID, int_data);
  7656. return;
  7657. break;
  7658. case SET_LOOP_ANIM:
  7659. if(!stricmp("true", ((char *)data)))
  7660. {
  7661. Q3_SetLoopAnim(entID, qtrue);
  7662. }
  7663. else
  7664. {
  7665. Q3_SetLoopAnim(entID, qfalse);
  7666. }
  7667. break;
  7668. case SET_INTERFACE:
  7669. if(!stricmp("true", ((char *)data)))
  7670. {
  7671. Q3_SetInterface(entID, "1");
  7672. }
  7673. else
  7674. {
  7675. Q3_SetInterface(entID, "0");
  7676. }
  7677. break;
  7678. case SET_SHIELDS:
  7679. if(!stricmp("true", ((char *)data)))
  7680. {
  7681. Q3_SetShields(entID, qtrue);
  7682. }
  7683. else
  7684. {
  7685. Q3_SetShields(entID, qfalse);
  7686. }
  7687. break;
  7688. case SET_SABERACTIVE:
  7689. if(!stricmp("true", ((char *)data)))
  7690. {
  7691. #ifdef _XBOX
  7692. // Big fat hack to ensure the saber blades get bolted on correctly
  7693. // Amended - to only run on the PC, or it screws up tavion in kor2
  7694. if( !entID )
  7695. {
  7696. Q3_SetWeapon ( entID, "wp_blaster");
  7697. Q3_SetWeapon ( entID, "wp_saber");
  7698. }
  7699. #endif
  7700. Q3_SetSaberActive( entID, qtrue );
  7701. }
  7702. else
  7703. {
  7704. Q3_SetSaberActive( entID, qfalse );
  7705. }
  7706. break;
  7707. // Created: 10/02/02 by Aurelio Reis, Modified: 10/02/02
  7708. // Make a specific Saber 1 Blade active.
  7709. case SET_SABER1BLADEON:
  7710. // Get which Blade to activate.
  7711. int_data = atoi((char *) data);
  7712. Q3_SetSaberBladeActive( entID, 0, int_data, qtrue );
  7713. break;
  7714. // Make a specific Saber 1 Blade inactive.
  7715. case SET_SABER1BLADEOFF:
  7716. // Get which Blade to deactivate.
  7717. int_data = atoi((char *) data);
  7718. Q3_SetSaberBladeActive( entID, 0, int_data, qfalse );
  7719. break;
  7720. // Make a specific Saber 2 Blade active.
  7721. case SET_SABER2BLADEON:
  7722. // Get which Blade to activate.
  7723. int_data = atoi((char *) data);
  7724. Q3_SetSaberBladeActive( entID, 1, int_data, qtrue );
  7725. break;
  7726. // Make a specific Saber 2 Blade inactive.
  7727. case SET_SABER2BLADEOFF:
  7728. // Get which Blade to deactivate.
  7729. int_data = atoi((char *) data);
  7730. Q3_SetSaberBladeActive( entID, 1, int_data, qfalse );
  7731. break;
  7732. case SET_DAMAGEENTITY:
  7733. int_data = atoi((char *) data);
  7734. G_Damage( ent, ent, ent, NULL, NULL, int_data, 0, MOD_UNKNOWN );
  7735. break;
  7736. case SET_SABER_ORIGIN:
  7737. sscanf( data, "%f %f %f", &vector_data[0], &vector_data[1], &vector_data[2] );
  7738. WP_SetSaberOrigin( ent, vector_data );
  7739. break;
  7740. case SET_ADJUST_AREA_PORTALS:
  7741. if(!stricmp("true", ((char *)data)))
  7742. {
  7743. Q3_SetAdjustAreaPortals( entID, qtrue );
  7744. }
  7745. else
  7746. {
  7747. Q3_SetAdjustAreaPortals( entID, qfalse );
  7748. }
  7749. break;
  7750. case SET_DMG_BY_HEAVY_WEAP_ONLY:
  7751. if(!stricmp("true", ((char *)data)))
  7752. {
  7753. Q3_SetDmgByHeavyWeapOnly( entID, qtrue );
  7754. }
  7755. else
  7756. {
  7757. Q3_SetDmgByHeavyWeapOnly( entID, qfalse );
  7758. }
  7759. break;
  7760. case SET_SHIELDED:
  7761. if(!stricmp("true", ((char *)data)))
  7762. {
  7763. Q3_SetShielded( entID, qtrue );
  7764. }
  7765. else
  7766. {
  7767. Q3_SetShielded( entID, qfalse );
  7768. }
  7769. break;
  7770. case SET_NO_GROUPS:
  7771. if(!stricmp("true", ((char *)data)))
  7772. {
  7773. Q3_SetNoGroups( entID, qtrue );
  7774. }
  7775. else
  7776. {
  7777. Q3_SetNoGroups( entID, qfalse );
  7778. }
  7779. break;
  7780. case SET_FIRE_WEAPON:
  7781. if(!stricmp("true", ((char *)data)))
  7782. {
  7783. Q3_SetFireWeapon( entID, qtrue);
  7784. }
  7785. else if(!stricmp("false", ((char *)data)))
  7786. {
  7787. Q3_SetFireWeapon( entID, qfalse);
  7788. }
  7789. break;
  7790. case SET_FIRE_WEAPON_NO_ANIM:
  7791. if(!stricmp("true", ((char *)data)))
  7792. {
  7793. Q3_SetFireWeaponNoAnim( entID, qtrue);
  7794. }
  7795. else if(!stricmp("false", ((char *)data)))
  7796. {
  7797. Q3_SetFireWeaponNoAnim( entID, qfalse);
  7798. }
  7799. break;
  7800. case SET_SAFE_REMOVE:
  7801. if(!stricmp("true", ((char *)data)))
  7802. {
  7803. Q3_SetSafeRemove( entID, qtrue);
  7804. }
  7805. else if(!stricmp("false", ((char *)data)))
  7806. {
  7807. Q3_SetSafeRemove( entID, qfalse);
  7808. }
  7809. break;
  7810. case SET_BOBA_JET_PACK:
  7811. if(!stricmp("true", ((char *)data)))
  7812. {
  7813. Q3_SetBobaJetPack( entID, qtrue);
  7814. }
  7815. else if(!stricmp("false", ((char *)data)))
  7816. {
  7817. Q3_SetBobaJetPack( entID, qfalse);
  7818. }
  7819. break;
  7820. case SET_INACTIVE:
  7821. if(!stricmp("true", ((char *)data)))
  7822. {
  7823. Q3_SetInactive( entID, qtrue);
  7824. }
  7825. else if(!stricmp("false", ((char *)data)))
  7826. {
  7827. Q3_SetInactive( entID, qfalse);
  7828. }
  7829. else if(!stricmp("unlocked", ((char *)data)))
  7830. {
  7831. extern void UnLockDoors(gentity_t *const ent);
  7832. UnLockDoors(&g_entities[entID]);
  7833. }
  7834. else if(!stricmp("locked", ((char *)data)))
  7835. {
  7836. extern void LockDoors(gentity_t *const ent);
  7837. LockDoors(&g_entities[entID]);
  7838. }
  7839. break;
  7840. case SET_END_SCREENDISSOLVE:
  7841. gi.SendConsoleCommand( "endscreendissolve\n");
  7842. break;
  7843. case SET_FUNC_USABLE_VISIBLE:
  7844. if(!stricmp("true", ((char *)data)))
  7845. {
  7846. Q3_SetFuncUsableVisible( entID, qtrue);
  7847. }
  7848. else if(!stricmp("false", ((char *)data)))
  7849. {
  7850. Q3_SetFuncUsableVisible( entID, qfalse);
  7851. }
  7852. break;
  7853. case SET_NO_KNOCKBACK:
  7854. if(!stricmp("true", ((char *)data)))
  7855. {
  7856. Q3_SetNoKnockback(entID, qtrue);
  7857. }
  7858. else
  7859. {
  7860. Q3_SetNoKnockback(entID, qfalse);
  7861. }
  7862. break;
  7863. case SET_VIDEO_PLAY:
  7864. // don't do this check now, James doesn't want a scripted cinematic to also skip any Video cinematics as well,
  7865. // the "timescale" and "skippingCinematic" cvars will be set back to normal in the Video code, so doing a
  7866. // skip will now only skip one section of a multiple-part story (eg VOY1 bridge sequence)
  7867. //
  7868. // if ( g_timescale->value <= 1.0f )
  7869. {
  7870. gi.SendConsoleCommand( va("inGameCinematic %s\n", (char *)data) );
  7871. }
  7872. break;
  7873. case SET_VIDEO_FADE_IN:
  7874. if(!stricmp("true", ((char *)data)))
  7875. {
  7876. gi.cvar_set("cl_VidFadeUp", "1");
  7877. }
  7878. else
  7879. {
  7880. gi.cvar_set("cl_VidFadeUp", "0");
  7881. }
  7882. break;
  7883. case SET_VIDEO_FADE_OUT:
  7884. if(!stricmp("true", ((char *)data)))
  7885. {
  7886. gi.cvar_set("cl_VidFadeDown", "1");
  7887. }
  7888. else
  7889. {
  7890. gi.cvar_set("cl_VidFadeDown", "0");
  7891. }
  7892. break;
  7893. case SET_REMOVE_TARGET:
  7894. Q3_SetRemoveTarget( entID, (const char *) data );
  7895. break;
  7896. case SET_LOADGAME:
  7897. gi.SendConsoleCommand( va("load %s\n", (const char *) data ) );
  7898. break;
  7899. case SET_MENU_SCREEN:
  7900. //UI_SetActiveMenu( (const char *) data );
  7901. gi.SendConsoleCommand( va("uimenu %s\n", (char *)data) );
  7902. break;
  7903. case SET_OBJECTIVE_SHOW:
  7904. missionInfo_Updated = qtrue; // Activate flashing text
  7905. gi.cvar_set("cg_updatedDataPadObjective", "1");
  7906. Q3_SetObjective((const char *) data ,SET_OBJ_SHOW);
  7907. Q3_SetObjective((const char *) data ,SET_OBJ_PENDING);
  7908. break;
  7909. case SET_OBJECTIVE_HIDE:
  7910. Q3_SetObjective((const char *) data ,SET_OBJ_HIDE);
  7911. break;
  7912. case SET_OBJECTIVE_SUCCEEDED:
  7913. missionInfo_Updated = qtrue; // Activate flashing text
  7914. gi.cvar_set("cg_updatedDataPadObjective", "1");
  7915. Q3_SetObjective((const char *) data ,SET_OBJ_SUCCEEDED);
  7916. break;
  7917. case SET_OBJECTIVE_SUCCEEDED_NO_UPDATE:
  7918. Q3_SetObjective((const char *) data ,SET_OBJ_SUCCEEDED);
  7919. break;
  7920. case SET_OBJECTIVE_FAILED:
  7921. Q3_SetObjective((const char *) data ,SET_OBJ_FAILED);
  7922. break;
  7923. case SET_OBJECTIVE_CLEARALL:
  7924. Q3_ObjectiveClearAll();
  7925. break;
  7926. case SET_MISSIONFAILED:
  7927. Q3_SetMissionFailed((const char *) data);
  7928. break;
  7929. case SET_MISSIONSTATUSTEXT:
  7930. Q3_SetStatusText((const char *) data);
  7931. break;
  7932. case SET_MISSIONSTATUSTIME:
  7933. int_data = atoi((char *) data);
  7934. cg.missionStatusDeadTime = level.time + int_data;
  7935. break;
  7936. case SET_CLOSINGCREDITS:
  7937. gi.cvar_set("cg_endcredits", "1");
  7938. break;
  7939. case SET_SKILL:
  7940. // //can never be set
  7941. break;
  7942. case SET_DISABLE_SHADER_ANIM:
  7943. if(!stricmp("true", ((char *)data)))
  7944. {
  7945. Q3_SetDisableShaderAnims( entID, qtrue);
  7946. }
  7947. else
  7948. {
  7949. Q3_SetDisableShaderAnims( entID, qfalse);
  7950. }
  7951. break;
  7952. case SET_SHADER_ANIM:
  7953. if(!stricmp("true", ((char *)data)))
  7954. {
  7955. Q3_SetShaderAnim( entID, qtrue);
  7956. }
  7957. else
  7958. {
  7959. Q3_SetShaderAnim( entID, qfalse);
  7960. }
  7961. break;
  7962. case SET_MUSIC_STATE:
  7963. Q3_SetMusicState( (char *) data );
  7964. break;
  7965. case SET_CLEAN_DAMAGING_ENTS:
  7966. Q3_SetCleanDamagingEnts();
  7967. break;
  7968. case SET_HUD:
  7969. if(!stricmp("true", ((char *)data)))
  7970. {
  7971. gi.cvar_set("cg_drawHUD", "1");
  7972. }
  7973. else
  7974. {
  7975. gi.cvar_set("cg_drawHUD", "0");
  7976. }
  7977. break;
  7978. case SET_FORCE_HEAL_LEVEL:
  7979. case SET_FORCE_JUMP_LEVEL:
  7980. case SET_FORCE_SPEED_LEVEL:
  7981. case SET_FORCE_PUSH_LEVEL:
  7982. case SET_FORCE_PULL_LEVEL:
  7983. case SET_FORCE_MINDTRICK_LEVEL:
  7984. case SET_FORCE_GRIP_LEVEL:
  7985. case SET_FORCE_LIGHTNING_LEVEL:
  7986. case SET_SABER_THROW:
  7987. case SET_SABER_DEFENSE:
  7988. case SET_SABER_OFFENSE:
  7989. case SET_FORCE_RAGE_LEVEL:
  7990. case SET_FORCE_PROTECT_LEVEL:
  7991. case SET_FORCE_ABSORB_LEVEL:
  7992. case SET_FORCE_DRAIN_LEVEL:
  7993. case SET_FORCE_SIGHT_LEVEL:
  7994. int_data = atoi((char *) data);
  7995. Q3_SetForcePowerLevel( entID, (toSet-SET_FORCE_HEAL_LEVEL), int_data );
  7996. break;
  7997. case SET_SABER1:
  7998. case SET_SABER2:
  7999. WP_SetSaber( &g_entities[entID], toSet-SET_SABER1, (char *)data );
  8000. break;
  8001. case SET_PLAYERMODEL:
  8002. G_ChangePlayerModel( &g_entities[entID], (const char *)data );
  8003. break;
  8004. // NOTE: Preconditions for entering a vehicle still exist. This is not assured to work. -Areis
  8005. case SET_VEHICLE:
  8006. Use( entID, (char *)data );
  8007. // G_DriveVehicle( &g_entities[entID], NULL, (char *)data );
  8008. break;
  8009. case SET_SECURITY_KEY:
  8010. Q3_GiveSecurityKey( entID, (char *)data );
  8011. break;
  8012. case SET_SABER1_COLOR1:
  8013. case SET_SABER1_COLOR2:
  8014. WP_SaberSetColor( &g_entities[entID], 0, toSet-SET_SABER1_COLOR1, (char *)data );
  8015. break;
  8016. case SET_SABER2_COLOR1:
  8017. case SET_SABER2_COLOR2:
  8018. WP_SaberSetColor( &g_entities[entID], 1, toSet-SET_SABER2_COLOR1, (char *)data );
  8019. break;
  8020. case SET_DISMEMBER_LIMB:
  8021. Q3_DismemberLimb( entID, (char *)data );
  8022. break;
  8023. case SET_NO_PVS_CULL:
  8024. Q3_SetBroadcast( entID, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8025. break;
  8026. // Set a Saboteur to cloak (true) or un-cloak (false).
  8027. case SET_CLOAK: // Created: 01/08/03 by AReis.
  8028. //extern void Jedi_Cloak( gentity_t *self );
  8029. extern void Saboteur_Cloak( gentity_t *self );
  8030. if( stricmp("true", ((char *)data)) == 0 )
  8031. {
  8032. Saboteur_Cloak( &g_entities[entID] );
  8033. }
  8034. else
  8035. {
  8036. Saboteur_Decloak( &g_entities[entID] );
  8037. }
  8038. break;
  8039. case SET_FORCE_HEAL:
  8040. Q3_SetForcePower( entID, FP_HEAL, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8041. break;
  8042. case SET_FORCE_SPEED:
  8043. Q3_SetForcePower( entID, FP_SPEED, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8044. break;
  8045. case SET_FORCE_PUSH:
  8046. Q3_SetForcePower( entID, FP_PUSH, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8047. break;
  8048. case SET_FORCE_PUSH_FAKE:
  8049. ForceThrow( &g_entities[entID], qfalse, qtrue );
  8050. break;
  8051. case SET_FORCE_PULL:
  8052. Q3_SetForcePower( entID, FP_PULL, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8053. break;
  8054. case SET_FORCE_MIND_TRICK:
  8055. Q3_SetForcePower( entID, FP_TELEPATHY, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8056. break;
  8057. case SET_FORCE_GRIP:
  8058. Q3_SetForcePower( entID, FP_GRIP, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8059. break;
  8060. case SET_FORCE_LIGHTNING:
  8061. Q3_SetForcePower( entID, FP_LIGHTNING, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8062. break;
  8063. case SET_FORCE_SABERTHROW:
  8064. Q3_SetForcePower( entID, FP_SABERTHROW, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8065. break;
  8066. case SET_FORCE_RAGE:
  8067. Q3_SetForcePower( entID, FP_RAGE, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8068. break;
  8069. case SET_FORCE_PROTECT:
  8070. Q3_SetForcePower( entID, FP_PROTECT, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8071. break;
  8072. case SET_FORCE_ABSORB:
  8073. Q3_SetForcePower( entID, FP_ABSORB, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8074. break;
  8075. case SET_FORCE_DRAIN:
  8076. Q3_SetForcePower( entID, FP_DRAIN, (qboolean)(Q_stricmp("true",(char*)data)==0) );
  8077. break;
  8078. extern cvar_t *g_char_model;
  8079. extern cvar_t *g_char_skin_head;
  8080. extern cvar_t *g_char_skin_torso;
  8081. extern cvar_t *g_char_skin_legs;
  8082. case SET_WINTER_GEAR: // Created: 03/26/03 by AReis.
  8083. {
  8084. // If this is a (fake) Player NPC or this IS the Player...
  8085. if ( entID == 0 || ( ent->NPC_type && stricmp( ent->NPC_type, "player" ) == 0 ) )
  8086. {
  8087. char strSkin[MAX_QPATH];
  8088. // Set the Winter Gear Skin if true, otherwise set back to normal configuration.
  8089. if( stricmp( "true", ((char *)data) ) == 0 )
  8090. {
  8091. Com_sprintf( strSkin, sizeof( strSkin ), "models/players/%s/|%s|%s|%s", g_char_model->string, g_char_skin_head->string, "torso_g1", "lower_e1" );
  8092. }
  8093. else
  8094. {
  8095. Com_sprintf( strSkin, sizeof( strSkin ), "models/players/%s/|%s|%s|%s", g_char_model->string, g_char_skin_head->string, g_char_skin_torso->string, g_char_skin_legs->string );
  8096. }
  8097. int iSkinID = gi.RE_RegisterSkin( strSkin );
  8098. if ( iSkinID )
  8099. {
  8100. gi.G2API_SetSkin( &ent->ghoul2[ent->playerModel], G_SkinIndex( strSkin ), iSkinID );
  8101. }
  8102. }
  8103. break;
  8104. }
  8105. case SET_NO_ANGLES:
  8106. if ( entID >= 0 && entID < ENTITYNUM_WORLD )
  8107. {
  8108. if ( (Q_stricmp("true",(char*)data)==0) )
  8109. {
  8110. g_entities[entID].flags |= FL_NO_ANGLES;
  8111. }
  8112. else
  8113. {
  8114. g_entities[entID].flags &= ~FL_NO_ANGLES;
  8115. }
  8116. }
  8117. break;
  8118. case SET_SKIN:
  8119. // If this is a (fake) Player NPC or this IS the Player...
  8120. {//just blindly sets whatever skin you set! include full path after "base/"... eg: "models/players/tavion_new/model_possessed.skin"
  8121. gentity_t *ent = &g_entities[entID];
  8122. if ( ent && ent->inuse && ent->ghoul2.size() )
  8123. {
  8124. int iSkinID = gi.RE_RegisterSkin( (char *)data );
  8125. if ( iSkinID )
  8126. {
  8127. gi.G2API_SetSkin( &ent->ghoul2[ent->playerModel], G_SkinIndex( (char *)data ), iSkinID );
  8128. }
  8129. }
  8130. }
  8131. break;
  8132. default:
  8133. //DebugPrint( WL_ERROR, "Set: '%s' is not a valid set field\n", type_name );
  8134. SetVar( taskID, entID, type_name, data );
  8135. PrisonerObjCheck(type_name,data);
  8136. break;
  8137. }
  8138. IIcarusInterface::GetIcarus()->Completed( ent->m_iIcarusID, taskID );
  8139. }
  8140. void CQuake3GameInterface::PrisonerObjCheck(const char *name,const char *data)
  8141. {
  8142. float float_data;
  8143. int holdData;
  8144. if (!Q_stricmp("ui_prisonerobj_currtotal",name))
  8145. {
  8146. GetFloatVariable( name, &float_data );
  8147. holdData = (int) float_data;
  8148. gi.cvar_set("ui_prisonerobj_currtotal", va("%d",holdData));
  8149. }
  8150. else if (!Q_stricmp("ui_prisonerobj_maxtotal",name))
  8151. {
  8152. gi.cvar_set("ui_prisonerobj_maxtotal", data);
  8153. }
  8154. }
  8155. // Uses an entity.
  8156. void CQuake3GameInterface::Use( int entID, const char *name )
  8157. {
  8158. gentity_t *ent = &g_entities[entID];
  8159. if ( !ent )
  8160. {
  8161. DebugPrint( WL_WARNING, "Use: invalid entID %d\n", entID );
  8162. return;
  8163. }
  8164. if( !name || !name[0] )
  8165. {
  8166. DebugPrint( WL_WARNING, "Use: string is NULL!\n" );
  8167. return;
  8168. }
  8169. if ( ent->s.number == 0 && ent->client->NPC_class == CLASS_ATST )
  8170. {//a player trying to get out of his ATST
  8171. GEntity_UseFunc( ent->activator, ent, ent );
  8172. return;
  8173. }
  8174. /*
  8175. if ( ent->client )
  8176. {//put the button on him, too, since some other things (like getting out of a vehicle?) check for the use button directly...
  8177. ent->client->usercmd.buttons |= BUTTON_USE;
  8178. }
  8179. */
  8180. G_UseTargets2( ent, ent, name );
  8181. }
  8182. void CQuake3GameInterface::Activate( int entID, const char *name )
  8183. {
  8184. Q3_SetInactive( entID, qtrue );
  8185. }
  8186. void CQuake3GameInterface::Deactivate( int entID, const char *name )
  8187. {
  8188. Q3_SetInactive( entID, qfalse );
  8189. }
  8190. // Kill an entity.
  8191. void CQuake3GameInterface::Kill( int entID, const char *name )
  8192. {
  8193. gentity_t *ent = &g_entities[entID];
  8194. gentity_t *victim = NULL;
  8195. int o_health;
  8196. if( !stricmp( name, "self") )
  8197. {
  8198. victim = ent;
  8199. }
  8200. else if( !stricmp( name, "enemy" ) )
  8201. {
  8202. victim = ent->enemy;
  8203. }
  8204. else
  8205. {
  8206. victim = G_Find (NULL, FOFS(targetname), (char *) name );
  8207. }
  8208. if ( !victim )
  8209. {
  8210. DebugPrint( WL_WARNING, "Kill: can't find %s\n", name);
  8211. return;
  8212. }
  8213. /*
  8214. if ( victim == ent )
  8215. {
  8216. DebugPrint( WL_ERROR, "Kill: entity %s trying to kill self - not allowed!\n", name);
  8217. return;
  8218. }
  8219. */
  8220. if ( victim == ent )
  8221. {//don't ICARUS_FreeEnt me, I'm in the middle of a script! (FIXME: shouldn't ICARUS handle this internally?)
  8222. victim->svFlags |= SVF_KILLED_SELF;
  8223. }
  8224. o_health = victim->health;
  8225. victim->health = 0;
  8226. if ( victim->client )
  8227. {
  8228. victim->flags |= FL_NO_KNOCKBACK;
  8229. }
  8230. //G_SetEnemy(victim, ent);
  8231. if( victim->e_DieFunc != dieF_NULL ) // check can be omitted
  8232. {
  8233. GEntity_DieFunc( victim, NULL, NULL, o_health, MOD_UNKNOWN );
  8234. }
  8235. }
  8236. // Remove an entity.
  8237. void CQuake3GameInterface::Remove( int entID, const char *name )
  8238. {
  8239. gentity_t *ent = &g_entities[entID];
  8240. gentity_t *victim = NULL;
  8241. if( !Q_stricmp( "self", name ) )
  8242. {
  8243. victim = ent;
  8244. if ( !victim )
  8245. {
  8246. DebugPrint( WL_WARNING, "Remove: can't find %s\n", name );
  8247. return;
  8248. }
  8249. Q3_RemoveEnt( victim );
  8250. }
  8251. else if( !Q_stricmp( "enemy", name ) )
  8252. {
  8253. victim = ent->enemy;
  8254. if ( !victim )
  8255. {
  8256. DebugPrint( WL_WARNING, "Remove: can't find %s\n", name );
  8257. return;
  8258. }
  8259. Q3_RemoveEnt( victim );
  8260. }
  8261. else
  8262. {
  8263. victim = G_Find( NULL, FOFS(targetname), (char *) name );
  8264. if ( !victim )
  8265. {
  8266. DebugPrint( WL_WARNING, "Remove: can't find %s\n", name );
  8267. return;
  8268. }
  8269. while ( victim )
  8270. {
  8271. Q3_RemoveEnt( victim );
  8272. victim = G_Find( victim, FOFS(targetname), (char *) name );
  8273. }
  8274. }
  8275. }
  8276. // Get a random (float) number.
  8277. float CQuake3GameInterface::Random( float min, float max )
  8278. {
  8279. return ((rand() * (max - min)) / 32768.0F) + min;
  8280. }
  8281. void CQuake3GameInterface::Play( int taskID, int entID, const char *type, const char *name )
  8282. {
  8283. gentity_t *ent = &g_entities[entID];
  8284. if ( !stricmp( type, "PLAY_ROFF" ) )
  8285. {
  8286. // Try to load the requested ROFF
  8287. if ( G_LoadRoff( name ) )
  8288. {
  8289. ent->roff = G_NewString( name );
  8290. // Start the roff from the beginning
  8291. ent->roff_ctr = 0;
  8292. //Save this off for later
  8293. Q3_TaskIDSet( ent, TID_MOVE_NAV, taskID );
  8294. // Let the ROFF playing start.
  8295. ent->next_roff_time = level.time;
  8296. // These need to be initialised up front...
  8297. VectorCopy( ent->currentOrigin, ent->pos1 );
  8298. VectorCopy( ent->currentAngles, ent->pos2 );
  8299. gi.linkentity( ent );
  8300. }
  8301. }
  8302. }
  8303. //Camera functions
  8304. void CQuake3GameInterface::CameraPan( vec3_t angles, vec3_t dir, float duration )
  8305. {
  8306. CGCam_Pan( angles, dir, duration );
  8307. }
  8308. void CQuake3GameInterface::CameraMove( vec3_t origin, float duration )
  8309. {
  8310. CGCam_Move( origin, duration );
  8311. }
  8312. void CQuake3GameInterface::CameraZoom( float fov, float duration )
  8313. {
  8314. CGCam_Zoom( fov, duration );
  8315. }
  8316. void CQuake3GameInterface::CameraRoll( float angle, float duration )
  8317. {
  8318. CGCam_Roll( angle, duration );
  8319. }
  8320. void CQuake3GameInterface::CameraFollow( const char *name, float speed, float initLerp )
  8321. {
  8322. CGCam_Follow( name, speed, initLerp );
  8323. }
  8324. void CQuake3GameInterface::CameraTrack( const char *name, float speed, float initLerp )
  8325. {
  8326. CGCam_Track( name, speed, initLerp );
  8327. }
  8328. void CQuake3GameInterface::CameraDistance( float dist, float initLerp )
  8329. {
  8330. CGCam_Distance( dist, initLerp );
  8331. }
  8332. void CQuake3GameInterface::CameraFade( float sr, float sg, float sb, float sa, float dr, float dg, float db, float da, float duration )
  8333. {
  8334. vec4_t src, dst;
  8335. src[0] = sr;
  8336. src[1] = sg;
  8337. src[2] = sb;
  8338. src[3] = sa;
  8339. dst[0] = dr;
  8340. dst[1] = dg;
  8341. dst[2] = db;
  8342. dst[3] = da;
  8343. CGCam_Fade( src, dst, duration );
  8344. }
  8345. void CQuake3GameInterface::CameraPath( const char *name )
  8346. {
  8347. CGCam_StartRoff( G_NewString( name ) );
  8348. }
  8349. void CQuake3GameInterface::CameraEnable( void )
  8350. {
  8351. CGCam_Enable();
  8352. }
  8353. void CQuake3GameInterface::CameraDisable( void )
  8354. {
  8355. CGCam_Disable();
  8356. }
  8357. void CQuake3GameInterface::CameraShake( float intensity, int duration )
  8358. {
  8359. CGCam_Shake( intensity, duration );
  8360. }
  8361. int CQuake3GameInterface::GetFloat( int entID, const char *name, float *value )
  8362. {
  8363. gentity_t *ent = &g_entities[entID];
  8364. // gclient_t *client;
  8365. if ( !ent )
  8366. {
  8367. return false;
  8368. }
  8369. int toGet = GetIDForString( setTable, name ); //FIXME: May want to make a "getTable" as well
  8370. //FIXME: I'm getting really sick of these huge switch statements!
  8371. //NOTENOTE: return true if the value was correctly obtained
  8372. switch ( toGet )
  8373. {
  8374. case SET_PARM1:
  8375. case SET_PARM2:
  8376. case SET_PARM3:
  8377. case SET_PARM4:
  8378. case SET_PARM5:
  8379. case SET_PARM6:
  8380. case SET_PARM7:
  8381. case SET_PARM8:
  8382. case SET_PARM9:
  8383. case SET_PARM10:
  8384. case SET_PARM11:
  8385. case SET_PARM12:
  8386. case SET_PARM13:
  8387. case SET_PARM14:
  8388. case SET_PARM15:
  8389. case SET_PARM16:
  8390. if (ent->parms == NULL)
  8391. {
  8392. DebugPrint( WL_ERROR, "GET_PARM: %s %s did not have any parms set!\n", ent->classname, ent->targetname );
  8393. return false; // would prefer qfalse, but I'm fitting in with what's here <sigh>
  8394. }
  8395. *value = atof( ent->parms->parm[toGet - SET_PARM1] );
  8396. break;
  8397. case SET_COUNT:
  8398. *value = ent->count;
  8399. break;
  8400. case SET_HEALTH:
  8401. *value = ent->health;
  8402. break;
  8403. case SET_SKILL:
  8404. *value = g_spskill->integer;
  8405. break;
  8406. case SET_XVELOCITY://## %f="0.0" # Velocity along X axis
  8407. if ( ent->client == NULL )
  8408. {
  8409. DebugPrint( WL_WARNING, "GetFloat: SET_XVELOCITY, %s not a client\n", ent->targetname );
  8410. return false;
  8411. }
  8412. *value = ent->client->ps.velocity[0];
  8413. break;
  8414. case SET_YVELOCITY://## %f="0.0" # Velocity along Y axis
  8415. if ( ent->client == NULL )
  8416. {
  8417. DebugPrint( WL_WARNING, "GetFloat: SET_YVELOCITY, %s not a client\n", ent->targetname );
  8418. return false;
  8419. }
  8420. *value = ent->client->ps.velocity[1];
  8421. break;
  8422. case SET_ZVELOCITY://## %f="0.0" # Velocity along Z axis
  8423. if ( ent->client == NULL )
  8424. {
  8425. DebugPrint( WL_WARNING, "GetFloat: SET_ZVELOCITY, %s not a client\n", ent->targetname );
  8426. return false;
  8427. }
  8428. *value = ent->client->ps.velocity[2];
  8429. break;
  8430. case SET_Z_OFFSET:
  8431. *value = ent->currentOrigin[2] - ent->s.origin[2];
  8432. break;
  8433. case SET_DPITCH://## %f="0.0" # Pitch for NPC to turn to
  8434. if ( ent->NPC == NULL )
  8435. {
  8436. DebugPrint( WL_WARNING, "GetFloat: SET_DPITCH, %s not an NPC\n", ent->targetname );
  8437. return false;
  8438. }
  8439. *value = ent->NPC->desiredPitch;
  8440. break;
  8441. case SET_DYAW://## %f="0.0" # Yaw for NPC to turn to
  8442. if ( ent->NPC == NULL )
  8443. {
  8444. DebugPrint( WL_WARNING, "GetFloat: SET_DYAW, %s not an NPC\n", ent->targetname );
  8445. return false;
  8446. }
  8447. *value = ent->NPC->desiredPitch;
  8448. break;
  8449. case SET_WIDTH://## %f="0.0" # Width of NPC bounding box
  8450. if ( ent->NPC == NULL )
  8451. {
  8452. DebugPrint( WL_WARNING, "GetFloat: SET_WIDTH, %s not an NPC\n", ent->targetname );
  8453. return false;
  8454. }
  8455. *value = ent->mins[0];
  8456. break;
  8457. case SET_TIMESCALE://## %f="0.0" # Speed-up slow down game (0 - 1.0)
  8458. *value = g_timescale->value;
  8459. break;
  8460. case SET_CAMERA_GROUP_Z_OFS://## %s="NULL" # all ents with this cameraGroup will be focused on
  8461. return false;
  8462. break;
  8463. case SET_VISRANGE://## %f="0.0" # How far away NPC can see
  8464. if ( ent->NPC == NULL )
  8465. {
  8466. DebugPrint( WL_WARNING, "GetFloat: SET_VISRANGE, %s not an NPC\n", ent->targetname );
  8467. return false;
  8468. }
  8469. *value = ent->NPC->stats.visrange;
  8470. break;
  8471. case SET_EARSHOT://## %f="0.0" # How far an NPC can hear
  8472. if ( ent->NPC == NULL )
  8473. {
  8474. DebugPrint( WL_WARNING, "GetFloat: SET_EARSHOT, %s not an NPC\n", ent->targetname );
  8475. return false;
  8476. }
  8477. *value = ent->NPC->stats.earshot;
  8478. break;
  8479. case SET_VIGILANCE://## %f="0.0" # How often to look for enemies (0 - 1.0)
  8480. if ( ent->NPC == NULL )
  8481. {
  8482. DebugPrint( WL_WARNING, "GetFloat: SET_VIGILANCE, %s not an NPC\n", ent->targetname );
  8483. return false;
  8484. }
  8485. *value = ent->NPC->stats.vigilance;
  8486. break;
  8487. case SET_GRAVITY://## %f="0.0" # Change this ent's gravity - 800 default
  8488. if ( (ent->svFlags&SVF_CUSTOM_GRAVITY) && ent->client )
  8489. {
  8490. *value = ent->client->ps.gravity;
  8491. }
  8492. else
  8493. {
  8494. *value = g_gravity->value;
  8495. }
  8496. break;
  8497. case SET_FACEEYESCLOSED:
  8498. case SET_FACEEYESOPENED:
  8499. case SET_FACEAUX: //## %f="0.0" # Set face to Aux expression for number of seconds
  8500. case SET_FACEBLINK: //## %f="0.0" # Set face to Blink expression for number of seconds
  8501. case SET_FACEBLINKFROWN: //## %f="0.0" # Set face to Blinkfrown expression for number of seconds
  8502. case SET_FACEFROWN: //## %f="0.0" # Set face to Frown expression for number of seconds
  8503. case SET_FACENORMAL: //## %f="0.0" # Set face to Normal expression for number of seconds
  8504. DebugPrint( WL_WARNING, "GetFloat: SET_FACE___ not implemented\n" );
  8505. return false;
  8506. break;
  8507. case SET_WAIT: //## %f="0.0" # Change an entity's wait field
  8508. *value = ent->wait;
  8509. break;
  8510. case SET_FOLLOWDIST: //## %f="0.0" # How far away to stay from leader in BS_FOLLOW_LEADER
  8511. if ( ent->NPC == NULL )
  8512. {
  8513. DebugPrint( WL_WARNING, "GetFloat: SET_FOLLOWDIST, %s not an NPC\n", ent->targetname );
  8514. return false;
  8515. }
  8516. *value = ent->NPC->followDist;
  8517. break;
  8518. //# #sep ints
  8519. case SET_ANIM_HOLDTIME_LOWER://## %d="0" # Hold lower anim for number of milliseconds
  8520. if ( ent->client == NULL )
  8521. {
  8522. DebugPrint( WL_WARNING, "GetFloat: SET_ANIM_HOLDTIME_LOWER, %s not a client\n", ent->targetname );
  8523. return false;
  8524. }
  8525. *value = ent->client->ps.legsAnimTimer;
  8526. break;
  8527. case SET_ANIM_HOLDTIME_UPPER://## %d="0" # Hold upper anim for number of milliseconds
  8528. if ( ent->client == NULL )
  8529. {
  8530. DebugPrint( WL_WARNING, "GetFloat: SET_ANIM_HOLDTIME_UPPER, %s not a client\n", ent->targetname );
  8531. return false;
  8532. }
  8533. *value = ent->client->ps.torsoAnimTimer;
  8534. break;
  8535. case SET_ANIM_HOLDTIME_BOTH://## %d="0" # Hold lower and upper anims for number of milliseconds
  8536. DebugPrint( WL_WARNING, "GetFloat: SET_ANIM_HOLDTIME_BOTH not implemented\n" );
  8537. return false;
  8538. break;
  8539. case SET_ARMOR://## %d="0" # Change armor
  8540. if ( ent->client == NULL )
  8541. {
  8542. DebugPrint( WL_WARNING, "GetFloat: SET_ARMOR, %s not a client\n", ent->targetname );
  8543. return false;
  8544. }
  8545. *value = ent->client->ps.stats[STAT_ARMOR];
  8546. break;
  8547. case SET_WALKSPEED://## %d="0" # Change walkSpeed
  8548. if ( ent->NPC == NULL )
  8549. {
  8550. DebugPrint( WL_WARNING, "GetFloat: SET_WALKSPEED, %s not an NPC\n", ent->targetname );
  8551. return false;
  8552. }
  8553. *value = ent->NPC->stats.walkSpeed;
  8554. break;
  8555. case SET_RUNSPEED://## %d="0" # Change runSpeed
  8556. if ( ent->NPC == NULL )
  8557. {
  8558. DebugPrint( WL_WARNING, "GetFloat: SET_RUNSPEED, %s not an NPC\n", ent->targetname );
  8559. return false;
  8560. }
  8561. *value = ent->NPC->stats.runSpeed;
  8562. break;
  8563. case SET_YAWSPEED://## %d="0" # Change yawSpeed
  8564. if ( ent->NPC == NULL )
  8565. {
  8566. DebugPrint( WL_WARNING, "GetFloat: SET_YAWSPEED, %s not an NPC\n", ent->targetname );
  8567. return false;
  8568. }
  8569. *value = ent->NPC->stats.yawSpeed;
  8570. break;
  8571. case SET_AGGRESSION://## %d="0" # Change aggression 1-5
  8572. if ( ent->NPC == NULL )
  8573. {
  8574. DebugPrint( WL_WARNING, "GetFloat: SET_AGGRESSION, %s not an NPC\n", ent->targetname );
  8575. return false;
  8576. }
  8577. *value = ent->NPC->stats.aggression;
  8578. break;
  8579. case SET_AIM://## %d="0" # Change aim 1-5
  8580. if ( ent->NPC == NULL )
  8581. {
  8582. DebugPrint( WL_WARNING, "GetFloat: SET_AIM, %s not an NPC\n", ent->targetname );
  8583. return false;
  8584. }
  8585. *value = ent->NPC->stats.aim;
  8586. break;
  8587. case SET_FRICTION://## %d="0" # Change ent's friction - 6 default
  8588. if ( ent->client == NULL )
  8589. {
  8590. DebugPrint( WL_WARNING, "GetFloat: SET_FRICTION, %s not a client\n", ent->targetname );
  8591. return false;
  8592. }
  8593. *value = ent->client->ps.friction;
  8594. break;
  8595. case SET_SHOOTDIST://## %d="0" # How far the ent can shoot - 0 uses weapon
  8596. if ( ent->NPC == NULL )
  8597. {
  8598. DebugPrint( WL_WARNING, "GetFloat: SET_SHOOTDIST, %s not an NPC\n", ent->targetname );
  8599. return false;
  8600. }
  8601. *value = ent->NPC->stats.shootDistance;
  8602. break;
  8603. case SET_HFOV://## %d="0" # Horizontal field of view
  8604. if ( ent->NPC == NULL )
  8605. {
  8606. DebugPrint( WL_WARNING, "GetFloat: SET_HFOV, %s not an NPC\n", ent->targetname );
  8607. return false;
  8608. }
  8609. *value = ent->NPC->stats.hfov;
  8610. break;
  8611. case SET_VFOV://## %d="0" # Vertical field of view
  8612. if ( ent->NPC == NULL )
  8613. {
  8614. DebugPrint( WL_WARNING, "GetFloat: SET_VFOV, %s not an NPC\n", ent->targetname );
  8615. return false;
  8616. }
  8617. *value = ent->NPC->stats.vfov;
  8618. break;
  8619. case SET_DELAYSCRIPTTIME://## %d="0" # How many seconds to wait before running delayscript
  8620. *value = ent->delayScriptTime - level.time;
  8621. break;
  8622. case SET_FORWARDMOVE://## %d="0" # NPC move forward -127(back) to 127
  8623. if ( ent->client == NULL )
  8624. {
  8625. DebugPrint( WL_WARNING, "GetFloat: SET_FORWARDMOVE, %s not a client\n", ent->targetname );
  8626. return false;
  8627. }
  8628. *value = ent->client->forced_forwardmove;
  8629. break;
  8630. case SET_RIGHTMOVE://## %d="0" # NPC move right -127(left) to 127
  8631. if ( ent->client == NULL )
  8632. {
  8633. DebugPrint( WL_WARNING, "GetFloat: SET_RIGHTMOVE, %s not a client\n", ent->targetname );
  8634. return false;
  8635. }
  8636. *value = ent->client->forced_rightmove;
  8637. break;
  8638. case SET_STARTFRAME: //## %d="0" # frame to start animation sequence on
  8639. *value = ent->startFrame;
  8640. break;
  8641. case SET_ENDFRAME: //## %d="0" # frame to end animation sequence on
  8642. *value = ent->endFrame;
  8643. break;
  8644. case SET_ANIMFRAME: //## %d="0" # of current frame
  8645. *value = ent->s.frame;
  8646. break;
  8647. case SET_SHOT_SPACING://## %d="1000" # Time between shots for an NPC - reset to defaults when changes weapon
  8648. if ( ent->NPC == NULL )
  8649. {
  8650. DebugPrint( WL_WARNING, "GetFloat: SET_SHOT_SPACING, %s not an NPC\n", ent->targetname );
  8651. return false;
  8652. }
  8653. *value = ent->NPC->burstSpacing;
  8654. break;
  8655. case SET_MISSIONSTATUSTIME://## %d="0" # Amount of time until Mission Status should be shown after death
  8656. *value = cg.missionStatusDeadTime - level.time;
  8657. break;
  8658. //# #sep booleans
  8659. case SET_IGNOREPAIN://## %t="BOOL_TYPES" # Do not react to pain
  8660. if ( ent->NPC == NULL )
  8661. {
  8662. DebugPrint( WL_WARNING, "GetFloat: SET_IGNOREPAIN, %s not an NPC\n", ent->targetname );
  8663. return false;
  8664. }
  8665. *value = ent->NPC->ignorePain;
  8666. break;
  8667. case SET_IGNOREENEMIES://## %t="BOOL_TYPES" # Do not acquire enemies
  8668. *value = (ent->svFlags&SVF_IGNORE_ENEMIES);
  8669. break;
  8670. case SET_IGNOREALERTS://## Do not get enemy set by allies in area(ambush)
  8671. if ( ent->NPC == NULL )
  8672. {
  8673. DebugPrint( WL_WARNING, "GetFloat: SET_IGNOREALERTS, %s not an NPC\n", ent->targetname );
  8674. return false;
  8675. }
  8676. *value = (ent->NPC->scriptFlags&SCF_IGNORE_ALERTS);
  8677. case SET_DONTSHOOT://## %t="BOOL_TYPES" # Others won't shoot you
  8678. *value = (ent->flags&FL_DONT_SHOOT);
  8679. break;
  8680. case SET_NOTARGET://## %t="BOOL_TYPES" # Others won't pick you as enemy
  8681. *value = (ent->flags&FL_NOTARGET);
  8682. break;
  8683. case SET_DONTFIRE://## %t="BOOL_TYPES" # Don't fire your weapon
  8684. if ( ent->NPC == NULL )
  8685. {
  8686. DebugPrint( WL_WARNING, "GetFloat: SET_DONTFIRE, %s not an NPC\n", ent->targetname );
  8687. return false;
  8688. }
  8689. *value = (ent->NPC->scriptFlags&SCF_DONT_FIRE);
  8690. break;
  8691. case SET_LOCKED_ENEMY://## %t="BOOL_TYPES" # Keep current enemy until dead
  8692. *value = (ent->svFlags&SVF_LOCKEDENEMY);
  8693. break;
  8694. case SET_CROUCHED://## %t="BOOL_TYPES" # Force NPC to crouch
  8695. if ( ent->NPC == NULL )
  8696. {
  8697. DebugPrint( WL_WARNING, "GetFloat: SET_CROUCHED, %s not an NPC\n", ent->targetname );
  8698. return false;
  8699. }
  8700. *value = (ent->NPC->scriptFlags&SCF_CROUCHED);
  8701. break;
  8702. case SET_WALKING://## %t="BOOL_TYPES" # Force NPC to move at walkSpeed
  8703. if ( ent->NPC == NULL )
  8704. {
  8705. DebugPrint( WL_WARNING, "GetFloat: SET_WALKING, %s not an NPC\n", ent->targetname );
  8706. return false;
  8707. }
  8708. *value = (ent->NPC->scriptFlags&SCF_WALKING);
  8709. break;
  8710. case SET_RUNNING://## %t="BOOL_TYPES" # Force NPC to move at runSpeed
  8711. if ( ent->NPC == NULL )
  8712. {
  8713. DebugPrint( WL_WARNING, "GetFloat: SET_RUNNING, %s not an NPC\n", ent->targetname );
  8714. return false;
  8715. }
  8716. *value = (ent->NPC->scriptFlags&SCF_RUNNING);
  8717. break;
  8718. case SET_CHASE_ENEMIES://## %t="BOOL_TYPES" # NPC will chase after enemies
  8719. if ( ent->NPC == NULL )
  8720. {
  8721. DebugPrint( WL_WARNING, "GetFloat: SET_CHASE_ENEMIES, %s not an NPC\n", ent->targetname );
  8722. return false;
  8723. }
  8724. *value = (ent->NPC->scriptFlags&SCF_CHASE_ENEMIES);
  8725. break;
  8726. case SET_LOOK_FOR_ENEMIES://## %t="BOOL_TYPES" # NPC will be on the lookout for enemies
  8727. if ( ent->NPC == NULL )
  8728. {
  8729. DebugPrint( WL_WARNING, "GetFloat: SET_LOOK_FOR_ENEMIES, %s not an NPC\n", ent->targetname );
  8730. return false;
  8731. }
  8732. *value = (ent->NPC->scriptFlags&SCF_LOOK_FOR_ENEMIES);
  8733. break;
  8734. case SET_FACE_MOVE_DIR://## %t="BOOL_TYPES" # NPC will face in the direction it's moving
  8735. if ( ent->NPC == NULL )
  8736. {
  8737. DebugPrint( WL_WARNING, "GetFloat: SET_FACE_MOVE_DIR, %s not an NPC\n", ent->targetname );
  8738. return false;
  8739. }
  8740. *value = (ent->NPC->scriptFlags&SCF_FACE_MOVE_DIR);
  8741. break;
  8742. case SET_FORCED_MARCH://## %t="BOOL_TYPES" # Force NPC to move at runSpeed
  8743. if ( ent->NPC == NULL )
  8744. {
  8745. DebugPrint( WL_WARNING, "GetFloat: SET_FORCED_MARCH, %s not an NPC\n", ent->targetname );
  8746. return false;
  8747. }
  8748. *value = (ent->NPC->scriptFlags&SET_FORCED_MARCH);
  8749. break;
  8750. case SET_UNDYING://## %t="BOOL_TYPES" # Can take damage down to 1 but not die
  8751. *value = (ent->flags&FL_UNDYING);
  8752. break;
  8753. case SET_NOAVOID://## %t="BOOL_TYPES" # Will not avoid other NPCs or architecture
  8754. if ( ent->NPC == NULL )
  8755. {
  8756. DebugPrint( WL_WARNING, "GetFloat: SET_NOAVOID, %s not an NPC\n", ent->targetname );
  8757. return false;
  8758. }
  8759. *value = (ent->NPC->aiFlags&NPCAI_NO_COLL_AVOID);
  8760. break;
  8761. case SET_SOLID://## %t="BOOL_TYPES" # Make yourself notsolid or solid
  8762. *value = ent->contents;
  8763. break;
  8764. case SET_PLAYER_USABLE://## %t="BOOL_TYPES" # Can be activateby the player's "use" button
  8765. *value = (ent->svFlags&SVF_PLAYER_USABLE);
  8766. break;
  8767. case SET_LOOP_ANIM://## %t="BOOL_TYPES" # For non-NPCs: loop your animation sequence
  8768. *value = ent->loopAnim;
  8769. break;
  8770. case SET_INTERFACE://## %t="BOOL_TYPES" # Player interface on/off
  8771. DebugPrint( WL_WARNING, "GetFloat: SET_INTERFACE not implemented\n" );
  8772. return false;
  8773. break;
  8774. case SET_SHIELDS://## %t="BOOL_TYPES" # NPC has no shields (Borg do not adapt)
  8775. if ( ent->NPC == NULL )
  8776. {
  8777. DebugPrint( WL_WARNING, "GetFloat: SET_SHIELDS, %s not an NPC\n", ent->targetname );
  8778. return false;
  8779. }
  8780. *value = (ent->NPC->aiFlags&NPCAI_SHIELDS);
  8781. case SET_SABERACTIVE:
  8782. if ( ent->client == NULL )
  8783. {
  8784. DebugPrint( WL_WARNING, "GetFloat: SET_SABERACTIVE, %s not a client\n", ent->targetname );
  8785. return false;
  8786. }
  8787. *value = (ent->client->ps.SaberActive());
  8788. break;
  8789. case SET_INVISIBLE://## %t="BOOL_TYPES" # Makes an NPC not solid and not visible
  8790. *value = (ent->s.eFlags&EF_NODRAW);
  8791. break;
  8792. case SET_VAMPIRE://## %t="BOOL_TYPES" # Makes an NPC not solid and not visible
  8793. if ( !ent->client )
  8794. {
  8795. return false;
  8796. }
  8797. else
  8798. {
  8799. *value = (ent->client->ps.powerups[PW_DISINT_2]>level.time);
  8800. }
  8801. break;
  8802. case SET_FORCE_INVINCIBLE://## %t="BOOL_TYPES" # Makes an NPC not solid and not visible
  8803. if ( !ent->client )
  8804. {
  8805. return false;
  8806. }
  8807. else
  8808. {
  8809. *value = (ent->client->ps.powerups[PW_INVINCIBLE]>level.time);
  8810. }
  8811. break;
  8812. case SET_GREET_ALLIES://## %t="BOOL_TYPES" # Makes an NPC greet teammates
  8813. if ( ent->NPC == NULL )
  8814. {
  8815. DebugPrint( WL_WARNING, "GetFloat: SET_GREET_ALLIES, %s not an NPC\n", ent->targetname );
  8816. return false;
  8817. }
  8818. *value = (ent->NPC->aiFlags&NPCAI_GREET_ALLIES);
  8819. break;
  8820. case SET_VIDEO_FADE_IN://## %t="BOOL_TYPES" # Makes video playback fade in
  8821. DebugPrint( WL_WARNING, "GetFloat: SET_VIDEO_FADE_IN not implemented\n" );
  8822. return false;
  8823. break;
  8824. case SET_VIDEO_FADE_OUT://## %t="BOOL_TYPES" # Makes video playback fade out
  8825. DebugPrint( WL_WARNING, "GetFloat: SET_VIDEO_FADE_OUT not implemented\n" );
  8826. return false;
  8827. break;
  8828. case SET_PLAYER_LOCKED://## %t="BOOL_TYPES" # Makes it so player cannot move
  8829. *value = player_locked;
  8830. break;
  8831. case SET_LOCK_PLAYER_WEAPONS://## %t="BOOL_TYPES" # Makes it so player cannot switch weapons
  8832. *value = (ent->flags&FL_LOCK_PLAYER_WEAPONS);
  8833. break;
  8834. case SET_NO_IMPACT_DAMAGE://## %t="BOOL_TYPES" # Makes it so player cannot switch weapons
  8835. *value = (ent->flags&FL_NO_IMPACT_DMG);
  8836. break;
  8837. case SET_NO_KNOCKBACK://## %t="BOOL_TYPES" # Stops this ent from taking knockback from weapons
  8838. *value = (ent->flags&FL_NO_KNOCKBACK);
  8839. break;
  8840. case SET_ALT_FIRE://## %t="BOOL_TYPES" # Force NPC to use altfire when shooting
  8841. if ( ent->NPC == NULL )
  8842. {
  8843. DebugPrint( WL_WARNING, "GetFloat: SET_ALT_FIRE, %s not an NPC\n", ent->targetname );
  8844. return false;
  8845. }
  8846. *value = (ent->NPC->scriptFlags&SCF_ALT_FIRE);
  8847. break;
  8848. case SET_NO_RESPONSE://## %t="BOOL_TYPES" # NPCs will do generic responses when this is on (usescripts override generic responses as well)
  8849. if ( ent->NPC == NULL )
  8850. {
  8851. DebugPrint( WL_WARNING, "GetFloat: SET_NO_RESPONSE, %s not an NPC\n", ent->targetname );
  8852. return false;
  8853. }
  8854. *value = (ent->NPC->scriptFlags&SCF_NO_RESPONSE);
  8855. break;
  8856. case SET_INVINCIBLE://## %t="BOOL_TYPES" # Completely unkillable
  8857. *value = (ent->flags&FL_GODMODE);
  8858. break;
  8859. case SET_MISSIONSTATUSACTIVE: //# Turns on Mission Status Screen
  8860. *value = cg.missionStatusShow;
  8861. break;
  8862. case SET_NO_COMBAT_TALK://## %t="BOOL_TYPES" # NPCs will not do their combat talking noises when this is on
  8863. if ( ent->NPC == NULL )
  8864. {
  8865. DebugPrint( WL_WARNING, "GetFloat: SET_NO_COMBAT_TALK, %s not an NPC\n", ent->targetname );
  8866. return false;
  8867. }
  8868. *value = (ent->NPC->scriptFlags&SCF_NO_COMBAT_TALK);
  8869. break;
  8870. case SET_NO_ALERT_TALK://## %t="BOOL_TYPES" # NPCs will not do their combat talking noises when this is on
  8871. if ( ent->NPC == NULL )
  8872. {
  8873. DebugPrint( WL_WARNING, "GetFloat: SET_NO_ALERT_TALK, %s not an NPC\n", ent->targetname );
  8874. return false;
  8875. }
  8876. *value = (ent->NPC->scriptFlags&SCF_NO_ALERT_TALK);
  8877. break;
  8878. case SET_USE_CP_NEAREST://## %t="BOOL_TYPES" # NPCs will use their closest combat points, not try and find ones next to the player, or flank player
  8879. if ( ent->NPC == NULL )
  8880. {
  8881. DebugPrint( WL_WARNING, "GetFloat: SET_USE_CP_NEAREST, %s not an NPC\n", ent->targetname );
  8882. return false;
  8883. }
  8884. *value = (ent->NPC->scriptFlags&SCF_USE_CP_NEAREST);
  8885. break;
  8886. case SET_DISMEMBERABLE://## %t="BOOL_TYPES" # NPC will not be affected by force powers
  8887. if ( ent->client == NULL )
  8888. {
  8889. DebugPrint( WL_WARNING, "GetFloat: SET_DISMEMBERABLE, %s not a client\n", ent->targetname );
  8890. return false;
  8891. }
  8892. *value = !(ent->client->dismembered);
  8893. break;
  8894. case SET_NO_FORCE:
  8895. if ( ent->NPC == NULL )
  8896. {
  8897. DebugPrint( WL_WARNING, "GetFloat: SET_NO_FORCE, %s not an NPC\n", ent->targetname );
  8898. return false;
  8899. }
  8900. *value = (ent->NPC->scriptFlags&SCF_NO_FORCE);
  8901. break;
  8902. case SET_NO_ACROBATICS:
  8903. if ( ent->NPC == NULL )
  8904. {
  8905. DebugPrint( WL_WARNING, "GetFloat: SET_NO_ACROBATICS, %s not an NPC\n", ent->targetname );
  8906. return false;
  8907. }
  8908. *value = (ent->NPC->scriptFlags&SCF_NO_ACROBATICS);
  8909. break;
  8910. case SET_USE_SUBTITLES:
  8911. if ( ent->NPC == NULL )
  8912. {
  8913. DebugPrint( WL_WARNING, "GetFloat: SET_USE_SUBTITLES, %s not an NPC\n", ent->targetname );
  8914. return false;
  8915. }
  8916. *value = (ent->NPC->scriptFlags&SCF_USE_SUBTITLES);
  8917. break;
  8918. case SET_NO_FALLTODEATH://## %t="BOOL_TYPES" # NPC will not be affected by force powers
  8919. if ( ent->NPC == NULL )
  8920. {
  8921. DebugPrint( WL_WARNING, "GetFloat: SET_NO_FALLTODEATH, %s not an NPC\n", ent->targetname );
  8922. return false;
  8923. }
  8924. *value = (ent->NPC->scriptFlags&SCF_NO_FALLTODEATH);
  8925. break;
  8926. case SET_MORELIGHT://## %t="BOOL_TYPES" # NPCs will use their closest combat points, not try and find ones next to the player, or flank player
  8927. if ( ent->NPC == NULL )
  8928. {
  8929. DebugPrint( WL_WARNING, "GetFloat: SET_MORELIGHT, %s not an NPC\n", ent->targetname );
  8930. return false;
  8931. }
  8932. *value = (ent->NPC->scriptFlags&SCF_MORELIGHT);
  8933. break;
  8934. case SET_TREASONED://## %t="BOOL_TYPES" # Player has turned on his own- scripts will stop: NPCs will turn on him and level changes load the brig
  8935. DebugPrint( WL_VERBOSE, "SET_TREASONED is disabled, do not use\n" );
  8936. *value = 0;//(ffireLevel>=FFIRE_LEVEL_RETALIATION);
  8937. break;
  8938. case SET_DISABLE_SHADER_ANIM: //## %t="BOOL_TYPES" # Shaders won't animate
  8939. *value = (ent->s.eFlags & EF_DISABLE_SHADER_ANIM);
  8940. break;
  8941. case SET_SHADER_ANIM: //## %t="BOOL_TYPES" # Shader will be under frame control
  8942. *value = (ent->s.eFlags & EF_SHADER_ANIM);
  8943. break;
  8944. case SET_OBJECTIVE_LIGHTSIDE:
  8945. {
  8946. *value = level.clients[0].sess.mission_objectives[LIGHTSIDE_OBJ].status;
  8947. break;
  8948. }
  8949. // kef 4/16/03 -- just trying to put together some scripted meta-AI for swoop riders
  8950. case SET_DISTSQRD_TO_PLAYER:
  8951. {
  8952. vec3_t distSquared;
  8953. VectorSubtract(player->currentOrigin, ent->s.origin, distSquared);
  8954. *value = VectorLengthSquared(distSquared);
  8955. break;
  8956. }
  8957. default:
  8958. if ( VariableDeclared( name ) != VTYPE_FLOAT )
  8959. return false;
  8960. return GetFloatVariable( name, value );
  8961. }
  8962. return true;
  8963. }
  8964. int CQuake3GameInterface::GetVector( int entID, const char *name, vec3_t value )
  8965. {
  8966. gentity_t *ent = &g_entities[entID];
  8967. if ( !ent )
  8968. {
  8969. return false;
  8970. }
  8971. int toGet = GetIDForString( setTable, name ); //FIXME: May want to make a "getTable" as well
  8972. //FIXME: I'm getting really sick of these huge switch statements!
  8973. //NOTENOTE: return true if the value was correctly obtained
  8974. switch ( toGet )
  8975. {
  8976. case SET_PARM1:
  8977. case SET_PARM2:
  8978. case SET_PARM3:
  8979. case SET_PARM4:
  8980. case SET_PARM5:
  8981. case SET_PARM6:
  8982. case SET_PARM7:
  8983. case SET_PARM8:
  8984. case SET_PARM9:
  8985. case SET_PARM10:
  8986. case SET_PARM11:
  8987. case SET_PARM12:
  8988. case SET_PARM13:
  8989. case SET_PARM14:
  8990. case SET_PARM15:
  8991. case SET_PARM16:
  8992. sscanf( ent->parms->parm[toGet - SET_PARM1], "%f %f %f", &value[0], &value[1], &value[2] );
  8993. break;
  8994. case SET_ORIGIN:
  8995. VectorCopy(ent->currentOrigin, value);
  8996. break;
  8997. case SET_ANGLES:
  8998. VectorCopy(ent->currentAngles, value);
  8999. break;
  9000. case SET_TELEPORT_DEST://## %v="0.0 0.0 0.0" # Set origin here as soon as the area is clear
  9001. DebugPrint( WL_WARNING, "GetVector: SET_TELEPORT_DEST not implemented\n" );
  9002. return false;
  9003. break;
  9004. default:
  9005. if ( VariableDeclared( name ) != VTYPE_VECTOR )
  9006. return false;
  9007. return GetVectorVariable( name, value );
  9008. }
  9009. return true;
  9010. }
  9011. int CQuake3GameInterface::GetString( int entID, const char *name, char **value )
  9012. {
  9013. gentity_t *ent = &g_entities[entID];
  9014. if ( !ent )
  9015. {
  9016. return false;
  9017. }
  9018. int toGet = GetIDForString( setTable, name ); //FIXME: May want to make a "getTable" as well
  9019. switch ( toGet )
  9020. {
  9021. case SET_ANIM_BOTH:
  9022. *value = (char *) Q3_GetAnimBoth( ent );
  9023. if ( VALIDSTRING( value ) == false )
  9024. return false;
  9025. break;
  9026. case SET_PARM1:
  9027. case SET_PARM2:
  9028. case SET_PARM3:
  9029. case SET_PARM4:
  9030. case SET_PARM5:
  9031. case SET_PARM6:
  9032. case SET_PARM7:
  9033. case SET_PARM8:
  9034. case SET_PARM9:
  9035. case SET_PARM10:
  9036. case SET_PARM11:
  9037. case SET_PARM12:
  9038. case SET_PARM13:
  9039. case SET_PARM14:
  9040. case SET_PARM15:
  9041. case SET_PARM16:
  9042. if ( ent->parms )
  9043. {
  9044. *value = (char *) ent->parms->parm[toGet - SET_PARM1];
  9045. }
  9046. else
  9047. {
  9048. DebugPrint( WL_WARNING, "GetString: invalid ent %s has no parms!\n", ent->targetname );
  9049. return false;
  9050. }
  9051. break;
  9052. case SET_TARGET:
  9053. *value = (char *) ent->target;
  9054. break;
  9055. case SET_LOCATION:
  9056. *value = G_GetLocationForEnt( ent );
  9057. if ( !value || !value[0] )
  9058. {
  9059. return false;
  9060. }
  9061. break;
  9062. //# #sep Scripts and other file paths
  9063. case SET_SPAWNSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when spawned //0 - do not change these, these are equal to BSET_SPAWN, etc
  9064. *value = ent->behaviorSet[BSET_SPAWN];
  9065. break;
  9066. case SET_USESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when used
  9067. *value = ent->behaviorSet[BSET_USE];
  9068. break;
  9069. case SET_AWAKESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when startled
  9070. *value = ent->behaviorSet[BSET_AWAKE];
  9071. break;
  9072. case SET_ANGERSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script run when find an enemy for the first time
  9073. *value = ent->behaviorSet[BSET_ANGER];
  9074. break;
  9075. case SET_ATTACKSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when you shoot
  9076. *value = ent->behaviorSet[BSET_ATTACK];
  9077. break;
  9078. case SET_VICTORYSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when killed someone
  9079. *value = ent->behaviorSet[BSET_VICTORY];
  9080. break;
  9081. case SET_LOSTENEMYSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when you can't find your enemy
  9082. *value = ent->behaviorSet[BSET_LOSTENEMY];
  9083. break;
  9084. case SET_PAINSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when hit
  9085. *value = ent->behaviorSet[BSET_PAIN];
  9086. break;
  9087. case SET_FLEESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when hit and low health
  9088. *value = ent->behaviorSet[BSET_FLEE];
  9089. break;
  9090. case SET_DEATHSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when killed
  9091. *value = ent->behaviorSet[BSET_DEATH];
  9092. break;
  9093. case SET_DELAYEDSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run after a delay
  9094. *value = ent->behaviorSet[BSET_DELAYED];
  9095. break;
  9096. case SET_BLOCKEDSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when blocked by teammate
  9097. *value = ent->behaviorSet[BSET_BLOCKED];
  9098. break;
  9099. case SET_FFIRESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when player has shot own team repeatedly
  9100. *value = ent->behaviorSet[BSET_FFIRE];
  9101. break;
  9102. case SET_FFDEATHSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when player kills a teammate
  9103. *value = ent->behaviorSet[BSET_FFDEATH];
  9104. break;
  9105. //# #sep Standard strings
  9106. case SET_ENEMY://## %s="NULL" # Set enemy by targetname
  9107. if ( ent->enemy != NULL )
  9108. {
  9109. *value = ent->enemy->targetname;
  9110. }
  9111. else return false;
  9112. break;
  9113. case SET_LEADER://## %s="NULL" # Set for BS_FOLLOW_LEADER
  9114. if ( ent->client == NULL )
  9115. {
  9116. DebugPrint( WL_WARNING, "GetString: SET_LEADER, %s not a client\n", ent->targetname );
  9117. return false;
  9118. }
  9119. else if ( ent->client->leader )
  9120. {
  9121. *value = ent->client->leader->targetname;
  9122. }
  9123. else return false;
  9124. break;
  9125. case SET_CAPTURE://## %s="NULL" # Set captureGoal by targetname
  9126. if ( ent->NPC == NULL )
  9127. {
  9128. DebugPrint( WL_WARNING, "GetString: SET_CAPTURE, %s not an NPC\n", ent->targetname );
  9129. return false;
  9130. }
  9131. else if ( ent->NPC->captureGoal != NULL )
  9132. {
  9133. *value = ent->NPC->captureGoal->targetname;
  9134. }
  9135. else return false;
  9136. break;
  9137. case SET_TARGETNAME://## %s="NULL" # Set/change your targetname
  9138. *value = ent->targetname;
  9139. break;
  9140. case SET_PAINTARGET://## %s="NULL" # Set/change what to use when hit
  9141. *value = ent->paintarget;
  9142. break;
  9143. case SET_PLAYERMODEL:
  9144. *value = ent->NPC_type;
  9145. break;
  9146. case SET_CAMERA_GROUP://## %s="NULL" # all ents with this cameraGroup will be focused on
  9147. *value = ent->cameraGroup;
  9148. break;
  9149. case SET_CAMERA_GROUP_TAG://## %s="NULL" # all ents with this cameraGroup will be focused on
  9150. return false;
  9151. break;
  9152. case SET_LOOK_TARGET://## %s="NULL" # object for NPC to look at
  9153. if ( ent->client == NULL )
  9154. {
  9155. DebugPrint( WL_WARNING, "GetString: SET_LOOK_TARGET, %s not a client\n", ent->targetname );
  9156. return false;
  9157. }
  9158. else
  9159. {
  9160. gentity_t *lookTarg = &g_entities[ent->client->renderInfo.lookTarget];
  9161. if ( lookTarg != NULL )
  9162. {
  9163. *value = lookTarg->targetname;
  9164. }
  9165. else return false;
  9166. }
  9167. break;
  9168. case SET_TARGET2://## %s="NULL" # Set/change your target2: on NPC's: this fires when they're knocked out by the red hypo
  9169. *value = ent->target2;
  9170. break;
  9171. case SET_REMOVE_TARGET://## %s="NULL" # Target that is fired when someone completes the BS_REMOVE behaviorState
  9172. *value = ent->target3;
  9173. break;
  9174. case SET_WEAPON:
  9175. if ( ent->client == NULL )
  9176. {
  9177. DebugPrint( WL_WARNING, "GetString: SET_WEAPON, %s not a client\n", ent->targetname );
  9178. return false;
  9179. }
  9180. else
  9181. {
  9182. *value = (char *)GetStringForID( WPTable, ent->client->ps.weapon );
  9183. }
  9184. break;
  9185. case SET_ITEM:
  9186. if ( ent->client == NULL )
  9187. {
  9188. DebugPrint( WL_WARNING, "GetString: SET_ITEM, %s not a client\n", ent->targetname );
  9189. return false;
  9190. }
  9191. else
  9192. {
  9193. // *value = (char *)GetStringForID( WPTable, ent->client->ps.weapon );
  9194. }
  9195. break;
  9196. case SET_MUSIC_STATE:
  9197. *value = (char *)GetStringForID( DMSTable, level.dmState );
  9198. break;
  9199. //The below cannot be gotten
  9200. case SET_NAVGOAL://## %s="NULL" # *Move to this navgoal then continue script
  9201. DebugPrint( WL_WARNING, "GetString: SET_NAVGOAL not implemented\n" );
  9202. return false;
  9203. break;
  9204. case SET_VIEWTARGET://## %s="NULL" # Set angles toward ent by targetname
  9205. DebugPrint( WL_WARNING, "GetString: SET_VIEWTARGET not implemented\n" );
  9206. return false;
  9207. break;
  9208. case SET_WATCHTARGET://## %s="NULL" # Set angles toward ent by targetname
  9209. if ( ent && ent->NPC && ent->NPC->watchTarget )
  9210. {
  9211. *value = ent->NPC->watchTarget->targetname;
  9212. }
  9213. else
  9214. {
  9215. DebugPrint( WL_WARNING, "GetString: SET_WATCHTARGET no watchTarget!\n" );
  9216. return false;
  9217. }
  9218. break;
  9219. case SET_VIEWENTITY:
  9220. DebugPrint( WL_WARNING, "GetString: SET_VIEWENTITY not implemented\n" );
  9221. return false;
  9222. break;
  9223. case SET_CAPTIONTEXTCOLOR: //## %s="" # Color of text RED:WHITE:BLUE: YELLOW
  9224. DebugPrint( WL_WARNING, "GetString: SET_CAPTIONTEXTCOLOR not implemented\n" );
  9225. return false;
  9226. break;
  9227. case SET_CENTERTEXTCOLOR: //## %s="" # Color of text RED:WHITE:BLUE: YELLOW
  9228. DebugPrint( WL_WARNING, "GetString: SET_CENTERTEXTCOLOR not implemented\n" );
  9229. return false;
  9230. break;
  9231. case SET_SCROLLTEXTCOLOR: //## %s="" # Color of text RED:WHITE:BLUE: YELLOW
  9232. DebugPrint( WL_WARNING, "GetString: SET_SCROLLTEXTCOLOR not implemented\n" );
  9233. return false;
  9234. break;
  9235. case SET_COPY_ORIGIN://## %s="targetname" # Copy the origin of the ent with targetname to your origin
  9236. DebugPrint( WL_WARNING, "GetString: SET_COPY_ORIGIN not implemented\n" );
  9237. return false;
  9238. break;
  9239. case SET_DEFEND_TARGET://## %s="targetname" # This NPC will attack the target NPC's enemies
  9240. DebugPrint( WL_WARNING, "GetString: SET_COPY_ORIGIN not implemented\n" );
  9241. return false;
  9242. break;
  9243. case SET_VIDEO_PLAY://## %s="filename" !!"W:\game\base\video\!!#*.roq" # Play a Video (inGame)
  9244. DebugPrint( WL_WARNING, "GetString: SET_VIDEO_PLAY not implemented\n" );
  9245. return false;
  9246. break;
  9247. case SET_LOADGAME://## %s="exitholodeck" # Load the savegame that was auto-saved when you started the holodeck
  9248. DebugPrint( WL_WARNING, "GetString: SET_LOADGAME not implemented\n" );
  9249. return false;
  9250. break;
  9251. case SET_LOCKYAW://## %s="off" # Lock legs to a certain yaw angle (or "off" or "auto" uses current)
  9252. DebugPrint( WL_WARNING, "GetString: SET_LOCKYAW not implemented\n" );
  9253. return false;
  9254. break;
  9255. case SET_SCROLLTEXT: //## %s="" # key of text string to print
  9256. DebugPrint( WL_WARNING, "GetString: SET_SCROLLTEXT not implemented\n" );
  9257. return false;
  9258. break;
  9259. case SET_LCARSTEXT: //## %s="" # key of text string to print in LCARS frame
  9260. DebugPrint( WL_WARNING, "GetString: SET_LCARSTEXT not implemented\n" );
  9261. return false;
  9262. break;
  9263. case SET_CENTERTEXT:
  9264. DebugPrint( WL_WARNING, "GetString: SET_CENTERTEXT not implemented\n" );
  9265. return false;
  9266. break;
  9267. default:
  9268. if ( VariableDeclared( name ) != VTYPE_STRING )
  9269. return false;
  9270. return GetStringVariable( name, (const char **) value );
  9271. }
  9272. return true;
  9273. }
  9274. int CQuake3GameInterface::Evaluate( int p1Type, const char *p1, int p2Type, const char *p2, int operatorType )
  9275. {
  9276. float f1=0, f2=0;
  9277. vec3_t v1, v2;
  9278. char *c1=0, *c2=0;
  9279. int i1=0, i2=0;
  9280. //Always demote to int on float to integer comparisons
  9281. if ( ( ( p1Type == TK_FLOAT ) && ( p2Type == TK_INT ) ) || ( ( p1Type == TK_INT ) && ( p2Type == TK_FLOAT ) ) )
  9282. {
  9283. p1Type = TK_INT;
  9284. p2Type = TK_INT;
  9285. }
  9286. //Cannot compare two disimilar types
  9287. if ( p1Type != p2Type )
  9288. {
  9289. DebugPrint( WL_ERROR, "Evaluate comparing two disimilar types!\n");
  9290. return false;
  9291. }
  9292. //Format the parameters
  9293. switch ( p1Type )
  9294. {
  9295. case TK_FLOAT:
  9296. sscanf( p1, "%f", &f1 );
  9297. sscanf( p2, "%f", &f2 );
  9298. break;
  9299. case TK_INT:
  9300. sscanf( p1, "%d", &i1 );
  9301. sscanf( p2, "%d", &i2 );
  9302. break;
  9303. case TK_VECTOR:
  9304. sscanf( p1, "%f %f %f", &v1[0], &v1[1], &v1[2] );
  9305. sscanf( p2, "%f %f %f", &v2[0], &v2[1], &v2[2] );
  9306. break;
  9307. case TK_STRING:
  9308. case TK_IDENTIFIER:
  9309. c1 = (char *) p1;
  9310. c2 = (char *) p2;
  9311. break;
  9312. default:
  9313. DebugPrint( WL_WARNING, "Evaluate unknown type used!\n");
  9314. return false;
  9315. }
  9316. //Compare them and return the result
  9317. //FIXME: YUCK!!! Better way to do this?
  9318. switch ( operatorType )
  9319. {
  9320. //
  9321. // EQUAL TO
  9322. //
  9323. case TK_EQUALS:
  9324. switch ( p1Type )
  9325. {
  9326. case TK_FLOAT:
  9327. return (int) ( f1 == f2 );
  9328. break;
  9329. case TK_INT:
  9330. return (int) ( i1 == i2 );
  9331. break;
  9332. case TK_VECTOR:
  9333. return (int) VectorCompare( v1, v2 );
  9334. break;
  9335. case TK_STRING:
  9336. case TK_IDENTIFIER:
  9337. return (int) !stricmp( c1, c2 ); //NOTENOTE: The script uses proper string comparison logic (ex. ( a == a ) == true )
  9338. break;
  9339. default:
  9340. DebugPrint( WL_ERROR, "Evaluate unknown type used!\n");
  9341. return false;
  9342. }
  9343. break;
  9344. //
  9345. // GREATER THAN
  9346. //
  9347. case TK_GREATER_THAN:
  9348. switch ( p1Type )
  9349. {
  9350. case TK_FLOAT:
  9351. return (int) ( f1 > f2 );
  9352. break;
  9353. case TK_INT:
  9354. return (int) ( i1 > i2 );
  9355. break;
  9356. case TK_VECTOR:
  9357. DebugPrint( WL_ERROR, "Evaluate vector comparisons of type GREATER THAN cannot be performed!");
  9358. return false;
  9359. break;
  9360. case TK_STRING:
  9361. case TK_IDENTIFIER:
  9362. DebugPrint( WL_ERROR, "Evaluate string comparisons of type GREATER THAN cannot be performed!");
  9363. return false;
  9364. break;
  9365. default:
  9366. DebugPrint( WL_ERROR, "Evaluate unknown type used!\n");
  9367. return false;
  9368. }
  9369. break;
  9370. //
  9371. // LESS THAN
  9372. //
  9373. case TK_LESS_THAN:
  9374. switch ( p1Type )
  9375. {
  9376. case TK_FLOAT:
  9377. return (int) ( f1 < f2 );
  9378. break;
  9379. case TK_INT:
  9380. return (int) ( i1 < i2 );
  9381. break;
  9382. case TK_VECTOR:
  9383. DebugPrint( WL_ERROR, "Evaluate vector comparisons of type LESS THAN cannot be performed!");
  9384. return false;
  9385. break;
  9386. case TK_STRING:
  9387. case TK_IDENTIFIER:
  9388. DebugPrint( WL_ERROR, "Evaluate string comparisons of type LESS THAN cannot be performed!");
  9389. return false;
  9390. break;
  9391. default:
  9392. DebugPrint( WL_ERROR, "Evaluate unknown type used!\n");
  9393. return false;
  9394. }
  9395. break;
  9396. //
  9397. // NOT
  9398. //
  9399. case TK_NOT: //NOTENOTE: Implied "NOT EQUAL TO"
  9400. switch ( p1Type )
  9401. {
  9402. case TK_FLOAT:
  9403. return (int) ( f1 != f2 );
  9404. break;
  9405. case TK_INT:
  9406. return (int) ( i1 != i2 );
  9407. break;
  9408. case TK_VECTOR:
  9409. return (int) !VectorCompare( v1, v2 );
  9410. break;
  9411. case TK_STRING:
  9412. case TK_IDENTIFIER:
  9413. return (int) stricmp( c1, c2 );
  9414. break;
  9415. default:
  9416. DebugPrint( WL_ERROR, "Evaluate unknown type used!\n");
  9417. return false;
  9418. }
  9419. break;
  9420. //
  9421. // GREATER THAN OR EQUAL TO
  9422. //
  9423. case TK_GE:
  9424. switch ( p1Type )
  9425. {
  9426. case TK_FLOAT:
  9427. return (int) ( f1 >= f2 );
  9428. break;
  9429. case TK_INT:
  9430. return (int) ( i1 >= i2 );
  9431. break;
  9432. case TK_VECTOR:
  9433. DebugPrint( WL_ERROR, "Evaluate vector comparisons of type GREATER THAN OR EQUAL TO cannot be performed!");
  9434. return false;
  9435. break;
  9436. case TK_STRING:
  9437. case TK_IDENTIFIER:
  9438. DebugPrint( WL_ERROR, "Evaluate string comparisons of type GREATER THAN OR EQUAL TO cannot be performed!");
  9439. return false;
  9440. break;
  9441. default:
  9442. DebugPrint( WL_ERROR, "Evaluate unknown type used!\n");
  9443. return false;
  9444. }
  9445. break;
  9446. //
  9447. // LESS THAN OR EQUAL TO
  9448. //
  9449. case TK_LE:
  9450. switch ( p1Type )
  9451. {
  9452. case TK_FLOAT:
  9453. return (int) ( f1 <= f2 );
  9454. break;
  9455. case TK_INT:
  9456. return (int) ( i1 <= i2 );
  9457. break;
  9458. case TK_VECTOR:
  9459. DebugPrint( WL_ERROR, "Evaluate vector comparisons of type LESS THAN OR EQUAL TO cannot be performed!");
  9460. return false;
  9461. break;
  9462. case TK_STRING:
  9463. case TK_IDENTIFIER:
  9464. DebugPrint( WL_ERROR, "Evaluate string comparisons of type LESS THAN OR EQUAL TO cannot be performed!");
  9465. return false;
  9466. break;
  9467. default:
  9468. DebugPrint( WL_ERROR, "Evaluate unknown type used!\n");
  9469. return false;
  9470. }
  9471. break;
  9472. default:
  9473. DebugPrint( WL_ERROR, "Evaluate unknown operator used!\n");
  9474. break;
  9475. }
  9476. return false;
  9477. }
  9478. void CQuake3GameInterface::DeclareVariable( int type, const char *name )
  9479. {
  9480. //Cannot declare the same variable twice
  9481. if ( VariableDeclared( name ) != VTYPE_NONE )
  9482. return;
  9483. if ( m_numVariables > MAX_VARIABLES )
  9484. {
  9485. DebugPrint( WL_ERROR, "too many variables already declared, maximum is %d\n", MAX_VARIABLES );
  9486. return;
  9487. }
  9488. switch( type )
  9489. {
  9490. case TK_FLOAT:
  9491. m_varFloats[ name ] = 0.0f;
  9492. break;
  9493. case TK_STRING:
  9494. m_varStrings[ name ] = "NULL";
  9495. break;
  9496. case TK_VECTOR:
  9497. m_varVectors[ name ] = "0.0 0.0 0.0";
  9498. break;
  9499. default:
  9500. DebugPrint( WL_ERROR, "unknown 'type' for declare() function!\n" );
  9501. return;
  9502. break;
  9503. }
  9504. m_numVariables++;
  9505. }
  9506. void CQuake3GameInterface::FreeVariable( const char *name )
  9507. {
  9508. //Check the strings
  9509. varString_m::iterator vsi = m_varStrings.find( name );
  9510. if ( vsi != m_varStrings.end() )
  9511. {
  9512. m_varStrings.erase( vsi );
  9513. m_numVariables--;
  9514. return;
  9515. }
  9516. //Check the floats
  9517. varFloat_m::iterator vfi = m_varFloats.find( name );
  9518. if ( vfi != m_varFloats.end() )
  9519. {
  9520. m_varFloats.erase( vfi );
  9521. m_numVariables--;
  9522. return;
  9523. }
  9524. //Check the strings
  9525. varString_m::iterator vvi = m_varVectors.find( name );
  9526. if ( vvi != m_varVectors.end() )
  9527. {
  9528. m_varVectors.erase( vvi );
  9529. m_numVariables--;
  9530. return;
  9531. }
  9532. }
  9533. //Save / Load functions
  9534. int CQuake3GameInterface::WriteSaveData( unsigned long chid, void *data, int length )
  9535. {
  9536. return gi.AppendToSaveGame( chid, data, length );
  9537. }
  9538. int CQuake3GameInterface::ReadSaveData( unsigned long chid, void *address, int length, void **addressptr )
  9539. {
  9540. return gi.ReadFromSaveGame( chid, address, length, addressptr );
  9541. }
  9542. int CQuake3GameInterface::LinkGame( int entID, int icarusID )
  9543. {
  9544. gentity_t *pEntity = &g_entities[entID];
  9545. if ( pEntity == NULL )
  9546. return false;
  9547. // Set the icarus ID.
  9548. pEntity->m_iIcarusID = icarusID;
  9549. // Associate this Entity with the entity list.
  9550. AssociateEntity( pEntity );
  9551. return true;
  9552. }
  9553. // Access functions
  9554. int CQuake3GameInterface::CreateIcarus( int entID )
  9555. {
  9556. gentity_t *pEntity = &g_entities[entID];
  9557. // If the entity doesn't have an Icarus ID, obtain and assign a new one.
  9558. if ( pEntity->m_iIcarusID == IIcarusInterface::ICARUS_INVALID )
  9559. pEntity->m_iIcarusID = IIcarusInterface::GetIcarus()->GetIcarusID( entID );
  9560. return pEntity->m_iIcarusID;
  9561. }
  9562. //Polls the engine for the sequencer of the entity matching the name passed
  9563. int CQuake3GameInterface::GetByName( const char *name )
  9564. {
  9565. gentity_t *ent;
  9566. entitylist_t::iterator ei;
  9567. char temp[1024];
  9568. if ( name == NULL || name[0] == NULL )
  9569. return -1;
  9570. strncpy( (char *) temp, name, sizeof(temp) );
  9571. temp[sizeof(temp)-1] = 0;
  9572. ei = m_EntityList.find( strupr( (char *) temp ) );
  9573. if ( ei == m_EntityList.end() )
  9574. return -1;
  9575. ent = &g_entities[(*ei).second];
  9576. return ent->s.number;
  9577. // this now returns the ent instead of the sequencer -- dmv 06/27/01
  9578. // if (ent == NULL)
  9579. // return NULL;
  9580. // return ent->sequencer;
  9581. }
  9582. // (g_entities[m_ownerID].svFlags&SVF_ICARUS_FREEZE)
  9583. // return -1 indicates invalid
  9584. int CQuake3GameInterface::IsFrozen( int entID )
  9585. {
  9586. return (g_entities[entID].svFlags & SVF_ICARUS_FREEZE);
  9587. }
  9588. void CQuake3GameInterface::Free(void* data)
  9589. {
  9590. gi.Free( data );
  9591. }
  9592. void* CQuake3GameInterface::Malloc( int size )
  9593. {
  9594. return gi.Malloc( size, TAG_ICARUS, qtrue );
  9595. }
  9596. float CQuake3GameInterface::MaxFloat(void)
  9597. {
  9598. // CHANGE!
  9599. return 34000000;
  9600. }
  9601. // Script Precache functions.
  9602. void CQuake3GameInterface::PrecacheRoff( const char *name )
  9603. {
  9604. G_LoadRoff( name );
  9605. }
  9606. void CQuake3GameInterface::PrecacheScript( const char *name )
  9607. {
  9608. char newname[1024]; //static char newname[1024];
  9609. // Strip the extension since we want the real name of the script.
  9610. COM_StripExtension( name, (char *) newname );
  9611. char *pBuf = NULL;
  9612. int iLength = 0;
  9613. // Try to Register the Script.
  9614. switch( RegisterScript( newname, (void **) &pBuf, iLength ) )
  9615. {
  9616. // If the script has already been registered (or could not be loaded), leave!
  9617. case SCRIPT_COULDNOTREGISTER:
  9618. if ( !Q_stricmp( newname, "NULL" ) || !Q_stricmp( newname, "default" ) )
  9619. {//these are not real errors, suppress warning
  9620. return;
  9621. }
  9622. Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "PrecacheScript: Failed to load %s!\n", newname );
  9623. assert(SCRIPT_COULDNOTREGISTER);
  9624. return;
  9625. case SCRIPT_ALREADYREGISTERED:
  9626. return;
  9627. // We loaded the script and registered it, so precache it through Icarus now.
  9628. case SCRIPT_REGISTERED:
  9629. IIcarusInterface::GetIcarus()->Precache( pBuf, iLength );
  9630. return;
  9631. }
  9632. }
  9633. void CQuake3GameInterface::PrecacheSound( const char *name )
  9634. {
  9635. char finalName[MAX_QPATH];
  9636. Q_strncpyz( finalName, name, MAX_QPATH, 0 );
  9637. strlwr(finalName);
  9638. if (com_buildScript->integer)
  9639. { //get the male sound first
  9640. G_SoundIndex( finalName );
  9641. }
  9642. G_AddSexToPlayerString( finalName, qtrue ); //now get female
  9643. G_SoundIndex( finalName );
  9644. }
  9645. void CQuake3GameInterface::PrecacheFromSet( const char *setname, const char *filename )
  9646. {
  9647. //JW NOTENOTE: This will not catch special case get() inlines! (There's not really a good way to do that)
  9648. // Get the id for this set identifier then check against valid types.
  9649. switch ( GetIDForString( setTable, setname ) )
  9650. {
  9651. case SET_SPAWNSCRIPT:
  9652. case SET_USESCRIPT:
  9653. case SET_AWAKESCRIPT:
  9654. case SET_ANGERSCRIPT:
  9655. case SET_ATTACKSCRIPT:
  9656. case SET_VICTORYSCRIPT:
  9657. case SET_LOSTENEMYSCRIPT:
  9658. case SET_PAINSCRIPT:
  9659. case SET_FLEESCRIPT:
  9660. case SET_DEATHSCRIPT:
  9661. case SET_DELAYEDSCRIPT:
  9662. case SET_BLOCKEDSCRIPT:
  9663. case SET_FFIRESCRIPT:
  9664. case SET_FFDEATHSCRIPT:
  9665. case SET_MINDTRICKSCRIPT:
  9666. case SET_CINEMATIC_SKIPSCRIPT:
  9667. PrecacheScript(filename);
  9668. break;
  9669. case SET_LOOPSOUND: //like ID_SOUND, but set's looping
  9670. G_SoundIndex( filename );
  9671. break;
  9672. case SET_VIDEO_PLAY: //in game cinematic
  9673. if (com_buildScript->integer)
  9674. {
  9675. fileHandle_t file;
  9676. char name[MAX_OSPATH];
  9677. if (strstr( filename, "/") == NULL && strstr( filename, "\\") == NULL) {
  9678. Com_sprintf ( name, sizeof(name), "video/%s", filename );
  9679. } else {
  9680. Com_sprintf ( name, sizeof(name), "%s", filename );
  9681. }
  9682. COM_StripExtension( name, name );
  9683. COM_DefaultExtension( name, sizeof( name ), ".roq" );
  9684. gi.FS_FOpenFile( name, &file, FS_READ ); // trigger the file copy
  9685. if (file)
  9686. {
  9687. gi.FS_FCloseFile( file );
  9688. }
  9689. }
  9690. break;
  9691. case SET_ADDRHANDBOLT_MODEL:
  9692. case SET_ADDLHANDBOLT_MODEL:
  9693. {
  9694. gi.G2API_PrecacheGhoul2Model( filename );
  9695. }
  9696. break;
  9697. case SET_WEAPON:
  9698. {
  9699. const int wp = GetIDForString( WPTable, filename );
  9700. if (wp > 0)
  9701. {
  9702. gitem_t *item = FindItemForWeapon( (weapon_t) wp);
  9703. RegisterItem( item ); //make sure the weapon is cached in case this runs at startup
  9704. }
  9705. }
  9706. break;
  9707. default:
  9708. break;
  9709. }
  9710. }
  9711. //////////////////////////////////////////////////////////////////////////
  9712. /* END Quake 3 Interface Declarations END */
  9713. //////////////////////////////////////////////////////////////////////////