Add doxygen for Arena and Battle AI
Plus some coding-style cleanup
This commit is contained in:
parent
b12f7a1079
commit
021509387d
@ -75,6 +75,8 @@ protected:
|
||||
float *radius) const;
|
||||
virtual void update (float delta);
|
||||
virtual void setSteering (float angle, float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return true if AI can skid now. */
|
||||
virtual bool canSkid(float steer_fraction) = 0;
|
||||
|
||||
public:
|
||||
|
@ -74,6 +74,7 @@ void ArenaAI::reset()
|
||||
/** This is the main entry point for the AI.
|
||||
* It is called once per frame for each AI and determines the behaviour of
|
||||
* the AI, e.g. steering, accelerating/braking, firing.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void ArenaAI::update(float dt)
|
||||
{
|
||||
@ -170,10 +171,7 @@ bool ArenaAI::updateAimingPosition(Vec3* target_point)
|
||||
m_debug_sphere_next->setVisible(false);
|
||||
#endif
|
||||
|
||||
// Notice: we use the point ahead of kart to determine next node,
|
||||
// to compensate the time difference between steering
|
||||
m_current_forward_point =
|
||||
m_kart->getTrans()(Vec3(0, 0, m_kart->getKartLength()));
|
||||
m_current_forward_point = m_kart->getTrans()(Vec3(0, 0, m_kart_length));
|
||||
|
||||
m_turn_radius = 0.0f;
|
||||
std::vector<int>* test_nodes = NULL;
|
||||
@ -238,7 +236,7 @@ bool ArenaAI::updateAimingPosition(Vec3* target_point)
|
||||
} // updateAimingPosition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function config the steering of AI.
|
||||
/** This function config the steering (\ref m_steering_angle) of AI.
|
||||
*/
|
||||
void ArenaAI::configSteering()
|
||||
{
|
||||
@ -294,6 +292,11 @@ void ArenaAI::configSteering()
|
||||
} // configSteering
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Determine whether AI is stuck, by checking if it stays on the same node for
|
||||
* a long period of time (see \ref m_on_node), or \ref isStuck() is true.
|
||||
* \param dt Time step size.
|
||||
* \return True if AI is stuck
|
||||
*/
|
||||
void ArenaAI::checkIfStuck(const float dt)
|
||||
{
|
||||
if (m_is_stuck) return;
|
||||
@ -312,8 +315,7 @@ void ArenaAI::checkIfStuck(const float dt)
|
||||
&& m_on_node.size() < 2 && !m_is_uturn &&
|
||||
fabsf(m_kart->getSpeed()) < 3.0f) || isStuck() == true)
|
||||
{
|
||||
// Check whether a kart stay on the same node for a period of time
|
||||
// Or crashed 3 times
|
||||
// AI is stuck, reset now and try to get unstuck at next frame
|
||||
m_on_node.clear();
|
||||
m_time_since_driving = 0.0f;
|
||||
AIBaseController::reset();
|
||||
@ -355,6 +357,8 @@ void ArenaAI::configSpeed()
|
||||
} // configSpeed
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Make AI reverse so that it faces in front of the last target point.
|
||||
*/
|
||||
void ArenaAI::doUTurn(const float dt)
|
||||
{
|
||||
float turn_angle = atan2f(m_target_point_lc.x(),
|
||||
@ -377,6 +381,10 @@ void ArenaAI::doUTurn(const float dt)
|
||||
} // doUTurn
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Function to let AI get unstuck.
|
||||
* \param dt Time step size.
|
||||
* \return True if getting stuck is needed to be done.
|
||||
*/
|
||||
bool ArenaAI::gettingUnstuck(const float dt)
|
||||
{
|
||||
if (!m_is_stuck || m_is_uturn) return false;
|
||||
@ -398,6 +406,10 @@ bool ArenaAI::gettingUnstuck(const float dt)
|
||||
} // gettingUnstuck
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Determine how AI should use its item, different \ref m_cur_difficulty will
|
||||
* have a corresponding strategy.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void ArenaAI::useItems(const float dt)
|
||||
{
|
||||
m_controls->setFire(false);
|
||||
@ -406,7 +418,7 @@ void ArenaAI::useItems(const float dt)
|
||||
return;
|
||||
|
||||
// Find a closest kart again, this time we ignore difficulty
|
||||
findClosestKart(false/*use_difficulty*/, false/*find_sta*/);
|
||||
findClosestKart(false/*consider_difficulty*/, false/*find_sta*/);
|
||||
if (!m_closest_kart) return;
|
||||
|
||||
Vec3 closest_kart_point_lc =
|
||||
@ -558,7 +570,12 @@ void ArenaAI::useItems(const float dt)
|
||||
} // useItems
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ArenaAI::collectItemInArena(Vec3* aim_point, int* target_node) const
|
||||
/** Try to collect item in arena, if no suitable item is found, like they are
|
||||
* swapped, it will follow closest kart instead.
|
||||
* \param[out] aim_point Location of item.
|
||||
* \param[out] target_node The node which item lied on.
|
||||
*/
|
||||
void ArenaAI::tryCollectItem(Vec3* aim_point, int* target_node) const
|
||||
{
|
||||
float distance = 999999.9f;
|
||||
Item* selected = (*target_node == Graph::UNKNOWN_SECTOR ? NULL :
|
||||
@ -611,13 +628,15 @@ void ArenaAI::collectItemInArena(Vec3* aim_point, int* target_node) const
|
||||
*aim_point = m_closest_kart_point;
|
||||
*target_node = m_closest_kart_node;
|
||||
}
|
||||
} // collectItemInArena
|
||||
} // tryCollectItem
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Determine if AI should skid: When it's close to target, but not straight
|
||||
* ahead, in front of it, same steering side and with suitable difficulties
|
||||
* which are in expert and supertux only.
|
||||
*/
|
||||
void ArenaAI::doSkiddingTest()
|
||||
{
|
||||
// Skid when close to target, but not straight ahead, in front of it, same
|
||||
// steering side and with suitable difficulties.
|
||||
const float abs_angle = atan2f(fabsf(m_target_point_lc.x()),
|
||||
fabsf(m_target_point_lc.z()));
|
||||
if ((m_cur_difficulty == RaceManager::DIFFICULTY_HARD ||
|
||||
@ -636,7 +655,7 @@ void ArenaAI::doSkiddingTest()
|
||||
/** Determine if the path to target needs to be changed to avoid bad items, it
|
||||
* will also set the turn radius based on the new path if necessary.
|
||||
* \param forward Forward node of current AI position.
|
||||
* \param path Default path to target.
|
||||
* \param[in,out] path Default path to follow, will be changed if needed.
|
||||
*/
|
||||
void ArenaAI::determinePath(int forward, std::vector<int>* path)
|
||||
{
|
||||
|
@ -32,7 +32,6 @@ class ArenaGraph;
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class ISceneNode; }
|
||||
namespace video { class ITexture; }
|
||||
}
|
||||
|
||||
/** A base class for AI that use navmesh to work.
|
||||
@ -41,12 +40,16 @@ namespace irr
|
||||
class ArenaAI : public AIBaseController
|
||||
{
|
||||
protected:
|
||||
/** Pointer to the \ref ArenaGraph. */
|
||||
ArenaGraph* m_graph;
|
||||
|
||||
/** Pointer to the closest kart around this kart. */
|
||||
AbstractKart *m_closest_kart;
|
||||
|
||||
/** The \ref ArenaNode at which the closest kart located on. */
|
||||
int m_closest_kart_node;
|
||||
|
||||
/** The closest kart location. */
|
||||
Vec3 m_closest_kart_point;
|
||||
|
||||
/** Holds the current difficulty. */
|
||||
@ -55,25 +58,39 @@ protected:
|
||||
/** For debugging purpose: a sphere indicating where the AI
|
||||
* is targeting at. */
|
||||
irr::scene::ISceneNode *m_debug_sphere;
|
||||
|
||||
/** For debugging purpose: a sphere indicating where the first
|
||||
* turning corner is located. */
|
||||
irr::scene::ISceneNode *m_debug_sphere_next;
|
||||
|
||||
/** The node(quad) at which the target point lies in. */
|
||||
/** The \ref ArenaNode at which the target point located on. */
|
||||
int m_target_node;
|
||||
|
||||
/** The target point. */
|
||||
/** The coordinates of target point. */
|
||||
Vec3 m_target_point;
|
||||
|
||||
/** True if AI can skid, currently only do when close to target, see
|
||||
* \ref doSkiddingTest(). */
|
||||
bool m_mini_skid;
|
||||
|
||||
void collectItemInArena(Vec3*, int*) const;
|
||||
virtual void findClosestKart(bool use_difficulty, bool find_sta) = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
void tryCollectItem(Vec3* aim_point, int* target_node) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Find the closest kart around this AI, implemented by sub-class.
|
||||
* \param consider_difficulty If take current difficulty into account.
|
||||
* \param find_sta If find \ref SpareTireAI only. */
|
||||
virtual void findClosestKart(bool consider_difficulty, bool find_sta) = 0;
|
||||
|
||||
private:
|
||||
/** Local coordinates of current target point. */
|
||||
Vec3 m_target_point_lc;
|
||||
|
||||
/** Save the last target point before reversing, so AI will end reversing
|
||||
* until facing in front of it. */
|
||||
Vec3 m_reverse_point;
|
||||
|
||||
/** Indicates that the kart is currently stuck, and m_time_since_reversing is
|
||||
* counting down. */
|
||||
/** Indicates that the kart is currently stuck, and m_time_since_reversing
|
||||
* is counting down. */
|
||||
bool m_is_stuck;
|
||||
|
||||
/** Indicates that the kart need a uturn to reach a node behind, and
|
||||
@ -99,39 +116,79 @@ private:
|
||||
/** This is a timer that counts when the kart start going off road. */
|
||||
float m_time_since_off_road;
|
||||
|
||||
/** Used to determine braking and nitro usage. */
|
||||
float m_turn_radius;
|
||||
|
||||
/** Used to determine if skidding can be done. */
|
||||
float m_steering_angle;
|
||||
|
||||
/** The point in front of the AI which distance is \ref m_kart_length, used
|
||||
* to compensate the time difference between steering when finding next
|
||||
* node. */
|
||||
Vec3 m_current_forward_point;
|
||||
|
||||
/** The \ref ArenaNode at which the forward point located on. */
|
||||
int m_current_forward_node;
|
||||
|
||||
void configSpeed();
|
||||
// ------------------------------------------------------------------------
|
||||
void configSteering();
|
||||
// ------------------------------------------------------------------------
|
||||
void checkIfStuck(const float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
void determinePath(int forward, std::vector<int>* path);
|
||||
// ------------------------------------------------------------------------
|
||||
void doSkiddingTest();
|
||||
// ------------------------------------------------------------------------
|
||||
void doUTurn(const float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
bool gettingUnstuck(const float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
bool updateAimingPosition(Vec3* target_point);
|
||||
// ------------------------------------------------------------------------
|
||||
void useItems(const float dt);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool canSkid(float steer_fraction) OVERRIDE
|
||||
{ return m_mini_skid; }
|
||||
{ return m_mini_skid; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Find a suitable target for this frame, implemented by sub-class. */
|
||||
virtual void findTarget() = 0;
|
||||
virtual bool forceBraking() { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** If true, AI will always try to brake for this frame. */
|
||||
virtual bool forceBraking() { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the current \ref ArenaNode the AI located on. */
|
||||
virtual int getCurrentNode() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the distance based on graph distance matrix to any kart.
|
||||
* \param kart \ref AbstractKart to check. */
|
||||
virtual float getKartDistance(const AbstractKart* kart) const = 0;
|
||||
virtual bool ignorePathFinding() { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** If true, AI will drive directly to target without path finding. */
|
||||
virtual bool ignorePathFinding() { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** If true, AI will stop moving. */
|
||||
virtual bool isWaiting() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** If true, AI stays on the \ref ArenaNode correctly, otherwise
|
||||
* \ref RescueAnimation will be done after sometime. */
|
||||
virtual bool isKartOnRoad() const = 0;
|
||||
virtual void resetAfterStop() {};
|
||||
// ------------------------------------------------------------------------
|
||||
/** Overridden if any action is needed to be done when AI stopped
|
||||
* moving or changed driving direction. */
|
||||
virtual void resetAfterStop() {}
|
||||
|
||||
public:
|
||||
ArenaAI(AbstractKart *kart);
|
||||
virtual ~ArenaAI() {};
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~ArenaAI() {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void update (float delta) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset () OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void newLap (int lap) OVERRIDE {}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -56,7 +56,6 @@ BattleAI::BattleAI(AbstractKart *kart)
|
||||
} // BattleAI
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
BattleAI::~BattleAI()
|
||||
{
|
||||
#ifdef AI_DEBUG
|
||||
@ -66,7 +65,12 @@ BattleAI::~BattleAI()
|
||||
} // ~BattleAI
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BattleAI::findClosestKart(bool use_difficulty, bool find_sta)
|
||||
/** Find the closest kart around this AI, if consider_difficulty is true, AI
|
||||
* will try to follow human players more or less depends on difficulty.
|
||||
* \param consider_difficulty If take current difficulty into account.
|
||||
* \param find_sta If find \ref SpareTireAI only.
|
||||
*/
|
||||
void BattleAI::findClosestKart(bool consider_difficulty, bool find_sta)
|
||||
{
|
||||
float distance = 99999.9f;
|
||||
int closest_kart_num = 0;
|
||||
@ -88,7 +92,8 @@ void BattleAI::findClosestKart(bool use_difficulty, bool find_sta)
|
||||
// Test whether takes current difficulty into account for closest kart
|
||||
// Notice: it don't affect aiming, this function will be called once
|
||||
// more when use items, which ignore difficulty.
|
||||
if (m_cur_difficulty == RaceManager::DIFFICULTY_EASY && use_difficulty)
|
||||
if (m_cur_difficulty == RaceManager::DIFFICULTY_EASY &&
|
||||
consider_difficulty)
|
||||
{
|
||||
// Skip human players for novice mode unless only they are left
|
||||
const AbstractKart* temp = m_world->getKart(start_id);
|
||||
@ -98,7 +103,7 @@ void BattleAI::findClosestKart(bool use_difficulty, bool find_sta)
|
||||
continue;
|
||||
}
|
||||
else if (m_cur_difficulty == RaceManager::DIFFICULTY_BEST &&
|
||||
use_difficulty)
|
||||
consider_difficulty)
|
||||
{
|
||||
// Skip AI players for supertux mode
|
||||
const AbstractKart* temp = m_world->getKart(start_id);
|
||||
@ -122,33 +127,44 @@ void BattleAI::findClosestKart(bool use_difficulty, bool find_sta)
|
||||
} // findClosestKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Find a suitable target to follow, it will find the closest kart first, it's
|
||||
* used as fallback if no item is found. It takes the current difficulty into
|
||||
* account, also collect life from \ref SpareTireAI depends on current
|
||||
* difficulty if actually they are spawned:
|
||||
* \li Novice and intermediate - collect them only AI has 1 life only.
|
||||
* \li Expert and supertux - collect them if AI dones't have 3 lives.
|
||||
*/
|
||||
void BattleAI::findTarget()
|
||||
{
|
||||
// Find the closest kart first, it's used as fallback if no item is found.
|
||||
// It takes the current difficulty into account, also collect life from
|
||||
// spare tire karts when neccessary
|
||||
bool find_sta = false;
|
||||
if (m_world->spareTireKartsSpawned())
|
||||
{
|
||||
switch (m_cur_difficulty)
|
||||
{
|
||||
case RaceManager::DIFFICULTY_EASY:
|
||||
case RaceManager::DIFFICULTY_MEDIUM:
|
||||
{
|
||||
find_sta = m_world->getKartLife(m_kart->getWorldKartId()) == 1;
|
||||
break;
|
||||
}
|
||||
case RaceManager::DIFFICULTY_HARD:
|
||||
case RaceManager::DIFFICULTY_BEST:
|
||||
{
|
||||
find_sta = m_world->getKartLife(m_kart->getWorldKartId()) != 3;
|
||||
break;
|
||||
}
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect life depends on current difficulty:
|
||||
// Novice and intermediate - collect them only AI has 1 life only
|
||||
// Expert and supertux - collect them if AI dones't have 3 lives
|
||||
// Also when actually spare tire karts are spawned
|
||||
bool find_sta = m_world->spareTireKartsSpawned() ?
|
||||
((m_cur_difficulty == RaceManager::DIFFICULTY_EASY ||
|
||||
m_cur_difficulty == RaceManager::DIFFICULTY_MEDIUM) &&
|
||||
m_world->getKartLife(m_kart->getWorldKartId()) == 1 ?
|
||||
true :
|
||||
(m_cur_difficulty == RaceManager::DIFFICULTY_HARD ||
|
||||
m_cur_difficulty == RaceManager::DIFFICULTY_BEST) &&
|
||||
m_world->getKartLife(m_kart->getWorldKartId()) != 3 ?
|
||||
true : false) : false;
|
||||
|
||||
findClosestKart(find_sta ? false : true/*use_difficulty*/, find_sta);
|
||||
bool consider_difficulty = !find_sta;
|
||||
findClosestKart(consider_difficulty, find_sta);
|
||||
|
||||
// Find a suitable target to drive to, either powerup or kart
|
||||
if (m_kart->getPowerup()->getType() == PowerupManager::POWERUP_NOTHING &&
|
||||
m_kart->getAttachment()->getType() != Attachment::ATTACH_SWATTER &&
|
||||
!find_sta)
|
||||
collectItemInArena(&m_target_point , &m_target_node);
|
||||
tryCollectItem(&m_target_point , &m_target_node);
|
||||
else
|
||||
{
|
||||
m_target_point = m_closest_kart_point;
|
||||
|
@ -33,16 +33,28 @@ class BattleAI : public ArenaAI
|
||||
protected:
|
||||
/** Keep a pointer to world. */
|
||||
ThreeStrikesBattle *m_world;
|
||||
virtual void findClosestKart(bool use_difficulty, bool find_sta) OVERRIDE;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void findClosestKart(bool consider_difficulty,
|
||||
bool find_sta) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual int getCurrentNode() const OVERRIDE;
|
||||
|
||||
private:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void findTarget() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual float getKartDistance(const AbstractKart* kart) const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool isKartOnRoad() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool isWaiting() const OVERRIDE;
|
||||
|
||||
public:
|
||||
BattleAI(AbstractKart *kart);
|
||||
// ------------------------------------------------------------------------
|
||||
~BattleAI();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -129,7 +129,7 @@ void SoccerAI::update(float dt)
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SoccerAI::findClosestKart(bool use_difficulty, bool find_sta)
|
||||
void SoccerAI::findClosestKart(bool consider_difficulty, bool find_sta)
|
||||
{
|
||||
float distance = 99999.9f;
|
||||
const unsigned int n = m_world->getNumKarts();
|
||||
@ -165,7 +165,7 @@ void SoccerAI::findClosestKart(bool use_difficulty, bool find_sta)
|
||||
//-----------------------------------------------------------------------------
|
||||
void SoccerAI::findTarget()
|
||||
{
|
||||
findClosestKart(true/*use_difficulty*/, false/*find_sta*/);
|
||||
findClosestKart(true/*consider_difficulty*/, false/*find_sta*/);
|
||||
// Check if this AI kart is the one who will chase the ball
|
||||
if (m_world->getBallChaser(m_cur_team) == (signed)m_kart->getWorldKartId())
|
||||
{
|
||||
@ -181,7 +181,7 @@ void SoccerAI::findTarget()
|
||||
if (m_kart->getPowerup()->getType() == PowerupManager::POWERUP_NOTHING &&
|
||||
m_kart->getAttachment()->getType() != Attachment::ATTACH_SWATTER)
|
||||
{
|
||||
collectItemInArena(&m_target_point , &m_target_node);
|
||||
tryCollectItem(&m_target_point , &m_target_node);
|
||||
}
|
||||
else if (m_world->getAttacker(m_cur_team) == (signed)m_kart
|
||||
->getWorldKartId())
|
||||
|
@ -65,7 +65,7 @@ private:
|
||||
|
||||
virtual bool canSkid(float steer_fraction) OVERRIDE
|
||||
{ return m_mini_skid && !(m_overtake_ball || m_chasing_ball); }
|
||||
virtual void findClosestKart(bool use_difficulty, bool find_sta) OVERRIDE;
|
||||
virtual void findClosestKart(bool consider_difficulty, bool find_sta) OVERRIDE;
|
||||
virtual void findTarget() OVERRIDE;
|
||||
virtual bool forceBraking() OVERRIDE { return m_force_brake; }
|
||||
virtual int getCurrentNode() const OVERRIDE;
|
||||
|
Loading…
Reference in New Issue
Block a user