Skip to content

Commit

Permalink
Improve AI targeting by looking at the angle as well as the distance …
Browse files Browse the repository at this point in the history
…for switching targets.
  • Loading branch information
daid committed Jan 16, 2015
1 parent c984cc0 commit 72e37b8
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 38 deletions.
83 changes: 52 additions & 31 deletions src/cpuShip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ void CpuShip::update(float delta)
missile_fire_delay -= delta;

//Check the weapon state,
bool has_missiles = weapon_tubes > 0 && weapon_storage[MW_Homing] > 0;
bool has_beams = false;
has_missiles = weapon_tubes > 0 && weapon_storage[MW_Homing] > 0;
has_beams = false;
//If we have weapon tubes, load them with torpedoes
for(int n=0; n<weapon_tubes; n++)
{
Expand All @@ -57,7 +57,7 @@ void CpuShip::update(float delta)
has_missiles = true;
}

float beam_weapon_range = 0;
beam_weapon_range = 0;
for(int n=0; n<maxBeamWeapons; n++)
{
if (beamWeapons[n].range > 0)
Expand All @@ -73,18 +73,14 @@ void CpuShip::update(float delta)

P<SpaceObject> target = getTarget();
P<SpaceObject> new_target;
float target_distance = 0.0;
if (target && target->hideInNebula() && (target->getPosition() - getPosition()) > 5000.0f && Nebula::blockedByNebula(getPosition(), target->getPosition()))
{
if (orders == AI_Roaming)
order_target_location = target->getPosition();
target = NULL;
}

if (target)
target_distance = sf::length(target->getPosition() - getPosition());

//Find new target
//Find new target which we might switch to
if (orders == AI_Roaming)
new_target = findBestTarget(getPosition(), 8000);
if (orders == AI_StandGround || orders == AI_FlyTowards)
Expand All @@ -104,9 +100,11 @@ void CpuShip::update(float delta)
}
if (orders == AI_Attack)
new_target = order_target;

//Check if we need to drop the current target
if (target)
{
float target_distance = sf::length(target->getPosition() - getPosition());
if (orders == AI_Idle)
target = NULL;
if (orders == AI_StandGround && target_distance > 8000)
Expand All @@ -129,21 +127,10 @@ void CpuShip::update(float delta)
//Check if we want to switch to a new target
if (new_target)
{
float new_distance = sf::length(new_target->getPosition() - getPosition());
P<SpaceStation> station = target;
if (station)
if (!target || betterTarget(new_target, target))
{
if (target_distance > new_distance - 5000)
{
target = new_target;
targetId = new_target->getMultiplayerId();
}
}else{
if (!target || (target_distance > new_distance * 1.5f && new_distance > 1500.0))
{
target = new_target;
targetId = new_target->getMultiplayerId();
}
target = new_target;
targetId = new_target->getMultiplayerId();
}
}

Expand Down Expand Up @@ -335,7 +322,7 @@ void CpuShip::update(float delta)

P<SpaceObject> CpuShip::findBestTarget(sf::Vector2f position, float radius)
{
float target_distance = 0.0;
float target_score = 0.0;
PVector<Collisionable> objectList = CollisionManager::queryArea(position - sf::Vector2f(radius, radius), position + sf::Vector2f(radius, radius));
P<SpaceObject> target;
foreach(Collisionable, obj, objectList)
Expand All @@ -345,21 +332,55 @@ P<SpaceObject> CpuShip::findBestTarget(sf::Vector2f position, float radius)
continue;
if (space_object->hideInNebula() && (space_object->getPosition() - getPosition()) > 5000.0f && Nebula::blockedByNebula(getPosition(), space_object->getPosition()))
continue;
float distance = sf::length(space_object->getPosition() - position);
if (distance > radius)
continue;
P<SpaceStation> station = space_object;
if (station)
distance += 5000;
if (!target || target_distance > distance)
float score = targetScore(space_object);
if (!target || score > target_score)
{
target = space_object;
target_distance = distance;
target_score = score;
}
}
return target;
}

float CpuShip::targetScore(P<SpaceObject> target)
{
sf::Vector2f position_difference = target->getPosition() - getPosition();
float distance = sf::length(position_difference);
//sf::Vector2f position_difference_normal = position_difference / distance;
//float rel_velocity = dot(target->getVelocity(), position_difference_normal) - dot(getVelocity(), position_difference_normal);
float angle_difference = sf::angleDifference(getRotation(), sf::vector2ToAngle(position_difference));
float score = -distance - fabsf(angle_difference / rotationSpeed * impulseMaxSpeed) * 1.5f;
if (P<SpaceStation>(target))
score -= 5000;
if (distance < 5000 && has_missiles)
score += 500;
/*
if (distance < beam_weapon_range)
{
for(int n=0; n<maxBeamWeapons; n++)
{
if (distance < beamWeapons[n].range)
{
//if (sf::angleDifference(angle_difference, beamWeapons[n].direction) < beamWeapons[n].arc / 2.0f)
// score += 1000;
}
}
}
*/
return score;
}

bool CpuShip::betterTarget(P<SpaceObject> new_target, P<SpaceObject> current_target)
{
float new_score = targetScore(new_target);
float current_score = targetScore(current_target);
if (new_score > current_score * 1.5f)
return true;
if (new_score > current_score + 5000.0f)
return true;
return false;
}

void CpuShip::orderIdle()
{
orders = AI_Idle;
Expand Down
11 changes: 9 additions & 2 deletions src/cpuShip.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ class CpuShip : public SpaceShip
sf::Vector2f order_target_location; //Server only
P<SpaceObject> order_target; //Server only
float missile_fire_delay;

bool has_missiles;//Server only, updated every update
bool has_beams;//Server only, updated every update
float beam_weapon_range;//Server only, updated every update

PathPlanner pathPlanner;
public:
CpuShip();

virtual void update(float delta);

P<SpaceObject> findBestTarget(sf::Vector2f position, float radius);

void orderIdle();
void orderRoaming();
void orderStandGround();
Expand All @@ -47,6 +49,11 @@ class CpuShip : public SpaceShip
EAIOrder getOrder() { return orders; }

friend class GameMasterUI;

private:
P<SpaceObject> findBestTarget(sf::Vector2f position, float radius);
float targetScore(P<SpaceObject> target);
bool betterTarget(P<SpaceObject> new_target, P<SpaceObject> current_target);
};
string getAIOrderString(EAIOrder order);

Expand Down
2 changes: 1 addition & 1 deletion src/crewCommsUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void CrewCommsUI::drawCommsRadar()
if (InputHandler::mouseIsReleased(sf::Mouse::Left) && mouse.x > x)
{
P<SpaceObject> target;
float target_pixel_distance;
float target_pixel_distance = 0.0;
foreach(SpaceObject, obj, visible_objects)
{
if(obj == my_spaceship)
Expand Down
2 changes: 1 addition & 1 deletion src/crewScienceUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void CrewScienceUI::onCrewUI()
if (sf::length(diff) < 400)
{
P<SpaceObject> target;
float target_pixel_distance;
float target_pixel_distance = 0.0;
for(unsigned int n=0; n<scan_ghost.size(); n++)
{
P<SpaceObject> obj = scan_ghost[n].object;
Expand Down
8 changes: 7 additions & 1 deletion src/gameMasterUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ void GameMasterUI::onGui()
sf::VertexArray a(sf::Lines, 2);
a[0].position = sf::Vector2f(800, 450) + (cpuShip->getPosition() - view_position) / view_distance * 400.0f;
a[1].position = sf::Vector2f(800, 450) + (target->getPosition() - view_position) / view_distance * 400.0f;
a[0].color = a[1].color = sf::Color(255, 255, 255, 32);
a[0].color = a[1].color = sf::Color(255, 128, 128, 32);
window.draw(a);
}
sf::VertexArray a(sf::LinesStrip, cpuShip->pathPlanner.route.size() + 1);
Expand All @@ -191,6 +191,12 @@ void GameMasterUI::onGui()
}
window.draw(a);
}
if (selection.size() == 1 && P<CpuShip>(selection[0]))
{
P<CpuShip> cpu = selection[0];
sf::Vector2f pos = sf::Vector2f(800, 450) + (obj->getPosition() - view_position) / view_distance * 400.0f;
text(sf::FloatRect(pos.x, pos.y - 20.0f, 0.0f, 0.0f), string(cpu->targetScore(obj)), AlignCenter, 20);
}
}
sf::RectangleShape sidebackBackground(sf::Vector2f(300, 900));
sidebackBackground.setFillColor(sf::Color(0, 0, 0, 128));
Expand Down
4 changes: 2 additions & 2 deletions src/spaceship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,9 @@ void SpaceShip::update(float delta)
float rotationDiff = sf::angleDifference(getRotation(), targetRotation);

if (rotationDiff > 1.0)
setAngularVelocity(rotationSpeed);
setAngularVelocity(rotationSpeed * getSystemEffectiveness(SYS_Maneuver));
else if (rotationDiff < -1.0)
setAngularVelocity(-rotationSpeed);
setAngularVelocity(-rotationSpeed * getSystemEffectiveness(SYS_Maneuver));
else
setAngularVelocity(rotationDiff * rotationSpeed * getSystemEffectiveness(SYS_Maneuver));

Expand Down

0 comments on commit 72e37b8

Please sign in to comment.