AI_Vagary.cpp (5205B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition 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 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 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. 25 26 =========================================================================== 27 */ 28 /*********************************************************************** 29 30 game/ai/AI_Vagary.cpp 31 32 Vagary specific AI code 33 34 ***********************************************************************/ 35 36 #pragma hdrstop 37 #include "../../idlib/precompiled.h" 38 39 40 #include "../Game_local.h" 41 42 class idAI_Vagary : public idAI { 43 public: 44 CLASS_PROTOTYPE( idAI_Vagary ); 45 46 private: 47 void Event_ChooseObjectToThrow( const idVec3 &mins, const idVec3 &maxs, float speed, float minDist, float offset ); 48 void Event_ThrowObjectAtEnemy( idEntity *ent, float speed ); 49 }; 50 51 const idEventDef AI_Vagary_ChooseObjectToThrow( "vagary_ChooseObjectToThrow", "vvfff", 'e' ); 52 const idEventDef AI_Vagary_ThrowObjectAtEnemy( "vagary_ThrowObjectAtEnemy", "ef" ); 53 54 CLASS_DECLARATION( idAI, idAI_Vagary ) 55 EVENT( AI_Vagary_ChooseObjectToThrow, idAI_Vagary::Event_ChooseObjectToThrow ) 56 EVENT( AI_Vagary_ThrowObjectAtEnemy, idAI_Vagary::Event_ThrowObjectAtEnemy ) 57 END_CLASS 58 59 /* 60 ================ 61 idAI_Vagary::Event_ChooseObjectToThrow 62 ================ 63 */ 64 void idAI_Vagary::Event_ChooseObjectToThrow( const idVec3 &mins, const idVec3 &maxs, float speed, float minDist, float offset ) { 65 idEntity * ent; 66 idEntity * entityList[ MAX_GENTITIES ]; 67 int numListedEntities; 68 int i, index; 69 float dist; 70 idVec3 vel; 71 idVec3 offsetVec( 0, 0, offset ); 72 idEntity *enemyEnt = enemy.GetEntity(); 73 74 if ( !enemyEnt ) { 75 idThread::ReturnEntity( NULL ); 76 return; 77 } 78 79 idVec3 enemyEyePos = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset; 80 const idBounds &myBounds = physicsObj.GetAbsBounds(); 81 idBounds checkBounds( mins, maxs ); 82 checkBounds.TranslateSelf( physicsObj.GetOrigin() ); 83 numListedEntities = gameLocal.clip.EntitiesTouchingBounds( checkBounds, -1, entityList, MAX_GENTITIES ); 84 85 index = gameLocal.random.RandomInt( numListedEntities ); 86 for ( i = 0; i < numListedEntities; i++, index++ ) { 87 if ( index >= numListedEntities ) { 88 index = 0; 89 } 90 ent = entityList[ index ]; 91 if ( !ent->IsType( idMoveable::Type ) ) { 92 continue; 93 } 94 95 if ( ent->fl.hidden ) { 96 // don't throw hidden objects 97 continue; 98 } 99 100 idPhysics *entPhys = ent->GetPhysics(); 101 const idVec3 &entOrg = entPhys->GetOrigin(); 102 dist = ( entOrg - enemyEyePos ).LengthFast(); 103 if ( dist < minDist ) { 104 continue; 105 } 106 107 idBounds expandedBounds = myBounds.Expand( entPhys->GetBounds().GetRadius() ); 108 if ( expandedBounds.LineIntersection( entOrg, enemyEyePos ) ) { 109 // ignore objects that are behind us 110 continue; 111 } 112 113 if ( PredictTrajectory( entPhys->GetOrigin() + offsetVec, enemyEyePos, speed, entPhys->GetGravity(), 114 entPhys->GetClipModel(), entPhys->GetClipMask(), MAX_WORLD_SIZE, NULL, enemyEnt, ai_debugTrajectory.GetBool() ? 4000 : 0, vel ) ) { 115 idThread::ReturnEntity( ent ); 116 return; 117 } 118 } 119 120 idThread::ReturnEntity( NULL ); 121 } 122 123 /* 124 ================ 125 idAI_Vagary::Event_ThrowObjectAtEnemy 126 ================ 127 */ 128 void idAI_Vagary::Event_ThrowObjectAtEnemy( idEntity *ent, float speed ) { 129 idVec3 vel; 130 idEntity *enemyEnt; 131 idPhysics *entPhys; 132 133 entPhys = ent->GetPhysics(); 134 enemyEnt = enemy.GetEntity(); 135 if ( !enemyEnt ) { 136 vel = ( viewAxis[ 0 ] * physicsObj.GetGravityAxis() ) * speed; 137 } else { 138 PredictTrajectory( entPhys->GetOrigin(), lastVisibleEnemyPos + lastVisibleEnemyEyeOffset, speed, entPhys->GetGravity(), 139 entPhys->GetClipModel(), entPhys->GetClipMask(), MAX_WORLD_SIZE, NULL, enemyEnt, ai_debugTrajectory.GetBool() ? 4000 : 0, vel ); 140 vel *= speed; 141 } 142 143 entPhys->SetLinearVelocity( vel ); 144 145 if ( ent->IsType( idMoveable::Type ) ) { 146 idMoveable *ment = static_cast<idMoveable*>( ent ); 147 ment->EnableDamage( true, 2.5f ); 148 } 149 }