void RPG_Pickup::CheckCharacterContact() { VArray<RPG_Character*> const& characters = RPG_GameManager::s_instance.GetCharacters(); hkvVec3 const& currentPosition = GetPosition(); for(int index = 0; index < characters.GetSize(); ++index) { RPG_Character* character = characters.GetAt(index); // only target players if(!character->IsOfType(V_RUNTIME_CLASS(RPG_PlayerCharacter))) { continue; } hkvVec3 const& targetPosition = character->GetPosition(); float currentRangeSquared = (currentPosition - targetPosition).getLengthSquared(); if(currentRangeSquared <= m_pickupRadius * m_pickupRadius) { // call OnPickup for subclasses OnPickup(character); // play the pickup effect CreateEffect(PKFX_Pickup, GetPosition(), GetOrientation()); // setup this object for deletion DisposeObject(); } } }
void RPG_Pickup::UpdateMagnetForces(float const deltaTime) { if(m_usePhysics) { // find the player VArray<RPG_Character*> const& characters = RPG_GameManager::s_instance.GetCharacters(); hkvVec3 const& currentPosition = GetPosition(); RPG_PlayerCharacter* player = NULL; // find a player in range for(int index = 0; index < characters.GetSize(); ++index) { RPG_Character* character = characters.GetAt(index); // only target apparently alive players if(!character->IsOfType(V_RUNTIME_CLASS(RPG_PlayerCharacter)) || character->IsDead() || character->IsFeigningDeath()) { continue; } player = static_cast<RPG_PlayerCharacter*>(character); break; } if(player) { hkvVec3 targetPosition = player->GetPosition(); targetPosition.z += 0.5f * player->GetBoundingBox().getSizeZ(); float distance = (currentPosition - targetPosition).getLength(); if(distance < m_pickupRadius) { distance = m_pickupRadius; } float const distanceSquared = distance * distance; if(distanceSquared < m_magnetMaxDistance * m_magnetMaxDistance) { hkvVec3 direction = targetPosition - GetPosition(); direction.normalizeIfNotZero(); float magnitude = m_magnetSpeedMultiplier * (1.0f / distanceSquared - m_magnetMaxDistanceInverseSquared); m_currentMagnetSpeed += deltaTime * magnitude * RPG_HEALTH_PICKUP_MAGNET_SPEED_MULTIPLIER_CONVERSION_VALUE; m_currentMagnetVelocity = m_currentMagnetSpeed * direction; } } } }
/// Finds and sets a target within range to interact with (usually to attack). /// @TODO: Implement teams and team relationships, as target must currently be a player. bool RPG_AiControllerComponent::AcquireTarget() { VArray<RPG_Character*> const& characters = RPG_GameManager::s_instance.GetCharacters(); hkvVec3 const& currentPosition = m_characterOwner->GetPosition(); bool returnVal = false; for(int index = 0; index < characters.GetSize(); ++index) { RPG_Character* character = characters.GetAt(index); // can't target yourself if(character == m_characterOwner) { continue; } // only target apparently alive players if(!character->IsOfType(V_RUNTIME_CLASS(RPG_PlayerCharacter)) || character->IsDead() || character->IsFeigningDeath()) { continue; } float const aggroRadius = m_characterOwner->GetAggroRadius(); hkvVec3 const& targetPosition = character->GetPosition(); float const currentRangeSquared = (currentPosition - targetPosition).getLengthSquared(); // check if they are within range if(currentRangeSquared <= aggroRadius * aggroRadius) { m_target = character; returnVal = true; } } return returnVal; }