示例#1
0
Vector3 SteeringBehaviour :: escort (const WorldInterface& world,
                                     const PhysicsObjectId& id_target,
                                     const Vector3& offset)
{
	assert(id_target != PhysicsObjectId::ID_NOTHING);

	// no initialization needed
	m_steering_behaviour = ESCORT;

	//
	//  This is a variation on the arrive steering behaviour.
	//    First we work out the desired position from the
	//    offset.  Then we arrive at that position.  Finally we
	//    add on the velocity of the target and truncate to our
	//    maximum speed.
	//
	//  A more sophisticated implementation would use a form of
	//    arrive based on pursue instead of seek.  Or maybe this
	//    already happens; I'm not sure.  In either case,
	//    slowing down for arrival messes up time predictions.
	//

	if(!world.isAlive(m_id_agent) ||
	   !world.isAlive(  id_target))
	{
		assert(invariant());
		return Vector3::ZERO;
	}

	assert(world.isAlive(m_id_agent ));
	assert(world.isAlive(  id_target));
	Vector3 agent_position  = world.getPosition(m_id_agent);
	Vector3 target_velocity = world.getVelocity(  id_target);
	Vector3 escort_position = calculateEscortPosition(world, id_target, offset);

	if(agent_position == escort_position)
	{
		// we are in the correct position, so just match speeds
		assert(invariant());
		return target_velocity;
	}

	double agent_speed_max    = world.getShipSpeedMax(m_id_agent);
	assert(agent_speed_max >= 0.0);
	double agent_acceleration = world.getShipSpeedMax(m_id_agent);
	assert(agent_acceleration >= 0.0);

	double current_distance = agent_position.getDistance(escort_position);

	double  desired_relative_speed    = calculateMaxSafeSpeed(current_distance, agent_acceleration);
	Vector3 desired_relative_velocity = (escort_position - agent_position).getCopyWithNorm(desired_relative_speed);
	Vector3 desired_agent_velocity    = desired_relative_velocity + target_velocity;

	// limit desired velocity to maximum speed
	assert(invariant());
	return desired_agent_velocity.getTruncated(agent_speed_max);
}
void UnitAiMoonGuard::steerToTargetAndShoot(const WorldInterface& world)
{
    assert(m_id_target != PhysicsObjectId::ID_NOTHING);
    assert(world.isAlive(m_id_target));

    Vector3 agent = getShip().getPosition();
    Vector3 agent_velocity = world.getVelocity(getShip().getId());

    Vector3 target = world.getPosition(m_id_target);
    Vector3 target_velocity = world.getVelocity(m_id_target);

    Vector3 desired_velocity;
    double agent_max_speed = world.getShipSpeedMax(getShip().getId());
    double fromAgentToTarget = agent.getAngle(target);
    double fromAgentToTargetFront = agent.getAngle(target + target_velocity);

    if (fromAgentToTargetFront < fromAgentToTarget) {
        desired_velocity = m_steering_behaviour.seek(world, m_id_target);
    }
    else {
        desired_velocity = m_steering_behaviour.getAimDirection(agent, Bullet::SPEED,
                           target, target_velocity);
        if (desired_velocity == Vector3::ZERO) {
            desired_velocity = m_steering_behaviour.pursue(world, m_id_target);
        }
        else {
            desired_velocity.setNorm(agent_max_speed);
        }
    }

    Vector3 avoid_velocity = avoidPlanets(world, desired_velocity);
    avoid_velocity = avoidParticles(world, avoid_velocity);
    avoid_velocity = avoidShips(world, avoid_velocity);
    getShipAi().setDesiredVelocity(avoid_velocity);

    double angle = agent_velocity.getAngle(desired_velocity);
    double distance = target.getDistanceSquared(agent);

    if (angle <= SHOOT_ANGLE_RADIANS_MAX && distance < FIRE_RANGE)
    {
        getShipAi().markFireBulletDesired();
    }
}
示例#3
0
void UnitAiMoonGuard::shootAtShip(const WorldInterface& world, const PhysicsObjectId& target)
{
    if (!world.isAlive(target)) return;

    Vector3 target_pos = world.getPosition(target);
    Vector3 target_vel = world.getVelocity(target);

    Vector3 aim_dir = steeringBehaviour->getAimDirection(getShip().getPosition(),
                      Bullet::SPEED,
                      target_pos,
                      target_vel);
    double angle = getShip().getVelocity().getAngleSafe(aim_dir);
    if (angle <= SHOOT_ANGLE_RADIANS_MAX && getShip().isReloaded())
    {
        getShipAi().markFireBulletDesired();
        //printf("\tShooting at (%f, %f, %f)\n", target_pos.x, target_pos.y, target_pos.z);
    };
}
示例#4
0
Vector3 SteeringBehaviour :: evade (const WorldInterface& world,
                                    const PhysicsObjectId& id_target)
{
	assert(id_target != PhysicsObjectId::ID_NOTHING);

	// no initialization needed
	m_steering_behaviour = EVADE;

	if(!world.isAlive(m_id_agent) ||
	   !world.isAlive(  id_target))
	{
		assert(invariant());
		return Vector3::ZERO;
	}

	Vector3 agent_position  = world.getPosition(m_id_agent);
	Vector3 target_position = world.getPosition(  id_target);

	if(agent_position == target_position)
	{
		assert(invariant());
		return Vector3::ZERO;
	}

	assert(world.isAlive(m_id_agent ));
	assert(world.isAlive(  id_target));
	Vector3 target_velocity   = world.getVelocity(id_target);
	double  agent_speed_max   = world.getShipSpeedMax(m_id_agent);
	assert(agent_speed_max >= 0.0);
	Vector3 aim_direction = getAimDirection(agent_position,
	                                        agent_speed_max,
	                                        target_position,
	                                        target_velocity);
	if(aim_direction.isZero())
	{
		assert(invariant());
		return (agent_position - target_position).getCopyWithNorm(agent_speed_max);
	}
	else
	{
		assert(invariant());
		return aim_direction * -agent_speed_max;
	}
}
示例#5
0
Vector3 SteeringBehaviour :: aim (const WorldInterface& world,
                                  const PhysicsObjectId& id_target,
                                  double shot_speed)
{
	assert(id_target != PhysicsObjectId::ID_NOTHING);
	assert(shot_speed >= 0.0);

	// no initialization needed
	m_steering_behaviour = AIM;

	if(!world.isAlive(m_id_agent) ||
	   !world.isAlive(  id_target))
	{
		assert(invariant());
		return Vector3::ZERO;
	}

	Vector3 agent_position  = world.getPosition(m_id_agent);
	Vector3 target_position = world.getPosition(  id_target);

	if(agent_position == target_position)
	{
		assert(invariant());
		return Vector3::ZERO;
	}

	assert(world.isAlive(m_id_agent ));
	assert(world.isAlive(  id_target));
	double  agent_speed_max = world.getShipSpeedMax(m_id_agent);
	assert(agent_speed_max >= 0.0);
	Vector3 target_velocity = world.getVelocity(id_target);
	Vector3   aim_direction = getAimDirection(agent_position, shot_speed, target_position, target_velocity);

	assert(invariant());
	return aim_direction * agent_speed_max;
}