/** @return true if there is an allied unit within the firing trajectory of <owner> (that might be hit) */ bool CGameHelper::TestTrajectoryAllyCone(const float3& from, const float3& flatdir, float length, float linear, float quadratic, float spread, float baseSize, int allyteam, CUnit* owner) { int quads[1000]; int* endQuad = quads; qf->GetQuadsOnRay(from, flatdir, length, endQuad); for (int* qi = quads; qi != endQuad; ++qi) { const CQuadField::Quad& quad = qf->GetQuad(*qi); for (std::list<CUnit*>::const_iterator ui = quad.teamUnits[allyteam].begin(); ui != quad.teamUnits[allyteam].end(); ++ui) { CUnit* u = *ui; if (u == owner) continue; if (TestTrajectoryConeHelper(from, flatdir, length, linear, quadratic, spread, baseSize, u)) return true; } } return false; }
/** @return true if there is an allied or neutral unit within the firing trajectory of <owner> (that might be hit) */ bool CGameHelper::TestTrajectoryCone( const float3& from, const float3& flatdir, float length, float linear, float quadratic, float spread, float baseSize, const CUnit* owner, unsigned int flags) { int quads[1024]; int* endQuad = quads; qf->GetQuadsOnRay(from, flatdir, length, endQuad); for (int* qi = quads; qi != endQuad; ++qi) { const CQuadField::Quad& quad = qf->GetQuad(*qi); const std::list<CUnit*>& units = ((flags & TEST_ALLIED) != 0)? quad.teamUnits[owner->allyteam]: quad.units; for (std::list<CUnit*>::const_iterator ui = units.begin(); ui != units.end(); ++ui) { const CUnit* u = *ui; if (u == owner) continue; if ((flags & TEST_NEUTRAL) != 0 && !u->IsNeutral()) continue; if (TestTrajectoryConeHelper(from, flatdir, length, linear, quadratic, spread, baseSize, u)) return true; } } return false; }
/** same as TestTrajectoryAllyCone, but looks for neutral units */ bool TestTrajectoryNeutralCone(const float3& from, const float3& flatdir, float length, float linear, float quadratic, float spread, float baseSize, CUnit* owner) { int quads[1000]; int* endQuad = quads; qf->GetQuadsOnRay(from, flatdir, length, endQuad); //FIXME we need a version with `spread` for (int* qi = quads; qi != endQuad; ++qi) { const CQuadField::Quad& quad = qf->GetQuad(*qi); for (std::list<CUnit*>::const_iterator ui = quad.units.begin(); ui != quad.units.end(); ++ui) { CUnit* u = *ui; if (u == owner) continue; if (u->IsNeutral()) { if (TestTrajectoryConeHelper(from, flatdir, length, linear, quadratic, spread, baseSize, u)) return true; } } } return false; }
bool TestTrajectoryCone( const float3& from, const float3& dir, float length, float linear, float quadratic, float spread, float baseSize, int allyteam, bool testFriendly, bool testNeutral, bool testFeatures, CUnit* owner) { GML_RECMUTEX_LOCK(quad); // TestTrajectoryCone int* begQuad = NULL; int* endQuad = NULL; if (qf->GetQuadsOnRay(from, dir, length, begQuad, endQuad) == 0) return true; for (int* quadPtr = begQuad; quadPtr != endQuad; ++quadPtr) { const CQuadField::Quad& quad = qf->GetQuad(*quadPtr); // friendly units in this quad if (testFriendly) { const std::list<CUnit*>& units = quad.teamUnits[allyteam]; std::list<CUnit*>::const_iterator unitsIt; for (unitsIt = units.begin(); unitsIt != units.end(); ++unitsIt) { const CUnit* u = *unitsIt; if (u == owner) continue; if (TestTrajectoryConeHelper(from, dir, length, linear, quadratic, spread, baseSize, u)) return true; } } // neutral units in this quad if (testNeutral) { const std::list<CUnit*>& units = quad.units; std::list<CUnit*>::const_iterator unitsIt; for (unitsIt = units.begin(); unitsIt != units.end(); ++unitsIt) { const CUnit* u = *unitsIt; if (u == owner) continue; if (!u->IsNeutral()) continue; if (TestTrajectoryConeHelper(from, dir, length, linear, quadratic, spread, baseSize, u)) return true; } } // features in this quad if (testFeatures) { const std::list<CFeature*>& features = quad.features; std::list<CFeature*>::const_iterator featuresIt; for (featuresIt = features.begin(); featuresIt != features.end(); ++featuresIt) { const CFeature* f = *featuresIt; if (!f->blocking) continue; if (TestTrajectoryConeHelper(from, dir, length, linear, quadratic, spread, baseSize, f)) return true; } } } return false; }
bool TestTrajectoryCone( const float3& from, const float3& dir, float length, float linear, float quadratic, float spread, int allyteam, int avoidFlags, CUnit* owner) { GML_RECMUTEX_LOCK(quad); // TestTrajectoryCone int* begQuad = NULL; int* endQuad = NULL; if (quadField->GetQuadsOnRay(from, dir, length, begQuad, endQuad) == 0) return true; const bool ignoreAllies = ((avoidFlags & Collision::NOFRIENDLIES) != 0); const bool ignoreNeutrals = ((avoidFlags & Collision::NONEUTRALS ) != 0); const bool ignoreFeatures = ((avoidFlags & Collision::NOFEATURES ) != 0); const float safetyRadii[2] = {2.0f, 0.5f}; for (int* quadPtr = begQuad; quadPtr != endQuad; ++quadPtr) { const CQuadField::Quad& quad = quadField->GetQuad(*quadPtr); // friendly units in this quad if (!ignoreAllies) { const std::list<CUnit*>& units = quad.teamUnits[allyteam]; std::list<CUnit*>::const_iterator unitsIt; for (unitsIt = units.begin(); unitsIt != units.end(); ++unitsIt) { const CUnit* u = *unitsIt; if (u == owner) continue; if (TestTrajectoryConeHelper(from, dir, length, linear, quadratic, spread, safetyRadii[u->immobile], u)) { return true; } } } // neutral units in this quad if (!ignoreNeutrals) { const std::list<CUnit*>& units = quad.units; std::list<CUnit*>::const_iterator unitsIt; for (unitsIt = units.begin(); unitsIt != units.end(); ++unitsIt) { const CUnit* u = *unitsIt; if (u == owner) continue; if (!u->IsNeutral()) continue; if (TestTrajectoryConeHelper(from, dir, length, linear, quadratic, spread, safetyRadii[u->immobile], u)) return true; } } // features in this quad if (!ignoreFeatures) { const std::list<CFeature*>& features = quad.features; std::list<CFeature*>::const_iterator featuresIt; for (featuresIt = features.begin(); featuresIt != features.end(); ++featuresIt) { const CFeature* f = *featuresIt; if (!f->blocking) continue; if (TestTrajectoryConeHelper(from, dir, length, linear, quadratic, spread, 0.0f, f)) return true; } } } return false; }