Merge branch 'walldriving' of github.com:supertuxkart/stk-code into walldriving
This commit is contained in:
commit
2e38154bd6
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user