Allow BattleAI to collect lives

This commit is contained in:
Benau
2016-10-09 13:24:00 +08:00
parent 6b8156c254
commit fb0f4fca3c
11 changed files with 53 additions and 26 deletions

View File

@@ -116,7 +116,6 @@ void ArenaAI::update(float dt)
if (gettingUnstuck(dt))
return;
findClosestKart(true);
findTarget();
// After found target, convert it to local coordinate, used for skidding or
@@ -414,7 +413,7 @@ void ArenaAI::useItems(const float dt)
return;
// Find a closest kart again, this time we ignore difficulty
findClosestKart(false);
findClosestKart(false/*use_difficulty*/, false/*find_sta*/);
if (!m_closest_kart) return;
Vec3 closest_kart_point_lc =

View File

@@ -65,7 +65,8 @@ protected:
bool m_mini_skid;
void collectItemInArena(Vec3*, int*) const;
void collectItemInArena(Vec3*, int*) const;
virtual void findClosestKart(bool use_difficulty, bool find_sta) = 0;
private:
/** Used by handleArenaUTurn, it tells whether to do left or right
* turning when steering is overridden. */
@@ -119,7 +120,6 @@ private:
void useItems(const float dt);
virtual bool canSkid(float steer_fraction) OVERRIDE
{ return m_mini_skid; }
virtual void findClosestKart(bool use_difficulty) = 0;
virtual void findTarget() = 0;
virtual bool forceBraking() { return false; }
virtual int getCurrentNode() const = 0;

View File

@@ -24,6 +24,7 @@
#include "items/powerup.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/kart_control.hpp"
#include "karts/controller/spare_tire_ai.hpp"
#include "modes/three_strikes_battle.hpp"
#include "tracks/arena_graph.hpp"
@@ -65,36 +66,42 @@ BattleAI::~BattleAI()
} // ~BattleAI
//-----------------------------------------------------------------------------
void BattleAI::findClosestKart(bool use_difficulty)
void BattleAI::findClosestKart(bool use_difficulty, bool find_sta)
{
float distance = 99999.9f;
const unsigned int n = m_world->getNumKarts();
int closest_kart_num = 0;
const int end = m_world->getNumKarts();
for (unsigned int i = 0; i < n; i++)
for (int start_id =
find_sta ? end - race_manager->getNumSpareTireKarts() : 0;
start_id < end; start_id++)
{
const AbstractKart* kart = m_world->getKart(i);
if (kart->isEliminated()) continue;
const AbstractKart* kart = m_world->getKart(start_id);
const SpareTireAI* sta =
dynamic_cast<const SpareTireAI*>(kart->getController());
if (kart->isEliminated() && !(find_sta && sta && sta->isMoving()))
continue;
if (kart->getWorldKartId() == m_kart->getWorldKartId())
continue; // Skip the same kart
// Test whether takes current difficulty into account for closest kart
// Notice: it don't affect aiming, this function will be called once
// more in handleArenaItems, which ignore difficulty.
// more when use items, which ignore difficulty.
if (m_cur_difficulty == RaceManager::DIFFICULTY_EASY && use_difficulty)
{
// Skip human players for novice mode unless only human players left
const AbstractKart* temp = m_world->getKart(i);
// Skip human players for novice mode unless only they are left
const AbstractKart* temp = m_world->getKart(start_id);
if (temp->getController()->isPlayerController() &&
(m_world->getCurrentNumKarts() -
m_world->getCurrentNumPlayers()) > 1)
continue;
}
else if (m_cur_difficulty == RaceManager::DIFFICULTY_BEST && use_difficulty)
else if (m_cur_difficulty == RaceManager::DIFFICULTY_BEST &&
use_difficulty)
{
// Skip AI players for supertux mode
const AbstractKart* temp = m_world->getKart(i);
const AbstractKart* temp = m_world->getKart(start_id);
if (!(temp->getController()->isPlayerController()))
continue;
}
@@ -104,7 +111,7 @@ void BattleAI::findClosestKart(bool use_difficulty)
if (dist_to_kart <= distance)
{
distance = dist_to_kart;
closest_kart_num = i;
closest_kart_num = start_id;
}
}
@@ -117,9 +124,30 @@ void BattleAI::findClosestKart(bool use_difficulty)
//-----------------------------------------------------------------------------
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
// 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);
// 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)
m_kart->getAttachment()->getType() != Attachment::ATTACH_SWATTER &&
!find_sta)
collectItemInArena(&m_target_point , &m_target_node);
else
{

View File

@@ -33,9 +33,9 @@ class BattleAI : public ArenaAI
protected:
/** Keep a pointer to world. */
ThreeStrikesBattle *m_world;
virtual void findClosestKart(bool use_difficulty, bool find_sta) OVERRIDE;
virtual int getCurrentNode() const OVERRIDE;
private:
virtual void findClosestKart(bool use_difficulty) OVERRIDE;
virtual void findTarget() OVERRIDE;
virtual float getKartDistance(const AbstractKart* kart) const OVERRIDE;
virtual bool isKartOnRoad() const OVERRIDE;

View File

@@ -129,7 +129,7 @@ void SoccerAI::update(float dt)
} // update
//-----------------------------------------------------------------------------
void SoccerAI::findClosestKart(bool use_difficulty)
void SoccerAI::findClosestKart(bool use_difficulty, bool find_sta)
{
float distance = 99999.9f;
const unsigned int n = m_world->getNumKarts();
@@ -165,6 +165,7 @@ void SoccerAI::findClosestKart(bool use_difficulty)
//-----------------------------------------------------------------------------
void SoccerAI::findTarget()
{
findClosestKart(true/*use_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())
{

View File

@@ -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) OVERRIDE;
virtual void findClosestKart(bool use_difficulty, bool find_sta) OVERRIDE;
virtual void findTarget() OVERRIDE;
virtual bool forceBraking() OVERRIDE { return m_force_brake; }
virtual int getCurrentNode() const OVERRIDE;

View File

@@ -33,7 +33,6 @@ private:
float m_timer;
virtual void findClosestKart(bool use_difficulty) OVERRIDE {}
virtual void findTarget() OVERRIDE;
void findDefaultPath();
public:
@@ -43,7 +42,7 @@ public:
virtual void reset() OVERRIDE;
void spawn(float time_to_last);
void unspawn();
bool needUpdate() const { return !m_fixed_target_nodes.empty(); }
bool isMoving() const { return !m_fixed_target_nodes.empty(); }
};
#endif

View File

@@ -571,7 +571,7 @@ void ThreeStrikesBattle::enterRaceOverState()
SpareTireAI* sta =
dynamic_cast<SpareTireAI*>(m_spare_tire_karts[i]->getController());
assert(sta);
if (sta->needUpdate())
if (sta->isMoving())
sta->unspawn();
}
@@ -597,7 +597,7 @@ bool ThreeStrikesBattle::spareTireKartsSpawned() const
dynamic_cast<SpareTireAI*>(m_spare_tire_karts[0]->getController());
assert(sta);
return sta->needUpdate();
return sta->isMoving();
} // spareTireKartsSpawned
//-----------------------------------------------------------------------------

View File

@@ -981,7 +981,7 @@ void World::update(float dt)
SpareTireAI* sta =
dynamic_cast<SpareTireAI*>(m_karts[i]->getController());
// Update all karts that are not eliminated
if(!m_karts[i]->isEliminated() || (sta && sta->needUpdate()))
if(!m_karts[i]->isEliminated() || (sta && sta->isMoving()))
m_karts[i]->update(dt);
}
PROFILER_POP_CPU_MARKER();

View File

@@ -254,7 +254,7 @@ void WorldWithRank::updateSectorForKarts()
{
SpareTireAI* sta =
dynamic_cast<SpareTireAI*>(m_karts[i]->getController());
if (!m_karts[i]->isEliminated() || (sta && sta->needUpdate()))
if (!m_karts[i]->isEliminated() || (sta && sta->isMoving()))
getTrackSector(i)->update(m_karts[i]->getXYZ());
}
} // updateSectorForKarts

View File

@@ -379,7 +379,7 @@ void RaceGUI::drawGlobalMiniMap()
const SpareTireAI* sta =
dynamic_cast<const SpareTireAI*>(kart->getController());
// don't draw eliminated kart
if(kart->isEliminated() && !(sta && sta->needUpdate())) continue;
if(kart->isEliminated() && !(sta && sta->isMoving())) continue;
const Vec3& xyz = kart->getXYZ();
Vec3 draw_at;
world->getTrack()->mapPoint2MiniMap(xyz, &draw_at);