Clean up ArenaAI

This commit is contained in:
Benau 2016-09-27 12:38:36 +08:00
parent 6f67fd6507
commit 3030b679df
6 changed files with 70 additions and 71 deletions

View File

@ -51,12 +51,12 @@ void ArenaAI::reset()
m_closest_kart = NULL;
m_closest_kart_node = Graph::UNKNOWN_SECTOR;
m_closest_kart_point = Vec3(0, 0, 0);
m_closest_kart_pos_data = {0};
m_cur_kart_pos_data = {0};
m_is_stuck = false;
m_is_uturn = false;
m_avoiding_item = false;
m_mini_skid = false;
m_target_point = Vec3(0, 0, 0);
m_target_point_lc = Vec3(0, 0, 0);
m_time_since_last_shot = 0.0f;
m_time_since_driving = 0.0f;
m_time_since_reversing = 0.0f;
@ -102,6 +102,10 @@ void ArenaAI::update(float dt)
findClosestKart(true);
findTarget();
// After found target, convert it to local coordinate, used for skidding or
// u-turn
m_target_point_lc = m_kart->getTrans().inverse()(m_target_point);
handleArenaItems(dt);
if (m_kart->getSpeed() > 15.0f && m_turn_angle < 20)
@ -201,13 +205,13 @@ void ArenaAI::handleArenaSteering(const float dt)
if (ignorePathFinding())
{
// Steer directly
checkPosition(m_target_point, &m_cur_kart_pos_data);
#ifdef AI_DEBUG
m_debug_sphere->setPosition(m_target_point.toIrrVector());
#endif
if (m_cur_kart_pos_data.behind)
if (m_target_point_lc.z() < 0)
{
m_adjusting_side = m_cur_kart_pos_data.lhs;
// Local coordinate z < 0 == target point is behind
m_adjusting_side = m_target_point_lc.x() < 0;
m_is_uturn = true;
}
else
@ -224,16 +228,16 @@ void ArenaAI::handleArenaSteering(const float dt)
updateTurnRadius(m_kart->getXYZ(), m_aiming_points[0],
m_aiming_points[1]);
m_target_point = m_aiming_points[1];
checkPosition(m_target_point, &m_cur_kart_pos_data);
m_target_point_lc = m_kart->getTrans().inverse()(m_target_point);
#ifdef AI_DEBUG
m_debug_sphere->setVisible(true);
m_debug_sphere_next->setVisible(true);
m_debug_sphere->setPosition(m_aiming_points[0].toIrrVector());
m_debug_sphere_next->setPosition(m_aiming_points[1].toIrrVector());
#endif
if (m_cur_kart_pos_data.behind)
if (m_target_point_lc.z() < 0)
{
m_adjusting_side = m_cur_kart_pos_data.lhs;
m_adjusting_side = m_target_point_lc.x() < 0;
m_is_uturn = true;
}
else
@ -324,10 +328,10 @@ void ArenaAI::handleArenaUTurn(const float dt)
setSteering(turn_side, dt);
m_time_since_uturn += dt;
checkPosition(m_target_point, &m_cur_kart_pos_data);
if (!m_cur_kart_pos_data.behind || m_time_since_uturn >
if (m_target_point_lc.z() > 0 || m_time_since_uturn >
(m_cur_difficulty == RaceManager::DIFFICULTY_EASY ? 3.5f : 3.0f))
{
// End U-turn until target point is in front of this AI
m_is_uturn = false;
m_time_since_uturn = 0.0f;
}
@ -376,9 +380,8 @@ void ArenaAI::updateBadItemLocation()
selected->getType() == Item::ITEM_BUBBLEGUM ||
selected->getType() == Item::ITEM_BUBBLEGUM_NOLOK))
{
Vec3 bad_item_lc;
checkPosition(selected->getXYZ(), NULL, &bad_item_lc,
true/*use_front_xyz*/);
Vec3 bad_item_lc =
m_kart->getTrans().inverse()(selected->getXYZ());
// If satisfy the below condition, AI should not be affected by it:
// bad_item_lc.z() < 0.0f, behind the kart
@ -501,18 +504,28 @@ void ArenaAI::handleArenaItems(const float dt)
// Find a closest kart again, this time we ignore difficulty
findClosestKart(false);
if (!m_closest_kart) return;
Vec3 closest_kart_point_lc =
m_kart->getTrans().inverse()(m_closest_kart_point);
m_time_since_last_shot += dt;
float min_bubble_time = 2.0f;
const bool difficulty = m_cur_difficulty == RaceManager::DIFFICULTY_EASY ||
m_cur_difficulty == RaceManager::DIFFICULTY_MEDIUM;
const bool fire_behind = m_closest_kart_pos_data.behind && !difficulty;
const bool fire_behind = closest_kart_point_lc.z() < 0 && !difficulty;
const bool perfect_aim = m_closest_kart_pos_data.angle < 0.2f;
const float abs_angle = atan2f(fabsf(closest_kart_point_lc.x()),
fabsf(closest_kart_point_lc.z()));
const bool perfect_aim = abs_angle < 0.2f;
// Compensate the distance because this distance is straight to straight
// in graph node, so if kart to kart are not facing like so as, their real
// distance maybe smaller
const float dist_to_kart =
getKartDistance(m_closest_kart->getWorldKartId()) * 0.8f;
switch(m_kart->getPowerup()->getType())
{
@ -530,7 +543,7 @@ void ArenaAI::handleArenaItems(const float dt)
if ((!m_kart->isShielded() &&
projectile_manager->projectileIsClose(m_kart,
m_ai_properties->m_shield_incoming_radius)) ||
(m_closest_kart_pos_data.distance < 15.0f &&
(dist_to_kart < 15.0f &&
((m_closest_kart->getAttachment()->
getType() == Attachment::ATTACH_SWATTER) ||
(m_closest_kart->getAttachment()->
@ -544,11 +557,9 @@ void ArenaAI::handleArenaItems(const float dt)
// Avoid dropping all bubble gums one after another
if (m_time_since_last_shot < 3.0f) break;
// Use bubblegum if the next kart behind is 'close' but not too close,
// Use bubblegum if the kart around is close,
// or can't find a close kart for too long time
if ((m_closest_kart_pos_data.distance < 15.0f &&
m_closest_kart_pos_data.distance > 3.0f) ||
m_time_since_last_shot > 15.0f)
if (dist_to_kart < 15.0f || m_time_since_last_shot > 15.0f)
{
m_controls->m_fire = true;
m_controls->m_look_back = true;
@ -566,7 +577,7 @@ void ArenaAI::handleArenaItems(const float dt)
// Leave some time between shots
if (m_time_since_last_shot < 1.0f) break;
if (m_closest_kart_pos_data.distance < 25.0f &&
if (dist_to_kart < 25.0f &&
!m_closest_kart->isInvulnerable())
{
m_controls->m_fire = true;
@ -586,7 +597,7 @@ void ArenaAI::handleArenaItems(const float dt)
// Leave some time between shots
if (m_time_since_last_shot < 1.0f) break;
if (m_closest_kart_pos_data.distance < 6.0f &&
if (dist_to_kart < 6.0f &&
(difficulty || perfect_aim) &&
!m_closest_kart->isInvulnerable())
{
@ -607,7 +618,7 @@ void ArenaAI::handleArenaItems(const float dt)
break;
if (!m_closest_kart->isSquashed() &&
m_closest_kart_pos_data.distance < d2 &&
dist_to_kart * dist_to_kart < d2 &&
m_closest_kart->getSpeed() < m_kart->getSpeed())
{
m_controls->m_fire = true;

View File

@ -22,7 +22,7 @@
#include "karts/controller/ai_base_controller.hpp"
#include "race/race_manager.hpp"
#undef AI_DEBUG
#define AI_DEBUG
#ifdef AI_DEBUG
#include "graphics/irr_driver.hpp"
#endif
@ -41,14 +41,14 @@ namespace irr
class ArenaAI : public AIBaseController
{
protected:
ArenaGraph* m_graph;
/** Pointer to the closest kart around this kart. */
AbstractKart *m_closest_kart;
int m_closest_kart_node;
Vec3 m_closest_kart_point;
posData m_closest_kart_pos_data;
/** Holds the current difficulty. */
RaceManager::Difficulty m_cur_difficulty;
@ -57,7 +57,7 @@ protected:
irr::scene::ISceneNode *m_debug_sphere;
irr::scene::ISceneNode *m_debug_sphere_next;
/** The node(poly) at which the target point lies in. */
/** The node(quad) at which the target point lies in. */
int m_target_node;
/** The target point. */
@ -68,13 +68,11 @@ protected:
void collectItemInArena(Vec3*, int*) const;
float findAngleFrom3Edges(float a, float b, float c);
private:
ArenaGraph* m_graph;
/** Used by handleArenaUTurn, it tells whether to do left or right
* turning when steering is overridden. */
bool m_adjusting_side;
posData m_cur_kart_pos_data;
Vec3 m_target_point_lc;
/** Indicates that the kart is currently stuck, and m_time_since_reversing is
* counting down. */
@ -109,6 +107,8 @@ private:
std::set<int> m_aiming_nodes;
std::vector<Vec3> m_aiming_points;
bool m_mini_skid;
void checkIfStuck(const float dt);
void handleArenaAcceleration(const float dt);
void handleArenaBraking();
@ -125,8 +125,10 @@ private:
virtual void resetAfterStop() {};
virtual void findClosestKart(bool use_difficulty) = 0;
virtual void findTarget() = 0;
virtual float getKartDistance(int to_id) const = 0;
virtual bool forceBraking() { return m_avoiding_item; }
virtual bool ignorePathFinding() { return false; }
virtual bool canSkid(float steer_fraction) { return m_mini_skid; }
public:
ArenaAI(AbstractKart *kart);
virtual ~ArenaAI() {};

View File

@ -25,12 +25,10 @@
#include "karts/abstract_kart.hpp"
#include "karts/controller/kart_control.hpp"
#include "modes/three_strikes_battle.hpp"
#include "tracks/arena_graph.hpp"
#ifdef AI_DEBUG
#include "irrlicht.h"
#include <iostream>
using namespace irr;
using namespace std;
#endif
BattleAI::BattleAI(AbstractKart *kart)
@ -72,14 +70,11 @@ BattleAI::~BattleAI()
void BattleAI::reset()
{
ArenaAI::reset();
AIBaseController::reset();
m_mini_skid = false;
} // reset
//-----------------------------------------------------------------------------
void BattleAI::update(float dt)
{
m_mini_skid = false;
ArenaAI::update(dt);
} // update
@ -118,33 +113,19 @@ void BattleAI::findClosestKart(bool use_difficulty)
continue;
}
Vec3 d = kart->getXYZ() - m_kart->getXYZ();
if (d.length() <= distance)
float dist_to_kart = m_graph->getDistance(getCurrentNode(),
m_world->getKartNode(kart->getWorldKartId()));
if (dist_to_kart <= distance)
{
distance = d.length();
distance = dist_to_kart;
closest_kart_num = i;
}
}
const AbstractKart* closest_kart = m_world->getKart(closest_kart_num);
m_closest_kart = m_world->getKart(closest_kart_num);
m_closest_kart_node = m_world->getKartNode(closest_kart_num);
m_closest_kart_point = closest_kart->getXYZ();
m_closest_kart_point = m_closest_kart->getXYZ();
if (!use_difficulty)
{
m_closest_kart = m_world->getKart(closest_kart_num);
checkPosition(m_closest_kart_point, &m_closest_kart_pos_data);
// Do a mini-skid to closest kart only when firing target,
// not straight ahead, not too far, in front of it
// and with suitable difficulties.
if (m_closest_kart_pos_data.angle > 0.2f &&
m_closest_kart_pos_data.distance < 20.0f &&
!m_closest_kart_pos_data.behind &&
(m_cur_difficulty == RaceManager::DIFFICULTY_HARD ||
m_cur_difficulty == RaceManager::DIFFICULTY_BEST))
m_mini_skid = true;
}
} // findClosestKart
//-----------------------------------------------------------------------------
@ -166,8 +147,15 @@ int BattleAI::getCurrentNode() const
{
return m_world->getKartNode(m_kart->getWorldKartId());
} // getCurrentNode
//-----------------------------------------------------------------------------
bool BattleAI::isWaiting() const
{
return m_world->isStartPhase();
} // isWaiting
//-----------------------------------------------------------------------------
float BattleAI::getKartDistance(int to_id) const
{
return m_graph->getDistance(getCurrentNode(), m_world->getKartNode(to_id));
} // getKartDistance

View File

@ -24,8 +24,6 @@
#include "karts/controller/arena_ai.hpp"
class ThreeStrikesBattle;
class Vec3;
class Item;
/** The actual battle AI.
* \ingroup controller
@ -36,13 +34,11 @@ private:
/** Keep a pointer to world. */
ThreeStrikesBattle *m_world;
bool m_mini_skid;
virtual void findClosestKart(bool use_difficulty);
virtual void findTarget();
virtual int getCurrentNode() const;
virtual bool isWaiting() const;
virtual bool canSkid(float steer_fraction) { return m_mini_skid; }
virtual float getKartDistance(int to_id) const;
public:
BattleAI(AbstractKart *kart);
~BattleAI();

View File

@ -24,12 +24,10 @@
#include "karts/controller/kart_control.hpp"
#include "karts/kart_properties.hpp"
#include "modes/soccer_world.hpp"
#include "tracks/arena_graph.hpp"
#ifdef AI_DEBUG
#include "irrlicht.h"
#include <iostream>
using namespace irr;
using namespace std;
#endif
#ifdef BALL_AIM_DEBUG
@ -94,7 +92,6 @@ SoccerAI::~SoccerAI()
void SoccerAI::reset()
{
ArenaAI::reset();
AIBaseController::reset();
m_overtake_ball = false;
m_force_brake = false;
@ -154,11 +151,9 @@ void SoccerAI::findClosestKart(bool use_difficulty)
}
}
const AbstractKart* closest_kart = m_world->getKart(closest_kart_num);
m_closest_kart_node = m_world->getKartNode(closest_kart_num);
m_closest_kart_point = closest_kart->getXYZ();
m_closest_kart = m_world->getKart(closest_kart_num);
checkPosition(m_closest_kart_point, &m_closest_kart_pos_data);
m_closest_kart_node = m_world->getKartNode(closest_kart_num);
m_closest_kart_point = m_closest_kart->getXYZ();
} // findClosestKart
@ -457,8 +452,15 @@ int SoccerAI::getCurrentNode() const
{
return m_world->getKartNode(m_kart->getWorldKartId());
} // getCurrentNode
//-----------------------------------------------------------------------------
bool SoccerAI::isWaiting() const
{
return m_world->isStartPhase();
} // isWaiting
//-----------------------------------------------------------------------------
float SoccerAI::getKartDistance(int to_id) const
{
return m_graph->getDistance(getCurrentNode(), m_world->getKartNode(to_id));
} // getKartDistance

View File

@ -27,7 +27,6 @@
#endif
class SoccerWorld;
class Vec3;
/** The actual soccer AI.
* \ingroup controller
@ -64,6 +63,7 @@ private:
virtual void findTarget();
virtual void resetAfterStop() OVERRIDE { m_overtake_ball = false; }
virtual int getCurrentNode() const;
virtual float getKartDistance(int to_id) const;
virtual bool isWaiting() const;
virtual bool canSkid(float steer_fraction) { return false; }
virtual bool forceBraking() OVERRIDE