Different AI intelligence per difficulties
This commit is contained in:
parent
b5d4610f45
commit
ab428dc8cf
@ -121,6 +121,7 @@ void BattleAI::reset()
|
||||
m_path_corners.clear();
|
||||
m_portals.clear();
|
||||
|
||||
m_cur_difficulty = race_manager->getDifficulty();
|
||||
AIBaseController::reset();
|
||||
} // reset
|
||||
|
||||
@ -164,7 +165,7 @@ void BattleAI::update(float dt)
|
||||
return;
|
||||
}
|
||||
|
||||
findClosestKart();
|
||||
findClosestKart(true);
|
||||
findTarget();
|
||||
handleItems(dt);
|
||||
|
||||
@ -233,7 +234,7 @@ void BattleAI::checkPosition(const Vec3 &point, posData *pos_data)
|
||||
} // checkPosition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BattleAI::findClosestKart()
|
||||
void BattleAI::findClosestKart(bool difficulty)
|
||||
{
|
||||
float distance = 99999.9f;
|
||||
const unsigned int n = m_world->getNumKarts();
|
||||
@ -247,6 +248,26 @@ void BattleAI::findClosestKart()
|
||||
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 handleItems, which ignore difficulty.
|
||||
if (m_cur_difficulty == RaceManager::DIFFICULTY_EASY && difficulty)
|
||||
{
|
||||
// Skip human players for novice mode unless only human players left
|
||||
const AbstractKart* temp = m_world->getKart(i);
|
||||
if (temp->getController()->isPlayerController() &&
|
||||
(m_world->getCurrentNumKarts() -
|
||||
m_world->getCurrentNumPlayers()) > 1)
|
||||
continue;
|
||||
}
|
||||
else if (m_cur_difficulty == RaceManager::DIFFICULTY_BEST && difficulty)
|
||||
{
|
||||
// Skip AI players for supertux mode
|
||||
const AbstractKart* temp = m_world->getKart(i);
|
||||
if (!(temp->getController()->isPlayerController()))
|
||||
continue;
|
||||
}
|
||||
|
||||
Vec3 d = kart->getXYZ() - m_kart->getXYZ();
|
||||
if (d.length_2d() <= distance)
|
||||
{
|
||||
@ -269,15 +290,24 @@ void BattleAI::findClosestKart()
|
||||
m_closest_kart_node = controller->getCurrentNode();
|
||||
m_closest_kart_point = closest_kart->getXYZ();
|
||||
}
|
||||
checkPosition(m_closest_kart_point, &m_closest_kart_pos_data);
|
||||
|
||||
if (!difficulty)
|
||||
checkPosition(m_closest_kart_point, &m_closest_kart_pos_data);
|
||||
} // findClosestKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BattleAI::findTarget()
|
||||
{
|
||||
// Don't try to hit a player continuously with swatter for easy and medium
|
||||
// mode, which make it too aggressive
|
||||
const bool continuous_swatter =
|
||||
m_kart->getAttachment()->getType() == Attachment::ATTACH_SWATTER &&
|
||||
(m_cur_difficulty == RaceManager::DIFFICULTY_HARD ||
|
||||
m_cur_difficulty == RaceManager::DIFFICULTY_BEST);
|
||||
|
||||
// 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)
|
||||
!continuous_swatter)
|
||||
handleItemCollection(&m_target_point , &m_target_node);
|
||||
else
|
||||
{
|
||||
@ -297,14 +327,20 @@ void BattleAI::handleAcceleration(const float dt)
|
||||
m_controls->m_accel = 0.0f;
|
||||
return;
|
||||
}
|
||||
m_controls->m_accel = stk_config->m_ai_acceleration;
|
||||
|
||||
const float handicap =
|
||||
(m_cur_difficulty == RaceManager::DIFFICULTY_EASY ? 0.7f : 1.0f);
|
||||
m_controls->m_accel = stk_config->m_ai_acceleration * handicap;
|
||||
|
||||
} // handleAcceleration
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BattleAI::handleUTurn(const float dt)
|
||||
{
|
||||
m_controls->m_accel = -2.0f;
|
||||
const float handicap =
|
||||
(m_cur_difficulty == RaceManager::DIFFICULTY_EASY ? 0.7f : 1.0f);
|
||||
|
||||
m_controls->m_accel = -2.0f * handicap;
|
||||
if (m_time_since_uturn >= 1.0f)
|
||||
setSteering(M_PI,dt); // Preventing keep going around circle
|
||||
else
|
||||
@ -315,7 +351,7 @@ void BattleAI::handleUTurn(const float dt)
|
||||
if (!m_cur_kart_pos_data.behind || m_time_since_uturn >= 1.5f)
|
||||
{
|
||||
m_is_uturn = false;
|
||||
m_controls->m_accel = 2.0f;
|
||||
m_controls->m_accel = 2.0f * handicap;
|
||||
m_time_since_uturn = 0.0f;
|
||||
}
|
||||
} // handleUTurn
|
||||
@ -631,9 +667,14 @@ void BattleAI::handleItems(const float dt)
|
||||
m_kart->getPowerup()->getType() == PowerupManager::POWERUP_NOTHING)
|
||||
return;
|
||||
|
||||
// Find a closest kart again, this time we ignore difficulty
|
||||
findClosestKart(false);
|
||||
m_time_since_last_shot += dt;
|
||||
|
||||
float min_bubble_time = 2.0f;
|
||||
bool fire_behind = m_closest_kart_pos_data.behind &&
|
||||
!(m_cur_difficulty == RaceManager::DIFFICULTY_EASY ||
|
||||
m_cur_difficulty == RaceManager::DIFFICULTY_MEDIUM);
|
||||
|
||||
switch(m_kart->getPowerup()->getType())
|
||||
{
|
||||
@ -686,10 +727,7 @@ void BattleAI::handleItems(const float dt)
|
||||
if (m_closest_kart_pos_data.distance < 25.0f)
|
||||
{
|
||||
m_controls->m_fire = true;
|
||||
if (m_closest_kart_pos_data.behind)
|
||||
m_controls->m_look_back = true;
|
||||
else
|
||||
m_controls->m_look_back = false;
|
||||
m_controls->m_look_back = fire_behind;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -707,11 +745,9 @@ void BattleAI::handleItems(const float dt)
|
||||
|
||||
if (m_closest_kart_pos_data.distance < 5.0f)
|
||||
{
|
||||
cout << m_closest_kart_pos_data.angle<<endl;
|
||||
m_controls->m_fire = true;
|
||||
if (m_closest_kart_pos_data.behind)
|
||||
m_controls->m_look_back = true;
|
||||
else
|
||||
m_controls->m_look_back = false;
|
||||
m_controls->m_look_back = fire_behind;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -775,6 +811,9 @@ void BattleAI::handleItemCollection(Vec3* aim_point, int* target_node)
|
||||
for (unsigned int i = 0; i < items_count; ++i)
|
||||
{
|
||||
Item* item = item_list[i].first;
|
||||
|
||||
if (item->wasCollected()) continue;
|
||||
|
||||
if ((item->getType() == Item::ITEM_NITRO_BIG ||
|
||||
item->getType() == Item::ITEM_NITRO_SMALL) &&
|
||||
((m_kart->getKartProperties()->getNitroSmallContainer() +
|
||||
@ -782,10 +821,10 @@ void BattleAI::handleItemCollection(Vec3* aim_point, int* target_node)
|
||||
continue; // Ignore nitro when already has some
|
||||
|
||||
Vec3 d = item->getXYZ() - m_kart->getXYZ();
|
||||
if (d.length_2d() <= distance && (item->getType() ==
|
||||
Item::ITEM_BONUS_BOX || item->getType() ==
|
||||
Item::ITEM_NITRO_BIG || item->getType() ==
|
||||
Item::ITEM_NITRO_SMALL) && !item->wasCollected())
|
||||
if (d.length_2d() <= distance &&
|
||||
(item->getType() == Item::ITEM_BONUS_BOX ||
|
||||
item->getType() == Item::ITEM_NITRO_BIG ||
|
||||
item->getType() == Item::ITEM_NITRO_SMALL))
|
||||
{
|
||||
closest_item_num = i;
|
||||
distance = d.length_2d();
|
||||
|
@ -59,6 +59,9 @@ private:
|
||||
posData m_closest_kart_pos_data;
|
||||
posData m_cur_kart_pos_data;
|
||||
|
||||
/** Holds the current difficulty. */
|
||||
RaceManager::Difficulty m_cur_difficulty;
|
||||
|
||||
/** Indicates that the kart is currently stuck, and m_time_since_stuck is
|
||||
* counting down. */
|
||||
bool m_is_stuck;
|
||||
@ -102,7 +105,7 @@ private:
|
||||
void checkIfStuck(const float dt);
|
||||
void checkPosition(const Vec3 &, posData*);
|
||||
float determineTurnRadius(std::vector<Vec3>& points);
|
||||
void findClosestKart();
|
||||
void findClosestKart(bool difficulty);
|
||||
void findPortals(int start, int end);
|
||||
void findTarget();
|
||||
void handleAcceleration(const float dt);
|
||||
|
@ -587,7 +587,7 @@ void Track::loadTrackInfo()
|
||||
|
||||
if(file_manager->fileExists(m_root+"navmesh.xml"))
|
||||
m_has_navmesh = true;
|
||||
else if (m_is_arena)
|
||||
else if(m_is_arena)
|
||||
{
|
||||
Log::warn("Track", "NavMesh is not found for arena %s, "
|
||||
"disable AI for it.\n", m_name.c_str());
|
||||
@ -719,16 +719,6 @@ void Track::loadQuadGraph(unsigned int mode_id, const bool reverse)
|
||||
}
|
||||
} // loadQuadGraph
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Loads the polygon graph for battle, i.e. the definition of all polys, and the way
|
||||
* they are connected to each other. Input file name is hardcoded for now
|
||||
*/
|
||||
void Track::loadBattleGraph()
|
||||
{
|
||||
if (m_has_navmesh)
|
||||
BattleGraph::create(m_root+"navmesh.xml");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void Track::mapPoint2MiniMap(const Vec3 &xyz, Vec3 *draw_at) const
|
||||
@ -1842,7 +1832,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
// added to ItemManager. Loading battle graph here is therefore a workaround
|
||||
// to the main problem.
|
||||
if (m_is_arena && !m_is_soccer && !m_is_cutscene && m_has_navmesh)
|
||||
loadBattleGraph();
|
||||
BattleGraph::create(m_root + "navmesh.xml");
|
||||
|
||||
if (UserConfigParams::m_track_debug &&
|
||||
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES &&
|
||||
|
@ -379,7 +379,6 @@ private:
|
||||
|
||||
void loadTrackInfo();
|
||||
void loadQuadGraph(unsigned int mode_id, const bool reverse);
|
||||
void loadBattleGraph();
|
||||
void convertTrackToBullet(scene::ISceneNode *node);
|
||||
bool loadMainTrack(const XMLNode &node);
|
||||
void createWater(const XMLNode &node);
|
||||
|
Loading…
x
Reference in New Issue
Block a user