Make gift package playable
This commit is contained in:
parent
cc92ee6ef3
commit
91b9d13611
@ -532,10 +532,9 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
|
||||
for (unsigned int j = 0; j < used_location.size(); j++)
|
||||
{
|
||||
if (!found) continue;
|
||||
Vec3 d = BattleGraph::get()
|
||||
->getPolyOfNode(used_location[j]).getCenter() -
|
||||
BattleGraph::get()->getPolyOfNode(node).getCenter();
|
||||
found = d.length_2d() > MIN_DIST;
|
||||
float test_distance = BattleGraph::get()
|
||||
->getDistance(used_location[j], node);
|
||||
found = test_distance > MIN_DIST;
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ ArenaAI::ArenaAI(AbstractKart *kart)
|
||||
void ArenaAI::reset()
|
||||
{
|
||||
m_target_node = BattleGraph::UNKNOWN_POLY;
|
||||
m_current_forward_node = BattleGraph::UNKNOWN_POLY;
|
||||
m_current_forward_point = Vec3(0, 0, 0);
|
||||
m_adjusting_side = false;
|
||||
m_closest_kart = NULL;
|
||||
m_closest_kart_node = BattleGraph::UNKNOWN_POLY;
|
||||
@ -57,8 +59,7 @@ void ArenaAI::reset()
|
||||
m_time_since_reversing = 0.0f;
|
||||
m_time_since_uturn = 0.0f;
|
||||
m_on_node.clear();
|
||||
m_path_corners.clear();
|
||||
m_portals.clear();
|
||||
m_aiming_points.clear();
|
||||
|
||||
m_cur_difficulty = race_manager->getDifficulty();
|
||||
AIBaseController::reset();
|
||||
@ -119,6 +120,108 @@ void ArenaAI::update(float dt)
|
||||
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ArenaAI::getAimingPoints()
|
||||
{
|
||||
m_current_forward_point =
|
||||
m_kart->getTrans()(Vec3(0, 0, m_kart->getKartLength()));
|
||||
m_current_forward_node = BattleGraph::get()->pointToNode
|
||||
(m_current_forward_node, m_current_forward_point,
|
||||
false/*ignore_vertical*/);
|
||||
|
||||
if (m_current_forward_node == BattleGraph::UNKNOWN_POLY ||
|
||||
m_current_forward_node == m_target_node)
|
||||
m_current_forward_node = getCurrentNode();
|
||||
|
||||
int first = m_current_forward_node;
|
||||
int last = m_target_node;
|
||||
|
||||
if (first == BattleGraph::UNKNOWN_POLY ||
|
||||
last == BattleGraph::UNKNOWN_POLY)
|
||||
return false;
|
||||
|
||||
if (m_current_forward_node == m_target_node)
|
||||
{
|
||||
m_aiming_points.push_back(BattleGraph::get()
|
||||
->getPolyOfNode(first).getCenter());
|
||||
m_aiming_points.push_back(m_target_point);
|
||||
return true;
|
||||
}
|
||||
|
||||
m_aiming_points.push_back(BattleGraph::get()
|
||||
->getPolyOfNode(first).getCenter());
|
||||
const int next_node = BattleGraph::get()
|
||||
->getNextShortestPathPoly(first, last);
|
||||
assert(next_node != BattleGraph::UNKNOWN_POLY);
|
||||
|
||||
m_aiming_points.push_back(BattleGraph::get()
|
||||
->getPolyOfNode(next_node).getCenter());
|
||||
|
||||
return true;
|
||||
} // getAimingPoints
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function sets the steering.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void ArenaAI::handleArenaSteering(const float dt)
|
||||
{
|
||||
const int current_node = getCurrentNode();
|
||||
|
||||
if (current_node == BattleGraph::UNKNOWN_POLY ||
|
||||
m_target_node == BattleGraph::UNKNOWN_POLY) return;
|
||||
|
||||
m_aiming_points.clear();
|
||||
const bool found_points = getAimingPoints();
|
||||
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)
|
||||
{
|
||||
m_adjusting_side = m_cur_kart_pos_data.lhs;
|
||||
m_is_uturn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float target_angle = steerToPoint(m_target_point);
|
||||
setSteering(target_angle, dt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (found_points)
|
||||
{
|
||||
m_target_point = m_aiming_points[1];
|
||||
checkPosition(m_target_point, &m_cur_kart_pos_data);
|
||||
#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)
|
||||
{
|
||||
m_adjusting_side = m_cur_kart_pos_data.lhs;
|
||||
m_is_uturn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float target_angle = steerToPoint(m_target_point);
|
||||
setSteering(target_angle, dt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do nothing (go straight) if no targets found
|
||||
setSteering(0.0f, dt);
|
||||
return;
|
||||
}
|
||||
} // handleSteering
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ArenaAI::checkIfStuck(const float dt)
|
||||
{
|
||||
@ -230,82 +333,6 @@ bool ArenaAI::handleArenaUnstuck(const float dt)
|
||||
|
||||
} // handleArenaUnstuck
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function sets the steering.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void ArenaAI::handleArenaSteering(const float dt)
|
||||
{
|
||||
const int current_node = getCurrentNode();
|
||||
|
||||
if (current_node == BattleGraph::UNKNOWN_POLY ||
|
||||
m_target_node == BattleGraph::UNKNOWN_POLY) return;
|
||||
|
||||
if (m_target_node == current_node || ignorePathFinding())
|
||||
{
|
||||
// Very close to the item, steer directly
|
||||
m_path_corners.clear();
|
||||
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)
|
||||
{
|
||||
m_adjusting_side = m_cur_kart_pos_data.lhs;
|
||||
m_is_uturn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float target_angle = steerToPoint(m_target_point);
|
||||
setSteering(target_angle, dt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else if (m_target_node != current_node)
|
||||
{
|
||||
findPortals(current_node, m_target_node);
|
||||
stringPull(m_kart->getXYZ(), m_target_point);
|
||||
if (m_path_corners.size() > 0)
|
||||
m_target_point = m_path_corners[0];
|
||||
|
||||
checkPosition(m_target_point, &m_cur_kart_pos_data);
|
||||
#ifdef AI_DEBUG
|
||||
m_debug_sphere->setPosition(m_path_corners[0].toIrrVector());
|
||||
/*if (m_path_corners.size() > 2)
|
||||
{
|
||||
m_debug_sphere->setVisible(true);
|
||||
m_debug_sphere_next->setVisible(true);
|
||||
m_debug_sphere->setPosition(m_path_corners[1].toIrrVector());
|
||||
m_debug_sphere_next->setPosition(m_path_corners[2].toIrrVector());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_debug_sphere->setVisible(false);
|
||||
m_debug_sphere_next->setVisible(false);
|
||||
}*/
|
||||
#endif
|
||||
if (m_cur_kart_pos_data.behind)
|
||||
{
|
||||
m_adjusting_side = m_cur_kart_pos_data.lhs;
|
||||
m_is_uturn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float target_angle = steerToPoint(m_target_point);
|
||||
setSteering(target_angle, dt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Do nothing (go straight) if no targets found
|
||||
setSteering(0.0f, dt);
|
||||
return;
|
||||
}
|
||||
} // handleSteering
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ArenaAI::handleArenaBanana()
|
||||
{
|
||||
@ -341,155 +368,6 @@ void ArenaAI::handleArenaBanana()
|
||||
|
||||
} // handleArenaBanana
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function finds the polyon edges(portals) that the AI will cross before
|
||||
* reaching its destination. We start from the current polygon and call
|
||||
* BattleGraph::getNextShortestPathPoly() to find the next polygon on the shortest
|
||||
* path to the destination. Then find the common edge between the current
|
||||
* poly and the next poly, store it and step through the channel.
|
||||
*
|
||||
* 1----2----3 In this case, the portals are:
|
||||
* |strt| | (2,5) (4,5) (10,7) (10,9) (11,12)
|
||||
* 6----5----4
|
||||
* | |
|
||||
* 7----10----11----14
|
||||
* | | | end |
|
||||
* 8----9-----12----13
|
||||
*
|
||||
* \param start The start node(polygon) of the channel.
|
||||
* \param end The end node(polygon) of the channel.
|
||||
*/
|
||||
void ArenaAI::findPortals(int start, int end)
|
||||
{
|
||||
int this_node = start;
|
||||
|
||||
// We can't use NULL because NULL==0 which is a valid node, so we initialize
|
||||
// with a value that is always invalid.
|
||||
int next_node = -999;
|
||||
|
||||
m_portals.clear();
|
||||
|
||||
while (next_node != end && this_node != -1 && next_node != -1 && this_node != end)
|
||||
{
|
||||
next_node = BattleGraph::get()->getNextShortestPathPoly(this_node, end);
|
||||
if (next_node == BattleGraph::UNKNOWN_POLY || next_node == -999) return;
|
||||
|
||||
std::vector<int> this_node_verts =
|
||||
NavMesh::get()->getNavPoly(this_node).getVerticesIndex();
|
||||
std::vector<int> next_node_verts=
|
||||
NavMesh::get()->getNavPoly(next_node).getVerticesIndex();
|
||||
|
||||
// this_node_verts and next_node_verts hold vertices of polygons in CCW order
|
||||
// We reverse next_node_verts so it becomes easy to compare edges in the next step
|
||||
std::reverse(next_node_verts.begin(),next_node_verts.end());
|
||||
|
||||
Vec3 portalLeft, portalRight;
|
||||
//bool flag = 0;
|
||||
for (unsigned int n_i = 0; n_i < next_node_verts.size(); n_i++)
|
||||
{
|
||||
for (unsigned int t_i = 0; t_i < this_node_verts.size(); t_i++)
|
||||
{
|
||||
if ((next_node_verts[n_i] == this_node_verts[t_i]) &&
|
||||
(next_node_verts[(n_i+1)%next_node_verts.size()] ==
|
||||
this_node_verts[(t_i+1)%this_node_verts.size()]))
|
||||
{
|
||||
portalLeft = NavMesh::get()->
|
||||
getVertex(this_node_verts[(t_i+1)%this_node_verts.size()]);
|
||||
|
||||
portalRight = NavMesh::get()->getVertex(this_node_verts[t_i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_portals.push_back(std::make_pair(portalLeft, portalRight));
|
||||
// for debugging:
|
||||
//m_debug_sphere->setPosition((portalLeft).toIrrVector());
|
||||
this_node = next_node;
|
||||
}
|
||||
} // findPortals
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function implements the funnel algorithm for finding shortest paths
|
||||
* through a polygon channel. This means that we should move from corner to
|
||||
* corner to move on the most straight and shortest path to the destination.
|
||||
* This can be visualized as pulling a string from the end point to the start.
|
||||
* The string will bend at the corners, and this algorithm will find those
|
||||
* corners using portals from findPortals(). The AI will aim at the first
|
||||
* corner and the rest can be used for estimating the curve (braking).
|
||||
*
|
||||
* 1----2----3 In this case, the corners are:
|
||||
* |strt| | <5,10,end>
|
||||
* 6----5----4
|
||||
* | |
|
||||
* 7----10----11----14
|
||||
* | | | end |
|
||||
* 8----9-----12----13
|
||||
*
|
||||
* \param start_pos The start position (usually the AI's current position).
|
||||
* \param end_pos The end position (m_target_point).
|
||||
*/
|
||||
void ArenaAI::stringPull(const Vec3& start_pos, const Vec3& end_pos)
|
||||
{
|
||||
Vec3 funnel_apex = start_pos;
|
||||
Vec3 funnel_left = m_portals[0].first;
|
||||
Vec3 funnel_right = m_portals[0].second;
|
||||
unsigned int apex_index=0, fun_left_index=0, fun_right_index=0;
|
||||
m_portals.push_back(std::make_pair(end_pos, end_pos));
|
||||
m_path_corners.clear();
|
||||
const float eps=0.0001f;
|
||||
|
||||
for (unsigned int i = 0; i < m_portals.size(); i++)
|
||||
{
|
||||
Vec3 portal_left = m_portals[i].first;
|
||||
Vec3 portal_right = m_portals[i].second;
|
||||
|
||||
//Compute for left edge
|
||||
if ((funnel_left == funnel_apex) ||
|
||||
portal_left.sideOfLine2D(funnel_apex, funnel_left) <= -eps)
|
||||
{
|
||||
funnel_left = 0.98f*portal_left + 0.02f*portal_right;
|
||||
//funnel_left = portal_left;
|
||||
fun_left_index = i;
|
||||
|
||||
if (portal_left.sideOfLine2D(funnel_apex, funnel_right) < -eps)
|
||||
{
|
||||
funnel_apex = funnel_right;
|
||||
apex_index = fun_right_index;
|
||||
m_path_corners.push_back(funnel_apex);
|
||||
|
||||
funnel_left = funnel_apex;
|
||||
funnel_right = funnel_apex;
|
||||
i = apex_index;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//Compute for right edge
|
||||
if ((funnel_right == funnel_apex) ||
|
||||
portal_right.sideOfLine2D(funnel_apex, funnel_right) >= eps)
|
||||
{
|
||||
funnel_right = 0.98f*portal_right + 0.02f*portal_left;
|
||||
//funnel_right = portal_right;
|
||||
fun_right_index = i;
|
||||
|
||||
if (portal_right.sideOfLine2D(funnel_apex, funnel_left) > eps)
|
||||
{
|
||||
funnel_apex = funnel_left;
|
||||
apex_index = fun_left_index;
|
||||
m_path_corners.push_back(funnel_apex);
|
||||
|
||||
funnel_left = funnel_apex;
|
||||
funnel_right = funnel_apex;
|
||||
i = apex_index;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Push end_pos to m_path_corners so if no corners, we aim at target
|
||||
m_path_corners.push_back(end_pos);
|
||||
} // stringPull
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This function handles braking. It calls determineTurnRadius() to find out
|
||||
* the curve radius. Depending on the turn radius, it finds out the maximum
|
||||
@ -515,16 +393,16 @@ void ArenaAI::handleArenaBraking()
|
||||
if (getCurrentNode() == BattleGraph::UNKNOWN_POLY ||
|
||||
m_target_node == BattleGraph::UNKNOWN_POLY) return;
|
||||
|
||||
if (m_path_corners.empty()) return;
|
||||
if (m_aiming_points.empty()) return;
|
||||
|
||||
float current_curve_radius = determineTurnRadius(m_kart->getXYZ(),
|
||||
m_path_corners[0], (m_path_corners.size() >= 2 ? m_path_corners[1] :
|
||||
m_path_corners[0]));
|
||||
m_aiming_points[0], m_aiming_points[1]);
|
||||
|
||||
float max_turn_speed = m_kart->getSpeedForTurnRadius(current_curve_radius);
|
||||
|
||||
if (m_kart->getSpeed() > max_turn_speed &&
|
||||
m_kart->getSpeed() > MIN_SPEED)
|
||||
m_kart->getSpeed() > MIN_SPEED &&
|
||||
fabsf(m_controls->m_steer) > 0.3f)
|
||||
{
|
||||
m_controls->m_brake = true;
|
||||
}
|
||||
@ -534,8 +412,8 @@ void ArenaAI::handleArenaBraking()
|
||||
//-----------------------------------------------------------------------------
|
||||
/** The turn radius is determined by fitting a parabola to 3 points: current
|
||||
* location of AI, first corner and the second corner. Once the constants are
|
||||
* computed, a formula is used to find the radius of curvature at the kart's
|
||||
* current location.
|
||||
* computed, a formula is used to find the radius of curvature at the vertex
|
||||
* of the parabola.
|
||||
*/
|
||||
float ArenaAI::determineTurnRadius(const Vec3& p1, const Vec3& p2,
|
||||
const Vec3& p3)
|
||||
@ -549,23 +427,26 @@ float ArenaAI::determineTurnRadius(const Vec3& p1, const Vec3& p2,
|
||||
// Avoid nan, this will happen if three values of coordinates x are too
|
||||
// close together, ie a straight line, return a large radius
|
||||
// so no braking is needed
|
||||
if (fabsf(denominator) < eps) return 25.0f;
|
||||
if (fabsf(denominator) < eps) return 40.0f;
|
||||
|
||||
const float a = (p3.x() * (p2.z() - p1.z()) +
|
||||
p2.x() * (p1.z() - p3.z()) +
|
||||
p1.x() * (p3.z() - p2.z())) / denominator;
|
||||
|
||||
// Should not happen, otherwise y=c which is a straight line
|
||||
if (fabsf(a) < eps) return 25.0f;
|
||||
if (fabsf(a) < eps) return 40.0f;
|
||||
|
||||
const float b = (p3.x() * p3.x() * (p1.z() - p2.z()) +
|
||||
p2.x() * p2.x() * (p3.z() - p1.z()) +
|
||||
p1.x() * p1.x() * (p2.z() - p3.z())) / denominator;
|
||||
|
||||
// Vertex: -b / 2a
|
||||
const float vertex_x = -b / (2 * a);
|
||||
|
||||
// Differentiate the function, so y=ax2+bx+c will become y=2ax+b for dy_dx,
|
||||
// y=2a for d2y_dx2
|
||||
// Use the p1 (current location of AI) as x
|
||||
const float dy_dx = 2 * a * p1.x() + b;
|
||||
// Use the vertex of the parabola as x
|
||||
const float dy_dx = 2 * a * vertex_x + b;
|
||||
const float d2y_dx2 = 2 * a;
|
||||
|
||||
// Calculate the radius of curvature at current location of AI
|
||||
@ -573,7 +454,7 @@ float ArenaAI::determineTurnRadius(const Vec3& p1, const Vec3& p2,
|
||||
assert(!std::isnan(radius));
|
||||
|
||||
// Avoid returning too large radius
|
||||
return (radius > 25.0f ? 25.0f : radius);
|
||||
return (radius > 40.0f ? 40.0f : radius);
|
||||
} // determineTurnRadius
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -765,14 +646,15 @@ void ArenaAI::collectItemInArena(Vec3* aim_point, int* target_node) const
|
||||
m_kart->getKartProperties()->getNitroSmallContainer()))
|
||||
continue; // Ignore nitro when already has some
|
||||
|
||||
Vec3 d = item->getXYZ() - m_kart->getXYZ();
|
||||
if (d.length_2d() <= distance &&
|
||||
float test_distance = BattleGraph::get()
|
||||
->getDistance(item_list[i].second, getCurrentNode());
|
||||
if (test_distance <= distance &&
|
||||
(item->getType() == Item::ITEM_BONUS_BOX ||
|
||||
item->getType() == Item::ITEM_NITRO_BIG ||
|
||||
item->getType() == Item::ITEM_NITRO_SMALL))
|
||||
{
|
||||
closest_item_num = i;
|
||||
distance = d.length_2d();
|
||||
distance = test_distance;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,9 @@ protected:
|
||||
/** The target point. */
|
||||
Vec3 m_target_point;
|
||||
|
||||
int m_current_forward_node;
|
||||
Vec3 m_current_forward_point;
|
||||
|
||||
/** For ignorePathFinding() to work */
|
||||
bool m_avoid_eating_banana;
|
||||
|
||||
@ -85,15 +88,9 @@ private:
|
||||
|
||||
/** Holds the unique node ai has driven through, useful to tell if AI is
|
||||
* stuck by determine the size of this set. */
|
||||
std::set <int> m_on_node;
|
||||
std::set<int> m_on_node;
|
||||
|
||||
/** Holds the corner points computed using the funnel algorithm that the AI
|
||||
* will eventaully move through. See stringPull(). */
|
||||
std::vector<Vec3> m_path_corners;
|
||||
|
||||
/** Holds the set of portals that the kart will cross when moving through
|
||||
* polygon channel. See findPortals(). */
|
||||
std::vector<std::pair<Vec3,Vec3> > m_portals;
|
||||
std::vector<Vec3> m_aiming_points;
|
||||
|
||||
/** Time an item has been collected and not used. */
|
||||
float m_time_since_last_shot;
|
||||
@ -110,7 +107,6 @@ private:
|
||||
void checkIfStuck(const float dt);
|
||||
float determineTurnRadius(const Vec3& p1, const Vec3& p2,
|
||||
const Vec3& p3);
|
||||
void findPortals(int start, int end);
|
||||
void handleArenaAcceleration(const float dt);
|
||||
void handleArenaBanana();
|
||||
void handleArenaBraking();
|
||||
@ -118,7 +114,7 @@ private:
|
||||
void handleArenaSteering(const float dt);
|
||||
void handleArenaUTurn(const float dt);
|
||||
bool handleArenaUnstuck(const float dt);
|
||||
void stringPull(const Vec3&, const Vec3&);
|
||||
bool getAimingPoints();
|
||||
virtual int getCurrentNode() const = 0;
|
||||
virtual bool isWaiting() const = 0;
|
||||
virtual void resetAfterStop() {};
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/kart_control.hpp"
|
||||
#include "modes/three_strikes_battle.hpp"
|
||||
#include "tracks/battle_graph.hpp"
|
||||
|
||||
#ifdef AI_DEBUG
|
||||
#include "irrlicht.h"
|
||||
@ -118,10 +119,11 @@ void BattleAI::findClosestKart(bool use_difficulty)
|
||||
continue;
|
||||
}
|
||||
|
||||
Vec3 d = kart->getXYZ() - m_kart->getXYZ();
|
||||
if (d.length_2d() <= distance)
|
||||
float test_distance = BattleGraph::get()->getDistance(m_world
|
||||
->getKartNode(kart->getWorldKartId()), getCurrentNode());
|
||||
if (test_distance <= distance)
|
||||
{
|
||||
distance = d.length_2d();
|
||||
distance = test_distance;
|
||||
closest_kart_num = i;
|
||||
}
|
||||
}
|
||||
@ -134,6 +136,7 @@ void BattleAI::findClosestKart(bool use_difficulty)
|
||||
{
|
||||
m_closest_kart = m_world->getKart(closest_kart_num);
|
||||
checkPosition(m_closest_kart_point, &m_closest_kart_pos_data);
|
||||
m_closest_kart_pos_data.distance = distance;
|
||||
|
||||
// Do a mini-skid to closest kart only when firing target,
|
||||
// not straight ahead, not too far, in front of it
|
||||
|
@ -120,6 +120,15 @@ public:
|
||||
{ return m_distance_matrix.size(); }
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns the distance between any two nodes */
|
||||
float getDistance(int from, int to) const
|
||||
{
|
||||
if (from == BattleGraph::UNKNOWN_POLY ||
|
||||
to == BattleGraph::UNKNOWN_POLY)
|
||||
return 0.0f;
|
||||
return m_distance_matrix[from][to];
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the NavPoly corresponding to the i-th node of the BattleGraph */
|
||||
const NavPoly& getPolyOfNode(int i) const
|
||||
{ return NavMesh::get()->getNavPoly(i); }
|
||||
|
Loading…
Reference in New Issue
Block a user