#pragma hdrstop #include "precompiled.h" #include "NAV_local.h" #include "../Game_local.h" #include "NAVCallback_FindAttackPosition.h" /* ============ idNAVFindAttackPosition::idNAVFindAttackPosition ============ */ idNAVFindAttackPosition::idNAVFindAttackPosition(const idAI* self, const idMat3& gravityAxis, idEntity* target, const idVec3& targetPos, const idVec3& fireOffset) { int numPVSAreas; this->target = target; this->targetPos = targetPos; this->fireOffset = fireOffset; this->self = self; this->gravityAxis = gravityAxis; excludeBounds = idBounds(idVec3(-64.0, -64.0f, -8.0f), idVec3(64.0, 64.0f, 64.0f)); excludeBounds.TranslateSelf(self->GetPhysics()->GetOrigin()); // setup PVS idBounds bounds(targetPos - idVec3(16, 16, 0), targetPos + idVec3(16, 16, 64)); numPVSAreas = gameLocal.pvs.GetPVSAreas(bounds, PVSAreas, idEntity::MAX_PVS_AREAS); targetPVS = gameLocal.pvs.SetupCurrentPVS(PVSAreas, numPVSAreas); } /* ============ idNAVFindAttackPosition::~idNAVFindAttackPosition ============ */ idNAVFindAttackPosition::~idNAVFindAttackPosition() { gameLocal.pvs.FreeCurrentPVS(targetPVS); } /* ============ idNAVFindAttackPosition::TestArea ============ */ bool idNAVFindAttackPosition::AreaIsGoal(const idNAV* aas, int areaNum) { idVec3 dir; idVec3 local_dir; idVec3 fromPos; idMat3 axis; idVec3 areaCenter; int numPVSAreas; int PVSAreas[idEntity::MAX_PVS_AREAS]; areaCenter = aas->AreaCenter(areaNum); areaCenter[2] += 1.0f; if (excludeBounds.ContainsPoint(areaCenter)) { // too close to where we already are return false; } numPVSAreas = gameLocal.pvs.GetPVSAreas(idBounds(areaCenter).Expand(16.0f), PVSAreas, idEntity::MAX_PVS_AREAS); if (!gameLocal.pvs.InCurrentPVS(targetPVS, PVSAreas, numPVSAreas)) { return false; } // calculate the world transform of the launch position dir = targetPos - areaCenter; gravityAxis.ProjectVector(dir, local_dir); local_dir.z = 0.0f; local_dir.ToVec2().Normalize(); axis = local_dir.ToMat3(); fromPos = areaCenter + fireOffset * axis; return self->GetAimDir(fromPos, target, self, dir); }