void ApplyTeamRepulsionFields( IGameObject* pGameObject, AUVec3f& desiredPosition, float frameDelta ) { const AUVec3f& refPos = pGameObject->GetEntity()->GetPosition(); const float refDist = pGameObject->GetCollisionRadius(); const float forceStartMultiplier = 1.5f; TGameObjects& data = m_Objects[pGameObject->GetGameTeam()]; TGameObjects::iterator it = data.begin(); TGameObjects::iterator itEnd = data.end(); while (it != itEnd) { IGameObject* pTeamObject = *it; if (pTeamObject != pGameObject) { const AUVec3f& teamObjectPos = pTeamObject->GetEntity()->GetPosition(); const float minAllowedDist = refDist + pTeamObject->GetCollisionRadius(); const float distSqr = (refPos - teamObjectPos).MagnitudeSqr(); const float forceStart = minAllowedDist * forceStartMultiplier; if ( distSqr < forceStart * forceStart ) { float repulsionMagnitude = (forceStart - sqrt(distSqr)) / ( forceStart * ( 1.0f - 1.0f / forceStartMultiplier ) ); AUVec3f dir = (refPos - teamObjectPos).GetNormalised(); desiredPosition += dir * pGameObject->GetMaxSpeed() * frameDelta * repulsionMagnitude; } } ++it; } }
void CheckForCollisions( IGameObject* pGameObject, AUVec3f& desiredPosition, float frameDelta ) { const AUVec3f& refPos = pGameObject->GetEntity()->GetPosition(); const float refDist = pGameObject->GetCollisionRadius(); for (int i=0; i<EGT_COUNT; ++i) { TGameObjects& data = m_Objects[i]; TGameObjects::iterator it = data.begin(); TGameObjects::iterator itEnd = data.end(); while (it != itEnd) { IGameObject* pTestObject = *it; if (pTestObject != pGameObject) { const AUVec3f& testObjectPos = pTestObject->GetEntity()->GetPosition(); float distSqr = (refPos - testObjectPos).MagnitudeSqr(); float minAllowedDist = refDist + pTestObject->GetCollisionRadius(); if ( (distSqr <= minAllowedDist * minAllowedDist) && (pGameObject->GetGameTeam() != pTestObject->GetGameTeam()) ) { // Set desired position to edge of collision radii AUVec3f dir = (refPos - testObjectPos).GetNormalised(); desiredPosition = testObjectPos + dir * minAllowedDist; pTestObject->OnCollision( pGameObject ); pGameObject->OnCollision( pTestObject ); } } ++it; } } }
IGameObject* GetSelectedObject( const AUVec3f& selectPos ) { IGameObject* pGameObject = 0; float dist = FLT_MAX; TGameObjects::iterator it = m_Objects.begin(); TGameObjects::iterator itEnd = m_Objects.end(); while (it != itEnd) { IGameObject* pObj = *it; const AUVec3f& objPos = pObj->GetEntity()->GetPosition(); float testDist = AUVec3f(objPos.x - selectPos.x, 0.0f, objPos.z - selectPos.z).Magnitude(); if ( testDist < pObj->GetCollisionRadius() && testDist < dist ) { pGameObject = pObj; dist = testDist; } ++it; } return pGameObject; }