Move check manager to track to allow copying easier later

This commit is contained in:
Benau
2020-02-24 10:57:57 +08:00
parent 306eb1b531
commit 3d13686af7
18 changed files with 272 additions and 254 deletions

View File

@@ -78,7 +78,7 @@ RubberBall::RubberBall(AbstractKart *kart)
void RubberBall::onFireFlyable()
{
Flyable::onFireFlyable();
CheckManager::get()->addFlyableToCannons(this);
Track::getCurrentTrack()->getCheckManager()->addFlyableToCannons(this);
// Don't let Flyable update the terrain information, since this object
// has to do it earlier than that.
setDoTerrainInfo(false);
@@ -129,7 +129,7 @@ void RubberBall::onFireFlyable()
RubberBall::~RubberBall()
{
removePingSFX();
CheckManager::get()->removeFlyableFromCannons(this);
Track::getCurrentTrack()->getCheckManager()->removeFlyableFromCannons(this);
} // ~RubberBall
// ----------------------------------------------------------------------------

View File

@@ -29,6 +29,7 @@
#include "network/network_string.hpp"
#include "tracks/check_cannon.hpp"
#include "tracks/check_manager.hpp"
#include "tracks/track.hpp"
#include "utils/mini_glm.hpp"
#include "LinearMath/btTransform.h"
@@ -399,13 +400,14 @@ void CannonAnimation::restoreData(BareNetworkString* buffer)
};
int cc_idx = buffer->getInt8();
if ((unsigned)cc_idx > CheckManager::get()->getCheckStructureCount())
CheckManager* cm = Track::getCurrentTrack()->getCheckManager();
if ((unsigned)cc_idx > cm->getCheckStructureCount())
{
throw CannonCreationException(
"Server has different check structure size.", skipping_offset);
}
CheckCannon* cc = dynamic_cast<CheckCannon*>
(CheckManager::get()->getCheckStructure(cc_idx));
(cm->getCheckStructure(cc_idx));
if (!cc)
{
throw CannonCreationException(

View File

@@ -1163,10 +1163,11 @@ void LinearWorld::saveCompleteState(BareNetworkString* bns, STKPeer* peer)
for (TrackSector* ts : m_kart_track_sector)
ts->saveCompleteState(bns);
const uint8_t cc = (uint8_t)CheckManager::get()->getCheckStructureCount();
CheckManager* cm = Track::getCurrentTrack()->getCheckManager();
const uint8_t cc = (uint8_t)cm->getCheckStructureCount();
bns->addUInt8(cc);
for (unsigned i = 0; i < cc; i++)
CheckManager::get()->getCheckStructure(i)->saveCompleteState(bns);
cm->getCheckStructure(i)->saveCompleteState(bns);
} // saveCompleteState
// ----------------------------------------------------------------------------
@@ -1190,14 +1191,15 @@ void LinearWorld::restoreCompleteState(const BareNetworkString& b)
updateRacePosition();
const unsigned cc = b.getUInt8();
if (cc != CheckManager::get()->getCheckStructureCount())
CheckManager* cm = Track::getCurrentTrack()->getCheckManager();
if (cc != cm->getCheckStructureCount())
{
Log::warn("LinearWorld",
"Server has different check structures size.");
return;
}
for (unsigned i = 0; i < cc; i++)
CheckManager::get()->getCheckStructure(i)->restoreCompleteState(b);
cm->getCheckStructure(i)->restoreCompleteState(b);
} // restoreCompleteState
// ----------------------------------------------------------------------------
@@ -1229,10 +1231,11 @@ void LinearWorld::updateCheckLinesServer(int check_id, int kart_id)
cl.addUInt32(m_fastest_lap_ticks);
cl.encodeString(m_fastest_lap_kart_name);
const uint8_t cc = (uint8_t)CheckManager::get()->getCheckStructureCount();
CheckManager* cm = Track::getCurrentTrack()->getCheckManager();
const uint8_t cc = (uint8_t)cm->getCheckStructureCount();
cl.addUInt8(cc);
for (unsigned i = 0; i < cc; i++)
CheckManager::get()->getCheckStructure(i)->saveIsActive(kart_id, &cl);
cm->getCheckStructure(i)->saveIsActive(kart_id, &cl);
STKHost::get()->sendPacketToAllPeers(&cl, true);
} // updateCheckLinesServer
@@ -1256,17 +1259,17 @@ void LinearWorld::updateCheckLinesClient(const BareNetworkString& b)
b.decodeStringW(&m_fastest_lap_kart_name);
const unsigned cc = b.getUInt8();
if (cc != CheckManager::get()->getCheckStructureCount())
if (cc != Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount())
return;
for (unsigned i = 0; i < cc; i++)
CheckManager::get()->getCheckStructure(i)->restoreIsActive(kart_id, b);
Track::getCurrentTrack()->getCheckManager()->getCheckStructure(i)->restoreIsActive(kart_id, b);
} // updateCheckLinesClient
// ----------------------------------------------------------------------------
void LinearWorld::handleServerCheckStructureCount(unsigned count)
{
if (count != CheckManager::get()->getCheckStructureCount())
if (count != Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount())
{
Log::warn("LinearWorld",
"Server has different check structures size.");

View File

@@ -35,6 +35,8 @@
#include "network/stk_peer.hpp"
#include "physics/physics.hpp"
#include "states_screens/race_gui_base.hpp"
#include "tracks/check_goal.hpp"
#include "tracks/check_manager.hpp"
#include "tracks/graph.hpp"
#include "tracks/quad.hpp"
#include "tracks/track.hpp"
@@ -46,6 +48,189 @@
#include <IMeshSceneNode.h>
#include <numeric>
#include <string>
//=============================================================================
class BallGoalData
{
// These data are used by AI to determine ball aiming angle
private:
// Radius of the ball
float m_radius;
// Slope of the line from ball to the center point of goals
float m_red_goal_slope;
float m_blue_goal_slope;
// The transform only takes the ball heading into account,
// ie no hpr of ball which allowing setting aim point easier
btTransform m_trans;
// Two goals
CheckGoal* m_blue_check_goal;
CheckGoal* m_red_check_goal;
// Location to red/blue goal points from the ball heading point of view
Vec3 m_red_goal_1;
Vec3 m_red_goal_2;
Vec3 m_red_goal_3;
Vec3 m_blue_goal_1;
Vec3 m_blue_goal_2;
Vec3 m_blue_goal_3;
public:
void reset()
{
m_red_goal_1 = Vec3(0, 0, 0);
m_red_goal_2 = Vec3(0, 0, 0);
m_red_goal_3 = Vec3(0, 0, 0);
m_blue_goal_1 = Vec3(0, 0, 0);
m_blue_goal_2 = Vec3(0, 0, 0);
m_blue_goal_3 = Vec3(0, 0, 0);
m_red_goal_slope = 1.0f;
m_blue_goal_slope = 1.0f;
m_trans = btTransform(btQuaternion(0, 0, 0, 1), Vec3(0, 0, 0));
} // reset
float getDiameter() const
{
return m_radius * 2;
} // getDiameter
void init(float ball_radius)
{
m_radius = ball_radius;
assert(m_radius > 0.0f);
// Save two goals
CheckManager* cm = Track::getCurrentTrack()->getCheckManager();
unsigned int n = cm->getCheckStructureCount();
for (unsigned int i = 0; i < n; i++)
{
CheckGoal* goal = dynamic_cast<CheckGoal*>
(cm->getCheckStructure(i));
if (goal)
{
if (goal->getTeam())
m_blue_check_goal = goal;
else
m_red_check_goal = goal;
}
}
if (m_blue_check_goal == NULL || m_red_check_goal == NULL)
{
Log::error("SoccerWorld", "Goal(s) is missing!");
}
} // init
void updateBallAndGoal(const Vec3& ball_pos, float heading)
{
btQuaternion quat(Vec3(0, 1, 0), -heading);
m_trans = btTransform(btQuaternion(Vec3(0, 1, 0), heading),
ball_pos);
// Red goal
m_red_goal_1 = quatRotate(quat, m_red_check_goal
->getPoint(CheckGoal::POINT_FIRST) - ball_pos);
m_red_goal_2 = quatRotate(quat, m_red_check_goal
->getPoint(CheckGoal::POINT_CENTER) - ball_pos);
m_red_goal_3 = quatRotate(quat, m_red_check_goal
->getPoint(CheckGoal::POINT_LAST) - ball_pos);
// Blue goal
m_blue_goal_1 = quatRotate(quat, m_blue_check_goal
->getPoint(CheckGoal::POINT_FIRST) - ball_pos);
m_blue_goal_2 = quatRotate(quat, m_blue_check_goal
->getPoint(CheckGoal::POINT_CENTER) - ball_pos);
m_blue_goal_3 = quatRotate(quat, m_blue_check_goal
->getPoint(CheckGoal::POINT_LAST) - ball_pos);
// Update the slope:
// Use y = mx + c as an equation from goal center to ball
// As the line always intercept in (0,0) which is the ball location,
// so y(z)/x is the slope , it is used for determine aiming position
// of ball later
m_red_goal_slope = m_red_goal_2.z() / m_red_goal_2.x();
m_blue_goal_slope = m_blue_goal_2.z() / m_blue_goal_2.x();
} // updateBallAndGoal
bool isApproachingGoal(KartTeam team) const
{
// If the ball lies between the first and last pos, and faces
// in front of either of them, (inside angular size of goal)
// than it's likely to goal
if (team == KART_TEAM_BLUE)
{
if ((m_blue_goal_1.z() > 0.0f || m_blue_goal_3.z() > 0.0f) &&
((m_blue_goal_1.x() < 0.0f && m_blue_goal_3.x() > 0.0f) ||
(m_blue_goal_3.x() < 0.0f && m_blue_goal_1.x() > 0.0f)))
return true;
}
else
{
if ((m_red_goal_1.z() > 0.0f || m_red_goal_3.z() > 0.0f) &&
((m_red_goal_1.x() < 0.0f && m_red_goal_3.x() > 0.0f) ||
(m_red_goal_3.x() < 0.0f && m_red_goal_1.x() > 0.0f)))
return true;
}
return false;
} // isApproachingGoal
Vec3 getAimPosition(KartTeam team, bool reverse) const
{
// If it's likely to goal already, aim the ball straight behind
// should do the job
if (isApproachingGoal(team))
return m_trans(Vec3(0, 0, reverse ? m_radius*2 : -m_radius*2));
// Otherwise do the below:
// This is done by using Pythagorean Theorem and solving the
// equation from ball to goal center (y = (m_***_goal_slope) x)
// We aim behind the ball from the center of the ball to its
// diameter, so 2*m_radius = sqrt (x2 + y2),
// which is next x = sqrt (2*m_radius - y2)
// And than we have x = y / m(m_***_goal_slope)
// After put that in the slope equation, we have
// y = sqrt(2*m_radius*m2 / (1+m2))
float x = 0.0f;
float y = 0.0f;
if (team == KART_TEAM_BLUE)
{
y = sqrt((m_blue_goal_slope * m_blue_goal_slope * m_radius*2) /
(1 + (m_blue_goal_slope * m_blue_goal_slope)));
if (m_blue_goal_2.x() == 0.0f ||
(m_blue_goal_2.x() > 0.0f && m_blue_goal_2.z() > 0.0f) ||
(m_blue_goal_2.x() < 0.0f && m_blue_goal_2.z() > 0.0f))
{
// Determine when y should be negative
y = -y;
}
x = y / m_blue_goal_slope;
}
else
{
y = sqrt((m_red_goal_slope * m_red_goal_slope * m_radius*2) /
(1 + (m_red_goal_slope * m_red_goal_slope)));
if (m_red_goal_2.x() == 0.0f ||
(m_red_goal_2.x() > 0.0f && m_red_goal_2.z() > 0.0f) ||
(m_red_goal_2.x() < 0.0f && m_red_goal_2.z() > 0.0f))
{
y = -y;
}
x = y / m_red_goal_slope;
}
assert (!std::isnan(x));
assert (!std::isnan(y));
// Return the world coordinates
return (reverse ? m_trans(Vec3(-x, 0, -y)) :
m_trans(Vec3(x, 0, y)));
} // getAimPosition
void resetCheckGoal(const Track* t)
{
m_red_check_goal->reset(*t);
m_blue_check_goal->reset(*t);
}
}; // BallGoalData
//-----------------------------------------------------------------------------
/** Constructor. Sets up the clock mode etc.
*/
@@ -66,6 +251,7 @@ SoccerWorld::SoccerWorld() : WorldWithRank()
m_red_ai = 0;
m_blue_ai = 0;
m_ball_track_sector = NULL;
m_bgd.reset(new BallGoalData());
} // SoccerWorld
//-----------------------------------------------------------------------------
@@ -118,7 +304,7 @@ void SoccerWorld::init()
if (!m_ball)
Log::fatal("SoccerWorld","Ball is missing in soccer field, abort.");
m_bgd.init(m_ball->getPhysicalObject()->getRadius());
m_bgd->init(m_ball->getPhysicalObject()->getRadius());
} // init
@@ -161,7 +347,7 @@ void SoccerWorld::reset(bool restart)
m_reset_ball_ticks = -1;
m_ball->reset();
m_bgd.reset();
m_bgd->reset();
m_ticks_back_to_own_goal = -1;
m_ball->setEnabled(false);
@@ -445,7 +631,7 @@ void SoccerWorld::resetKartsToSelfGoals()
{
m_ball->setEnabled(true);
m_ball->reset();
m_bgd.resetCheckGoal(Track::getCurrentTrack());
m_bgd->resetCheckGoal(Track::getCurrentTrack());
for (unsigned i = 0; i < m_karts.size(); i++)
{
auto& kart = m_karts[i];
@@ -635,7 +821,7 @@ void SoccerWorld::updateAIData()
std::sort(m_blue_kdm.begin(), m_blue_kdm.end());
// Fill Ball and goals data
m_bgd.updateBallAndGoal(getBallPosition(), getBallHeading());
m_bgd->updateBallAndGoal(getBallPosition(), getBallHeading());
} // updateAIData
@@ -855,3 +1041,21 @@ void SoccerWorld::restoreCompleteState(const BareNetworkString& b)
m_reset_ball_ticks = b.getTime();
m_ticks_back_to_own_goal = b.getTime();
} // restoreCompleteState
// ----------------------------------------------------------------------------
float SoccerWorld::getBallDiameter() const
{
return m_bgd->getDiameter();
} // getBallDiameter
// ----------------------------------------------------------------------------
bool SoccerWorld::ballApproachingGoal(KartTeam team) const
{
return m_bgd->isApproachingGoal(team);
} // ballApproachingGoal
// ----------------------------------------------------------------------------
Vec3 SoccerWorld::getBallAimPosition(KartTeam team, bool reverse) const
{
return m_bgd->getAimPosition(team, reverse);
} // getBallAimPosition

View File

@@ -22,13 +22,12 @@
#include "modes/world_with_rank.hpp"
#include "states_screens/race_gui_base.hpp"
#include "karts/abstract_kart.hpp"
#include "tracks/check_goal.hpp"
#include "tracks/check_manager.hpp"
#include <IMesh.h>
#include <string>
class AbstractKart;
class BallGoalData;
class Controller;
class NetworkString;
class TrackObject;
@@ -79,189 +78,9 @@ private:
}
}; // KartDistanceMap
class BallGoalData
{
// These data are used by AI to determine ball aiming angle
private:
// Radius of the ball
float m_radius;
// Slope of the line from ball to the center point of goals
float m_red_goal_slope;
float m_blue_goal_slope;
// The transform only takes the ball heading into account,
// ie no hpr of ball which allowing setting aim point easier
btTransform m_trans;
// Two goals
CheckGoal* m_blue_check_goal;
CheckGoal* m_red_check_goal;
// Location to red/blue goal points from the ball heading point of view
Vec3 m_red_goal_1;
Vec3 m_red_goal_2;
Vec3 m_red_goal_3;
Vec3 m_blue_goal_1;
Vec3 m_blue_goal_2;
Vec3 m_blue_goal_3;
public:
void reset()
{
m_red_goal_1 = Vec3(0, 0, 0);
m_red_goal_2 = Vec3(0, 0, 0);
m_red_goal_3 = Vec3(0, 0, 0);
m_blue_goal_1 = Vec3(0, 0, 0);
m_blue_goal_2 = Vec3(0, 0, 0);
m_blue_goal_3 = Vec3(0, 0, 0);
m_red_goal_slope = 1.0f;
m_blue_goal_slope = 1.0f;
m_trans = btTransform(btQuaternion(0, 0, 0, 1), Vec3(0, 0, 0));
} // reset
float getDiameter() const
{
return m_radius * 2;
} // getDiameter
void init(float ball_radius)
{
m_radius = ball_radius;
assert(m_radius > 0.0f);
// Save two goals
unsigned int n = CheckManager::get()->getCheckStructureCount();
for (unsigned int i = 0; i < n; i++)
{
CheckGoal* goal = dynamic_cast<CheckGoal*>
(CheckManager::get()->getCheckStructure(i));
if (goal)
{
if (goal->getTeam())
m_blue_check_goal = goal;
else
m_red_check_goal = goal;
}
}
if (m_blue_check_goal == NULL || m_red_check_goal == NULL)
{
Log::error("SoccerWorld", "Goal(s) is missing!");
}
} // init
void updateBallAndGoal(const Vec3& ball_pos, float heading)
{
btQuaternion quat(Vec3(0, 1, 0), -heading);
m_trans = btTransform(btQuaternion(Vec3(0, 1, 0), heading),
ball_pos);
// Red goal
m_red_goal_1 = quatRotate(quat, m_red_check_goal
->getPoint(CheckGoal::POINT_FIRST) - ball_pos);
m_red_goal_2 = quatRotate(quat, m_red_check_goal
->getPoint(CheckGoal::POINT_CENTER) - ball_pos);
m_red_goal_3 = quatRotate(quat, m_red_check_goal
->getPoint(CheckGoal::POINT_LAST) - ball_pos);
// Blue goal
m_blue_goal_1 = quatRotate(quat, m_blue_check_goal
->getPoint(CheckGoal::POINT_FIRST) - ball_pos);
m_blue_goal_2 = quatRotate(quat, m_blue_check_goal
->getPoint(CheckGoal::POINT_CENTER) - ball_pos);
m_blue_goal_3 = quatRotate(quat, m_blue_check_goal
->getPoint(CheckGoal::POINT_LAST) - ball_pos);
// Update the slope:
// Use y = mx + c as an equation from goal center to ball
// As the line always intercept in (0,0) which is the ball location,
// so y(z)/x is the slope , it is used for determine aiming position
// of ball later
m_red_goal_slope = m_red_goal_2.z() / m_red_goal_2.x();
m_blue_goal_slope = m_blue_goal_2.z() / m_blue_goal_2.x();
} // updateBallAndGoal
bool isApproachingGoal(KartTeam team) const
{
// If the ball lies between the first and last pos, and faces
// in front of either of them, (inside angular size of goal)
// than it's likely to goal
if (team == KART_TEAM_BLUE)
{
if ((m_blue_goal_1.z() > 0.0f || m_blue_goal_3.z() > 0.0f) &&
((m_blue_goal_1.x() < 0.0f && m_blue_goal_3.x() > 0.0f) ||
(m_blue_goal_3.x() < 0.0f && m_blue_goal_1.x() > 0.0f)))
return true;
}
else
{
if ((m_red_goal_1.z() > 0.0f || m_red_goal_3.z() > 0.0f) &&
((m_red_goal_1.x() < 0.0f && m_red_goal_3.x() > 0.0f) ||
(m_red_goal_3.x() < 0.0f && m_red_goal_1.x() > 0.0f)))
return true;
}
return false;
} // isApproachingGoal
Vec3 getAimPosition(KartTeam team, bool reverse) const
{
// If it's likely to goal already, aim the ball straight behind
// should do the job
if (isApproachingGoal(team))
return m_trans(Vec3(0, 0, reverse ? m_radius*2 : -m_radius*2));
// Otherwise do the below:
// This is done by using Pythagorean Theorem and solving the
// equation from ball to goal center (y = (m_***_goal_slope) x)
// We aim behind the ball from the center of the ball to its
// diameter, so 2*m_radius = sqrt (x2 + y2),
// which is next x = sqrt (2*m_radius - y2)
// And than we have x = y / m(m_***_goal_slope)
// After put that in the slope equation, we have
// y = sqrt(2*m_radius*m2 / (1+m2))
float x = 0.0f;
float y = 0.0f;
if (team == KART_TEAM_BLUE)
{
y = sqrt((m_blue_goal_slope * m_blue_goal_slope * m_radius*2) /
(1 + (m_blue_goal_slope * m_blue_goal_slope)));
if (m_blue_goal_2.x() == 0.0f ||
(m_blue_goal_2.x() > 0.0f && m_blue_goal_2.z() > 0.0f) ||
(m_blue_goal_2.x() < 0.0f && m_blue_goal_2.z() > 0.0f))
{
// Determine when y should be negative
y = -y;
}
x = y / m_blue_goal_slope;
}
else
{
y = sqrt((m_red_goal_slope * m_red_goal_slope * m_radius*2) /
(1 + (m_red_goal_slope * m_red_goal_slope)));
if (m_red_goal_2.x() == 0.0f ||
(m_red_goal_2.x() > 0.0f && m_red_goal_2.z() > 0.0f) ||
(m_red_goal_2.x() < 0.0f && m_red_goal_2.z() > 0.0f))
{
y = -y;
}
x = y / m_red_goal_slope;
}
assert (!std::isnan(x));
assert (!std::isnan(y));
// Return the world coordinates
return (reverse ? m_trans(Vec3(-x, 0, -y)) :
m_trans(Vec3(x, 0, y)));
} // getAimPosition
void resetCheckGoal(const Track* t)
{
m_red_check_goal->reset(*t);
m_blue_check_goal->reset(*t);
}
}; // BallGoalData
std::vector<KartDistanceMap> m_red_kdm;
std::vector<KartDistanceMap> m_blue_kdm;
BallGoalData m_bgd;
std::unique_ptr<BallGoalData> m_bgd;
/** Keep a pointer to the track object of soccer ball */
TrackObject* m_ball;
@@ -367,14 +186,11 @@ public:
float getBallHeading() const
{ return m_ball_heading; }
// ------------------------------------------------------------------------
float getBallDiameter() const
{ return m_bgd.getDiameter(); }
float getBallDiameter() const;
// ------------------------------------------------------------------------
bool ballApproachingGoal(KartTeam team) const
{ return m_bgd.isApproachingGoal(team); }
bool ballApproachingGoal(KartTeam team) const;
// ------------------------------------------------------------------------
Vec3 getBallAimPosition(KartTeam team, bool reverse = false) const
{ return m_bgd.getAimPosition(team, reverse); }
Vec3 getBallAimPosition(KartTeam team, bool reverse = false) const;
// ------------------------------------------------------------------------
bool isCorrectGoal(unsigned int kart_id, bool first_goal) const;
// ------------------------------------------------------------------------

View File

@@ -883,7 +883,7 @@ void World::moveKartTo(AbstractKart* kart, const btTransform &transform)
// Project kart to surface of track
// This will set the physics transform
Track::getCurrentTrack()->findGround(kart);
CheckManager::get()->resetAfterKartMove(kart);
Track::getCurrentTrack()->getCheckManager()->resetAfterKartMove(kart);
} // moveKartTo

View File

@@ -1946,7 +1946,7 @@ void ServerLobby::finishedLoadingLiveJoinClient(Event* event)
spectator = true;
}
const uint8_t cc = (uint8_t)CheckManager::get()->getCheckStructureCount();
const uint8_t cc = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount();
NetworkString* ns = getNetworkString(10);
ns->setSynchronous(true);
ns->addUInt8(LE_LIVE_JOIN_ACK).addUInt64(m_client_starting_time)
@@ -4386,7 +4386,7 @@ void ServerLobby::configPeersStartTime()
NetworkString* ns = getNetworkString(10);
ns->setSynchronous(true);
ns->addUInt8(LE_START_RACE).addUInt64(start_time);
const uint8_t cc = (uint8_t)CheckManager::get()->getCheckStructureCount();
const uint8_t cc = (uint8_t)Track::getCurrentTrack()->getCheckManager()->getCheckStructureCount();
ns->addUInt8(cc);
*ns += *m_items_complete_state;
m_client_starting_time = start_time;

View File

@@ -358,7 +358,7 @@ void RewindManager::rewindTo(int rewind_ticks, int now_ticks,
}
// Update check line, so the cannon animation can be replayed correctly
CheckManager::get()->resetAfterRewind();
Track::getCurrentTrack()->getCheckManager()->resetAfterRewind();
if (exact_rewind_ticks >= 2)
{

View File

@@ -25,11 +25,10 @@
#include "items/item.hpp"
#include "modes/world.hpp"
#include "race/race_manager.hpp"
#include "tracks/check_manager.hpp"
CheckCylinder::CheckCylinder(const XMLNode &node,
std::function<void(int)> triggering_function)
: CheckStructure(CheckManager::get()->getCheckStructureCount())
: CheckStructure()
{
m_radius2 = 1;
m_height = 0;

View File

@@ -33,8 +33,6 @@
#include "tracks/drive_graph.hpp"
#include "utils/log.hpp"
CheckManager *CheckManager::m_check_manager = NULL;
/** Loads all check structure informaiton from the specified xml file.
*/
void CheckManager::load(const XMLNode &node)
@@ -106,7 +104,6 @@ CheckManager::~CheckManager()
{
delete m_all_checks[i];
}
m_check_manager = NULL;
} // ~CheckManager
// ----------------------------------------------------------------------------

View File

@@ -40,12 +40,8 @@ class CheckManager : public NoCopy
{
private:
std::vector<CheckStructure*> m_all_checks;
static CheckManager *m_check_manager;
/** Private constructor, to make sure it is only called via
* the static create function. */
CheckManager() {m_all_checks.clear();};
~CheckManager();
public:
~CheckManager();
void add(CheckStructure* strct) { m_all_checks.push_back(strct); }
void addFlyableToCannons(Flyable *flyable);
void removeFlyableFromCannons(Flyable *flyable);
@@ -57,21 +53,9 @@ public:
unsigned int getLapLineIndex() const;
int getChecklineTriggering(const Vec3 &from, const Vec3 &to) const;
// ------------------------------------------------------------------------
/** Creates an instance of the check manager. */
static void create()
{
assert(!m_check_manager);
m_check_manager = new CheckManager();
} // create
// ------------------------------------------------------------------------
/** Returns the instance of the check manager. */
static CheckManager* get() { return m_check_manager; }
// ------------------------------------------------------------------------
/** Destroys the check manager. */
static void destroy() { delete m_check_manager; m_check_manager = NULL; }
// ------------------------------------------------------------------------
/** Returns the number of check structures defined. */
unsigned int getCheckStructureCount() const { return (unsigned int) m_all_checks.size(); }
unsigned int getCheckStructureCount() const
{ return (unsigned int) m_all_checks.size(); }
// ------------------------------------------------------------------------
/** Returns the nth. check structure. */
CheckStructure *getCheckStructure(unsigned int n) const

View File

@@ -27,6 +27,7 @@
#include "race/race_manager.hpp"
#include "tracks/check_lap.hpp"
#include "tracks/check_manager.hpp"
#include "tracks/track.hpp"
#include <algorithm>
@@ -73,6 +74,15 @@ CheckStructure::CheckStructure(const XMLNode &node, unsigned int index)
node.get("active", &m_active_at_reset);
} // CheckStructure
// ----------------------------------------------------------------------------
CheckStructure::CheckStructure()
: m_active_at_reset(true),
m_index(Track::getCurrentTrack()->getCheckManager()
->getCheckStructureCount()),
m_check_type(CT_TRIGGER)
{
} // CheckStructure
// ----------------------------------------------------------------------------
/** Initialises the 'previous positions' of all karts with the start position
* defined for this track.
@@ -138,10 +148,10 @@ void CheckStructure::changeStatus(const std::vector<int> &indices,
UserConfigParams::m_check_debug && race_manager->getNumPlayers()>0 &&
kart_index == (int)World::getWorld()->getPlayerKart(0)->getWorldKartId();
CheckManager* cm = Track::getCurrentTrack()->getCheckManager();
for(unsigned int i=0; i<indices.size(); i++)
{
CheckStructure *cs =
CheckManager::get()->getCheckStructure(indices[i]);
CheckStructure *cs = cm->getCheckStructure(indices[i]);
if (cs == NULL) continue;
switch(change_state)
@@ -187,9 +197,9 @@ void CheckStructure::changeStatus(const std::vector<int> &indices,
/*
printf("--------\n");
for (int n=0; n<CheckManager::get()->getCheckStructureCount(); n++)
for (int n=0; n<m->getCheckStructureCount(); n++)
{
CheckStructure *cs = CheckManager::get()->getCheckStructure(n);
CheckStructure *cs = cm->getCheckStructure(n);
if (dynamic_cast<CheckLap*>(cs) != NULL)
printf("Checkline %i (LAP) : %i\n", n, (int)cs->m_is_active[kart_index]);
else

View File

@@ -84,8 +84,7 @@ protected:
unsigned int m_index;
/** For CheckTrigger or CheckCylinder */
CheckStructure(unsigned index) : m_active_at_reset(true), m_index(index),
m_check_type(CT_TRIGGER) {}
CheckStructure();
private:
/** The type of this checkline. */
CheckType m_check_type;

View File

@@ -18,7 +18,6 @@
#include "tracks/check_trigger.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp"
#include "tracks/check_manager.hpp"
#include "utils/time.hpp"
/** Constructor for a check trigger.
@@ -28,7 +27,7 @@
*/
CheckTrigger::CheckTrigger(const Vec3& center, float distance,
std::function<void(int)> triggering_function)
: CheckStructure(CheckManager::get()->getCheckStructureCount()),
: CheckStructure(),
m_center(center), m_distance2(distance * distance),
m_triggering_function(triggering_function)
{

View File

@@ -283,7 +283,7 @@ unsigned int DriveGraph::getStartNode() const
void DriveGraph::computeChecklineRequirements()
{
computeChecklineRequirements(getNode(0),
CheckManager::get()->getLapLineIndex());
Track::getCurrentTrack()->getCheckManager()->getLapLineIndex());
} // computeChecklineRequirements
// ----------------------------------------------------------------------------
@@ -302,7 +302,7 @@ void DriveGraph::computeChecklineRequirements(DriveNode* node,
DriveNode* succ = getNode(succ_id);
int new_latest_checkline =
CheckManager::get()->getChecklineTriggering(node->getCenter(),
Track::getCurrentTrack()->getCheckManager()->getChecklineTriggering(node->getCenter(),
succ->getCenter() );
if(new_latest_checkline==-1)
new_latest_checkline = latest_checkline;

View File

@@ -164,6 +164,7 @@ Track::Track(const std::string &filename)
m_cache_track = UserConfigParams::m_cache_overworld &&
m_ident=="overworld";
m_render_target = NULL;
m_check_manager = NULL;
m_minimap_x_scale = 1.0f;
m_minimap_y_scale = 1.0f;
m_force_disable_fog = false;
@@ -289,7 +290,7 @@ void Track::removeCachedData()
void Track::reset()
{
m_ambient_color = m_default_ambient_color;
CheckManager::get()->reset(*this);
m_check_manager->reset(*this);
ItemManager::get()->reset();
m_track_object_manager->reset();
m_startup_run = false;
@@ -347,7 +348,8 @@ void Track::cleanup()
m_all_emitters.clearAndDeleteAll();
CheckManager::destroy();
delete m_check_manager;
m_check_manager = NULL;
delete m_track_object_manager;
m_track_object_manager = NULL;
@@ -1623,7 +1625,7 @@ void Track::update(int ticks)
m_startup_run = true;
}
float dt = stk_config->ticks2Time(ticks);
CheckManager::get()->update(dt);
m_check_manager->update(dt);
ItemManager::get()->update(ticks);
// TODO: enable onUpdate scripts if we ever find a compelling use for them
@@ -1788,7 +1790,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
reverse_track = false;
}
main_loop->renderGUI(3000);
CheckManager::create();
m_check_manager = new CheckManager();
assert(m_all_cached_meshes.size()==0);
if(UserConfigParams::logMemory())
{
@@ -2222,7 +2224,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
// Only print warning if not in battle mode, since battle tracks don't have
// any quads or check lines.
if (CheckManager::get()->getCheckStructureCount()==0 &&
if (m_check_manager->getCheckStructureCount()==0 &&
!race_manager->isBattleMode() && !m_is_cutscene)
{
Log::warn("track", "No check lines found in track '%s'.",
@@ -2342,7 +2344,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path,
}
else if (name == "checks")
{
CheckManager::get()->load(*node);
m_check_manager->load(*node);
}
else if (name == "particle-emitter")
{

View File

@@ -352,6 +352,7 @@ private:
/** The render target for the mini map, which is displayed in the race gui. */
RenderTarget *m_render_target;
CheckManager* m_check_manager;
float m_minimap_x_scale;
float m_minimap_y_scale;
@@ -709,6 +710,8 @@ public:
bool isAddon() const { return m_is_addon; }
// ------------------------------------------------------------------------
void convertTrackToBullet(scene::ISceneNode *node);
// ------------------------------------------------------------------------
CheckManager* getCheckManager() const { return m_check_manager; }
}; // class Track
#endif

View File

@@ -679,7 +679,7 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(
if (trigger_when_near)
{
CheckManager::get()->add(
Track::getCurrentTrack()->getCheckManager()->add(
new CheckTrigger(m_init_xyz, trigger_distance, std::bind(
&TrackObjectPresentationSound::onTriggerItemApproached,
this, std::placeholders::_1)));
@@ -1097,14 +1097,14 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(
if (m_type == TRIGGER_TYPE_POINT)
{
CheckManager::get()->add(
Track::getCurrentTrack()->getCheckManager()->add(
new CheckTrigger(m_init_xyz, trigger_distance, std::bind(
&TrackObjectPresentationActionTrigger::onTriggerItemApproached,
this, std::placeholders::_1)));
}
else if (m_type == TRIGGER_TYPE_CYLINDER)
{
CheckManager::get()->add(new CheckCylinder(xml_node, std::bind(
Track::getCurrentTrack()->getCheckManager()->add(new CheckCylinder(xml_node, std::bind(
&TrackObjectPresentationActionTrigger::onTriggerItemApproached,
this, std::placeholders::_1)));
}
@@ -1129,7 +1129,7 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(
m_xml_reenable_timeout = 999999.9f;
setReenableTimeout(0.0f);
m_type = TRIGGER_TYPE_POINT;
CheckManager::get()->add(
Track::getCurrentTrack()->getCheckManager()->add(
new CheckTrigger(m_init_xyz, trigger_distance, std::bind(
&TrackObjectPresentationActionTrigger::onTriggerItemApproached,
this, std::placeholders::_1)));