123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../../idlib/precompiled.h"
- #pragma hdrstop
- #include "../Game_local.h"
- /***********************************************************************
- AI Events
- ***********************************************************************/
- const idEventDef AI_FindEnemy( "findEnemy", "d", 'e' );
- const idEventDef AI_FindEnemyAI( "findEnemyAI", "d", 'e' );
- const idEventDef AI_FindEnemyInCombatNodes( "findEnemyInCombatNodes", NULL, 'e' );
- const idEventDef AI_ClosestReachableEnemyOfEntity( "closestReachableEnemyOfEntity", "E", 'e' );
- const idEventDef AI_HeardSound( "heardSound", "d", 'e' );
- const idEventDef AI_SetEnemy( "setEnemy", "E" );
- const idEventDef AI_ClearEnemy( "clearEnemy" );
- const idEventDef AI_MuzzleFlash( "muzzleFlash", "s" );
- const idEventDef AI_CreateMissile( "createMissile", "s", 'e' );
- const idEventDef AI_AttackMissile( "attackMissile", "s", 'e' );
- const idEventDef AI_FireMissileAtTarget( "fireMissileAtTarget", "ss", 'e' );
- const idEventDef AI_LaunchMissile( "launchMissile", "vv", 'e' );
- #ifdef _D3XP
- const idEventDef AI_LaunchProjectile( "launchProjectile", "s" );
- #endif
- const idEventDef AI_AttackMelee( "attackMelee", "s", 'd' );
- const idEventDef AI_DirectDamage( "directDamage", "es" );
- const idEventDef AI_RadiusDamageFromJoint( "radiusDamageFromJoint", "ss" );
- const idEventDef AI_BeginAttack( "attackBegin", "s" );
- const idEventDef AI_EndAttack( "attackEnd" );
- const idEventDef AI_MeleeAttackToJoint( "meleeAttackToJoint", "ss", 'd' );
- const idEventDef AI_RandomPath( "randomPath", NULL, 'e' );
- const idEventDef AI_CanBecomeSolid( "canBecomeSolid", NULL, 'f' );
- const idEventDef AI_BecomeSolid( "becomeSolid" );
- const idEventDef AI_BecomeRagdoll( "becomeRagdoll", NULL, 'd' );
- const idEventDef AI_StopRagdoll( "stopRagdoll" );
- const idEventDef AI_SetHealth( "setHealth", "f" );
- const idEventDef AI_GetHealth( "getHealth", NULL, 'f' );
- const idEventDef AI_AllowDamage( "allowDamage" );
- const idEventDef AI_IgnoreDamage( "ignoreDamage" );
- const idEventDef AI_GetCurrentYaw( "getCurrentYaw", NULL, 'f' );
- const idEventDef AI_TurnTo( "turnTo", "f" );
- const idEventDef AI_TurnToPos( "turnToPos", "v" );
- const idEventDef AI_TurnToEntity( "turnToEntity", "E" );
- const idEventDef AI_MoveStatus( "moveStatus", NULL, 'd' );
- const idEventDef AI_StopMove( "stopMove" );
- const idEventDef AI_MoveToCover( "moveToCover" );
- const idEventDef AI_MoveToEnemy( "moveToEnemy" );
- const idEventDef AI_MoveToEnemyHeight( "moveToEnemyHeight" );
- const idEventDef AI_MoveOutOfRange( "moveOutOfRange", "ef" );
- const idEventDef AI_MoveToAttackPosition( "moveToAttackPosition", "es" );
- const idEventDef AI_Wander( "wander" );
- const idEventDef AI_MoveToEntity( "moveToEntity", "e" );
- const idEventDef AI_MoveToPosition( "moveToPosition", "v" );
- const idEventDef AI_SlideTo( "slideTo", "vf" );
- const idEventDef AI_FacingIdeal( "facingIdeal", NULL, 'd' );
- const idEventDef AI_FaceEnemy( "faceEnemy" );
- const idEventDef AI_FaceEntity( "faceEntity", "E" );
- const idEventDef AI_GetCombatNode( "getCombatNode", NULL, 'e' );
- const idEventDef AI_EnemyInCombatCone( "enemyInCombatCone", "Ed", 'd' );
- const idEventDef AI_WaitMove( "waitMove" );
- const idEventDef AI_GetJumpVelocity( "getJumpVelocity", "vff", 'v' );
- const idEventDef AI_EntityInAttackCone( "entityInAttackCone", "E", 'd' );
- const idEventDef AI_CanSeeEntity( "canSee", "E", 'd' );
- const idEventDef AI_SetTalkTarget( "setTalkTarget", "E" );
- const idEventDef AI_GetTalkTarget( "getTalkTarget", NULL, 'e' );
- const idEventDef AI_SetTalkState( "setTalkState", "d" );
- const idEventDef AI_EnemyRange( "enemyRange", NULL, 'f' );
- const idEventDef AI_EnemyRange2D( "enemyRange2D", NULL, 'f' );
- const idEventDef AI_GetEnemy( "getEnemy", NULL, 'e' );
- const idEventDef AI_GetEnemyPos( "getEnemyPos", NULL, 'v' );
- const idEventDef AI_GetEnemyEyePos( "getEnemyEyePos", NULL, 'v' );
- const idEventDef AI_PredictEnemyPos( "predictEnemyPos", "f", 'v' );
- const idEventDef AI_CanHitEnemy( "canHitEnemy", NULL, 'd' );
- const idEventDef AI_CanHitEnemyFromAnim( "canHitEnemyFromAnim", "s", 'd' );
- const idEventDef AI_CanHitEnemyFromJoint( "canHitEnemyFromJoint", "s", 'd' );
- const idEventDef AI_EnemyPositionValid( "enemyPositionValid", NULL, 'd' );
- const idEventDef AI_ChargeAttack( "chargeAttack", "s" );
- const idEventDef AI_TestChargeAttack( "testChargeAttack", NULL, 'f' );
- const idEventDef AI_TestMoveToPosition( "testMoveToPosition", "v", 'd' );
- const idEventDef AI_TestAnimMoveTowardEnemy( "testAnimMoveTowardEnemy", "s", 'd' );
- const idEventDef AI_TestAnimMove( "testAnimMove", "s", 'd' );
- const idEventDef AI_TestMeleeAttack( "testMeleeAttack", NULL, 'd' );
- const idEventDef AI_TestAnimAttack( "testAnimAttack", "s", 'd' );
- const idEventDef AI_Shrivel( "shrivel", "f" );
- const idEventDef AI_Burn( "burn" );
- const idEventDef AI_ClearBurn( "clearBurn" );
- const idEventDef AI_PreBurn( "preBurn" );
- const idEventDef AI_SetSmokeVisibility( "setSmokeVisibility", "dd" );
- const idEventDef AI_NumSmokeEmitters( "numSmokeEmitters", NULL, 'd' );
- const idEventDef AI_WaitAction( "waitAction", "s" );
- const idEventDef AI_StopThinking( "stopThinking" );
- const idEventDef AI_GetTurnDelta( "getTurnDelta", NULL, 'f' );
- const idEventDef AI_GetMoveType( "getMoveType", NULL, 'd' );
- const idEventDef AI_SetMoveType( "setMoveType", "d" );
- const idEventDef AI_SaveMove( "saveMove" );
- const idEventDef AI_RestoreMove( "restoreMove" );
- const idEventDef AI_AllowMovement( "allowMovement", "f" );
- const idEventDef AI_JumpFrame( "<jumpframe>" );
- const idEventDef AI_EnableClip( "enableClip" );
- const idEventDef AI_DisableClip( "disableClip" );
- const idEventDef AI_EnableGravity( "enableGravity" );
- const idEventDef AI_DisableGravity( "disableGravity" );
- const idEventDef AI_EnableAFPush( "enableAFPush" );
- const idEventDef AI_DisableAFPush( "disableAFPush" );
- const idEventDef AI_SetFlySpeed( "setFlySpeed", "f" );
- const idEventDef AI_SetFlyOffset( "setFlyOffset", "d" );
- const idEventDef AI_ClearFlyOffset( "clearFlyOffset" );
- const idEventDef AI_GetClosestHiddenTarget( "getClosestHiddenTarget", "s", 'e' );
- const idEventDef AI_GetRandomTarget( "getRandomTarget", "s", 'e' );
- const idEventDef AI_TravelDistanceToPoint( "travelDistanceToPoint", "v", 'f' );
- const idEventDef AI_TravelDistanceToEntity( "travelDistanceToEntity", "e", 'f' );
- const idEventDef AI_TravelDistanceBetweenPoints( "travelDistanceBetweenPoints", "vv", 'f' );
- const idEventDef AI_TravelDistanceBetweenEntities( "travelDistanceBetweenEntities", "ee", 'f' );
- const idEventDef AI_LookAtEntity( "lookAt", "Ef" );
- const idEventDef AI_LookAtEnemy( "lookAtEnemy", "f" );
- const idEventDef AI_SetJointMod( "setBoneMod", "d" );
- const idEventDef AI_ThrowMoveable( "throwMoveable" );
- const idEventDef AI_ThrowAF( "throwAF" );
- const idEventDef AI_RealKill( "<kill>" );
- const idEventDef AI_Kill( "kill" );
- const idEventDef AI_WakeOnFlashlight( "wakeOnFlashlight", "d" );
- const idEventDef AI_LocateEnemy( "locateEnemy" );
- const idEventDef AI_KickObstacles( "kickObstacles", "Ef" );
- const idEventDef AI_GetObstacle( "getObstacle", NULL, 'e' );
- const idEventDef AI_PushPointIntoAAS( "pushPointIntoAAS", "v", 'v' );
- const idEventDef AI_GetTurnRate( "getTurnRate", NULL, 'f' );
- const idEventDef AI_SetTurnRate( "setTurnRate", "f" );
- const idEventDef AI_AnimTurn( "animTurn", "f" );
- const idEventDef AI_AllowHiddenMovement( "allowHiddenMovement", "d" );
- const idEventDef AI_TriggerParticles( "triggerParticles", "s" );
- const idEventDef AI_FindActorsInBounds( "findActorsInBounds", "vv", 'e' );
- const idEventDef AI_CanReachPosition( "canReachPosition", "v", 'd' );
- const idEventDef AI_CanReachEntity( "canReachEntity", "E", 'd' );
- const idEventDef AI_CanReachEnemy( "canReachEnemy", NULL, 'd' );
- const idEventDef AI_GetReachableEntityPosition( "getReachableEntityPosition", "e", 'v' );
- #ifdef _D3XP
- const idEventDef AI_MoveToPositionDirect( "moveToPositionDirect", "v" );
- const idEventDef AI_AvoidObstacles( "avoidObstacles", "d" );
- const idEventDef AI_TriggerFX( "triggerFX", "ss" );
- const idEventDef AI_StartEmitter( "startEmitter", "sss", 'e' );
- const idEventDef AI_GetEmitter( "getEmitter", "s", 'e' );
- const idEventDef AI_StopEmitter( "stopEmitter", "s" );
- #endif
- CLASS_DECLARATION( idActor, idAI )
- EVENT( EV_Activate, idAI::Event_Activate )
- EVENT( EV_Touch, idAI::Event_Touch )
- EVENT( AI_FindEnemy, idAI::Event_FindEnemy )
- EVENT( AI_FindEnemyAI, idAI::Event_FindEnemyAI )
- EVENT( AI_FindEnemyInCombatNodes, idAI::Event_FindEnemyInCombatNodes )
- EVENT( AI_ClosestReachableEnemyOfEntity, idAI::Event_ClosestReachableEnemyOfEntity )
- EVENT( AI_HeardSound, idAI::Event_HeardSound )
- EVENT( AI_SetEnemy, idAI::Event_SetEnemy )
- EVENT( AI_ClearEnemy, idAI::Event_ClearEnemy )
- EVENT( AI_MuzzleFlash, idAI::Event_MuzzleFlash )
- EVENT( AI_CreateMissile, idAI::Event_CreateMissile )
- EVENT( AI_AttackMissile, idAI::Event_AttackMissile )
- EVENT( AI_FireMissileAtTarget, idAI::Event_FireMissileAtTarget )
- EVENT( AI_LaunchMissile, idAI::Event_LaunchMissile )
- #ifdef _D3XP
- EVENT( AI_LaunchProjectile, idAI::Event_LaunchProjectile )
- #endif
- EVENT( AI_AttackMelee, idAI::Event_AttackMelee )
- EVENT( AI_DirectDamage, idAI::Event_DirectDamage )
- EVENT( AI_RadiusDamageFromJoint, idAI::Event_RadiusDamageFromJoint )
- EVENT( AI_BeginAttack, idAI::Event_BeginAttack )
- EVENT( AI_EndAttack, idAI::Event_EndAttack )
- EVENT( AI_MeleeAttackToJoint, idAI::Event_MeleeAttackToJoint )
- EVENT( AI_RandomPath, idAI::Event_RandomPath )
- EVENT( AI_CanBecomeSolid, idAI::Event_CanBecomeSolid )
- EVENT( AI_BecomeSolid, idAI::Event_BecomeSolid )
- EVENT( EV_BecomeNonSolid, idAI::Event_BecomeNonSolid )
- EVENT( AI_BecomeRagdoll, idAI::Event_BecomeRagdoll )
- EVENT( AI_StopRagdoll, idAI::Event_StopRagdoll )
- EVENT( AI_SetHealth, idAI::Event_SetHealth )
- EVENT( AI_GetHealth, idAI::Event_GetHealth )
- EVENT( AI_AllowDamage, idAI::Event_AllowDamage )
- EVENT( AI_IgnoreDamage, idAI::Event_IgnoreDamage )
- EVENT( AI_GetCurrentYaw, idAI::Event_GetCurrentYaw )
- EVENT( AI_TurnTo, idAI::Event_TurnTo )
- EVENT( AI_TurnToPos, idAI::Event_TurnToPos )
- EVENT( AI_TurnToEntity, idAI::Event_TurnToEntity )
- EVENT( AI_MoveStatus, idAI::Event_MoveStatus )
- EVENT( AI_StopMove, idAI::Event_StopMove )
- EVENT( AI_MoveToCover, idAI::Event_MoveToCover )
- EVENT( AI_MoveToEnemy, idAI::Event_MoveToEnemy )
- EVENT( AI_MoveToEnemyHeight, idAI::Event_MoveToEnemyHeight )
- EVENT( AI_MoveOutOfRange, idAI::Event_MoveOutOfRange )
- EVENT( AI_MoveToAttackPosition, idAI::Event_MoveToAttackPosition )
- EVENT( AI_Wander, idAI::Event_Wander )
- EVENT( AI_MoveToEntity, idAI::Event_MoveToEntity )
- EVENT( AI_MoveToPosition, idAI::Event_MoveToPosition )
- EVENT( AI_SlideTo, idAI::Event_SlideTo )
- EVENT( AI_FacingIdeal, idAI::Event_FacingIdeal )
- EVENT( AI_FaceEnemy, idAI::Event_FaceEnemy )
- EVENT( AI_FaceEntity, idAI::Event_FaceEntity )
- EVENT( AI_WaitAction, idAI::Event_WaitAction )
- EVENT( AI_GetCombatNode, idAI::Event_GetCombatNode )
- EVENT( AI_EnemyInCombatCone, idAI::Event_EnemyInCombatCone )
- EVENT( AI_WaitMove, idAI::Event_WaitMove )
- EVENT( AI_GetJumpVelocity, idAI::Event_GetJumpVelocity )
- EVENT( AI_EntityInAttackCone, idAI::Event_EntityInAttackCone )
- EVENT( AI_CanSeeEntity, idAI::Event_CanSeeEntity )
- EVENT( AI_SetTalkTarget, idAI::Event_SetTalkTarget )
- EVENT( AI_GetTalkTarget, idAI::Event_GetTalkTarget )
- EVENT( AI_SetTalkState, idAI::Event_SetTalkState )
- EVENT( AI_EnemyRange, idAI::Event_EnemyRange )
- EVENT( AI_EnemyRange2D, idAI::Event_EnemyRange2D )
- EVENT( AI_GetEnemy, idAI::Event_GetEnemy )
- EVENT( AI_GetEnemyPos, idAI::Event_GetEnemyPos )
- EVENT( AI_GetEnemyEyePos, idAI::Event_GetEnemyEyePos )
- EVENT( AI_PredictEnemyPos, idAI::Event_PredictEnemyPos )
- EVENT( AI_CanHitEnemy, idAI::Event_CanHitEnemy )
- EVENT( AI_CanHitEnemyFromAnim, idAI::Event_CanHitEnemyFromAnim )
- EVENT( AI_CanHitEnemyFromJoint, idAI::Event_CanHitEnemyFromJoint )
- EVENT( AI_EnemyPositionValid, idAI::Event_EnemyPositionValid )
- EVENT( AI_ChargeAttack, idAI::Event_ChargeAttack )
- EVENT( AI_TestChargeAttack, idAI::Event_TestChargeAttack )
- EVENT( AI_TestAnimMoveTowardEnemy, idAI::Event_TestAnimMoveTowardEnemy )
- EVENT( AI_TestAnimMove, idAI::Event_TestAnimMove )
- EVENT( AI_TestMoveToPosition, idAI::Event_TestMoveToPosition )
- EVENT( AI_TestMeleeAttack, idAI::Event_TestMeleeAttack )
- EVENT( AI_TestAnimAttack, idAI::Event_TestAnimAttack )
- EVENT( AI_Shrivel, idAI::Event_Shrivel )
- EVENT( AI_Burn, idAI::Event_Burn )
- EVENT( AI_PreBurn, idAI::Event_PreBurn )
- EVENT( AI_SetSmokeVisibility, idAI::Event_SetSmokeVisibility )
- EVENT( AI_NumSmokeEmitters, idAI::Event_NumSmokeEmitters )
- EVENT( AI_ClearBurn, idAI::Event_ClearBurn )
- EVENT( AI_StopThinking, idAI::Event_StopThinking )
- EVENT( AI_GetTurnDelta, idAI::Event_GetTurnDelta )
- EVENT( AI_GetMoveType, idAI::Event_GetMoveType )
- EVENT( AI_SetMoveType, idAI::Event_SetMoveType )
- EVENT( AI_SaveMove, idAI::Event_SaveMove )
- EVENT( AI_RestoreMove, idAI::Event_RestoreMove )
- EVENT( AI_AllowMovement, idAI::Event_AllowMovement )
- EVENT( AI_JumpFrame, idAI::Event_JumpFrame )
- EVENT( AI_EnableClip, idAI::Event_EnableClip )
- EVENT( AI_DisableClip, idAI::Event_DisableClip )
- EVENT( AI_EnableGravity, idAI::Event_EnableGravity )
- EVENT( AI_DisableGravity, idAI::Event_DisableGravity )
- EVENT( AI_EnableAFPush, idAI::Event_EnableAFPush )
- EVENT( AI_DisableAFPush, idAI::Event_DisableAFPush )
- EVENT( AI_SetFlySpeed, idAI::Event_SetFlySpeed )
- EVENT( AI_SetFlyOffset, idAI::Event_SetFlyOffset )
- EVENT( AI_ClearFlyOffset, idAI::Event_ClearFlyOffset )
- EVENT( AI_GetClosestHiddenTarget, idAI::Event_GetClosestHiddenTarget )
- EVENT( AI_GetRandomTarget, idAI::Event_GetRandomTarget )
- EVENT( AI_TravelDistanceToPoint, idAI::Event_TravelDistanceToPoint )
- EVENT( AI_TravelDistanceToEntity, idAI::Event_TravelDistanceToEntity )
- EVENT( AI_TravelDistanceBetweenPoints, idAI::Event_TravelDistanceBetweenPoints )
- EVENT( AI_TravelDistanceBetweenEntities, idAI::Event_TravelDistanceBetweenEntities )
- EVENT( AI_LookAtEntity, idAI::Event_LookAtEntity )
- EVENT( AI_LookAtEnemy, idAI::Event_LookAtEnemy )
- EVENT( AI_SetJointMod, idAI::Event_SetJointMod )
- EVENT( AI_ThrowMoveable, idAI::Event_ThrowMoveable )
- EVENT( AI_ThrowAF, idAI::Event_ThrowAF )
- EVENT( EV_GetAngles, idAI::Event_GetAngles )
- EVENT( EV_SetAngles, idAI::Event_SetAngles )
- EVENT( AI_RealKill, idAI::Event_RealKill )
- EVENT( AI_Kill, idAI::Event_Kill )
- EVENT( AI_WakeOnFlashlight, idAI::Event_WakeOnFlashlight )
- EVENT( AI_LocateEnemy, idAI::Event_LocateEnemy )
- EVENT( AI_KickObstacles, idAI::Event_KickObstacles )
- EVENT( AI_GetObstacle, idAI::Event_GetObstacle )
- EVENT( AI_PushPointIntoAAS, idAI::Event_PushPointIntoAAS )
- EVENT( AI_GetTurnRate, idAI::Event_GetTurnRate )
- EVENT( AI_SetTurnRate, idAI::Event_SetTurnRate )
- EVENT( AI_AnimTurn, idAI::Event_AnimTurn )
- EVENT( AI_AllowHiddenMovement, idAI::Event_AllowHiddenMovement )
- EVENT( AI_TriggerParticles, idAI::Event_TriggerParticles )
- EVENT( AI_FindActorsInBounds, idAI::Event_FindActorsInBounds )
- EVENT( AI_CanReachPosition, idAI::Event_CanReachPosition )
- EVENT( AI_CanReachEntity, idAI::Event_CanReachEntity )
- EVENT( AI_CanReachEnemy, idAI::Event_CanReachEnemy )
- EVENT( AI_GetReachableEntityPosition, idAI::Event_GetReachableEntityPosition )
- #ifdef _D3XP
- EVENT( AI_MoveToPositionDirect, idAI::Event_MoveToPositionDirect )
- EVENT( AI_AvoidObstacles, idAI::Event_AvoidObstacles )
- EVENT( AI_TriggerFX, idAI::Event_TriggerFX )
- EVENT( AI_StartEmitter, idAI::Event_StartEmitter )
- EVENT( AI_GetEmitter, idAI::Event_GetEmitter )
- EVENT( AI_StopEmitter, idAI::Event_StopEmitter )
- #endif
- END_CLASS
- /*
- =====================
- idAI::Event_Activate
- =====================
- */
- void idAI::Event_Activate( idEntity *activator ) {
- Activate( activator );
- }
- /*
- =====================
- idAI::Event_Touch
- =====================
- */
- void idAI::Event_Touch( idEntity *other, trace_t *trace ) {
- if ( !enemy.GetEntity() && !other->fl.notarget && ( ReactionTo( other ) & ATTACK_ON_ACTIVATE ) ) {
- Activate( other );
- }
- AI_PUSHED = true;
- }
- /*
- =====================
- idAI::Event_FindEnemy
- =====================
- */
- void idAI::Event_FindEnemy( int useFOV ) {
- int i;
- idEntity *ent;
- idActor *actor;
- if ( gameLocal.InPlayerPVS( this ) ) {
- for ( i = 0; i < gameLocal.numClients ; i++ ) {
- ent = gameLocal.entities[ i ];
- if ( !ent || !ent->IsType( idActor::Type ) ) {
- continue;
- }
- actor = static_cast<idActor *>( ent );
- if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) {
- continue;
- }
- if ( CanSee( actor, useFOV != 0 ) ) {
- idThread::ReturnEntity( actor );
- return;
- }
- }
- }
- idThread::ReturnEntity( NULL );
- }
- /*
- =====================
- idAI::Event_FindEnemyAI
- =====================
- */
- void idAI::Event_FindEnemyAI( int useFOV ) {
- idEntity *ent;
- idActor *actor;
- idActor *bestEnemy;
- float bestDist;
- float dist;
- idVec3 delta;
- pvsHandle_t pvs;
- pvs = gameLocal.pvs.SetupCurrentPVS( GetPVSAreas(), GetNumPVSAreas() );
- bestDist = idMath::INFINITY;
- bestEnemy = NULL;
- for ( ent = gameLocal.activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) {
- if ( ent->fl.hidden || ent->fl.isDormant || !ent->IsType( idActor::Type ) ) {
- continue;
- }
- actor = static_cast<idActor *>( ent );
- if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) {
- continue;
- }
- if ( !gameLocal.pvs.InCurrentPVS( pvs, actor->GetPVSAreas(), actor->GetNumPVSAreas() ) ) {
- continue;
- }
- delta = physicsObj.GetOrigin() - actor->GetPhysics()->GetOrigin();
- dist = delta.LengthSqr();
- if ( ( dist < bestDist ) && CanSee( actor, useFOV != 0 ) ) {
- bestDist = dist;
- bestEnemy = actor;
- }
- }
- gameLocal.pvs.FreeCurrentPVS( pvs );
- idThread::ReturnEntity( bestEnemy );
- }
- /*
- =====================
- idAI::Event_FindEnemyInCombatNodes
- =====================
- */
- void idAI::Event_FindEnemyInCombatNodes( void ) {
- int i, j;
- idCombatNode *node;
- idEntity *ent;
- idEntity *targetEnt;
- idActor *actor;
- if ( !gameLocal.InPlayerPVS( this ) ) {
- // don't locate the player when we're not in his PVS
- idThread::ReturnEntity( NULL );
- return;
- }
- for ( i = 0; i < gameLocal.numClients ; i++ ) {
- ent = gameLocal.entities[ i ];
- if ( !ent || !ent->IsType( idActor::Type ) ) {
- continue;
- }
- actor = static_cast<idActor *>( ent );
- if ( ( actor->health <= 0 ) || !( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) {
- continue;
- }
- for( j = 0; j < targets.Num(); j++ ) {
- targetEnt = targets[ j ].GetEntity();
- if ( !targetEnt || !targetEnt->IsType( idCombatNode::Type ) ) {
- continue;
- }
- node = static_cast<idCombatNode *>( targetEnt );
- if ( !node->IsDisabled() && node->EntityInView( actor, actor->GetPhysics()->GetOrigin() ) ) {
- idThread::ReturnEntity( actor );
- return;
- }
- }
- }
- idThread::ReturnEntity( NULL );
- }
- /*
- =====================
- idAI::Event_ClosestReachableEnemyOfEntity
- =====================
- */
- void idAI::Event_ClosestReachableEnemyOfEntity( idEntity *team_mate ) {
- idActor *actor;
- idActor *ent;
- idActor *bestEnt;
- float bestDistSquared;
- float distSquared;
- idVec3 delta;
- int areaNum;
- int enemyAreaNum;
- aasPath_t path;
-
- if ( !team_mate->IsType( idActor::Type ) ) {
- gameLocal.Error( "Entity '%s' is not an AI character or player", team_mate->GetName() );
- }
- actor = static_cast<idActor *>( team_mate );
- const idVec3 &origin = physicsObj.GetOrigin();
- areaNum = PointReachableAreaNum( origin );
- bestDistSquared = idMath::INFINITY;
- bestEnt = NULL;
- for( ent = actor->enemyList.Next(); ent != NULL; ent = ent->enemyNode.Next() ) {
- if ( ent->fl.hidden ) {
- continue;
- }
- delta = ent->GetPhysics()->GetOrigin() - origin;
- distSquared = delta.LengthSqr();
- if ( distSquared < bestDistSquared ) {
- const idVec3 &enemyPos = ent->GetPhysics()->GetOrigin();
- enemyAreaNum = PointReachableAreaNum( enemyPos );
- if ( ( areaNum != 0 ) && PathToGoal( path, areaNum, origin, enemyAreaNum, enemyPos ) ) {
- bestEnt = ent;
- bestDistSquared = distSquared;
- }
- }
- }
- idThread::ReturnEntity( bestEnt );
- }
- /*
- =====================
- idAI::Event_HeardSound
- =====================
- */
- void idAI::Event_HeardSound( int ignore_team ) {
- // check if we heard any sounds in the last frame
- idActor *actor = gameLocal.GetAlertEntity();
- if ( actor && ( !ignore_team || ( ReactionTo( actor ) & ATTACK_ON_SIGHT ) ) && gameLocal.InPlayerPVS( this ) ) {
- idVec3 pos = actor->GetPhysics()->GetOrigin();
- idVec3 org = physicsObj.GetOrigin();
- float dist = ( pos - org ).LengthSqr();
- if ( dist < Square( AI_HEARING_RANGE ) ) {
- idThread::ReturnEntity( actor );
- return;
- }
- }
- idThread::ReturnEntity( NULL );
- }
- /*
- =====================
- idAI::Event_SetEnemy
- =====================
- */
- void idAI::Event_SetEnemy( idEntity *ent ) {
- if ( !ent ) {
- ClearEnemy();
- } else if ( !ent->IsType( idActor::Type ) ) {
- gameLocal.Error( "'%s' is not an idActor (player or ai controlled character)", ent->name.c_str() );
- } else {
- SetEnemy( static_cast<idActor *>( ent ) );
- }
- }
- /*
- =====================
- idAI::Event_ClearEnemy
- =====================
- */
- void idAI::Event_ClearEnemy( void ) {
- ClearEnemy();
- }
- /*
- =====================
- idAI::Event_MuzzleFlash
- =====================
- */
- void idAI::Event_MuzzleFlash( const char *jointname ) {
- idVec3 muzzle;
- idMat3 axis;
- GetMuzzle( jointname, muzzle, axis );
- TriggerWeaponEffects( muzzle );
- }
- /*
- =====================
- idAI::Event_CreateMissile
- =====================
- */
- void idAI::Event_CreateMissile( const char *jointname ) {
- idVec3 muzzle;
- idMat3 axis;
- if ( !projectileDef ) {
- gameLocal.Warning( "%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName() );
- return idThread::ReturnEntity( NULL );
- }
- GetMuzzle( jointname, muzzle, axis );
- CreateProjectile( muzzle, viewAxis[ 0 ] * physicsObj.GetGravityAxis() );
- if ( projectile.GetEntity() ) {
- if ( !jointname || !jointname[ 0 ] ) {
- projectile.GetEntity()->Bind( this, true );
- } else {
- projectile.GetEntity()->BindToJoint( this, jointname, true );
- }
- }
- idThread::ReturnEntity( projectile.GetEntity() );
- }
- /*
- =====================
- idAI::Event_AttackMissile
- =====================
- */
- void idAI::Event_AttackMissile( const char *jointname ) {
- idProjectile *proj;
- proj = LaunchProjectile( jointname, enemy.GetEntity(), true );
- idThread::ReturnEntity( proj );
- }
- /*
- =====================
- idAI::Event_FireMissileAtTarget
- =====================
- */
- void idAI::Event_FireMissileAtTarget( const char *jointname, const char *targetname ) {
- idEntity *aent;
- idProjectile *proj;
- aent = gameLocal.FindEntity( targetname );
- if ( !aent ) {
- gameLocal.Warning( "Entity '%s' not found for 'fireMissileAtTarget'", targetname );
- }
- proj = LaunchProjectile( jointname, aent, false );
- idThread::ReturnEntity( proj );
- }
- /*
- =====================
- idAI::Event_LaunchMissile
- =====================
- */
- void idAI::Event_LaunchMissile( const idVec3 &org, const idAngles &ang ) {
- idVec3 start;
- trace_t tr;
- idBounds projBounds;
- const idClipModel *projClip;
- idMat3 axis;
- float distance;
- if ( !projectileDef ) {
- gameLocal.Warning( "%s (%s) doesn't have a projectile specified", name.c_str(), GetEntityDefName() );
- idThread::ReturnEntity( NULL );
- return;
- }
- axis = ang.ToMat3();
- if ( !projectile.GetEntity() ) {
- CreateProjectile( org, axis[ 0 ] );
- }
- // make sure the projectile starts inside the monster bounding box
- const idBounds &ownerBounds = physicsObj.GetAbsBounds();
- projClip = projectile.GetEntity()->GetPhysics()->GetClipModel();
- projBounds = projClip->GetBounds().Rotate( projClip->GetAxis() );
- // check if the owner bounds is bigger than the projectile bounds
- if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) &&
- ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) &&
- ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) {
- if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) {
- start = org + distance * viewAxis[ 0 ];
- } else {
- start = ownerBounds.GetCenter();
- }
- } else {
- // projectile bounds bigger than the owner bounds, so just start it from the center
- start = ownerBounds.GetCenter();
- }
- gameLocal.clip.Translation( tr, start, org, projClip, projClip->GetAxis(), MASK_SHOT_RENDERMODEL, this );
- // launch the projectile
- idThread::ReturnEntity( projectile.GetEntity() );
- projectile.GetEntity()->Launch( tr.endpos, axis[ 0 ], vec3_origin );
- projectile = NULL;
- TriggerWeaponEffects( tr.endpos );
- lastAttackTime = gameLocal.time;
- }
- #ifdef _D3XP
- /*
- =====================
- idAI::Event_LaunchProjectile
- =====================
- */
- void idAI::Event_LaunchProjectile( const char *entityDefName ) {
- idVec3 muzzle, start, dir;
- const idDict *projDef;
- idMat3 axis;
- const idClipModel *projClip;
- idBounds projBounds;
- trace_t tr;
- idEntity *ent;
- const char *clsname;
- float distance;
- idProjectile *proj = NULL;
- projDef = gameLocal.FindEntityDefDict( entityDefName );
- gameLocal.SpawnEntityDef( *projDef, &ent, false );
- if ( !ent ) {
- clsname = projectileDef->GetString( "classname" );
- gameLocal.Error( "Could not spawn entityDef '%s'", clsname );
- }
- if ( !ent->IsType( idProjectile::Type ) ) {
- clsname = ent->GetClassname();
- gameLocal.Error( "'%s' is not an idProjectile", clsname );
- }
- proj = ( idProjectile * )ent;
- GetMuzzle( "pistol", muzzle, axis );
- proj->Create( this, muzzle, axis[0] );
- // make sure the projectile starts inside the monster bounding box
- const idBounds &ownerBounds = physicsObj.GetAbsBounds();
- projClip = proj->GetPhysics()->GetClipModel();
- projBounds = projClip->GetBounds().Rotate( projClip->GetAxis() );
- if ( (ownerBounds - projBounds).RayIntersection( muzzle, viewAxis[ 0 ], distance ) ) {
- start = muzzle + distance * viewAxis[ 0 ];
- } else {
- start = ownerBounds.GetCenter();
- }
- gameLocal.clip.Translation( tr, start, muzzle, projClip, projClip->GetAxis(), MASK_SHOT_RENDERMODEL, this );
- muzzle = tr.endpos;
- GetAimDir( muzzle, enemy.GetEntity(), this, dir );
- proj->Launch( muzzle, dir, vec3_origin );
- TriggerWeaponEffects( muzzle );
- }
- #endif
- /*
- =====================
- idAI::Event_AttackMelee
- =====================
- */
- void idAI::Event_AttackMelee( const char *meleeDefName ) {
- bool hit;
-
- hit = AttackMelee( meleeDefName );
- idThread::ReturnInt( hit );
- }
- /*
- =====================
- idAI::Event_DirectDamage
- =====================
- */
- void idAI::Event_DirectDamage( idEntity *damageTarget, const char *damageDefName ) {
- DirectDamage( damageDefName, damageTarget );
- }
- /*
- =====================
- idAI::Event_RadiusDamageFromJoint
- =====================
- */
- void idAI::Event_RadiusDamageFromJoint( const char *jointname, const char *damageDefName ) {
- jointHandle_t joint;
- idVec3 org;
- idMat3 axis;
- if ( !jointname || !jointname[ 0 ] ) {
- org = physicsObj.GetOrigin();
- } else {
- joint = animator.GetJointHandle( jointname );
- if ( joint == INVALID_JOINT ) {
- gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() );
- }
- GetJointWorldTransform( joint, gameLocal.time, org, axis );
- }
- gameLocal.RadiusDamage( org, this, this, this, this, damageDefName );
- }
- /*
- =====================
- idAI::Event_RandomPath
- =====================
- */
- void idAI::Event_RandomPath( void ) {
- idPathCorner *path;
- path = idPathCorner::RandomPath( this, NULL );
- idThread::ReturnEntity( path );
- }
- /*
- =====================
- idAI::Event_BeginAttack
- =====================
- */
- void idAI::Event_BeginAttack( const char *name ) {
- BeginAttack( name );
- }
- /*
- =====================
- idAI::Event_EndAttack
- =====================
- */
- void idAI::Event_EndAttack( void ) {
- EndAttack();
- }
- /*
- =====================
- idAI::Event_MeleeAttackToJoint
- =====================
- */
- void idAI::Event_MeleeAttackToJoint( const char *jointname, const char *meleeDefName ) {
- jointHandle_t joint;
- idVec3 start;
- idVec3 end;
- idMat3 axis;
- trace_t trace;
- idEntity *hitEnt;
- joint = animator.GetJointHandle( jointname );
- if ( joint == INVALID_JOINT ) {
- gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() );
- }
- animator.GetJointTransform( joint, gameLocal.time, end, axis );
- end = physicsObj.GetOrigin() + ( end + modelOffset ) * viewAxis * physicsObj.GetGravityAxis();
- start = GetEyePosition();
-
- if ( ai_debugMove.GetBool() ) {
- gameRenderWorld->DebugLine( colorYellow, start, end, gameLocal.msec );
- }
- gameLocal.clip.TranslationEntities( trace, start, end, NULL, mat3_identity, MASK_SHOT_BOUNDINGBOX, this );
- if ( trace.fraction < 1.0f ) {
- hitEnt = gameLocal.GetTraceEntity( trace );
- if ( hitEnt && hitEnt->IsType( idActor::Type ) ) {
- DirectDamage( meleeDefName, hitEnt );
- idThread::ReturnInt( true );
- return;
- }
- }
- idThread::ReturnInt( false );
- }
- /*
- =====================
- idAI::Event_CanBecomeSolid
- =====================
- */
- void idAI::Event_CanBecomeSolid( void ) {
- int i;
- int num;
- #ifdef _D3XP
- bool returnValue = true;
- #endif
- idEntity * hit;
- idClipModel *cm;
- idClipModel *clipModels[ MAX_GENTITIES ];
- num = gameLocal.clip.ClipModelsTouchingBounds( physicsObj.GetAbsBounds(), MASK_MONSTERSOLID, clipModels, MAX_GENTITIES );
- for ( i = 0; i < num; i++ ) {
- cm = clipModels[ i ];
- // don't check render entities
- if ( cm->IsRenderModel() ) {
- continue;
- }
- hit = cm->GetEntity();
- if ( ( hit == this ) || !hit->fl.takedamage ) {
- continue;
- }
- #ifdef _D3XP
- if ( spawnClearMoveables && hit->IsType( idMoveable::Type ) || hit->IsType( idBarrel::Type ) || hit->IsType( idExplodingBarrel::Type ) ) {
- idVec3 push;
- push = hit->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin();
- push.z = 30.f;
- push.NormalizeFast();
- if ( (idMath::Fabs(push.x) < 0.15f) && (idMath::Fabs(push.y) < 0.15f) ) {
- push.x = 10.f; push.y = 10.f; push.z = 15.f;
- push.NormalizeFast();
- }
- push *= 300.f;
- hit->GetPhysics()->SetLinearVelocity( push );
- }
- #endif
- if ( physicsObj.ClipContents( cm ) ) {
- #ifdef _D3XP
- returnValue = false;
- #else
- idThread::ReturnFloat( false );
- return;
- #endif
- }
- }
- #ifdef _D3XP
- idThread::ReturnFloat( returnValue );
- #else
- idThread::ReturnFloat( true );
- #endif
- }
- /*
- =====================
- idAI::Event_BecomeSolid
- =====================
- */
- void idAI::Event_BecomeSolid( void ) {
- physicsObj.EnableClip();
- if ( spawnArgs.GetBool( "big_monster" ) ) {
- physicsObj.SetContents( 0 );
- } else if ( use_combat_bbox ) {
- physicsObj.SetContents( CONTENTS_BODY|CONTENTS_SOLID );
- } else {
- physicsObj.SetContents( CONTENTS_BODY );
- }
- physicsObj.GetClipModel()->Link( gameLocal.clip );
- fl.takedamage = !spawnArgs.GetBool( "noDamage" );
- }
- /*
- =====================
- idAI::Event_BecomeNonSolid
- =====================
- */
- void idAI::Event_BecomeNonSolid( void ) {
- fl.takedamage = false;
- physicsObj.SetContents( 0 );
- physicsObj.GetClipModel()->Unlink();
- }
- /*
- =====================
- idAI::Event_BecomeRagdoll
- =====================
- */
- void idAI::Event_BecomeRagdoll( void ) {
- bool result;
- result = StartRagdoll();
- idThread::ReturnInt( result );
- }
- /*
- =====================
- idAI::Event_StopRagdoll
- =====================
- */
- void idAI::Event_StopRagdoll( void ) {
- StopRagdoll();
- // set back the monster physics
- SetPhysics( &physicsObj );
- }
- /*
- =====================
- idAI::Event_SetHealth
- =====================
- */
- void idAI::Event_SetHealth( float newHealth ) {
- health = newHealth;
- fl.takedamage = true;
- if ( health > 0 ) {
- AI_DEAD = false;
- } else {
- AI_DEAD = true;
- }
- }
- /*
- =====================
- idAI::Event_GetHealth
- =====================
- */
- void idAI::Event_GetHealth( void ) {
- idThread::ReturnFloat( health );
- }
- /*
- =====================
- idAI::Event_AllowDamage
- =====================
- */
- void idAI::Event_AllowDamage( void ) {
- fl.takedamage = true;
- }
- /*
- =====================
- idAI::Event_IgnoreDamage
- =====================
- */
- void idAI::Event_IgnoreDamage( void ) {
- fl.takedamage = false;
- }
- /*
- =====================
- idAI::Event_GetCurrentYaw
- =====================
- */
- void idAI::Event_GetCurrentYaw( void ) {
- idThread::ReturnFloat( current_yaw );
- }
- /*
- =====================
- idAI::Event_TurnTo
- =====================
- */
- void idAI::Event_TurnTo( float angle ) {
- TurnToward( angle );
- }
- /*
- =====================
- idAI::Event_TurnToPos
- =====================
- */
- void idAI::Event_TurnToPos( const idVec3 &pos ) {
- TurnToward( pos );
- }
- /*
- =====================
- idAI::Event_TurnToEntity
- =====================
- */
- void idAI::Event_TurnToEntity( idEntity *ent ) {
- if ( ent ) {
- TurnToward( ent->GetPhysics()->GetOrigin() );
- }
- }
- /*
- =====================
- idAI::Event_MoveStatus
- =====================
- */
- void idAI::Event_MoveStatus( void ) {
- idThread::ReturnInt( move.moveStatus );
- }
- /*
- =====================
- idAI::Event_StopMove
- =====================
- */
- void idAI::Event_StopMove( void ) {
- StopMove( MOVE_STATUS_DONE );
- }
- /*
- =====================
- idAI::Event_MoveToCover
- =====================
- */
- void idAI::Event_MoveToCover( void ) {
- idActor *enemyEnt = enemy.GetEntity();
- StopMove( MOVE_STATUS_DEST_NOT_FOUND );
- if ( !enemyEnt || !MoveToCover( enemyEnt, lastVisibleEnemyPos ) ) {
- return;
- }
- }
- /*
- =====================
- idAI::Event_MoveToEnemy
- =====================
- */
- void idAI::Event_MoveToEnemy( void ) {
- StopMove( MOVE_STATUS_DEST_NOT_FOUND );
- if ( !enemy.GetEntity() || !MoveToEnemy() ) {
- return;
- }
- }
- /*
- =====================
- idAI::Event_MoveToEnemyHeight
- =====================
- */
- void idAI::Event_MoveToEnemyHeight( void ) {
- StopMove( MOVE_STATUS_DEST_NOT_FOUND );
- MoveToEnemyHeight();
- }
- /*
- =====================
- idAI::Event_MoveOutOfRange
- =====================
- */
- void idAI::Event_MoveOutOfRange( idEntity *entity, float range ) {
- StopMove( MOVE_STATUS_DEST_NOT_FOUND );
- MoveOutOfRange( entity, range );
- }
- /*
- =====================
- idAI::Event_MoveToAttackPosition
- =====================
- */
- void idAI::Event_MoveToAttackPosition( idEntity *entity, const char *attack_anim ) {
- int anim;
- StopMove( MOVE_STATUS_DEST_NOT_FOUND );
- anim = GetAnim( ANIMCHANNEL_LEGS, attack_anim );
- if ( !anim ) {
- gameLocal.Error( "Unknown anim '%s'", attack_anim );
- }
- MoveToAttackPosition( entity, anim );
- }
- /*
- =====================
- idAI::Event_MoveToEntity
- =====================
- */
- void idAI::Event_MoveToEntity( idEntity *ent ) {
- StopMove( MOVE_STATUS_DEST_NOT_FOUND );
- if ( ent ) {
- MoveToEntity( ent );
- }
- }
- /*
- =====================
- idAI::Event_MoveToPosition
- =====================
- */
- void idAI::Event_MoveToPosition( const idVec3 &pos ) {
- StopMove( MOVE_STATUS_DONE );
- MoveToPosition( pos );
- }
- /*
- =====================
- idAI::Event_SlideTo
- =====================
- */
- void idAI::Event_SlideTo( const idVec3 &pos, float time ) {
- SlideToPosition( pos, time );
- }
- /*
- =====================
- idAI::Event_Wander
- =====================
- */
- void idAI::Event_Wander( void ) {
- WanderAround();
- }
- /*
- =====================
- idAI::Event_FacingIdeal
- =====================
- */
- void idAI::Event_FacingIdeal( void ) {
- bool facing = FacingIdeal();
- idThread::ReturnInt( facing );
- }
- /*
- =====================
- idAI::Event_FaceEnemy
- =====================
- */
- void idAI::Event_FaceEnemy( void ) {
- FaceEnemy();
- }
- /*
- =====================
- idAI::Event_FaceEntity
- =====================
- */
- void idAI::Event_FaceEntity( idEntity *ent ) {
- FaceEntity( ent );
- }
- /*
- =====================
- idAI::Event_WaitAction
- =====================
- */
- void idAI::Event_WaitAction( const char *waitForState ) {
- if ( idThread::BeginMultiFrameEvent( this, &AI_WaitAction ) ) {
- SetWaitState( waitForState );
- }
- if ( !WaitState() ) {
- idThread::EndMultiFrameEvent( this, &AI_WaitAction );
- }
- }
- /*
- =====================
- idAI::Event_GetCombatNode
- =====================
- */
- void idAI::Event_GetCombatNode( void ) {
- int i;
- float dist;
- idEntity *targetEnt;
- idCombatNode *node;
- float bestDist;
- idCombatNode *bestNode;
- idActor *enemyEnt = enemy.GetEntity();
- if ( !targets.Num() ) {
- // no combat nodes
- idThread::ReturnEntity( NULL );
- return;
- }
- if ( !enemyEnt || !EnemyPositionValid() ) {
- // don't return a combat node if we don't have an enemy or
- // if we can see he's not in the last place we saw him
- #ifdef _D3XP
- if ( team == 0 ) {
- // find the closest attack node to the player
- bestNode = NULL;
- const idVec3 &myPos = physicsObj.GetOrigin();
- const idVec3 &playerPos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin();
- bestDist = ( myPos - playerPos ).LengthSqr();
- for( i = 0; i < targets.Num(); i++ ) {
- targetEnt = targets[ i ].GetEntity();
- if ( !targetEnt || !targetEnt->IsType( idCombatNode::Type ) ) {
- continue;
- }
- node = static_cast<idCombatNode *>( targetEnt );
- if ( !node->IsDisabled() ) {
- idVec3 org = node->GetPhysics()->GetOrigin();
- dist = ( playerPos - org ).LengthSqr();
- if ( dist < bestDist ) {
- bestNode = node;
- bestDist = dist;
- }
- }
- }
- idThread::ReturnEntity( bestNode );
- return;
- }
- #endif
- idThread::ReturnEntity( NULL );
- return;
- }
- // find the closest attack node that can see our enemy and is closer than our enemy
- bestNode = NULL;
- const idVec3 &myPos = physicsObj.GetOrigin();
- bestDist = ( myPos - lastVisibleEnemyPos ).LengthSqr();
- for( i = 0; i < targets.Num(); i++ ) {
- targetEnt = targets[ i ].GetEntity();
- if ( !targetEnt || !targetEnt->IsType( idCombatNode::Type ) ) {
- continue;
- }
- node = static_cast<idCombatNode *>( targetEnt );
- if ( !node->IsDisabled() && node->EntityInView( enemyEnt, lastVisibleEnemyPos ) ) {
- idVec3 org = node->GetPhysics()->GetOrigin();
- dist = ( myPos - org ).LengthSqr();
- if ( dist < bestDist ) {
- bestNode = node;
- bestDist = dist;
- }
- }
- }
- idThread::ReturnEntity( bestNode );
- }
- /*
- =====================
- idAI::Event_EnemyInCombatCone
- =====================
- */
- void idAI::Event_EnemyInCombatCone( idEntity *ent, int use_current_enemy_location ) {
- idCombatNode *node;
- bool result;
- idActor *enemyEnt = enemy.GetEntity();
- if ( !targets.Num() ) {
- // no combat nodes
- idThread::ReturnInt( false );
- return;
- }
- if ( !enemyEnt ) {
- // have to have an enemy
- idThread::ReturnInt( false );
- return;
- }
- if ( !ent || !ent->IsType( idCombatNode::Type ) ) {
- // not a combat node
- idThread::ReturnInt( false );
- return;
- }
- #ifdef _D3XP
- //Allow the level designers define attack nodes that the enemy should never leave.
- //This is different that the turrent type combat nodes because they can play an animation
- if(ent->spawnArgs.GetBool("neverLeave", "0")) {
- idThread::ReturnInt( true );
- return;
- }
- #endif
- node = static_cast<idCombatNode *>( ent );
- if ( use_current_enemy_location ) {
- const idVec3 &pos = enemyEnt->GetPhysics()->GetOrigin();
- result = node->EntityInView( enemyEnt, pos );
- } else {
- result = node->EntityInView( enemyEnt, lastVisibleEnemyPos );
- }
- idThread::ReturnInt( result );
- }
- /*
- =====================
- idAI::Event_WaitMove
- =====================
- */
- void idAI::Event_WaitMove( void ) {
- idThread::BeginMultiFrameEvent( this, &AI_WaitMove );
- if ( MoveDone() ) {
- idThread::EndMultiFrameEvent( this, &AI_WaitMove );
- }
- }
- /*
- =====================
- idAI::Event_GetJumpVelocity
- =====================
- */
- void idAI::Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height ) {
- idVec3 start;
- idVec3 end;
- idVec3 dir;
- float dist;
- bool result;
- idEntity *enemyEnt = enemy.GetEntity();
- if ( !enemyEnt ) {
- idThread::ReturnVector( vec3_zero );
- return;
- }
- if ( speed <= 0.0f ) {
- gameLocal.Error( "Invalid speed. speed must be > 0." );
- }
- start = physicsObj.GetOrigin();
- end = pos;
- dir = end - start;
- dist = dir.Normalize();
- if ( dist > 16.0f ) {
- dist -= 16.0f;
- end -= dir * 16.0f;
- }
- result = PredictTrajectory( start, end, speed, physicsObj.GetGravity(), physicsObj.GetClipModel(), MASK_MONSTERSOLID, max_height, this, enemyEnt, ai_debugMove.GetBool() ? 4000 : 0, dir );
- if ( result ) {
- idThread::ReturnVector( dir * speed );
- } else {
- idThread::ReturnVector( vec3_zero );
- }
- }
- /*
- =====================
- idAI::Event_EntityInAttackCone
- =====================
- */
- void idAI::Event_EntityInAttackCone( idEntity *ent ) {
- float attack_cone;
- idVec3 delta;
- float yaw;
- float relYaw;
-
- if ( !ent ) {
- idThread::ReturnInt( false );
- return;
- }
- delta = ent->GetPhysics()->GetOrigin() - GetEyePosition();
- // get our gravity normal
- const idVec3 &gravityDir = GetPhysics()->GetGravityNormal();
- // infinite vertical vision, so project it onto our orientation plane
- delta -= gravityDir * ( gravityDir * delta );
- delta.Normalize();
- yaw = delta.ToYaw();
- attack_cone = spawnArgs.GetFloat( "attack_cone", "70" );
- relYaw = idMath::AngleNormalize180( ideal_yaw - yaw );
- if ( idMath::Fabs( relYaw ) < ( attack_cone * 0.5f ) ) {
- idThread::ReturnInt( true );
- } else {
- idThread::ReturnInt( false );
- }
- }
- /*
- =====================
- idAI::Event_CanSeeEntity
- =====================
- */
- void idAI::Event_CanSeeEntity( idEntity *ent ) {
- if ( !ent ) {
- idThread::ReturnInt( false );
- return;
- }
- bool cansee = CanSee( ent, false );
- idThread::ReturnInt( cansee );
- }
- /*
- =====================
- idAI::Event_SetTalkTarget
- =====================
- */
- void idAI::Event_SetTalkTarget( idEntity *target ) {
- if ( target && !target->IsType( idActor::Type ) ) {
- gameLocal.Error( "Cannot set talk target to '%s'. Not a character or player.", target->GetName() );
- }
- talkTarget = static_cast<idActor *>( target );
- if ( target ) {
- AI_TALK = true;
- } else {
- AI_TALK = false;
- }
- }
- /*
- =====================
- idAI::Event_GetTalkTarget
- =====================
- */
- void idAI::Event_GetTalkTarget( void ) {
- idThread::ReturnEntity( talkTarget.GetEntity() );
- }
- /*
- ================
- idAI::Event_SetTalkState
- ================
- */
- void idAI::Event_SetTalkState( int state ) {
- if ( ( state < 0 ) || ( state >= NUM_TALK_STATES ) ) {
- gameLocal.Error( "Invalid talk state (%d)", state );
- }
- talk_state = static_cast<talkState_t>( state );
- }
- /*
- =====================
- idAI::Event_EnemyRange
- =====================
- */
- void idAI::Event_EnemyRange( void ) {
- float dist;
- idActor *enemyEnt = enemy.GetEntity();
- if ( enemyEnt ) {
- dist = ( enemyEnt->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin() ).Length();
- } else {
- // Just some really high number
- dist = idMath::INFINITY;
- }
- idThread::ReturnFloat( dist );
- }
- /*
- =====================
- idAI::Event_EnemyRange2D
- =====================
- */
- void idAI::Event_EnemyRange2D( void ) {
- float dist;
- idActor *enemyEnt = enemy.GetEntity();
- if ( enemyEnt ) {
- dist = ( enemyEnt->GetPhysics()->GetOrigin().ToVec2() - GetPhysics()->GetOrigin().ToVec2() ).Length();
- } else {
- // Just some really high number
- dist = idMath::INFINITY;
- }
- idThread::ReturnFloat( dist );
- }
- /*
- =====================
- idAI::Event_GetEnemy
- =====================
- */
- void idAI::Event_GetEnemy( void ) {
- idThread::ReturnEntity( enemy.GetEntity() );
- }
- /*
- =====================
- idAI::Event_GetEnemyPos
- =====================
- */
- void idAI::Event_GetEnemyPos( void ) {
- idThread::ReturnVector( lastVisibleEnemyPos );
- }
- /*
- =====================
- idAI::Event_GetEnemyEyePos
- =====================
- */
- void idAI::Event_GetEnemyEyePos( void ) {
- idThread::ReturnVector( lastVisibleEnemyPos + lastVisibleEnemyEyeOffset );
- }
- /*
- =====================
- idAI::Event_PredictEnemyPos
- =====================
- */
- void idAI::Event_PredictEnemyPos( float time ) {
- predictedPath_t path;
- idActor *enemyEnt = enemy.GetEntity();
- // if no enemy set
- if ( !enemyEnt ) {
- idThread::ReturnVector( physicsObj.GetOrigin() );
- return;
- }
- // predict the enemy movement
- idAI::PredictPath( enemyEnt, aas, lastVisibleEnemyPos, enemyEnt->GetPhysics()->GetLinearVelocity(), SEC2MS( time ), SEC2MS( time ), ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path );
- idThread::ReturnVector( path.endPos );
- }
- /*
- =====================
- idAI::Event_CanHitEnemy
- =====================
- */
- void idAI::Event_CanHitEnemy( void ) {
- trace_t tr;
- idEntity *hit;
- idActor *enemyEnt = enemy.GetEntity();
- if ( !AI_ENEMY_VISIBLE || !enemyEnt ) {
- idThread::ReturnInt( false );
- return;
- }
- // don't check twice per frame
- if ( gameLocal.time == lastHitCheckTime ) {
- idThread::ReturnInt( lastHitCheckResult );
- return;
- }
- lastHitCheckTime = gameLocal.time;
- idVec3 toPos = enemyEnt->GetEyePosition();
- idVec3 eye = GetEyePosition();
- idVec3 dir;
- // expand the ray out as far as possible so we can detect anything behind the enemy
- dir = toPos - eye;
- dir.Normalize();
- toPos = eye + dir * MAX_WORLD_SIZE;
- gameLocal.clip.TracePoint( tr, eye, toPos, MASK_SHOT_BOUNDINGBOX, this );
- hit = gameLocal.GetTraceEntity( tr );
- if ( tr.fraction >= 1.0f || ( hit == enemyEnt ) ) {
- lastHitCheckResult = true;
- } else if ( ( tr.fraction < 1.0f ) && ( hit->IsType( idAI::Type ) ) &&
- ( static_cast<idAI *>( hit )->team != team ) ) {
- lastHitCheckResult = true;
- } else {
- lastHitCheckResult = false;
- }
- idThread::ReturnInt( lastHitCheckResult );
- }
- /*
- =====================
- idAI::Event_CanHitEnemyFromAnim
- =====================
- */
- void idAI::Event_CanHitEnemyFromAnim( const char *animname ) {
- int anim;
- idVec3 dir;
- idVec3 local_dir;
- idVec3 fromPos;
- idMat3 axis;
- idVec3 start;
- trace_t tr;
- float distance;
- idActor *enemyEnt = enemy.GetEntity();
- if ( !AI_ENEMY_VISIBLE || !enemyEnt ) {
- idThread::ReturnInt( false );
- return;
- }
- anim = GetAnim( ANIMCHANNEL_LEGS, animname );
- if ( !anim ) {
- idThread::ReturnInt( false );
- return;
- }
- // just do a ray test if close enough
- if ( enemyEnt->GetPhysics()->GetAbsBounds().IntersectsBounds( physicsObj.GetAbsBounds().Expand( 16.0f ) ) ) {
- Event_CanHitEnemy();
- return;
- }
- // calculate the world transform of the launch position
- const idVec3 &org = physicsObj.GetOrigin();
- dir = lastVisibleEnemyPos - org;
- physicsObj.GetGravityAxis().ProjectVector( dir, local_dir );
- local_dir.z = 0.0f;
- local_dir.ToVec2().Normalize();
- axis = local_dir.ToMat3();
- fromPos = physicsObj.GetOrigin() + missileLaunchOffset[ anim ] * axis;
- if ( projectileClipModel == NULL ) {
- CreateProjectileClipModel();
- }
- // check if the owner bounds is bigger than the projectile bounds
- const idBounds &ownerBounds = physicsObj.GetAbsBounds();
- const idBounds &projBounds = projectileClipModel->GetBounds();
- if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) &&
- ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) &&
- ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) {
- if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) {
- start = org + distance * viewAxis[ 0 ];
- } else {
- start = ownerBounds.GetCenter();
- }
- } else {
- // projectile bounds bigger than the owner bounds, so just start it from the center
- start = ownerBounds.GetCenter();
- }
- gameLocal.clip.Translation( tr, start, fromPos, projectileClipModel, mat3_identity, MASK_SHOT_RENDERMODEL, this );
- fromPos = tr.endpos;
- if ( GetAimDir( fromPos, enemy.GetEntity(), this, dir ) ) {
- idThread::ReturnInt( true );
- } else {
- idThread::ReturnInt( false );
- }
- }
- /*
- =====================
- idAI::Event_CanHitEnemyFromJoint
- =====================
- */
- void idAI::Event_CanHitEnemyFromJoint( const char *jointname ) {
- trace_t tr;
- idVec3 muzzle;
- idMat3 axis;
- idVec3 start;
- float distance;
- idActor *enemyEnt = enemy.GetEntity();
- if ( !AI_ENEMY_VISIBLE || !enemyEnt ) {
- idThread::ReturnInt( false );
- return;
- }
- // don't check twice per frame
- if ( gameLocal.time == lastHitCheckTime ) {
- idThread::ReturnInt( lastHitCheckResult );
- return;
- }
- lastHitCheckTime = gameLocal.time;
- const idVec3 &org = physicsObj.GetOrigin();
- idVec3 toPos = enemyEnt->GetEyePosition();
- jointHandle_t joint = animator.GetJointHandle( jointname );
- if ( joint == INVALID_JOINT ) {
- gameLocal.Error( "Unknown joint '%s' on %s", jointname, GetEntityDefName() );
- }
- animator.GetJointTransform( joint, gameLocal.time, muzzle, axis );
- muzzle = org + ( muzzle + modelOffset ) * viewAxis * physicsObj.GetGravityAxis();
- if ( projectileClipModel == NULL ) {
- CreateProjectileClipModel();
- }
- // check if the owner bounds is bigger than the projectile bounds
- const idBounds &ownerBounds = physicsObj.GetAbsBounds();
- const idBounds &projBounds = projectileClipModel->GetBounds();
- if ( ( ( ownerBounds[1][0] - ownerBounds[0][0] ) > ( projBounds[1][0] - projBounds[0][0] ) ) &&
- ( ( ownerBounds[1][1] - ownerBounds[0][1] ) > ( projBounds[1][1] - projBounds[0][1] ) ) &&
- ( ( ownerBounds[1][2] - ownerBounds[0][2] ) > ( projBounds[1][2] - projBounds[0][2] ) ) ) {
- if ( (ownerBounds - projBounds).RayIntersection( org, viewAxis[ 0 ], distance ) ) {
- start = org + distance * viewAxis[ 0 ];
- } else {
- start = ownerBounds.GetCenter();
- }
- } else {
- // projectile bounds bigger than the owner bounds, so just start it from the center
- start = ownerBounds.GetCenter();
- }
- gameLocal.clip.Translation( tr, start, muzzle, projectileClipModel, mat3_identity, MASK_SHOT_BOUNDINGBOX, this );
- muzzle = tr.endpos;
- gameLocal.clip.Translation( tr, muzzle, toPos, projectileClipModel, mat3_identity, MASK_SHOT_BOUNDINGBOX, this );
- if ( tr.fraction >= 1.0f || ( gameLocal.GetTraceEntity( tr ) == enemyEnt ) ) {
- lastHitCheckResult = true;
- } else {
- lastHitCheckResult = false;
- }
- idThread::ReturnInt( lastHitCheckResult );
- }
- /*
- =====================
- idAI::Event_EnemyPositionValid
- =====================
- */
- void idAI::Event_EnemyPositionValid( void ) {
- bool result;
- result = EnemyPositionValid();
- idThread::ReturnInt( result );
- }
- /*
- =====================
- idAI::Event_ChargeAttack
- =====================
- */
- void idAI::Event_ChargeAttack( const char *damageDef ) {
- idActor *enemyEnt = enemy.GetEntity();
- StopMove( MOVE_STATUS_DEST_NOT_FOUND );
- if ( enemyEnt ) {
- idVec3 enemyOrg;
- if ( move.moveType == MOVETYPE_FLY ) {
- // position destination so that we're in the enemy's view
- enemyOrg = enemyEnt->GetEyePosition();
- enemyOrg -= enemyEnt->GetPhysics()->GetGravityNormal() * fly_offset;
- } else {
- enemyOrg = enemyEnt->GetPhysics()->GetOrigin();
- }
- BeginAttack( damageDef );
- DirectMoveToPosition( enemyOrg );
- TurnToward( enemyOrg );
- }
- }
- /*
- =====================
- idAI::Event_TestChargeAttack
- =====================
- */
- void idAI::Event_TestChargeAttack( void ) {
- trace_t trace;
- idActor *enemyEnt = enemy.GetEntity();
- predictedPath_t path;
- idVec3 end;
- if ( !enemyEnt ) {
- idThread::ReturnFloat( 0.0f );
- return;
- }
- if ( move.moveType == MOVETYPE_FLY ) {
- // position destination so that we're in the enemy's view
- end = enemyEnt->GetEyePosition();
- end -= enemyEnt->GetPhysics()->GetGravityNormal() * fly_offset;
- } else {
- end = enemyEnt->GetPhysics()->GetOrigin();
- }
- idAI::PredictPath( this, aas, physicsObj.GetOrigin(), end - physicsObj.GetOrigin(), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path );
- if ( ai_debugMove.GetBool() ) {
- gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), end, gameLocal.msec );
- gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), end, gameLocal.msec );
- }
- if ( ( path.endEvent == 0 ) || ( path.blockingEntity == enemyEnt ) ) {
- idVec3 delta = end - physicsObj.GetOrigin();
- float time = delta.LengthFast();
- idThread::ReturnFloat( time );
- } else {
- idThread::ReturnFloat( 0.0f );
- }
- }
- /*
- =====================
- idAI::Event_TestAnimMoveTowardEnemy
- =====================
- */
- void idAI::Event_TestAnimMoveTowardEnemy( const char *animname ) {
- int anim;
- predictedPath_t path;
- idVec3 moveVec;
- float yaw;
- idVec3 delta;
- idActor *enemyEnt;
-
- enemyEnt = enemy.GetEntity();
- if ( !enemyEnt ) {
- idThread::ReturnInt( false );
- return;
- }
- anim = GetAnim( ANIMCHANNEL_LEGS, animname );
- if ( !anim ) {
- gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() );
- idThread::ReturnInt( false );
- return;
- }
- delta = enemyEnt->GetPhysics()->GetOrigin() - physicsObj.GetOrigin();
- yaw = delta.ToYaw();
- moveVec = animator.TotalMovementDelta( anim ) * idAngles( 0.0f, yaw, 0.0f ).ToMat3() * physicsObj.GetGravityAxis();
- idAI::PredictPath( this, aas, physicsObj.GetOrigin(), moveVec, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path );
- if ( ai_debugMove.GetBool() ) {
- gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), physicsObj.GetOrigin() + moveVec, gameLocal.msec );
- gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), physicsObj.GetOrigin() + moveVec, gameLocal.msec );
- }
- idThread::ReturnInt( path.endEvent == 0 );
- }
- /*
- =====================
- idAI::Event_TestAnimMove
- =====================
- */
- void idAI::Event_TestAnimMove( const char *animname ) {
- int anim;
- predictedPath_t path;
- idVec3 moveVec;
- anim = GetAnim( ANIMCHANNEL_LEGS, animname );
- if ( !anim ) {
- gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() );
- idThread::ReturnInt( false );
- return;
- }
- moveVec = animator.TotalMovementDelta( anim ) * idAngles( 0.0f, ideal_yaw, 0.0f ).ToMat3() * physicsObj.GetGravityAxis();
- idAI::PredictPath( this, aas, physicsObj.GetOrigin(), moveVec, 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path );
- if ( ai_debugMove.GetBool() ) {
- gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), physicsObj.GetOrigin() + moveVec, gameLocal.msec );
- gameRenderWorld->DebugBounds( path.endEvent == 0 ? colorYellow : colorRed, physicsObj.GetBounds(), physicsObj.GetOrigin() + moveVec, gameLocal.msec );
- }
- idThread::ReturnInt( path.endEvent == 0 );
- }
- /*
- =====================
- idAI::Event_TestMoveToPosition
- =====================
- */
- void idAI::Event_TestMoveToPosition( const idVec3 &position ) {
- predictedPath_t path;
- idAI::PredictPath( this, aas, physicsObj.GetOrigin(), position - physicsObj.GetOrigin(), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path );
- if ( ai_debugMove.GetBool() ) {
- gameRenderWorld->DebugLine( colorGreen, physicsObj.GetOrigin(), position, gameLocal.msec );
- gameRenderWorld->DebugBounds( colorYellow, physicsObj.GetBounds(), position, gameLocal.msec );
- if ( path.endEvent ) {
- gameRenderWorld->DebugBounds( colorRed, physicsObj.GetBounds(), path.endPos, gameLocal.msec );
- }
- }
- idThread::ReturnInt( path.endEvent == 0 );
- }
- /*
- =====================
- idAI::Event_TestMeleeAttack
- =====================
- */
- void idAI::Event_TestMeleeAttack( void ) {
- bool result = TestMelee();
- idThread::ReturnInt( result );
- }
- /*
- =====================
- idAI::Event_TestAnimAttack
- =====================
- */
- void idAI::Event_TestAnimAttack( const char *animname ) {
- int anim;
- predictedPath_t path;
- anim = GetAnim( ANIMCHANNEL_LEGS, animname );
- if ( !anim ) {
- gameLocal.DWarning( "missing '%s' animation on '%s' (%s)", animname, name.c_str(), GetEntityDefName() );
- idThread::ReturnInt( false );
- return;
- }
- idAI::PredictPath( this, aas, physicsObj.GetOrigin(), animator.TotalMovementDelta( anim ), 1000, 1000, ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_ENTER_OBSTACLE | SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path );
- idThread::ReturnInt( path.blockingEntity && ( path.blockingEntity == enemy.GetEntity() ) );
- }
- /*
- =====================
- idAI::Event_Shrivel
- =====================
- */
- void idAI::Event_Shrivel( float shrivel_time ) {
- float t;
- if ( idThread::BeginMultiFrameEvent( this, &AI_Shrivel ) ) {
- if ( shrivel_time <= 0.0f ) {
- idThread::EndMultiFrameEvent( this, &AI_Shrivel );
- return;
- }
- shrivel_rate = 0.001f / shrivel_time;
- shrivel_start = gameLocal.time;
- }
- t = ( gameLocal.time - shrivel_start ) * shrivel_rate;
- if ( t > 0.25f ) {
- renderEntity.noShadow = true;
- }
- if ( t > 1.0f ) {
- t = 1.0f;
- idThread::EndMultiFrameEvent( this, &AI_Shrivel );
- }
- renderEntity.shaderParms[ SHADERPARM_MD5_SKINSCALE ] = 1.0f - t * 0.5f;
- UpdateVisuals();
- }
- /*
- =====================
- idAI::Event_PreBurn
- =====================
- */
- void idAI::Event_PreBurn( void ) {
- #ifdef _D3XP
- // No grabbing after the burn has started!
- noGrab = true;
- #endif
- // for now this just turns shadows off
- renderEntity.noShadow = true;
- }
- /*
- =====================
- idAI::Event_Burn
- =====================
- */
- void idAI::Event_Burn( void ) {
- renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = gameLocal.time * 0.001f;
- SpawnParticles( "smoke_burnParticleSystem" );
- UpdateVisuals();
- }
- /*
- =====================
- idAI::Event_ClearBurn
- =====================
- */
- void idAI::Event_ClearBurn( void ) {
- renderEntity.noShadow = spawnArgs.GetBool( "noshadows" );
- renderEntity.shaderParms[ SHADERPARM_TIME_OF_DEATH ] = 0.0f;
- UpdateVisuals();
- }
- /*
- =====================
- idAI::Event_SetSmokeVisibility
- =====================
- */
- void idAI::Event_SetSmokeVisibility( int num, int on ) {
- int i;
- int time;
- if ( num >= particles.Num() ) {
- gameLocal.Warning( "Particle #%d out of range (%d particles) on entity '%s'", num, particles.Num(), name.c_str() );
- return;
- }
- if ( on != 0 ) {
- time = gameLocal.time;
- BecomeActive( TH_UPDATEPARTICLES );
- } else {
- time = 0;
- }
- if ( num >= 0 ) {
- particles[ num ].time = time;
- } else {
- for ( i = 0; i < particles.Num(); i++ ) {
- particles[ i ].time = time;
- }
- }
- UpdateVisuals();
- }
- /*
- =====================
- idAI::Event_NumSmokeEmitters
- =====================
- */
- void idAI::Event_NumSmokeEmitters( void ) {
- idThread::ReturnInt( particles.Num() );
- }
- /*
- =====================
- idAI::Event_StopThinking
- =====================
- */
- void idAI::Event_StopThinking( void ) {
- BecomeInactive( TH_THINK );
- idThread *thread = idThread::CurrentThread();
- if ( thread ) {
- thread->DoneProcessing();
- }
- }
- /*
- =====================
- idAI::Event_GetTurnDelta
- =====================
- */
- void idAI::Event_GetTurnDelta( void ) {
- float amount;
- if ( turnRate ) {
- amount = idMath::AngleNormalize180( ideal_yaw - current_yaw );
- idThread::ReturnFloat( amount );
- } else {
- idThread::ReturnFloat( 0.0f );
- }
- }
- /*
- =====================
- idAI::Event_GetMoveType
- =====================
- */
- void idAI::Event_GetMoveType( void ) {
- idThread::ReturnInt( move.moveType );
- }
- /*
- =====================
- idAI::Event_SetMoveTypes
- =====================
- */
- void idAI::Event_SetMoveType( int moveType ) {
- if ( ( moveType < 0 ) || ( moveType >= NUM_MOVETYPES ) ) {
- gameLocal.Error( "Invalid movetype %d", moveType );
- }
- move.moveType = static_cast<moveType_t>( moveType );
- if ( move.moveType == MOVETYPE_FLY ) {
- travelFlags = TFL_WALK|TFL_AIR|TFL_FLY;
- } else {
- travelFlags = TFL_WALK|TFL_AIR;
- }
- }
- /*
- =====================
- idAI::Event_SaveMove
- =====================
- */
- void idAI::Event_SaveMove( void ) {
- savedMove = move;
- }
- /*
- =====================
- idAI::Event_RestoreMove
- =====================
- */
- void idAI::Event_RestoreMove( void ) {
- idVec3 goalPos;
- idVec3 dest;
- switch( savedMove.moveCommand ) {
- case MOVE_NONE :
- StopMove( savedMove.moveStatus );
- break;
- case MOVE_FACE_ENEMY :
- FaceEnemy();
- break;
- case MOVE_FACE_ENTITY :
- FaceEntity( savedMove.goalEntity.GetEntity() );
- break;
- case MOVE_TO_ENEMY :
- MoveToEnemy();
- break;
- case MOVE_TO_ENEMYHEIGHT :
- MoveToEnemyHeight();
- break;
- case MOVE_TO_ENTITY :
- MoveToEntity( savedMove.goalEntity.GetEntity() );
- break;
- case MOVE_OUT_OF_RANGE :
- MoveOutOfRange( savedMove.goalEntity.GetEntity(), savedMove.range );
- break;
- case MOVE_TO_ATTACK_POSITION :
- MoveToAttackPosition( savedMove.goalEntity.GetEntity(), savedMove.anim );
- break;
- case MOVE_TO_COVER :
- MoveToCover( savedMove.goalEntity.GetEntity(), lastVisibleEnemyPos );
- break;
- case MOVE_TO_POSITION :
- MoveToPosition( savedMove.moveDest );
- break;
- case MOVE_TO_POSITION_DIRECT :
- DirectMoveToPosition( savedMove.moveDest );
- break;
- case MOVE_SLIDE_TO_POSITION :
- SlideToPosition( savedMove.moveDest, savedMove.duration );
- break;
- case MOVE_WANDER :
- WanderAround();
- break;
- }
- if ( GetMovePos( goalPos ) ) {
- CheckObstacleAvoidance( goalPos, dest );
- }
- }
- /*
- =====================
- idAI::Event_AllowMovement
- =====================
- */
- void idAI::Event_AllowMovement( float flag ) {
- allowMove = ( flag != 0.0f );
- }
- /*
- =====================
- idAI::Event_JumpFrame
- =====================
- */
- void idAI::Event_JumpFrame( void ) {
- AI_JUMP = true;
- }
- /*
- =====================
- idAI::Event_EnableClip
- =====================
- */
- void idAI::Event_EnableClip( void ) {
- physicsObj.SetClipMask( MASK_MONSTERSOLID );
- disableGravity = false;
- }
- /*
- =====================
- idAI::Event_DisableClip
- =====================
- */
- void idAI::Event_DisableClip( void ) {
- physicsObj.SetClipMask( 0 );
- disableGravity = true;
- }
- /*
- =====================
- idAI::Event_EnableGravity
- =====================
- */
- void idAI::Event_EnableGravity( void ) {
- disableGravity = false;
- }
- /*
- =====================
- idAI::Event_DisableGravity
- =====================
- */
- void idAI::Event_DisableGravity( void ) {
- disableGravity = true;
- }
- /*
- =====================
- idAI::Event_EnableAFPush
- =====================
- */
- void idAI::Event_EnableAFPush( void ) {
- af_push_moveables = true;
- }
- /*
- =====================
- idAI::Event_DisableAFPush
- =====================
- */
- void idAI::Event_DisableAFPush( void ) {
- af_push_moveables = false;
- }
- /*
- =====================
- idAI::Event_SetFlySpeed
- =====================
- */
- void idAI::Event_SetFlySpeed( float speed ) {
- if ( move.speed == fly_speed ) {
- move.speed = speed;
- }
- fly_speed = speed;
- }
- /*
- ================
- idAI::Event_SetFlyOffset
- ================
- */
- void idAI::Event_SetFlyOffset( int offset ) {
- fly_offset = offset;
- }
- /*
- ================
- idAI::Event_ClearFlyOffset
- ================
- */
- void idAI::Event_ClearFlyOffset( void ) {
- spawnArgs.GetInt( "fly_offset", "0", fly_offset );
- }
- /*
- =====================
- idAI::Event_GetClosestHiddenTarget
- =====================
- */
- void idAI::Event_GetClosestHiddenTarget( const char *type ) {
- int i;
- idEntity *ent;
- idEntity *bestEnt;
- float time;
- float bestTime;
- const idVec3 &org = physicsObj.GetOrigin();
- idActor *enemyEnt = enemy.GetEntity();
- if ( !enemyEnt ) {
- // no enemy to hide from
- idThread::ReturnEntity( NULL );
- return;
- }
- if ( targets.Num() == 1 ) {
- ent = targets[ 0 ].GetEntity();
- if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) {
- if ( !EntityCanSeePos( enemyEnt, lastVisibleEnemyPos, ent->GetPhysics()->GetOrigin() ) ) {
- idThread::ReturnEntity( ent );
- return;
- }
- }
- idThread::ReturnEntity( NULL );
- return;
- }
- bestEnt = NULL;
- bestTime = idMath::INFINITY;
- for( i = 0; i < targets.Num(); i++ ) {
- ent = targets[ i ].GetEntity();
- if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) {
- const idVec3 &destOrg = ent->GetPhysics()->GetOrigin();
- time = TravelDistance( org, destOrg );
- if ( ( time >= 0.0f ) && ( time < bestTime ) ) {
- if ( !EntityCanSeePos( enemyEnt, lastVisibleEnemyPos, destOrg ) ) {
- bestEnt = ent;
- bestTime = time;
- }
- }
- }
- }
- idThread::ReturnEntity( bestEnt );
- }
- /*
- =====================
- idAI::Event_GetRandomTarget
- =====================
- */
- void idAI::Event_GetRandomTarget( const char *type ) {
- int i;
- int num;
- int which;
- idEntity *ent;
- idEntity *ents[ MAX_GENTITIES ];
- num = 0;
- for( i = 0; i < targets.Num(); i++ ) {
- ent = targets[ i ].GetEntity();
- if ( ent && idStr::Cmp( ent->GetEntityDefName(), type ) == 0 ) {
- ents[ num++ ] = ent;
- if ( num >= MAX_GENTITIES ) {
- break;
- }
- }
- }
- if ( !num ) {
- idThread::ReturnEntity( NULL );
- return;
- }
- which = gameLocal.random.RandomInt( num );
- idThread::ReturnEntity( ents[ which ] );
- }
- /*
- ================
- idAI::Event_TravelDistanceToPoint
- ================
- */
- void idAI::Event_TravelDistanceToPoint( const idVec3 &pos ) {
- float time;
- time = TravelDistance( physicsObj.GetOrigin(), pos );
- idThread::ReturnFloat( time );
- }
- /*
- ================
- idAI::Event_TravelDistanceToEntity
- ================
- */
- void idAI::Event_TravelDistanceToEntity( idEntity *ent ) {
- float time;
- time = TravelDistance( physicsObj.GetOrigin(), ent->GetPhysics()->GetOrigin() );
- idThread::ReturnFloat( time );
- }
- /*
- ================
- idAI::Event_TravelDistanceBetweenPoints
- ================
- */
- void idAI::Event_TravelDistanceBetweenPoints( const idVec3 &source, const idVec3 &dest ) {
- float time;
- time = TravelDistance( source, dest );
- idThread::ReturnFloat( time );
- }
- /*
- ================
- idAI::Event_TravelDistanceBetweenEntities
- ================
- */
- void idAI::Event_TravelDistanceBetweenEntities( idEntity *source, idEntity *dest ) {
- float time;
- assert( source );
- assert( dest );
- time = TravelDistance( source->GetPhysics()->GetOrigin(), dest->GetPhysics()->GetOrigin() );
- idThread::ReturnFloat( time );
- }
- /*
- =====================
- idAI::Event_LookAtEntity
- =====================
- */
- void idAI::Event_LookAtEntity( idEntity *ent, float duration ) {
- if ( ent == this ) {
- ent = NULL;
- }
- if ( ( ent != focusEntity.GetEntity() ) || ( focusTime < gameLocal.time ) ) {
- focusEntity = ent;
- alignHeadTime = gameLocal.time;
- forceAlignHeadTime = gameLocal.time + SEC2MS( 1 );
- blink_time = 0;
- }
- focusTime = gameLocal.time + SEC2MS( duration );
- }
- /*
- =====================
- idAI::Event_LookAtEnemy
- =====================
- */
- void idAI::Event_LookAtEnemy( float duration ) {
- idActor *enemyEnt;
- enemyEnt = enemy.GetEntity();
- if ( ( enemyEnt != focusEntity.GetEntity() ) || ( focusTime < gameLocal.time ) ) {
- focusEntity = enemyEnt;
- alignHeadTime = gameLocal.time;
- forceAlignHeadTime = gameLocal.time + SEC2MS( 1 );
- blink_time = 0;
- }
- focusTime = gameLocal.time + SEC2MS( duration );
- }
- /*
- ===============
- idAI::Event_SetJointMod
- ===============
- */
- void idAI::Event_SetJointMod( int allow ) {
- allowJointMod = ( allow != 0 );
- }
- /*
- ================
- idAI::Event_ThrowMoveable
- ================
- */
- void idAI::Event_ThrowMoveable( void ) {
- idEntity *ent;
- idEntity *moveable = NULL;
- for ( ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity() ) {
- if ( ent->GetBindMaster() == this && ent->IsType( idMoveable::Type ) ) {
- moveable = ent;
- break;
- }
- }
- if ( moveable ) {
- moveable->Unbind();
- moveable->PostEventMS( &EV_SetOwner, 200, NULL );
- }
- }
- /*
- ================
- idAI::Event_ThrowAF
- ================
- */
- void idAI::Event_ThrowAF( void ) {
- idEntity *ent;
- idEntity *af = NULL;
- for ( ent = GetNextTeamEntity(); ent != NULL; ent = ent->GetNextTeamEntity() ) {
- if ( ent->GetBindMaster() == this && ent->IsType( idAFEntity_Base::Type ) ) {
- af = ent;
- break;
- }
- }
- if ( af ) {
- af->Unbind();
- af->PostEventMS( &EV_SetOwner, 200, NULL );
- }
- }
- /*
- ================
- idAI::Event_SetAngles
- ================
- */
- void idAI::Event_SetAngles( idAngles const &ang ) {
- current_yaw = ang.yaw;
- viewAxis = idAngles( 0, current_yaw, 0 ).ToMat3();
- }
- /*
- ================
- idAI::Event_GetAngles
- ================
- */
- void idAI::Event_GetAngles( void ) {
- idThread::ReturnVector( idVec3( 0.0f, current_yaw, 0.0f ) );
- }
- /*
- ================
- idAI::Event_RealKill
- ================
- */
- void idAI::Event_RealKill( void ) {
- health = 0;
- if ( af.IsLoaded() ) {
- // clear impacts
- af.Rest();
- // physics is turned off by calling af.Rest()
- BecomeActive( TH_PHYSICS );
- }
- Killed( this, this, 0, vec3_zero, INVALID_JOINT );
- }
- /*
- ================
- idAI::Event_Kill
- ================
- */
- void idAI::Event_Kill( void ) {
- PostEventMS( &AI_RealKill, 0 );
- }
- /*
- ================
- idAI::Event_WakeOnFlashlight
- ================
- */
- void idAI::Event_WakeOnFlashlight( int enable ) {
- wakeOnFlashlight = ( enable != 0 );
- }
- /*
- ================
- idAI::Event_LocateEnemy
- ================
- */
- void idAI::Event_LocateEnemy( void ) {
- idActor *enemyEnt;
- int areaNum;
-
- enemyEnt = enemy.GetEntity();
- if ( !enemyEnt ) {
- return;
- }
- enemyEnt->GetAASLocation( aas, lastReachableEnemyPos, areaNum );
- SetEnemyPosition();
- UpdateEnemyPosition();
- }
- /*
- ================
- idAI::Event_KickObstacles
- ================
- */
- void idAI::Event_KickObstacles( idEntity *kickEnt, float force ) {
- idVec3 dir;
- idEntity *obEnt;
-
- if ( kickEnt ) {
- obEnt = kickEnt;
- } else {
- obEnt = move.obstacle.GetEntity();
- }
- if ( obEnt ) {
- dir = obEnt->GetPhysics()->GetOrigin() - physicsObj.GetOrigin();
- dir.Normalize();
- } else {
- dir = viewAxis[ 0 ];
- }
- KickObstacles( dir, force, obEnt );
- }
- /*
- ================
- idAI::Event_GetObstacle
- ================
- */
- void idAI::Event_GetObstacle( void ) {
- idThread::ReturnEntity( move.obstacle.GetEntity() );
- }
- /*
- ================
- idAI::Event_PushPointIntoAAS
- ================
- */
- void idAI::Event_PushPointIntoAAS( const idVec3 &pos ) {
- int areaNum;
- idVec3 newPos;
- areaNum = PointReachableAreaNum( pos );
- if ( areaNum ) {
- newPos = pos;
- aas->PushPointIntoAreaNum( areaNum, newPos );
- idThread::ReturnVector( newPos );
- } else {
- idThread::ReturnVector( pos );
- }
- }
- /*
- ================
- idAI::Event_GetTurnRate
- ================
- */
- void idAI::Event_GetTurnRate( void ) {
- idThread::ReturnFloat( turnRate );
- }
- /*
- ================
- idAI::Event_SetTurnRate
- ================
- */
- void idAI::Event_SetTurnRate( float rate ) {
- turnRate = rate;
- }
- /*
- ================
- idAI::Event_AnimTurn
- ================
- */
- void idAI::Event_AnimTurn( float angles ) {
- turnVel = 0.0f;
- anim_turn_angles = angles;
- if ( angles ) {
- anim_turn_yaw = current_yaw;
- anim_turn_amount = idMath::Fabs( idMath::AngleNormalize180( current_yaw - ideal_yaw ) );
- if ( anim_turn_amount > anim_turn_angles ) {
- anim_turn_amount = anim_turn_angles;
- }
- } else {
- anim_turn_amount = 0.0f;
- animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 0, 1.0f );
- animator.CurrentAnim( ANIMCHANNEL_LEGS )->SetSyncedAnimWeight( 1, 0.0f );
- animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 0, 1.0f );
- animator.CurrentAnim( ANIMCHANNEL_TORSO )->SetSyncedAnimWeight( 1, 0.0f );
- }
- }
- /*
- ================
- idAI::Event_AllowHiddenMovement
- ================
- */
- void idAI::Event_AllowHiddenMovement( int enable ) {
- allowHiddenMovement = ( enable != 0 );
- }
- /*
- ================
- idAI::Event_TriggerParticles
- ================
- */
- void idAI::Event_TriggerParticles( const char *jointName ) {
- TriggerParticles( jointName );
- }
- /*
- =====================
- idAI::Event_FindActorsInBounds
- =====================
- */
- void idAI::Event_FindActorsInBounds( const idVec3 &mins, const idVec3 &maxs ) {
- idEntity * ent;
- idEntity * entityList[ MAX_GENTITIES ];
- int numListedEntities;
- int i;
- numListedEntities = gameLocal.clip.EntitiesTouchingBounds( idBounds( mins, maxs ), CONTENTS_BODY, entityList, MAX_GENTITIES );
- for( i = 0; i < numListedEntities; i++ ) {
- ent = entityList[ i ];
- if ( ent != this && !ent->IsHidden() && ( ent->health > 0 ) && ent->IsType( idActor::Type ) ) {
- idThread::ReturnEntity( ent );
- return;
- }
- }
- idThread::ReturnEntity( NULL );
- }
- /*
- ================
- idAI::Event_CanReachPosition
- ================
- */
- void idAI::Event_CanReachPosition( const idVec3 &pos ) {
- aasPath_t path;
- int toAreaNum;
- int areaNum;
- toAreaNum = PointReachableAreaNum( pos );
- areaNum = PointReachableAreaNum( physicsObj.GetOrigin() );
- if ( !toAreaNum || !PathToGoal( path, areaNum, physicsObj.GetOrigin(), toAreaNum, pos ) ) {
- idThread::ReturnInt( false );
- } else {
- idThread::ReturnInt( true );
- }
- }
- /*
- ================
- idAI::Event_CanReachEntity
- ================
- */
- void idAI::Event_CanReachEntity( idEntity *ent ) {
- aasPath_t path;
- int toAreaNum;
- int areaNum;
- idVec3 pos;
- if ( !ent ) {
- idThread::ReturnInt( false );
- return;
- }
- if ( move.moveType != MOVETYPE_FLY ) {
- if ( !ent->GetFloorPos( 64.0f, pos ) ) {
- idThread::ReturnInt( false );
- return;
- }
- if ( ent->IsType( idActor::Type ) && static_cast<idActor *>( ent )->OnLadder() ) {
- idThread::ReturnInt( false );
- return;
- }
- } else {
- pos = ent->GetPhysics()->GetOrigin();
- }
- toAreaNum = PointReachableAreaNum( pos );
- if ( !toAreaNum ) {
- idThread::ReturnInt( false );
- return;
- }
- const idVec3 &org = physicsObj.GetOrigin();
- areaNum = PointReachableAreaNum( org );
- if ( !toAreaNum || !PathToGoal( path, areaNum, org, toAreaNum, pos ) ) {
- idThread::ReturnInt( false );
- } else {
- idThread::ReturnInt( true );
- }
- }
- /*
- ================
- idAI::Event_CanReachEnemy
- ================
- */
- void idAI::Event_CanReachEnemy( void ) {
- aasPath_t path;
- int toAreaNum;
- int areaNum;
- idVec3 pos;
- idActor *enemyEnt;
- enemyEnt = enemy.GetEntity();
- if ( !enemyEnt ) {
- idThread::ReturnInt( false );
- return;
- }
- if ( move.moveType != MOVETYPE_FLY ) {
- if ( enemyEnt->OnLadder() ) {
- idThread::ReturnInt( false );
- return;
- }
- enemyEnt->GetAASLocation( aas, pos, toAreaNum );
- } else {
- pos = enemyEnt->GetPhysics()->GetOrigin();
- toAreaNum = PointReachableAreaNum( pos );
- }
- if ( !toAreaNum ) {
- idThread::ReturnInt( false );
- return;
- }
- const idVec3 &org = physicsObj.GetOrigin();
- areaNum = PointReachableAreaNum( org );
- if ( !PathToGoal( path, areaNum, org, toAreaNum, pos ) ) {
- idThread::ReturnInt( false );
- } else {
- idThread::ReturnInt( true );
- }
- }
- /*
- ================
- idAI::Event_GetReachableEntityPosition
- ================
- */
- void idAI::Event_GetReachableEntityPosition( idEntity *ent ) {
- int toAreaNum;
- idVec3 pos;
- if ( move.moveType != MOVETYPE_FLY ) {
- if ( !ent->GetFloorPos( 64.0f, pos ) ) {
- // NOTE: not a good way to return 'false'
- return idThread::ReturnVector( vec3_zero );
- }
- if ( ent->IsType( idActor::Type ) && static_cast<idActor *>( ent )->OnLadder() ) {
- // NOTE: not a good way to return 'false'
- return idThread::ReturnVector( vec3_zero );
- }
- } else {
- pos = ent->GetPhysics()->GetOrigin();
- }
- if ( aas ) {
- toAreaNum = PointReachableAreaNum( pos );
- aas->PushPointIntoAreaNum( toAreaNum, pos );
- }
- idThread::ReturnVector( pos );
- }
- #ifdef _D3XP
- /*
- ================
- idAI::Event_MoveToPositionDirect
- ================
- */
- void idAI::Event_MoveToPositionDirect( const idVec3 &pos ) {
- StopMove( MOVE_STATUS_DONE );
- DirectMoveToPosition( pos );
- }
- /*
- ================
- idAI::Event_AvoidObstacles
- ================
- */
- void idAI::Event_AvoidObstacles( int ignore) {
- ignore_obstacles = (ignore == 1) ? false : true;
- }
- /*
- ================
- idAI::Event_TriggerFX
- ================
- */
- void idAI::Event_TriggerFX( const char* joint, const char* fx ) {
- TriggerFX(joint, fx);
- }
- void idAI::Event_StartEmitter( const char* name, const char* joint, const char* particle ) {
- idEntity *ent = StartEmitter(name, joint, particle);
- idThread::ReturnEntity(ent);
- }
- void idAI::Event_GetEmitter( const char* name ) {
- idThread::ReturnEntity(GetEmitter(name));
- }
- void idAI::Event_StopEmitter( const char* name ) {
- StopEmitter(name);
- }
- #endif
|