Exemplo n.º 1
0
UnitAiMoonGuard :: UnitAiMoonGuard (const AiShipReference& ship,
                                    const WorldInterface& world,
                                    const PhysicsObjectId& id_moon)
    : UnitAiSuperclass(ship)
{
    assert(ship.isShip());
    assert(id_moon.m_type == PhysicsObjectId::TYPE_PLANETOID);
    assert(world.isAlive(id_moon));
    assert(world.isPlanetoidMoon(id_moon));

    steeringBehaviour = new FleetName::SteeringBehaviour(ship.getId());
    moon = id_moon;
    scanCount = rand() % SCAN_COUNT_MAX;

}
Exemplo n.º 2
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;
}
Exemplo n.º 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);
    };
}
Exemplo n.º 4
0
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();
    }
}
Exemplo n.º 5
0
Vector3 SteeringBehaviour :: explore (const WorldInterface& world,
                                      double distance_new_position_min,
                                      double distance_new_position_max)
{
	assert(distance_new_position_min >= 0.0);
	assert(distance_new_position_min <= distance_new_position_max);
	assert(distance_new_position_min >  EXPLORE_DISTANCE_NEW_POSITION);

	double position_distance           = (distance_new_position_max + distance_new_position_min) * 0.5;
	double position_distance_tolerance = (distance_new_position_max - distance_new_position_min) * 0.5;

	bool is_new_position_needed = false;
	if(m_steering_behaviour         != EXPLORE ||
	   m_desired_distance           != position_distance ||
	   m_desired_distance_tolerance != position_distance_tolerance)
	{
		m_steering_behaviour         = EXPLORE;
		m_desired_distance           = position_distance;
		m_desired_distance_tolerance = position_distance_tolerance;
		is_new_position_needed       = true;
	}

	if(!world.isAlive(m_id_agent))
	{
		// the explore position doesn't matter at this point

		assert(invariant());
		return Vector3::ZERO;
	}

	Vector3 agent_position = world.getPosition(m_id_agent);
	double agent_speed_max = world.getShipSpeedMax(m_id_agent);
	assert(agent_speed_max >= 0.0);

	if(agent_position.isDistanceLessThan(m_explore_position, EXPLORE_DISTANCE_NEW_POSITION) ||
	   is_new_position_needed)
	{
		m_explore_position = calculateExplorePosition(agent_position);
	}

	return (m_explore_position - agent_position).getCopyWithNorm(agent_speed_max);
}
Exemplo n.º 6
0
Vector3 UnitAiMoonGuard::chargeAtTarget(const WorldInterface& world, const PhysicsObjectId& target, const Vector3& orig_velocity)
{
    if (!world.isAlive(target))
    {
        return orig_velocity;
    }

    Vector3 unit_pos = getShip().getPosition();
    Vector3 target_pos = world.getPosition(target);
    Vector3 target_forward = world.getForward(target);


    //Vector3 desired_velocity = steeringBehaviour->seek(world, target);
    Vector3 desired_velocity = steeringBehaviour->aim(world, target, Bullet::SPEED);
    //Vector3 desired_velocity = steeringBehaviour->escort(world, target, -target_forward * 50);
    Vector3 v = avoidPlanetoids(world, desired_velocity);

    //printf("\tRamming\n");
    return v;
}
Exemplo n.º 7
0
Vector3 SteeringBehaviour :: calculateEscortPosition (const WorldInterface& world,
                                                      const PhysicsObjectId& id_target,
                                                      const Vector3& offset) const
{
	assert(m_steering_behaviour == ESCORT);
	assert(id_target != PhysicsObjectId::ID_NOTHING);

	if(!world.isAlive(id_target))
		return Vector3::ZERO;

	Vector3 target_position = world.getPosition(id_target);
	Vector3 target_forward  = world.getForward (id_target);
	Vector3 target_up       = world.getUp      (id_target);
	Vector3 target_right    = world.getRight   (id_target);

	return target_position +
	       target_forward * offset.x +
	       target_up      * offset.y +
	       target_right   * offset.z;
}
Exemplo n.º 8
0
Vector3 UnitAiMoonGuard::avoidShips(const WorldInterface &world, const Vector3& orig_velocity)
{
    if (nearestShip == PhysicsObjectId::ID_NOTHING ||
            !world.isAlive(nearestShip) ||
            nearestShip == nearestEnemyShip)
    {
        return orig_velocity;
    }

    Vector3 target_pos = world.getPosition(nearestShip);
    double target_radius = world.getRadius(nearestShip);

    Vector3 v = steeringBehaviour->avoid(world,
                                         orig_velocity,
                                         target_pos,
                                         target_radius,
                                         SHIP_CLEARANCE,
                                         SHIP_AVOID_DISTANCE);
    //printf("\tAvoiding Ships\n");
    return v;
}
Exemplo n.º 9
0
void UnitAiMoonGuard::getClosestEnemyShip(const WorldInterface& world)
{
    PhysicsObjectId nearestShip;
    Vector3 ship_pos = getShip().getPosition();

    double min_distance = std::numeric_limits<double>::max();
    nearestShip = PhysicsObjectId::ID_NOTHING;
    for (int i = 0; i < nearbyShips.size(); i++)
    {
        if (!world.isAlive(nearbyShips[i])) continue;
        if (nearbyShips[i].m_fleet == getShipId().m_fleet) continue;

        double temp = ship_pos.getDistanceSquared(world.getPosition(nearbyShips[i]));
        if (temp < min_distance)
        {
            min_distance = temp;
            nearestShip = nearbyShips[i];
        }
    }

    this->nearestEnemyShip = nearestShip;
}
Exemplo n.º 10
0
Vector3 SteeringBehaviour :: arrive (const WorldInterface& world,
                                     const Vector3& target_position)
{
	// no initialization needed
	m_steering_behaviour = ARRIVE;

	PhysicsObjectId id_agent = m_id_agent;

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

	Vector3 agent_position = world.getPosition(id_agent);

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

	double agent_speed = world.getShipSpeedMax(id_agent);
	assert(agent_speed >= 0.0);
	double agent_acceleration = world.getShipAcceleration(id_agent);
	assert(agent_acceleration >= 0.0);

	double distance       = agent_position.getDistance(target_position);
	double max_safe_speed = calculateMaxSafeSpeed(distance, agent_acceleration);
	if(max_safe_speed < agent_speed)
		agent_speed = max_safe_speed;
	assert(agent_speed >= 0.0);
	assert(agent_speed <= max_safe_speed);

	assert(invariant());
	return (target_position - agent_position).getCopyWithNorm(agent_speed);
}
Exemplo n.º 11
0
Vector3 SteeringBehaviour :: flee (const WorldInterface& world,
                                   const Vector3& target_position)
{
	// no initialization needed
	m_steering_behaviour = FLEE;

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

	Vector3 agent_position = world.getPosition(m_id_agent);

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

	double agent_speed_max = world.getShipSpeedMax(m_id_agent);
	assert(agent_speed_max >= 0.0);
	return (agent_position - target_position).getCopyWithNorm(agent_speed_max);
}
Exemplo n.º 12
0
// avoid only when going to collide
Vector3 SteeringBehaviour :: avoid (const WorldInterface& world,
                                    const Vector3& original_velocity,
                                    const Vector3& sphere_center,
                                    double sphere_radius,
                                    double clearance,
                                    double avoid_distance) const
{
	assert(sphere_radius >= 0.0);
	assert(clearance > 0.0);
	assert(clearance <= avoid_distance);

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

	Vector3 agent_position    = world.getPosition(m_id_agent);
	double  agent_radius      = world.getRadius(m_id_agent);
	double  desired_speed     = world.getShipSpeedMax(m_id_agent);
	Vector3 relative_position = sphere_center - agent_position;
	double  radius_sum        = sphere_radius + agent_radius;

	if(relative_position.isNormGreaterThan(radius_sum + avoid_distance))
	{
		if(DEBUGGING_AVOID)
			cout << "Avoid: Outside avoid distance" << endl;
		assert(invariant());
		return original_velocity.getTruncated(desired_speed);  // too far away to worry about
	}

	Vector3 agent_forward = world.getForward(m_id_agent);

	if(relative_position.dotProduct(agent_forward) < 0.0)
	{
		// past center of object; no cylinder
		if(DEBUGGING_AVOID)
			cout << "Avoid: Departing from object" << endl;

		if(relative_position.isNormLessThan(radius_sum + clearance))
		{
			// we are too close, so flee and slow down

			double distance_fraction = (relative_position.getNorm() - radius_sum) / clearance;
			if(DEBUGGING_AVOID)
				cout << "\tInside panic distance: fraction = " << distance_fraction << endl;
			if(distance_fraction < 0.0)
				distance_fraction = 0.0;

			Vector3 interpolated =  original_velocity.getNormalized() *        distance_fraction +
			                       -relative_position.getNormalized() * (1.0 - distance_fraction);

			if(distance_fraction > AVOID_SPEED_FACTOR_MIN)
				desired_speed *= distance_fraction;
			else
				desired_speed *= AVOID_SPEED_FACTOR_MIN;

			if(original_velocity.isNormLessThan(desired_speed))
				desired_speed = original_velocity.getNorm();

			assert(invariant());
			return interpolated.getCopyWithNorm(desired_speed);
		}
		else
		{
			if(DEBUGGING_AVOID)
				cout << "\tPast object" << endl;
			assert(invariant());
			return original_velocity.getTruncated(desired_speed);  // far enough past object
		}
	}
	else
	{
		// have not reached center of object; check against cylinder
		if(DEBUGGING_AVOID)
			cout << "Avoid: Approaching object" << endl;

		double distance_from_cylinder_center = relative_position.getAntiProjection(agent_forward).getNorm();
		double clearance_fraction            = (distance_from_cylinder_center - radius_sum) / clearance;
		if(DEBUGGING_AVOID)
		{
			cout << "\tTo sphere:         " << relative_position << endl;
			cout << "\tDistance_from_cylinder_center: " << distance_from_cylinder_center << endl;
			cout << "\tRadius_sum:        " << radius_sum << endl;
			cout << "\tClearance:         " << clearance << endl;
			cout << "\tFraction:          " << clearance_fraction << endl;
		}

		if(clearance_fraction < 0.0)
		{
			clearance_fraction = 0.0;
			if(DEBUGGING_AVOID)
				cout << "\tLined up at sphere" << endl;
		}

		if(clearance_fraction > 1.0)
		{
			if(DEBUGGING_AVOID)
				cout << "\tOutside cylinder" << endl;
			assert(invariant());
			return original_velocity;  // outside of danger cylinder
		}
		if(DEBUGGING_AVOID)
			cout << "\tModified fraction: " << clearance_fraction << endl;

		assert(!original_velocity.isZero());
		assert(!agent_forward.isZero());
		Vector3 sideways_vector = -relative_position.getAntiProjection(agent_forward);
		while(sideways_vector.isNormLessThan(AVOID_SIDEWAYS_NORM_MIN))
		{
			// we have almost no sideways, so use a random value
			sideways_vector = Vector3::getRandomUnitVector().getAntiProjection(agent_forward);
			// keep trying until we get a good one
		}
		assert(!original_velocity.isZero());
		assert(!sideways_vector.isZero());
		assert(sideways_vector.isOrthogonal(agent_forward));
		if(DEBUGGING_AVOID)
			cout << "\tSideways: " << sideways_vector << endl;

		Vector3 interpolated = original_velocity.getNormalized() *        clearance_fraction +
		                       sideways_vector  .getNormalized() * (1.0 - clearance_fraction);

		if(original_velocity.isNormLessThan(desired_speed))
			desired_speed = original_velocity.getNorm();

		if(DEBUGGING_AVOID)
			cout << "\tDodging out of cylinder: " << interpolated.getCopyWithNorm(desired_speed) << endl;
		assert(invariant());
		return interpolated.getCopyWithNorm(desired_speed);
	}
}
Exemplo n.º 13
0
Vector3 SteeringBehaviour :: patrolSphere (const WorldInterface& world,
                                           const Vector3& sphere_center,
                                           double patrol_radius,
                                           double patrol_radius_tolerance)
{
	assert(patrol_radius >= 0.0);
	assert(patrol_radius_tolerance >= 0.0);

	bool is_new_position_needed = false;
	if(m_steering_behaviour         != PATROL_SPHERE ||
	   m_sphere_center              != sphere_center ||
	   m_desired_distance           != patrol_radius ||
	   m_desired_distance_tolerance != patrol_radius_tolerance)
	{
		m_steering_behaviour         = PATROL_SPHERE;
		m_sphere_center              = sphere_center;
		m_desired_distance           = patrol_radius;
		m_desired_distance_tolerance = patrol_radius_tolerance;
		is_new_position_needed       = true;
	}

	if(!world.isAlive(m_id_agent))
	{
		// the explore position doesn't matter at this point

		assert(invariant());
		return Vector3::ZERO;
	}

	Vector3 agent_position = world.getPosition(m_id_agent);

	if(isNearEnoughPatrolSpherePoint(agent_position) ||
	   is_new_position_needed)
	{
		m_explore_position = calculatePatrolSpherePosition(agent_position);
	}

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

	if(DEBUGGING_PATROL_SPHERE)
	{
		cout << "Explore:" << endl;
		cout << "\tAgent position:   " << agent_position << endl;
		cout << "\tSphere position:  " << m_sphere_center << endl;
		cout << "\tExplore position: " << m_explore_position << endl;
	}

	double distance_from_sphere = agent_position.getDistance(m_sphere_center);

	double weight_parallel = 1.0;
	if(m_desired_distance_tolerance > 0.0)
	{
		double distance_outside_optimum = distance_from_sphere - m_desired_distance;

		weight_parallel = distance_outside_optimum / m_desired_distance_tolerance;
		if(weight_parallel > 1.0)
			weight_parallel = 1.0;
		if(weight_parallel < -1.0)
			weight_parallel = -1.0;

		if(DEBUGGING_PATROL_SPHERE)
		{
				cout << "\tSphere distance:  " << distance_from_sphere << endl;
				cout << "\tDesired distance: " << m_desired_distance << endl;
				cout << "\tTolerance:        " << m_desired_distance_tolerance << endl;
				cout << "\tweight_parallel:      " << weight_parallel << endl;
		}

		if(weight_parallel >= 0.0)
			weight_parallel =   weight_parallel * weight_parallel;
		else
			weight_parallel = -(weight_parallel * weight_parallel);

		if(DEBUGGING_PATROL_SPHERE)
				cout << "\t                   => " << weight_parallel << endl;

		assert(weight_parallel <=  1.0);
		assert(weight_parallel >= -1.0);
	}
	assert(weight_parallel <=  1.0);
	assert(weight_parallel >= -1.0);
	double weight_perpendicular = 1.0 - fabs(weight_parallel);
	assert(weight_perpendicular <=  1.0);
	assert(weight_perpendicular >= -1.0);

	if(DEBUGGING_PATROL_SPHERE)
		cout << "\tweight_perpendicular: " << weight_perpendicular << endl;

	Vector3 to_sphere               = m_sphere_center    - agent_position;
	Vector3 to_destination          = m_explore_position - agent_position;
	Vector3 parallel_to_normal      = to_destination.getProjection(to_sphere);
	Vector3 perpendicular_to_normal = to_destination - parallel_to_normal;
	Vector3 desired_vector          = parallel_to_normal      * weight_parallel +
	                                  perpendicular_to_normal * weight_perpendicular;

	assert(invariant());
	return desired_vector.getCopyWithNormSafe(agent_speed_max);
}