void CGameHelper::DoExplosionDamage(CFeature* feature, const float3& expPos, float expRad, CUnit* owner, const DamageArray& damages) { CollisionVolume* cv = feature->collisionVolume; if (cv) { float3 dif = (feature->midPos + cv->GetOffsets()) - expPos; float expDist = std::max(dif.Length(), 0.1f); float expMod = (expRad - expDist) / expRad; // always do some damage with explosive stuff // (DDM wreckage etc. is too big to normally // be damaged otherwise, even by BB shells) // NOTE: this will also be only approximate // for non-spherical volumes if ((expRad > 8.0f) && (expDist < (cv->GetBoundingRadius() * 1.1f)) && (expMod < 0.1f)) { expMod = 0.1f; } if (expMod > 0.0f) { feature->DoDamage(damages * expMod, owner, dif * (damages.impulseFactor * expMod / expDist * (damages[0] + damages.impulseBoost))); } } }
float CGameHelper::GuiTraceRayFeature(const float3& start, const float3& dir, float length, CFeature*& feature) { float nearHit = length; GML_RECMUTEX_LOCK(quad); // GuiTraceRayFeature std::vector<int> quads = qf->GetQuadsOnRay(start, dir, length); std::vector<int>::iterator qi; for (qi = quads.begin(); qi != quads.end(); ++qi) { const CQuadField::Quad& quad = qf->GetQuad(*qi); std::list<CFeature*>::const_iterator ui; // NOTE: switch this to custom volumes fully? // (not used for any LOF checks, maybe wasteful) for (ui = quad.features.begin(); ui != quad.features.end(); ++ui) { CFeature* f = *ui; if (!gu->spectatingFullView && !f->IsInLosForAllyTeam(gu->myAllyTeam)) { continue; } if (f->noSelect) { continue; } CollisionVolume* cv = f->collisionVolume; const float3& midPosOffset = cv? cv->GetOffsets(): ZeroVector; const float3 dif = (f->midPos + midPosOffset) - start; float closeLength = dif.dot(dir); if (closeLength < 0) continue; if (closeLength > nearHit) continue; float3 closeVect = dif - dir * closeLength; if (closeVect.SqLength() < f->sqRadius) { nearHit = closeLength; feature = f; } } } return nearHit; }