Merge branch 'walldriving' of github.com:supertuxkart/stk-code into walldriving

This commit is contained in:
hiker 2016-09-29 15:12:11 +10:00
commit 2e38154bd6
24 changed files with 358 additions and 406 deletions

View File

@ -183,7 +183,6 @@ public:
const AbstractKart* getEmitter() const { return m_emitter; }
// ------------------------------------------------------------------------
/** Returns true if the Kart is close enough to hit this item, the item is
* not deactivated anymore, and it wasn't placed by this kart (this is
@ -192,31 +191,12 @@ public:
* \param xyz Location of kart (avoiding to use kart->getXYZ() so that
* kart.hpp does not need to be included here).
*/
bool hitKart (const Vec3 &xyz, const AbstractKart *kart=NULL) const
bool hitKart(const Vec3 &xyz, const AbstractKart *kart=NULL) const
{
return (m_event_handler!=kart || m_deactive_time <=0) &&
(xyz-m_xyz).length2()<m_distance_2;
} // hitKart
private:
// ------------------------------------------------------------------------
/** Returns true if the Kart is close enough to hit this item, the item is
* not deactivated anymore, and it wasn't placed by this kart (this is
* e.g. used to avoid that a kart hits a bubble gum it just dropped).
* This function only uses the 2d coordinates, and it used by the AI only.
* \param kart Kart to test.
* \param xyz Location of kart (avoiding to use kart->getXYZ() so that
* kart.hpp does not need to be included here).
*/
bool hitKart (const core::vector2df &xyz,
const AbstractKart *kart=NULL) const
{
if(m_event_handler==kart && m_deactive_time >0) return false;
float d2 = (m_xyz.getX()-xyz.X)*(m_xyz.getX()-xyz.X)
+ (m_xyz.getZ()-xyz.Y)*(m_xyz.getZ()-xyz.Y);
return d2 < m_distance_2;
} // hitKart
protected:
// ------------------------------------------------------------------------
// Some convenient functions for the AI only

View File

@ -280,13 +280,11 @@ void Swatter::pointToTarget()
}
else
{
Vec3 swatter_to_target = m_target->getXYZ()
-Vec3(m_scene_node->getAbsolutePosition());
Vec3 swatter_to_target =
m_kart->getTrans().inverse()(m_target->getXYZ());
float dy = -swatter_to_target.getZ();
float dx = swatter_to_target.getX();
float angle = SWAT_ANGLE_OFFSET + (atan2(dy, dx)-m_kart->getHeading())
* 180.0f/M_PI;
float angle = SWAT_ANGLE_OFFSET + atan2f(dy, dx) * 180 / M_PI;
m_scene_node->setRotation(core::vector3df(0.0, angle, 0.0));
}
} // pointToTarget

View File

@ -279,35 +279,3 @@ void AIBaseController::crashed(const Material *m)
}
} // crashed(Material)
//-----------------------------------------------------------------------------
void AIBaseController::checkPosition(const Vec3 &point, posData *pos_data,
Vec3 *lc, bool use_front_xyz) const
{
// Convert to local coordinates from the point of view of current kart
btTransform t;
t.setBasis(m_kart->getTrans().getBasis());
t.setOrigin(use_front_xyz ? m_kart->getFrontXYZ() : m_kart->getXYZ());
Vec3 local_coordinates = t.inverse()(point);
// Save local coordinates for later use if needed
if (lc) *lc = local_coordinates;
if (pos_data == NULL) return;
// lhs: tell whether it's left or right hand side
if (local_coordinates.getX() < 0)
pos_data->lhs = true;
else
pos_data->lhs = false;
// behind: tell whether it's behind or not
if (local_coordinates.getZ() < 0)
pos_data->behind = true;
else
pos_data->behind = false;
pos_data->angle = atan2f(fabsf(local_coordinates.getX()),
fabsf(local_coordinates.getZ()));
pos_data->distance = local_coordinates.length();
} // checkPosition

View File

@ -64,9 +64,6 @@ protected:
* for AI testing only. */
static int m_test_ai;
/** Position info structure of targets. */
struct posData {bool behind; bool lhs; float angle; float distance;};
void setControllerName(const std::string &name);
float steerToPoint(const Vec3 &point);
float normalizeAngle(float angle);
@ -77,9 +74,6 @@ protected:
/** This can be called to detect if the kart is stuck (i.e. repeatedly
* hitting part of the track). */
bool isStuck() const { return m_stuck; }
void checkPosition(const Vec3&, posData*,
Vec3* lc = NULL,
bool use_front_xyz = false) const;
public:
AIBaseController(AbstractKart *kart);

View File

@ -23,12 +23,11 @@
#include "items/powerup.hpp"
#include "items/projectile_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/player_controller.hpp"
#include "karts/controller/ai_properties.hpp"
#include "karts/kart_properties.hpp"
#include "karts/rescue_animation.hpp"
#include "tracks/arena_graph.hpp"
#include "tracks/arena_node.hpp"
#include "utils/log.hpp"
ArenaAI::ArenaAI(AbstractKart *kart)
: AIBaseController(kart)
@ -51,18 +50,20 @@ 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_off_road = 0.0f;
m_time_since_reversing = 0.0f;
m_time_since_uturn = 0.0f;
m_turn_radius = 0.0f;
m_turn_angle = 0.0f;
m_steering_angle = 0.0f;
m_on_node.clear();
m_aiming_points.clear();
m_aiming_nodes.clear();
@ -90,6 +91,24 @@ void ArenaAI::update(float dt)
return;
}
if (!isKartOnRoad() && !m_kart->getKartAnimation())
{
m_time_since_off_road += dt;
}
else if (m_time_since_off_road != 0.0f)
{
m_time_since_off_road = 0.0f;
}
// If the kart needs to be rescued, do it now (and nothing else)
if (m_time_since_off_road > 5.0f && !m_kart->getKartAnimation())
{
m_time_since_off_road = 0.0f;
new RescueAnimation(m_kart);
AIBaseController::update(dt);
return;
}
if (isWaiting())
{
AIBaseController::update(dt);
@ -102,6 +121,11 @@ 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);
doSkiddingTest();
handleArenaItems(dt);
if (m_kart->getSpeed() > 15.0f && m_turn_angle < 20)
@ -201,19 +225,19 @@ 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
{
float target_angle = steerToPoint(m_target_point);
setSteering(target_angle, dt);
m_steering_angle = steerToPoint(m_target_point);
setSteering(m_steering_angle, dt);
}
return;
}
@ -224,22 +248,22 @@ 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
{
float target_angle = steerToPoint(m_target_point);
setSteering(target_angle, dt);
m_steering_angle = steerToPoint(m_target_point);
setSteering(m_steering_angle, dt);
}
return;
}
@ -324,10 +348,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 +400,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 +524,27 @@ 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) * 0.8f;
switch(m_kart->getPowerup()->getType())
{
@ -530,7 +562,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 +576,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 +596,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 +616,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 +637,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;
@ -702,3 +732,27 @@ void ArenaAI::collectItemInArena(Vec3* aim_point, int* target_node) const
*target_node = m_closest_kart_node;
}
} // collectItemInArena
//-----------------------------------------------------------------------------
void ArenaAI::doSkiddingTest()
{
m_mini_skid = false;
// No skidding when u-turn
if (m_is_uturn) return;
// 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 ||
m_cur_difficulty == RaceManager::DIFFICULTY_BEST) &&
m_target_point_lc.z() > 0 && abs_angle > 0.15f &&
m_target_point_lc.length() < 10.0f &&
((m_steering_angle < 0 && m_target_point_lc.x() < 0) ||
(m_steering_angle > 0 && m_target_point_lc.x() > 0)))
{
m_mini_skid = true;
}
} // doSkiddingTest

View File

@ -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. */
@ -65,16 +65,15 @@ protected:
bool m_avoiding_item;
void collectItemInArena(Vec3*, int*) const;
float findAngleFrom3Edges(float a, float b, float c);
private:
ArenaGraph* m_graph;
bool m_mini_skid;
void collectItemInArena(Vec3*, int*) const;
private:
/** 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. */
@ -100,8 +99,12 @@ private:
/** This is a timer that counts down when the kart is doing u-turn. */
float m_time_since_uturn;
/** This is a timer that counts when the kart start going off road. */
float m_time_since_off_road;
float m_turn_radius;
float m_turn_angle;
float m_steering_angle;
Vec3 m_current_forward_point;
int m_current_forward_node;
@ -110,6 +113,8 @@ private:
std::vector<Vec3> m_aiming_points;
void checkIfStuck(const float dt);
void doSkiddingTest();
float findAngleFrom3Edges(float a, float b, float c);
void handleArenaAcceleration(const float dt);
void handleArenaBraking();
void handleArenaItems(const float dt);
@ -120,19 +125,23 @@ private:
void updateBadItemLocation();
void updateTurnRadius(const Vec3& p1, const Vec3& p2,
const Vec3& p3);
virtual int getCurrentNode() const = 0;
virtual bool isWaiting() const = 0;
virtual void resetAfterStop() {};
virtual void findClosestKart(bool use_difficulty) = 0;
virtual void findTarget() = 0;
virtual bool forceBraking() { return m_avoiding_item; }
virtual bool ignorePathFinding() { return false; }
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 m_avoiding_item; }
virtual int getCurrentNode() const = 0;
virtual float getKartDistance(const AbstractKart* kart) const = 0;
virtual bool ignorePathFinding() { return false; }
virtual bool isWaiting() const = 0;
virtual bool isKartOnRoad() const = 0;
virtual void resetAfterStop() {};
public:
ArenaAI(AbstractKart *kart);
virtual ~ArenaAI() {};
virtual void update (float delta);
virtual void reset ();
virtual void newLap(int lap) {};
virtual void update (float delta) OVERRIDE;
virtual void reset () OVERRIDE;
virtual void newLap (int lap) OVERRIDE {}
};
#endif

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->getSectorForKart(kart));
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_node = m_world->getKartNode(closest_kart_num);
m_closest_kart_point = closest_kart->getXYZ();
m_closest_kart = m_world->getKart(closest_kart_num);
m_closest_kart_node = m_world->getSectorForKart(m_closest_kart);
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
//-----------------------------------------------------------------------------
@ -164,10 +145,24 @@ void BattleAI::findTarget()
//-----------------------------------------------------------------------------
int BattleAI::getCurrentNode() const
{
return m_world->getKartNode(m_kart->getWorldKartId());
return m_world->getSectorForKart(m_kart);
} // getCurrentNode
//-----------------------------------------------------------------------------
bool BattleAI::isWaiting() const
{
return m_world->isStartPhase();
} // isWaiting
//-----------------------------------------------------------------------------
float BattleAI::getKartDistance(const AbstractKart* kart) const
{
return m_graph->getDistance(getCurrentNode(),
m_world->getSectorForKart(kart));
} // getKartDistance
//-----------------------------------------------------------------------------
bool BattleAI::isKartOnRoad() const
{
return m_world->isOnRoad(m_kart->getWorldKartId());
} // isKartOnRoad

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,18 +34,17 @@ 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 void findClosestKart(bool use_difficulty) OVERRIDE;
virtual void findTarget() OVERRIDE;
virtual int getCurrentNode() const OVERRIDE;
virtual float getKartDistance(const AbstractKart* kart) const OVERRIDE;
virtual bool isKartOnRoad() const OVERRIDE;
virtual bool isWaiting() const OVERRIDE;
public:
BattleAI(AbstractKart *kart);
~BattleAI();
virtual void update (float delta);
virtual void reset ();
virtual void update (float delta) OVERRIDE;
virtual void reset () OVERRIDE;
};
#endif

View File

@ -1081,10 +1081,6 @@ void SkiddingAI::evaluateItems(const Item *item, Vec3 kart_aim_direction,
// to avoid are collected).
if(!avoid)
{
// Project the item's location onto the plane of the current quad.
// This is necessary because the kart's aim point may not be on the track
// in 3D curves. So we project the item's location onto the plane in which
// the kart is. The current quad provides a good estimate of the kart's plane.
const Vec3 &xyz = item->getXYZ();
float angle_to_item =
(xyz - m_kart->getXYZ()).angle(kart_aim_direction);

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,12 +92,14 @@ SoccerAI::~SoccerAI()
void SoccerAI::reset()
{
ArenaAI::reset();
AIBaseController::reset();
m_overtake_ball = false;
m_force_brake = false;
m_chasing_ball = false;
m_front_transform.setOrigin(m_kart->getFrontXYZ());
m_front_transform.setBasis(m_kart->getTrans().getBasis());
} // reset
//-----------------------------------------------------------------------------
@ -113,6 +113,8 @@ void SoccerAI::update(float dt)
#endif
m_force_brake = false;
m_chasing_ball = false;
m_front_transform.setOrigin(m_kart->getFrontXYZ());
m_front_transform.setBasis(m_kart->getTrans().getBasis());
if (m_world->getPhase() == World::GOAL_PHASE)
{
@ -154,11 +156,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->getSectorForKart(m_closest_kart);
m_closest_kart_point = m_closest_kart->getXYZ();
} // findClosestKart
@ -187,8 +187,9 @@ void SoccerAI::findTarget()
{
// This AI will attack the other team ball chaser
int id = m_world->getBallChaser(m_opp_team);
m_target_point = m_world->getKart(id)->getXYZ();
m_target_node = m_world->getKartNode(id);
const AbstractKart* kart = m_world->getKart(id);
m_target_point = kart->getXYZ();
m_target_node = m_world->getSectorForKart(kart);
}
else
{
@ -214,10 +215,8 @@ Vec3 SoccerAI::determineBallAimingPosition()
const Vec3& ball_aim_pos = m_world->getBallAimPosition(m_opp_team);
const Vec3& orig_pos = m_world->getBallPosition();
Vec3 ball_lc;
Vec3 aim_lc;
checkPosition(orig_pos, NULL, &ball_lc, true/*use_front_xyz*/);
checkPosition(ball_aim_pos, NULL, &aim_lc, true/*use_front_xyz*/);
Vec3 ball_lc = m_front_transform.inverse()(orig_pos);
Vec3 aim_lc = m_front_transform.inverse()(ball_aim_pos);
// Too far from the ball,
// use path finding from arena ai to get close
@ -235,7 +234,7 @@ Vec3 SoccerAI::determineBallAimingPosition()
return ball_aim_pos;
}
else
return m_kart->getTrans()(Vec3(overtake_lc));
return m_front_transform(overtake_lc);
}
else
{
@ -455,10 +454,24 @@ float SoccerAI::rotateSlope(float old_slope, bool rotate_up)
//-----------------------------------------------------------------------------
int SoccerAI::getCurrentNode() const
{
return m_world->getKartNode(m_kart->getWorldKartId());
return m_world->getSectorForKart(m_kart);
} // getCurrentNode
//-----------------------------------------------------------------------------
bool SoccerAI::isWaiting() const
{
return m_world->isStartPhase();
} // isWaiting
//-----------------------------------------------------------------------------
float SoccerAI::getKartDistance(const AbstractKart* kart) const
{
return m_graph->getDistance(getCurrentNode(),
m_world->getSectorForKart(kart));
} // getKartDistance
//-----------------------------------------------------------------------------
bool SoccerAI::isKartOnRoad() const
{
return m_world->isOnRoad(m_kart->getWorldKartId());
} // isKartOnRoad

View File

@ -21,13 +21,14 @@
#include "karts/controller/arena_ai.hpp"
#include "LinearMath/btTransform.h"
#undef BALL_AIM_DEBUG
#ifdef BALL_AIM_DEBUG
#include "graphics/irr_driver.hpp"
#endif
class SoccerWorld;
class Vec3;
/** The actual soccer AI.
* \ingroup controller
@ -54,27 +55,32 @@ private:
bool m_force_brake;
bool m_chasing_ball;
Vec3 determineBallAimingPosition();
bool isOvertakable(const Vec3& ball_lc);
bool determineOvertakePosition(const Vec3& ball_lc, const Vec3& aim_lc,
Vec3* overtake_lc);
btTransform m_front_transform;
Vec3 determineBallAimingPosition();
bool determineOvertakePosition(const Vec3& ball_lc, const Vec3& aim_lc,
Vec3* overtake_lc);
bool isOvertakable(const Vec3& ball_lc);
float rotateSlope(float old_slope, bool rotate_up);
virtual void findClosestKart(bool use_difficulty);
virtual void findTarget();
virtual void resetAfterStop() OVERRIDE { m_overtake_ball = false; }
virtual int getCurrentNode() const;
virtual bool isWaiting() const;
virtual bool canSkid(float steer_fraction) { return false; }
virtual bool forceBraking() OVERRIDE
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 findTarget() OVERRIDE;
virtual bool forceBraking() OVERRIDE
{ return m_avoiding_item || m_force_brake; }
virtual bool ignorePathFinding() OVERRIDE
virtual int getCurrentNode() const OVERRIDE;
virtual float getKartDistance(const AbstractKart* kart) const OVERRIDE;
virtual bool ignorePathFinding() OVERRIDE
{ return m_overtake_ball || m_chasing_ball; }
virtual bool isKartOnRoad() const OVERRIDE;
virtual bool isWaiting() const OVERRIDE;
virtual void resetAfterStop() OVERRIDE { m_overtake_ball = false; }
public:
SoccerAI(AbstractKart *kart);
~SoccerAI();
virtual void update (float delta);
virtual void reset ();
virtual void update (float delta) OVERRIDE;
virtual void reset () OVERRIDE;
};
#endif

View File

@ -68,6 +68,7 @@
#include "tracks/drive_node.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "tracks/track_sector.hpp"
#include "utils/constants.hpp"
#include "utils/log.hpp" //TODO: remove after debugging is done
#include "utils/vs.hpp"
@ -1210,6 +1211,9 @@ void Kart::update(float dt)
// Update the position and other data taken from the physics
Moveable::update(dt);
Vec3 front(0, 0, getKartLength()*0.5f);
m_xyz_front = getTrans()(front);
if(!history->replayHistory())
m_controller->update(dt);
@ -1252,7 +1256,10 @@ void Kart::update(float dt)
m_kart_properties->getStabilityChassisAngularDamping());
}
if(m_kart_animation)
// Used to prevent creating a rescue animation after an explosion animation
// got deleted
const bool has_animation_before = m_kart_animation!= NULL;
if(has_animation_before)
m_kart_animation->update(dt);
m_attachment->update(dt);
@ -1300,7 +1307,7 @@ void Kart::update(float dt)
if (lw && DriveGraph::get())
{
const int sector =
lw->getTrackSector(getWorldKartId()).getCurrentGraphNode();
lw->getTrackSector(getWorldKartId())->getCurrentGraphNode();
dist_to_sector = getXYZ().distance
(DriveGraph::get()->getNode(sector)->getCenter());
@ -1313,7 +1320,7 @@ void Kart::update(float dt)
if (World::getWorld()->getTrack()->isAutoRescueEnabled() &&
(!m_terrain_info->getMaterial() ||
!m_terrain_info->getMaterial()->hasGravity()) &&
!getKartAnimation() && fabs(roll) > 60 * DEGREE_TO_RAD &&
!has_animation_before && fabs(roll) > 60 * DEGREE_TO_RAD &&
fabs(getSpeed()) < 3.0f)
{
new RescueAnimation(this, /*is_auto_rescue*/true);
@ -1330,9 +1337,6 @@ void Kart::update(float dt)
m_body->getBroadphaseHandle()->m_collisionFilterGroup = 0;
}
Vec3 front(0, 0, getKartLength()*0.5f);
m_xyz_front = getTrans()(front);
// After the physics step was done, the position of the wheels (as stored
// in wheelInfo) is actually outdated, since the chassis was moved
// according to the force acting from the wheels. So the center of the

View File

@ -94,7 +94,6 @@ void LinearWorld::reset()
for(unsigned int i=0; i<kart_amount; i++)
{
m_kart_info[i].reset();
m_kart_info[i].getTrackSector()->update(m_karts[i]->getXYZ());
m_karts[i]->setWrongwayCounter(0);
} // next kart
@ -181,12 +180,12 @@ void LinearWorld::update(float dt)
// in the position of the kart (e.g. while falling the kart
// might get too close to another part of the track, shortly
// jump to position one, then on reset fall back to last)
if ((!kart_info.getTrackSector()->isOnRoad() &&
if ((!getTrackSector(n)->isOnRoad() &&
(!kart->getMaterial() ||
kart->getMaterial()->isDriveReset())) &&
!kart->isGhostKart())
continue;
kart_info.getTrackSector()->update(kart->getFrontXYZ());
getTrackSector(n)->update(kart->getFrontXYZ());
kart_info.m_overall_distance = kart_info.m_race_lap
* m_track->getTrackLength()
+ getDistanceDownTrackForKart(kart->getWorldKartId());
@ -380,24 +379,6 @@ void LinearWorld::newLap(unsigned int kart_index)
kart->getController()->newLap(kart_info.m_race_lap);
} // newLap
//-----------------------------------------------------------------------------
/** Gets the sector a kart is on. This function returns UNKNOWN_SECTOR if the
* kart_id is larger than the current kart info. This is necessary in the case
* that a collision with the track happens during resetAllKarts: at this time
* m_kart_info is not initialised (and has size 0), so it would trigger this
* assert. While this normally does not happen, it is useful for track
* designers that STK does not crash.
* \param kart_id The world kart id of the kart for which to return
* the sector.
*/
int LinearWorld::getSectorForKart(const AbstractKart *kart) const
{
if(kart->getWorldKartId()>=m_kart_info.size())
return Graph::UNKNOWN_SECTOR;
return m_kart_info[kart->getWorldKartId()].getTrackSector()
->getCurrentGraphNode();
} // getSectorForKart
//-----------------------------------------------------------------------------
/** Returns the distance the kart has travelled along the track since
* crossing the start line..
@ -405,8 +386,7 @@ int LinearWorld::getSectorForKart(const AbstractKart *kart) const
*/
float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
{
assert(kart_id < (int)m_kart_info.size());
return m_kart_info[kart_id].getTrackSector()->getDistanceFromStart();
return getTrackSector(kart_id)->getDistanceFromStart();
} // getDistanceDownTrackForKart
//-----------------------------------------------------------------------------
@ -416,8 +396,7 @@ float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
*/
float LinearWorld::getDistanceToCenterForKart(const int kart_id) const
{
assert(kart_id < (int)m_kart_info.size());
return m_kart_info[kart_id].getTrackSector()->getDistanceToCenter();
return getTrackSector(kart_id)->getDistanceToCenter();
} // getDistanceToCenterForKart
//-----------------------------------------------------------------------------
@ -635,13 +614,13 @@ unsigned int LinearWorld::getNumberOfRescuePositions() const
// ------------------------------------------------------------------------
unsigned int LinearWorld::getRescuePositionIndex(AbstractKart *kart)
{
KartInfo& info = m_kart_info[kart->getWorldKartId()];
const unsigned int kart_id = kart->getWorldKartId();
info.getTrackSector()->rescue();
getTrackSector(kart_id)->rescue();
// Setting XYZ for the kart is important since otherwise the kart
// will not detect the right material again when doing the next
// raycast to detect where it is driving on (--> potential rescue loop)
return info.getTrackSector()->getCurrentGraphNode();
return getTrackSector(kart_id)->getCurrentGraphNode();
} // getRescuePositionIndex
// ------------------------------------------------------------------------
@ -864,7 +843,7 @@ void LinearWorld::checkForWrongDirection(unsigned int i, float dt)
// If the kart can go in more than one directions from the current track
// don't do any reverse message handling, since it is likely that there
// will be one direction in which it isn't going backwards anyway.
int sector = m_kart_info[i].getTrackSector()->getCurrentGraphNode();
int sector = getTrackSector(i)->getCurrentGraphNode();
if (DriveGraph::get()->getNumberOfSuccessors(sector) > 1)
return;
@ -915,3 +894,8 @@ void LinearWorld::checkForWrongDirection(unsigned int i, float dt)
} // checkForWrongDirection
//-----------------------------------------------------------------------------
void LinearWorld::setLastTriggeredCheckline(unsigned int kart_index, int index)
{
if (m_kart_info.size() == 0) return;
getTrackSector(kart_index)->setLastTriggeredCheckline(index);
} // setLastTriggeredCheckline

View File

@ -21,7 +21,6 @@
#include <vector>
#include "modes/world_with_rank.hpp"
#include "tracks/track_sector.hpp"
#include "utils/aligned_array.hpp"
class SFXBase;
@ -78,9 +77,6 @@ private:
* track-length plus distance-along-track). */
float m_overall_distance;
/** Stores the current graph node and track coordinates etc. */
TrackSector m_track_sector;
/** Initialises all fields. */
KartInfo() { reset(); }
// --------------------------------------------------------------------
@ -92,14 +88,7 @@ private:
m_time_at_last_lap = 99999.9f;
m_estimated_finish = -1.0f;
m_overall_distance = 0.0f;
m_track_sector.reset();
} // reset
// --------------------------------------------------------------------
/** Returns a pointer to the current node object. */
TrackSector *getTrackSector() {return &m_track_sector; }
// --------------------------------------------------------------------
/** Returns a pointer to the current node object. */
const TrackSector *getTrackSector() const {return &m_track_sector; }
};
// ------------------------------------------------------------------------
@ -124,7 +113,6 @@ public:
virtual ~LinearWorld();
virtual void update(float delta) OVERRIDE;
int getSectorForKart(const AbstractKart *kart) const;
float getDistanceDownTrackForKart(const int kart_id) const;
float getDistanceToCenterForKart(const int kart_id) const;
float getEstimatedFinishTime(const int kart_id) const;
@ -149,14 +137,6 @@ public:
// ------------------------------------------------------------------------
/** Override settings from base class */
virtual bool useChecklineRequirements() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
/** Returns true if the kart is on a valid driveline quad.
* \param kart_index Index of the kart. */
bool isOnRoad(unsigned int kart_index) const
{
return m_kart_info[kart_index].getTrackSector()->isOnRoad();
} // isOnRoad
// ------------------------------------------------------------------------
/** Returns the number of laps a kart has completed.
* \param kart_index World index of the kart. */
@ -165,21 +145,8 @@ public:
assert(kart_index < m_kart_info.size());
return m_kart_info[kart_index].m_race_lap;
} // getkartLap
// ------------------------------------------------------------------------
/** Returns the track_sector object for the specified kart.
* \param kart_index World index of the kart. */
TrackSector& getTrackSector(unsigned int kart_index)
{
return m_kart_info[kart_index].m_track_sector;
} // getTrackSector
// ------------------------------------------------------------------------
void setLastTriggeredCheckline(unsigned int kart_index, int index)
{
if (m_kart_info.size() == 0)
return;
m_kart_info[kart_index].m_track_sector.setLastTriggeredCheckline(index);
}
void setLastTriggeredCheckline(unsigned int kart_index, int index);
// ------------------------------------------------------------------------
/** Returns how far the kart has driven so far (i.e.
* number-of-laps-finished times track-length plus distance-on-track.

View File

@ -39,7 +39,7 @@
#include "tracks/track_object_manager.hpp"
//-----------------------------------------------------------------------------
OverWorld::OverWorld() : WorldWithRank()
OverWorld::OverWorld() : World()
{
m_return_to_garage = false;
m_stop_music_when_dialog_open = false;
@ -118,8 +118,8 @@ void OverWorld::update(float dt)
music_manager->startMusic();
m_karts[0]->startEngineSFX();
}
WorldWithRank::update(dt);
WorldWithRank::updateTrack(dt);
World::update(dt);
World::updateTrack(dt);
const unsigned int kart_amount = (unsigned int)m_karts.size();
// isn't it cool, on the overworld nitro is free!
@ -269,7 +269,7 @@ void OverWorld::onMouseClick(int x, int y)
if(challenge)
{
// Use the 'get closest start point' rescue function
// from WorldWithRank by setting the kart's position to
// from World by setting the kart's position to
// be the location of the challenge bubble.
AbstractKart* kart = getKart(0);
kart->setXYZ(challenge->m_position);

View File

@ -20,19 +20,18 @@
#include <vector>
#include "modes/world_with_rank.hpp"
#include "modes/world.hpp"
#include "utils/aligned_array.hpp"
#include "LinearMath/btTransform.h"
/*
* The overworld map where challenges are played.
* \note This mode derives from LinearWorld to get support for drivelines,
* minimap and rescue, even though this world is not technically
* linear.
* \note Extends world to make a simple world where karts can drive around,
* it adds challenges and starting of races.
* \ingroup modes
*/
class OverWorld : public WorldWithRank
class OverWorld : public World
{
protected:

View File

@ -25,13 +25,11 @@
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart.hpp"
#include "karts/kart_model.hpp"
#include "karts/kart_properties.hpp"
#include "karts/rescue_animation.hpp"
#include "karts/controller/local_player_controller.hpp"
#include "karts/controller/soccer_ai.hpp"
#include "physics/physics.hpp"
#include "states_screens/race_gui_base.hpp"
#include "tracks/track.hpp"
@ -73,12 +71,6 @@ SoccerWorld::~SoccerWorld()
delete m_ball_track_sector;
m_ball_track_sector = NULL;
for (unsigned int i = 0; i < m_kart_track_sector.size(); i++)
{
delete m_kart_track_sector[i];
}
m_kart_track_sector.clear();
} // ~SoccerWorld
//-----------------------------------------------------------------------------
@ -100,10 +92,8 @@ void SoccerWorld::init()
if (m_track->hasNavMesh())
{
// Init track sector if navmesh is found
// Init track sector for ball if navmesh is found
m_ball_track_sector = new TrackSector();
for (unsigned int i = 0; i < m_karts.size(); i++)
m_kart_track_sector.push_back(new TrackSector());
}
TrackObjectManager* tom = getTrack()->getTrackObjectManager();
@ -162,8 +152,6 @@ void SoccerWorld::reset()
if (m_track->hasNavMesh())
{
m_ball_track_sector->reset();
for (unsigned int i = 0; i < m_karts.size(); i++)
m_kart_track_sector[i]->reset();
}
initKartList();
@ -194,7 +182,7 @@ void SoccerWorld::update(float dt)
updateBallPosition(dt);
if (m_track->hasNavMesh())
{
updateKartNodes();
updateSectorForKarts();
updateAIData();
}
@ -452,22 +440,6 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
return new_kart;
} // createKart
//-----------------------------------------------------------------------------
/** Updates the m_kart_on_node value of each kart to localize it
* on the navigation mesh.
*/
void SoccerWorld::updateKartNodes()
{
if (isRaceOver()) return;
const unsigned int n = getNumKarts();
for (unsigned int i = 0; i < n; i++)
{
if (m_karts[i]->isEliminated()) continue;
m_kart_track_sector[i]->update(m_karts[i]->getXYZ());
}
} // updateKartNodes
//-----------------------------------------------------------------------------
/** Localize the ball on the navigation mesh.
*/
@ -506,13 +478,6 @@ void SoccerWorld::updateBallPosition(float dt)
} // updateBallPosition
//-----------------------------------------------------------------------------
int SoccerWorld::getKartNode(unsigned int kart_id) const
{
assert(kart_id < m_kart_track_sector.size());
return m_kart_track_sector[kart_id]->getCurrentGraphNode();
} // getKartNode
//-----------------------------------------------------------------------------
int SoccerWorld::getBallNode() const
{

View File

@ -33,7 +33,7 @@ class Controller;
class TrackObject;
class TrackSector;
/** An implementation of World, to provide the soccer game mode
/** \brief An implementation of WorldWithRank, to provide the soccer game mode
* Notice: In soccer world, true goal means blue, false means red.
* \ingroup modes
*/
@ -280,7 +280,6 @@ private:
std::map<int, unsigned int> m_kart_position_map;
/** Data generated from navmesh */
std::vector<TrackSector*> m_kart_track_sector;
TrackSector* m_ball_track_sector;
int m_red_ai;
@ -290,8 +289,6 @@ private:
/** Set the team for the karts */
void initKartList();
/** Function to update the locations of all karts on the polygon map */
void updateKartNodes();
/** Function to update the location the ball on the polygon map */
void updateBallPosition(float dt);
/** Function to update data for AI usage. */
@ -356,8 +353,6 @@ public:
m_blue_score_times : m_red_score_times);
}
// ------------------------------------------------------------------------
int getKartNode(unsigned int kart_id) const;
// ------------------------------------------------------------------------
int getBallNode() const;
// ------------------------------------------------------------------------
const Vec3& getBallPosition() const

View File

@ -30,7 +30,6 @@
#include "states_screens/race_gui_base.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object_manager.hpp"
#include "tracks/track_sector.hpp"
#include "utils/constants.hpp"
#include <string>
@ -65,12 +64,6 @@ void ThreeStrikesBattle::init()
WorldWithRank::init();
m_display_rank = false;
m_kart_info.resize(m_karts.size());
if (m_track->hasNavMesh())
{
// Init track sector if navmesh is found
for (unsigned int i = 0; i < m_karts.size(); i++)
m_kart_track_sector.push_back(new TrackSector());
}
} // ThreeStrikesBattle
//-----------------------------------------------------------------------------
@ -86,12 +79,6 @@ ThreeStrikesBattle::~ThreeStrikesBattle()
// freed once all refernces to it (which will happen once all
// karts are being freed, which would have a pointer to this mesh)
irr_driver->removeMeshFromCache(m_tire);
for (unsigned int i = 0; i < m_kart_track_sector.size(); i++)
{
delete m_kart_track_sector[i];
}
m_kart_track_sector.clear();
} // ~ThreeStrikesBattle
//-----------------------------------------------------------------------------
@ -145,12 +132,6 @@ void ThreeStrikesBattle::reset()
m_track->getTrackObjectManager()->removeObject(obj);
}
m_tires.clearWithoutDeleting();
if (m_track->hasNavMesh())
{
for (unsigned int i = 0; i < kart_amount; i++)
m_kart_track_sector[i]->reset();
}
} // reset
//-----------------------------------------------------------------------------
@ -325,7 +306,7 @@ void ThreeStrikesBattle::update(float dt)
WorldWithRank::updateTrack(dt);
if (m_track->hasNavMesh())
updateKartNodes();
updateSectorForKarts();
// insert blown away tire(s) now if was requested
while (m_insert_tire > 0)
@ -475,31 +456,6 @@ bool ThreeStrikesBattle::isRaceOver()
return getCurrentNumKarts()==1 || getCurrentNumPlayers()==0;
} // isRaceOver
//-----------------------------------------------------------------------------
/** Updates the m_on_node value of each kart to localize it
* on the navigation mesh.
*/
void ThreeStrikesBattle::updateKartNodes()
{
if (isRaceOver()) return;
const unsigned int n = getNumKarts();
for (unsigned int i = 0; i < n; i++)
{
if (m_karts[i]->isEliminated()) continue;
m_kart_track_sector[i]->update(m_karts[i]->getXYZ());
}
} // updateKartNodes
//-----------------------------------------------------------------------------
/** Get the which node the kart located in navigation mesh.
*/
int ThreeStrikesBattle::getKartNode(unsigned int kart_id) const
{
assert(kart_id < m_kart_track_sector.size());
return m_kart_track_sector[kart_id]->getCurrentGraphNode();
} // getKartNode
//-----------------------------------------------------------------------------
/** Called when the race finishes, i.e. after playing (if necessary) an
* end of race animation. It updates the time for all karts still racing,

View File

@ -29,10 +29,10 @@
#include <string>
class PhysicalObject;
class TrackSector;
/**
* \brief An implementation of World, to provide the 3 strikes battle game mode
* \brief An implementation of WorldWithRank, to provide the 3 strikes battle
* game mode
* \ingroup modes
*/
class ThreeStrikesBattle : public WorldWithRank
@ -71,11 +71,6 @@ private:
PtrVector<TrackObject, REF> m_tires;
std::vector<TrackSector*> m_kart_track_sector;
/** Function to update the locations of all karts on the navigation map */
void updateKartNodes();
/** Profiling usage */
int m_total_rescue;
int m_frame_count;
@ -95,31 +90,29 @@ public:
ThreeStrikesBattle();
virtual ~ThreeStrikesBattle();
virtual void init();
virtual void init() OVERRIDE;
// clock events
virtual bool isRaceOver();
virtual void terminateRace();
virtual bool isRaceOver() OVERRIDE;
virtual void terminateRace() OVERRIDE;
// overriding World methods
virtual void reset();
virtual void reset() OVERRIDE;
//virtual void getDefaultCollectibles(int& collectible_type, int& amount);
virtual bool useFastMusicNearEnd() const { return false; }
virtual bool useFastMusicNearEnd() const OVERRIDE { return false; }
virtual void getKartsDisplayInfo(
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
virtual bool raceHasLaps(){ return false; }
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
virtual bool raceHasLaps() OVERRIDE { return false; }
virtual const std::string& getIdent() const;
virtual const std::string& getIdent() const OVERRIDE;
virtual void kartHit(const unsigned int kart_id);
virtual void update(float dt);
virtual void kartHit(const unsigned int kart_id) OVERRIDE;
virtual void update(float dt) OVERRIDE;
virtual void kartAdded(AbstractKart* kart, scene::ISceneNode* node);
virtual void kartAdded(AbstractKart* kart, scene::ISceneNode* node) OVERRIDE;
virtual void enterRaceOverState() OVERRIDE;
int getKartNode(unsigned int kart_id) const;
void updateKartRanks();
void increaseRescueCount() { m_total_rescue++; }
}; // ThreeStrikesBattles

View File

@ -1237,20 +1237,36 @@ void World::unpause()
void World::delayedSelfDestruct()
{
m_self_destruct = true;
}
} // delayedSelfDestruct
//-----------------------------------------------------------------------------
void World::escapePressed()
{
new RacePausedDialog(0.8f, 0.6f);
}
} // escapePressed
//-----------------------------------------------------------------------------
bool World::isFogEnabled() const
{
return !m_force_disable_fog && (m_track != NULL && m_track->isFogEnabled());
}
} // isFogEnabled
// ----------------------------------------------------------------------------
/** Returns the start transform with the give index.
* \param rescue_pos Index of the start position to be returned.
* \returns The transform of the corresponding start position.
*/
btTransform World::getRescueTransform(unsigned int rescue_pos) const
{
return m_track->getStartTransform(rescue_pos);
} // getRescueTransform
//-----------------------------------------------------------------------------
/** Uses the start position as rescue positions, override if necessary
*/
unsigned int World::getNumberOfRescuePositions() const
{
return m_track->getNumberOfStartPositions();
} // getNumberOfRescuePositions
/* EOF */

View File

@ -221,13 +221,13 @@ public:
// ------------------------------------------------------------------------
/** Returns the number of rescue positions on a given track and game
* mode. */
virtual unsigned int getNumberOfRescuePositions() const = 0;
virtual unsigned int getNumberOfRescuePositions() const;
// ------------------------------------------------------------------------
/** Determines the rescue position index of the specified kart. */
virtual unsigned int getRescuePositionIndex(AbstractKart *kart) = 0;
// ------------------------------------------------------------------------
/** Returns the bullet transformation for the specified rescue index. */
virtual btTransform getRescueTransform(unsigned int index) const = 0;
virtual btTransform getRescueTransform(unsigned int index) const;
// ------------------------------------------------------------------------
virtual void moveKartAfterRescue(AbstractKart* kart);
// ------------------------------------------------------------------------

View File

@ -20,11 +20,23 @@
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "race/history.hpp"
#include "tracks/graph.hpp"
#include "tracks/track.hpp"
#include "tracks/track_sector.hpp"
#include "utils/log.hpp"
#include <iostream>
//-----------------------------------------------------------------------------
WorldWithRank::~WorldWithRank()
{
for (unsigned int i = 0; i < m_kart_track_sector.size(); i++)
{
delete m_kart_track_sector[i];
}
m_kart_track_sector.clear();
} // ~WorldWithRank
//-----------------------------------------------------------------------------
void WorldWithRank::init()
{
@ -39,8 +51,23 @@ void WorldWithRank::init()
#endif
stk_config->getAllScores(&m_score_for_position, getNumKarts());
// Don't init track sector if navmesh is not found in arena
if ((m_track->isArena() || m_track->isSoccer()) && !m_track->hasNavMesh())
return;
for (unsigned int i = 0; i < m_karts.size(); i++)
m_kart_track_sector.push_back(new TrackSector());
} // init
//-----------------------------------------------------------------------------
void WorldWithRank::reset()
{
World::reset();
for (unsigned int i = 0; i < m_kart_track_sector.size(); i++)
getTrackSector(i)->update(m_karts[i]->getXYZ());
} // reset
//-----------------------------------------------------------------------------
/** Returns the kart with a given position.
* \param p The position of the kart, 1<=p<=num_karts).
@ -124,16 +151,6 @@ void WorldWithRank::endSetKartPositions()
#endif
} // endSetKartPositions
//-----------------------------------------------------------------------------
/** WorldWithRank uses the start position as rescue positions. So return
* the number of start positions.
*/
unsigned int WorldWithRank::getNumberOfRescuePositions() const
{
return getTrack()->getNumberOfStartPositions();
} // getNumberOfRescuePositions
//-----------------------------------------------------------------------------
/** Determines the rescue position for a kart. The rescue position is the
* start position which is has the biggest accumulated distance to all other
@ -184,16 +201,6 @@ unsigned int WorldWithRank::getRescuePositionIndex(AbstractKart *kart)
return furthest_id_found;
} // getRescuePositionIndex
// ----------------------------------------------------------------------------
/** Returns the start transform with the give index.
* \param rescue_pos Index of the start position to be returned.
* \returns The transform of the corresponding start position.
*/
btTransform WorldWithRank::getRescueTransform(unsigned int rescue_pos) const
{
return getTrack()->getStartTransform(rescue_pos);
} // getRescueTransform
//-----------------------------------------------------------------------------
/** Returns the number of points for a kart at a specified position.
* \param p Position (starting with 1).
@ -204,3 +211,44 @@ int WorldWithRank::getScoreForPosition(int p)
assert(p - 1 <(int) m_score_for_position.size());
return m_score_for_position[p - 1];
} // getScoreForPosition
//-----------------------------------------------------------------------------
/** Returns true if the kart is on a valid graph quad.
* \param kart_index Index of the kart.
*/
bool WorldWithRank::isOnRoad(unsigned int kart_index) const
{
return getTrackSector(kart_index)->isOnRoad();
} // isOnRoad
//-----------------------------------------------------------------------------
/** Gets the sector a kart is on. This function returns UNKNOWN_SECTOR if the
* kart_id is larger than the current kart sector. This is necessary in the
* case that a collision with the track happens during resetAllKarts: at this
* time m_kart_track_sector is not initialised (and has size 0), so it would
* trigger this assert. While this normally does not happen, it is useful for
* track designers that STK does not crash.
* \param kart Kart for which to return the sector.
*/
int WorldWithRank::getSectorForKart(const AbstractKart *kart) const
{
if (kart->getWorldKartId() >= m_kart_track_sector.size())
return Graph::UNKNOWN_SECTOR;
return getTrackSector(kart->getWorldKartId())->getCurrentGraphNode();
} // getSectorForKart
//-----------------------------------------------------------------------------
/** Localize each kart on the graph using its center xyz.
*/
void WorldWithRank::updateSectorForKarts()
{
if (isRaceOver()) return;
const unsigned int n = getNumKarts();
assert(n == m_kart_track_sector.size());
for (unsigned int i = 0; i < n; i++)
{
if (m_karts[i]->isEliminated()) continue;
getTrackSector(i)->update(m_karts[i]->getXYZ());
}
} // updateSectorForKarts

View File

@ -23,6 +23,7 @@
#include "modes/world.hpp"
class AbstractKart;
class TrackSector;
/**
* A WorldWithRank is a world where the karts are ranked. This is the base
@ -60,28 +61,42 @@ protected:
unsigned int getClosestStartPoint(AbstractKart *kart);
/** Stores the current graph node and track coordinates for each kart. */
std::vector<TrackSector*> m_kart_track_sector;
// ------------------------------------------------------------------------
void updateSectorForKarts();
public:
WorldWithRank() : World() {}
virtual ~WorldWithRank();
/** call just after instanciating. can't be moved to the contructor as child
classes must be instanciated, otherwise polymorphism will fail and the
results will be incorrect */
virtual void init() OVERRIDE;
virtual void reset() OVERRIDE;
bool displayRank() const { return m_display_rank; }
void beginSetKartPositions();
bool setKartPosition(unsigned int kart_id,
unsigned int position);
unsigned int position);
void endSetKartPositions();
AbstractKart* getKartAtPosition(unsigned int p) const;
virtual int getScoreForPosition(int p);
virtual unsigned int getNumberOfRescuePositions() const OVERRIDE;
virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE;
virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE;
// ------------------------------------------------------------------------
/** Returns the track_sector object for the specified kart.
* \param kart_index World index of the kart. */
TrackSector* getTrackSector(unsigned int kart_index) const
{
assert(kart_index < m_kart_track_sector.size());
return m_kart_track_sector[kart_index];
} // getTrackSector
// ------------------------------------------------------------------------
bool isOnRoad(unsigned int kart_index) const;
// ------------------------------------------------------------------------
int getSectorForKart(const AbstractKart *kart) const;
}; // WorldWithRank