Ejemplo n.º 1
0
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;
}
bool RPG_AiControllerComponent::HasValidTarget() const
{
  if (HasTarget())
  {
    VArray<RPG_DamageableEntity*> const& attackableEntities = RPG_GameManager::s_instance.GetAttackableEntities();
    if(attackableEntities.Find(m_target) < 0)
    {
      return false;
    }

    if(m_target->IsFrom(RPG_Character))
    {
      RPG_Character* targetCharacter = static_cast<RPG_Character*>(m_target);
      return !targetCharacter->IsDead() && !targetCharacter->IsFeigningDeath();
    }
    else
    {
      return true;
    }
  }
  return false;
}
bool RPG_AiControllerComponent::HasValidTarget() const
{
  if (m_target)
  {
    VArray<RPG_DamageableEntity*> const& attackableEntities = RPG_GameManager::s_instance.GetAttackableEntities();
    if(attackableEntities.Find(GetTarget()) < 0)
    {
      return false;
    }

    if(m_target->IsFrom(RPG_Character))
    {
      float const aggroRadius = GetCharacter()->GetAggroRadius();
      hkvVec3 const& currentPosition = GetCharacter()->GetPosition();

      RPG_Character* targetCharacter = static_cast<RPG_Character*>(GetTarget());
      hkvVec3 const& targetPosition = targetCharacter->GetPosition();

      float const currentRangeSquared = (currentPosition - targetPosition).getLengthSquared();

      // check if target is still within range
      if(currentRangeSquared > aggroRadius * aggroRadius)
      {
        return false;
      }
      else
      {
        return !targetCharacter->IsDead() && !targetCharacter->IsFeigningDeath();
      }
    }
    else
    {
      return true;
    }
  }
  return false;
}