Add support for CTF map
This commit is contained in:
parent
03728708cd
commit
73c264df94
@ -36,7 +36,6 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/explosion_animation.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "network/compress_network_body.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
@ -243,14 +242,11 @@ void Flyable::getClosestKart(const AbstractKart **minKart,
|
||||
kart->isInvulnerable() ||
|
||||
kart->getKartAnimation() ) continue;
|
||||
|
||||
const SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());
|
||||
if (sw)
|
||||
{
|
||||
// Don't hit teammates in soccer world
|
||||
if (sw->getKartTeam(kart->getWorldKartId()) == sw
|
||||
->getKartTeam(m_owner->getWorldKartId()))
|
||||
// Don't hit teammates in team world
|
||||
if (world->hasTeam() &&
|
||||
world->getKartTeam(kart->getWorldKartId()) ==
|
||||
world->getKartTeam(m_owner->getWorldKartId()))
|
||||
continue;
|
||||
}
|
||||
|
||||
btTransform t=kart->getTrans();
|
||||
|
||||
@ -548,15 +544,12 @@ void Flyable::explode(AbstractKart *kart_hit, PhysicalObject *object,
|
||||
for ( unsigned int i = 0 ; i < world->getNumKarts() ; i++ )
|
||||
{
|
||||
AbstractKart *kart = world->getKart(i);
|
||||
|
||||
const SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());
|
||||
if (sw)
|
||||
{
|
||||
// Don't explode teammates in soccer world
|
||||
if (sw->getKartTeam(kart->getWorldKartId()) == sw
|
||||
->getKartTeam(m_owner->getWorldKartId()))
|
||||
// Don't explode teammates in team world
|
||||
if (world->hasTeam() &&
|
||||
world->getKartTeam(kart->getWorldKartId()) ==
|
||||
world->getKartTeam(m_owner->getWorldKartId()))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kart->isGhostKart()) continue;
|
||||
|
||||
// If no secondary hits should be done, only hit the
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "karts/explosion_animation.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
|
||||
@ -290,14 +289,11 @@ void Swatter::chooseTarget()
|
||||
if (kart->isInvulnerable() || kart->isSquashed())
|
||||
continue;
|
||||
|
||||
const SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());
|
||||
if (sw)
|
||||
{
|
||||
// Don't hit teammates in soccer world
|
||||
if (sw->getKartTeam(kart->getWorldKartId()) == sw
|
||||
->getKartTeam(m_kart->getWorldKartId()))
|
||||
// Don't hit teammates in team world
|
||||
if (world->hasTeam() &&
|
||||
world->getKartTeam(kart->getWorldKartId()) ==
|
||||
world->getKartTeam(m_kart->getWorldKartId()))
|
||||
continue;
|
||||
}
|
||||
|
||||
float dist2 = (kart->getXYZ()-m_kart->getXYZ()).length2();
|
||||
if(dist2<min_dist2)
|
||||
|
@ -16,8 +16,11 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "modes/capture_the_flag.hpp"
|
||||
|
||||
#include "io/file_manager.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -25,10 +28,55 @@
|
||||
*/
|
||||
CaptureTheFlag::CaptureTheFlag() : FreeForAll()
|
||||
{
|
||||
|
||||
m_red_flag_node = m_blue_flag_node = NULL;
|
||||
m_red_flag_mesh = m_blue_flag_mesh = NULL;
|
||||
#ifndef SERVER_ONLY
|
||||
file_manager->pushTextureSearchPath(
|
||||
file_manager->getAsset(FileManager::MODEL,""), "models");
|
||||
m_red_flag_mesh = irr_driver->getAnimatedMesh
|
||||
(file_manager->getAsset(FileManager::MODEL, "red_flag.spm"));
|
||||
m_blue_flag_mesh = irr_driver->getAnimatedMesh
|
||||
(file_manager->getAsset(FileManager::MODEL, "blue_flag.spm"));
|
||||
assert(m_red_flag_mesh);
|
||||
assert(m_blue_flag_mesh);
|
||||
irr_driver->grabAllTextures(m_red_flag_mesh);
|
||||
irr_driver->grabAllTextures(m_blue_flag_mesh);
|
||||
file_manager->popTextureSearchPath();
|
||||
#endif
|
||||
} // CaptureTheFlag
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CaptureTheFlag::~CaptureTheFlag()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
irr_driver->dropAllTextures(m_red_flag_mesh);
|
||||
irr_driver->dropAllTextures(m_blue_flag_mesh);
|
||||
irr_driver->removeMeshFromCache(m_red_flag_mesh);
|
||||
irr_driver->removeMeshFromCache(m_blue_flag_mesh);
|
||||
#endif
|
||||
} // ~CaptureTheFlag
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CaptureTheFlag::init()
|
||||
{
|
||||
FreeForAll::init();
|
||||
const btTransform& red_pos = Track::getCurrentTrack()->getRedFlag();
|
||||
const btTransform& blue_pos = Track::getCurrentTrack()->getBlueFlag();
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
m_red_flag_node = irr_driver->addAnimatedMesh(m_red_flag_mesh, "red_flag");
|
||||
m_blue_flag_node = irr_driver->addAnimatedMesh(m_blue_flag_mesh,
|
||||
"blue_flag");
|
||||
assert(m_red_flag_node);
|
||||
assert(m_blue_flag_node);
|
||||
|
||||
m_red_flag_node->setPosition(Vec3(red_pos.getOrigin()).toIrrVector());
|
||||
Vec3 hpr;
|
||||
hpr.setHPR(red_pos.getRotation());
|
||||
m_red_flag_node->setRotation(hpr.toIrrHPR());
|
||||
|
||||
m_blue_flag_node->setPosition(Vec3(blue_pos.getOrigin()).toIrrVector());
|
||||
hpr.setHPR(blue_pos.getRotation());
|
||||
m_blue_flag_node->setRotation(hpr.toIrrHPR());
|
||||
#endif
|
||||
} // init
|
||||
|
@ -23,14 +23,36 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
class IAnimatedMeshSceneNode; class IAnimatedMesh;
|
||||
}
|
||||
}
|
||||
|
||||
class CaptureTheFlag : public FreeForAll
|
||||
{
|
||||
private:
|
||||
scene::IAnimatedMeshSceneNode* m_red_flag_node;
|
||||
|
||||
scene::IAnimatedMeshSceneNode* m_blue_flag_node;
|
||||
|
||||
irr::scene::IAnimatedMesh* m_red_flag_mesh;
|
||||
|
||||
irr::scene::IAnimatedMesh* m_blue_flag_mesh;
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
CaptureTheFlag();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~CaptureTheFlag();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool hasTeam() const OVERRIDE { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
}; // CaptureTheFlag
|
||||
|
||||
#endif
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/render_info.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
@ -166,7 +165,6 @@ void SoccerWorld::reset()
|
||||
}
|
||||
|
||||
m_reset_ball_ticks = -1;
|
||||
initKartList();
|
||||
m_ball->reset();
|
||||
m_bgd.reset();
|
||||
m_ball->setEnabled(false);
|
||||
@ -484,40 +482,6 @@ void SoccerWorld::countdownReachedZero()
|
||||
m_count_down_reached_zero = true;
|
||||
} // countdownReachedZero
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SoccerWorld::initKartList()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
const unsigned int kart_amount = (unsigned int)m_karts.size();
|
||||
|
||||
//Loading the indicator textures
|
||||
std::string red_path =
|
||||
file_manager->getAsset(FileManager::GUI, "soccer_player_red.png");
|
||||
std::string blue_path =
|
||||
file_manager->getAsset(FileManager::GUI, "soccer_player_blue.png");
|
||||
|
||||
//Assigning indicators
|
||||
for(unsigned int i = 0; i < kart_amount; i++)
|
||||
{
|
||||
scene::ISceneNode *arrow_node = NULL;
|
||||
|
||||
KartModel* km = m_karts[i]->getKartModel();
|
||||
// Color of karts can be changed using shaders if the model supports
|
||||
if (km->supportColorization() && CVS->isGLSL()) continue;
|
||||
|
||||
float arrow_pos_height = km->getHeight() + 0.5f;
|
||||
KartTeam team = getKartTeam(i);
|
||||
|
||||
arrow_node = irr_driver->addBillboard(
|
||||
core::dimension2d<irr::f32>(0.3f,0.3f),
|
||||
team == KART_TEAM_BLUE ? blue_path : red_path,
|
||||
m_karts[i]->getNode());
|
||||
|
||||
arrow_node->setPosition(core::vector3df(0, arrow_pos_height, 0));
|
||||
}
|
||||
#endif
|
||||
} // initKartList
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SoccerWorld::getKartSoccerResult(unsigned int kart_id) const
|
||||
{
|
||||
@ -534,112 +498,6 @@ bool SoccerWorld::getKartSoccerResult(unsigned int kart_id) const
|
||||
|
||||
} // getKartSoccerResult
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::shared_ptr<AbstractKart> SoccerWorld::createKart
|
||||
(const std::string &kart_ident, int index, int local_player_id,
|
||||
int global_player_id, RaceManager::KartType kart_type,
|
||||
PerPlayerDifficulty difficulty)
|
||||
{
|
||||
int cur_red = getTeamNum(KART_TEAM_RED);
|
||||
int cur_blue = getTeamNum(KART_TEAM_BLUE);
|
||||
int pos_index = 0;
|
||||
int position = index + 1;
|
||||
KartTeam team = KART_TEAM_BLUE;
|
||||
|
||||
if (kart_type == RaceManager::KT_AI)
|
||||
{
|
||||
if (index < m_red_ai)
|
||||
team = KART_TEAM_RED;
|
||||
else
|
||||
team = KART_TEAM_BLUE;
|
||||
m_kart_team_map[index] = team;
|
||||
}
|
||||
else if (NetworkConfig::get()->isNetworking())
|
||||
{
|
||||
m_kart_team_map[index] = race_manager->getKartInfo(index).getKartTeam();
|
||||
team = race_manager->getKartInfo(index).getKartTeam();
|
||||
}
|
||||
else
|
||||
{
|
||||
int rm_id = index -
|
||||
(race_manager->getNumberOfKarts() - race_manager->getNumPlayers());
|
||||
|
||||
assert(rm_id >= 0);
|
||||
team = race_manager->getKartInfo(rm_id).getKartTeam();
|
||||
m_kart_team_map[index] = team;
|
||||
}
|
||||
|
||||
core::stringw online_name;
|
||||
if (global_player_id > -1)
|
||||
{
|
||||
online_name = race_manager->getKartInfo(global_player_id)
|
||||
.getPlayerName();
|
||||
}
|
||||
|
||||
// Notice: In blender, please set 1,3,5,7... for blue starting position;
|
||||
// 2,4,6,8... for red.
|
||||
if (team == KART_TEAM_BLUE)
|
||||
{
|
||||
pos_index = 1 + 2 * cur_blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos_index = 2 + 2 * cur_red;
|
||||
}
|
||||
|
||||
btTransform init_pos = getStartTransform(pos_index - 1);
|
||||
m_kart_position_map[index] = (unsigned)(pos_index - 1);
|
||||
|
||||
std::shared_ptr<RenderInfo> ri = std::make_shared<RenderInfo>();
|
||||
ri = (team == KART_TEAM_BLUE ? std::make_shared<RenderInfo>(0.66f) :
|
||||
std::make_shared<RenderInfo>(1.0f));
|
||||
|
||||
std::shared_ptr<AbstractKart> new_kart;
|
||||
if (RewindManager::get()->isEnabled())
|
||||
{
|
||||
auto kr = std::make_shared<KartRewinder>(kart_ident, index, position,
|
||||
init_pos, difficulty, ri);
|
||||
kr->rewinderAdd();
|
||||
new_kart = kr;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_kart = std::make_shared<Kart>(kart_ident, index, position,
|
||||
init_pos, difficulty, ri);
|
||||
}
|
||||
|
||||
new_kart->init(race_manager->getKartType(index));
|
||||
Controller *controller = NULL;
|
||||
|
||||
switch(kart_type)
|
||||
{
|
||||
case RaceManager::KT_PLAYER:
|
||||
controller = new LocalPlayerController(new_kart.get(), local_player_id,
|
||||
difficulty);
|
||||
m_num_players ++;
|
||||
break;
|
||||
case RaceManager::KT_NETWORK_PLAYER:
|
||||
controller = new NetworkPlayerController(new_kart.get());
|
||||
if (!online_name.empty())
|
||||
new_kart->setOnScreenText(online_name.c_str());
|
||||
m_num_players++;
|
||||
break;
|
||||
case RaceManager::KT_AI:
|
||||
controller = loadAIController(new_kart.get());
|
||||
break;
|
||||
case RaceManager::KT_GHOST:
|
||||
break;
|
||||
case RaceManager::KT_LEADER:
|
||||
break;
|
||||
case RaceManager::KT_SPARE_TIRE:
|
||||
break;
|
||||
}
|
||||
|
||||
new_kart->setController(controller);
|
||||
|
||||
return new_kart;
|
||||
} // createKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Localize the ball on the navigation mesh.
|
||||
*/
|
||||
@ -709,16 +567,6 @@ int SoccerWorld::getBallNode() const
|
||||
return m_ball_track_sector->getCurrentGraphNode();
|
||||
} // getBallNode
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
KartTeam SoccerWorld::getKartTeam(unsigned int kart_id) const
|
||||
{
|
||||
std::map<int, KartTeam>::const_iterator n =
|
||||
m_kart_team_map.find(kart_id);
|
||||
|
||||
assert(n != m_kart_team_map.end());
|
||||
return n->second;
|
||||
} // getKartTeam
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SoccerWorld::isCorrectGoal(unsigned int kart_id, bool first_goal) const
|
||||
{
|
||||
@ -800,20 +648,6 @@ int SoccerWorld::getAttacker(KartTeam team) const
|
||||
return -1;
|
||||
} // getAttacker
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int SoccerWorld::getTeamNum(KartTeam team) const
|
||||
{
|
||||
int total = 0;
|
||||
if (m_kart_team_map.empty()) return total;
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned)m_karts.size(); ++i)
|
||||
{
|
||||
if (team == getKartTeam(m_karts[i]->getWorldKartId())) total++;
|
||||
}
|
||||
|
||||
return total;
|
||||
} // getTeamNum
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int SoccerWorld::getRescuePositionIndex(AbstractKart *kart)
|
||||
{
|
||||
@ -911,52 +745,3 @@ void SoccerWorld::enterRaceOverState()
|
||||
}
|
||||
|
||||
} // enterRaceOverState
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SoccerWorld::setAITeam()
|
||||
{
|
||||
const int total_player = race_manager->getNumPlayers();
|
||||
const int total_karts = race_manager->getNumberOfKarts();
|
||||
|
||||
// No AI
|
||||
if ((total_karts - total_player) == 0) return;
|
||||
|
||||
int red_player = 0;
|
||||
int blue_player = 0;
|
||||
for (int i = 0; i < total_player; i++)
|
||||
{
|
||||
KartTeam team = race_manager->getKartInfo(i).getKartTeam();
|
||||
|
||||
// Happen in profiling mode
|
||||
if (team == KART_TEAM_NONE)
|
||||
{
|
||||
race_manager->setKartTeam(i, KART_TEAM_BLUE);
|
||||
team = KART_TEAM_BLUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
team == KART_TEAM_BLUE ? blue_player++ : red_player++;
|
||||
}
|
||||
|
||||
int available_ai = total_karts - red_player - blue_player;
|
||||
while (available_ai > 0)
|
||||
{
|
||||
if ((m_red_ai + red_player) > (m_blue_ai + blue_player))
|
||||
{
|
||||
m_blue_ai++;
|
||||
available_ai--;
|
||||
}
|
||||
else if ((m_blue_ai + blue_player) > (m_red_ai + red_player))
|
||||
{
|
||||
m_red_ai++;
|
||||
available_ai--;
|
||||
}
|
||||
else if ((m_blue_ai + blue_player) == (m_red_ai + red_player))
|
||||
{
|
||||
blue_player > red_player ? m_red_ai++ : m_blue_ai++;
|
||||
available_ai--;
|
||||
}
|
||||
}
|
||||
Log::debug("SoccerWorld","blue AI: %d red AI: %d", m_blue_ai, m_red_ai);
|
||||
|
||||
} // setAITeam
|
||||
|
@ -50,12 +50,6 @@ public:
|
||||
bool m_correct_goal;
|
||||
}; // ScorerData
|
||||
|
||||
protected:
|
||||
virtual std::shared_ptr<AbstractKart> createKart
|
||||
(const std::string &kart_ident, int index, int local_player_id,
|
||||
int global_player_id, RaceManager::KartType type,
|
||||
PerPlayerDifficulty difficulty) OVERRIDE;
|
||||
|
||||
private:
|
||||
class KartDistanceMap
|
||||
{
|
||||
@ -284,20 +278,12 @@ private:
|
||||
std::vector<ScorerData> m_blue_scorers;
|
||||
std::vector<float> m_blue_score_times;
|
||||
|
||||
std::map<int, KartTeam> m_kart_team_map;
|
||||
std::map<int, unsigned int> m_kart_position_map;
|
||||
|
||||
/** Data generated from navmesh */
|
||||
TrackSector* m_ball_track_sector;
|
||||
|
||||
int m_red_ai;
|
||||
int m_blue_ai;
|
||||
|
||||
float m_ball_heading;
|
||||
|
||||
std::vector<btTransform> m_goal_transforms;
|
||||
/** Set the team for the karts */
|
||||
void initKartList();
|
||||
/** Function to update the location the ball on the polygon map */
|
||||
void updateBallPosition(int ticks);
|
||||
/** Function to update data for AI usage. */
|
||||
@ -350,9 +336,6 @@ public:
|
||||
/** Get the soccer result of kart in soccer world (including AIs) */
|
||||
bool getKartSoccerResult(unsigned int kart_id) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the team of kart in soccer world (including AIs) */
|
||||
KartTeam getKartTeam(unsigned int kart_id) const;
|
||||
// ------------------------------------------------------------------------
|
||||
int getScore(KartTeam team) const
|
||||
{
|
||||
return (int)(team == KART_TEAM_BLUE ? m_blue_scorers.size()
|
||||
@ -404,8 +387,6 @@ public:
|
||||
/** Get the AI who will attack the other team ball chaser. */
|
||||
int getAttacker(KartTeam team) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void setAITeam();
|
||||
// ------------------------------------------------------------------------
|
||||
void handlePlayerGoalFromServer(const NetworkString& ns);
|
||||
// ------------------------------------------------------------------------
|
||||
void handleResetBallFromServer(const NetworkString& ns);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
@ -45,11 +46,11 @@
|
||||
#include "karts/controller/test_ai.hpp"
|
||||
#include "karts/controller/network_player_controller.hpp"
|
||||
#include "karts/kart.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "karts/kart_rewinder.hpp"
|
||||
#include "modes/overworld.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/rewind_manager.hpp"
|
||||
#include "physics/btKart.hpp"
|
||||
@ -67,6 +68,7 @@
|
||||
#include "states_screens/race_gui.hpp"
|
||||
#include "states_screens/race_result_gui.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "tracks/check_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "tracks/track_manager.hpp"
|
||||
#include "tracks/track_object_manager.hpp"
|
||||
@ -154,6 +156,7 @@ void World::init()
|
||||
m_eliminated_players = 0;
|
||||
m_num_players = 0;
|
||||
unsigned int gk = 0;
|
||||
m_red_ai = m_blue_ai = 0;
|
||||
if (race_manager->hasGhostKarts())
|
||||
gk = ReplayPlay::get()->getNumGhostKart();
|
||||
|
||||
@ -199,10 +202,9 @@ void World::init()
|
||||
m_karts.push_back(ReplayPlay::get()->getGhostKart(k));
|
||||
}
|
||||
|
||||
// Assign team of AIs for soccer mode before createKart
|
||||
SoccerWorld* sw = dynamic_cast<SoccerWorld*>(this);
|
||||
if (sw)
|
||||
sw->setAITeam();
|
||||
// Assign team of AIs for team mode before createKart
|
||||
if (hasTeam())
|
||||
setAITeam();
|
||||
|
||||
for(unsigned int i=0; i<num_karts; i++)
|
||||
{
|
||||
@ -212,10 +214,20 @@ void World::init()
|
||||
: race_manager->getKartIdent(i);
|
||||
int local_player_id = race_manager->getKartLocalPlayerId(i);
|
||||
int global_player_id = race_manager->getKartGlobalPlayerId(i);
|
||||
auto newkart = createKart(kart_ident, i, local_player_id,
|
||||
global_player_id, race_manager->getKartType(i),
|
||||
race_manager->getPlayerDifficulty(i));
|
||||
m_karts.push_back(newkart);
|
||||
std::shared_ptr<AbstractKart> new_kart;
|
||||
if (hasTeam())
|
||||
{
|
||||
new_kart = createKartWithTeam(kart_ident, i, local_player_id,
|
||||
global_player_id, race_manager->getKartType(i),
|
||||
race_manager->getPlayerDifficulty(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
new_kart = createKart(kart_ident, i, local_player_id,
|
||||
global_player_id, race_manager->getKartType(i),
|
||||
race_manager->getPlayerDifficulty(i));
|
||||
}
|
||||
m_karts.push_back(new_kart);
|
||||
|
||||
} // for i
|
||||
|
||||
@ -244,6 +256,7 @@ void World::init()
|
||||
|
||||
} // if server with graphics of is watching replay
|
||||
} // if getNumCameras()==0
|
||||
initTeamArrows();
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1356,4 +1369,219 @@ unsigned int World::getNumberOfRescuePositions() const
|
||||
return Track::getCurrentTrack()->getNumberOfStartPositions();
|
||||
} // getNumberOfRescuePositions
|
||||
|
||||
/* EOF */
|
||||
//-----------------------------------------------------------------------------
|
||||
std::shared_ptr<AbstractKart> World::createKartWithTeam
|
||||
(const std::string &kart_ident, int index, int local_player_id,
|
||||
int global_player_id, RaceManager::KartType kart_type,
|
||||
PerPlayerDifficulty difficulty)
|
||||
{
|
||||
int cur_red = getTeamNum(KART_TEAM_RED);
|
||||
int cur_blue = getTeamNum(KART_TEAM_BLUE);
|
||||
int pos_index = 0;
|
||||
int position = index + 1;
|
||||
KartTeam team = KART_TEAM_BLUE;
|
||||
|
||||
if (kart_type == RaceManager::KT_AI)
|
||||
{
|
||||
if (index < m_red_ai)
|
||||
team = KART_TEAM_RED;
|
||||
else
|
||||
team = KART_TEAM_BLUE;
|
||||
m_kart_team_map[index] = team;
|
||||
}
|
||||
else if (NetworkConfig::get()->isNetworking())
|
||||
{
|
||||
m_kart_team_map[index] = race_manager->getKartInfo(index).getKartTeam();
|
||||
team = race_manager->getKartInfo(index).getKartTeam();
|
||||
}
|
||||
else
|
||||
{
|
||||
int rm_id = index -
|
||||
(race_manager->getNumberOfKarts() - race_manager->getNumPlayers());
|
||||
|
||||
assert(rm_id >= 0);
|
||||
team = race_manager->getKartInfo(rm_id).getKartTeam();
|
||||
m_kart_team_map[index] = team;
|
||||
}
|
||||
|
||||
core::stringw online_name;
|
||||
if (global_player_id > -1)
|
||||
{
|
||||
online_name = race_manager->getKartInfo(global_player_id)
|
||||
.getPlayerName();
|
||||
}
|
||||
|
||||
// Notice: In blender, please set 1,3,5,7... for blue starting position;
|
||||
// 2,4,6,8... for red.
|
||||
if (team == KART_TEAM_BLUE)
|
||||
{
|
||||
pos_index = 1 + 2 * cur_blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos_index = 2 + 2 * cur_red;
|
||||
}
|
||||
|
||||
btTransform init_pos = getStartTransform(pos_index - 1);
|
||||
m_kart_position_map[index] = (unsigned)(pos_index - 1);
|
||||
|
||||
std::shared_ptr<RenderInfo> ri = std::make_shared<RenderInfo>();
|
||||
ri = (team == KART_TEAM_BLUE ? std::make_shared<RenderInfo>(0.66f) :
|
||||
std::make_shared<RenderInfo>(1.0f));
|
||||
|
||||
std::shared_ptr<AbstractKart> new_kart;
|
||||
if (RewindManager::get()->isEnabled())
|
||||
{
|
||||
auto kr = std::make_shared<KartRewinder>(kart_ident, index, position,
|
||||
init_pos, difficulty, ri);
|
||||
kr->rewinderAdd();
|
||||
new_kart = kr;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_kart = std::make_shared<Kart>(kart_ident, index, position,
|
||||
init_pos, difficulty, ri);
|
||||
}
|
||||
|
||||
new_kart->init(race_manager->getKartType(index));
|
||||
Controller *controller = NULL;
|
||||
|
||||
switch(kart_type)
|
||||
{
|
||||
case RaceManager::KT_PLAYER:
|
||||
controller = new LocalPlayerController(new_kart.get(), local_player_id,
|
||||
difficulty);
|
||||
m_num_players ++;
|
||||
break;
|
||||
case RaceManager::KT_NETWORK_PLAYER:
|
||||
controller = new NetworkPlayerController(new_kart.get());
|
||||
if (!online_name.empty())
|
||||
new_kart->setOnScreenText(online_name.c_str());
|
||||
m_num_players++;
|
||||
break;
|
||||
case RaceManager::KT_AI:
|
||||
controller = loadAIController(new_kart.get());
|
||||
break;
|
||||
case RaceManager::KT_GHOST:
|
||||
break;
|
||||
case RaceManager::KT_LEADER:
|
||||
break;
|
||||
case RaceManager::KT_SPARE_TIRE:
|
||||
break;
|
||||
}
|
||||
|
||||
new_kart->setController(controller);
|
||||
|
||||
return new_kart;
|
||||
} // createKartWithTeam
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int World::getTeamNum(KartTeam team) const
|
||||
{
|
||||
int total = 0;
|
||||
if (m_kart_team_map.empty()) return total;
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned)m_karts.size(); ++i)
|
||||
{
|
||||
if (team == getKartTeam(m_karts[i]->getWorldKartId())) total++;
|
||||
}
|
||||
|
||||
return total;
|
||||
} // getTeamNum
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
KartTeam World::getKartTeam(unsigned int kart_id) const
|
||||
{
|
||||
std::map<int, KartTeam>::const_iterator n =
|
||||
m_kart_team_map.find(kart_id);
|
||||
|
||||
assert(n != m_kart_team_map.end());
|
||||
return n->second;
|
||||
} // getKartTeam
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void World::initTeamArrows()
|
||||
{
|
||||
if (!hasTeam())
|
||||
return;
|
||||
#ifndef SERVER_ONLY
|
||||
const unsigned int kart_amount = (unsigned int)m_karts.size();
|
||||
|
||||
//Loading the indicator textures
|
||||
std::string red_path =
|
||||
file_manager->getAsset(FileManager::GUI, "soccer_player_red.png");
|
||||
std::string blue_path =
|
||||
file_manager->getAsset(FileManager::GUI, "soccer_player_blue.png");
|
||||
|
||||
//Assigning indicators
|
||||
for(unsigned int i = 0; i < kart_amount; i++)
|
||||
{
|
||||
scene::ISceneNode *arrow_node = NULL;
|
||||
|
||||
KartModel* km = m_karts[i]->getKartModel();
|
||||
// Color of karts can be changed using shaders if the model supports
|
||||
if (km->supportColorization() && CVS->isGLSL()) continue;
|
||||
|
||||
float arrow_pos_height = km->getHeight() + 0.5f;
|
||||
KartTeam team = getKartTeam(i);
|
||||
|
||||
arrow_node = irr_driver->addBillboard(
|
||||
core::dimension2d<irr::f32>(0.3f,0.3f),
|
||||
team == KART_TEAM_BLUE ? blue_path : red_path,
|
||||
m_karts[i]->getNode());
|
||||
|
||||
arrow_node->setPosition(core::vector3df(0, arrow_pos_height, 0));
|
||||
}
|
||||
#endif
|
||||
} // initTeamArrows
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void World::setAITeam()
|
||||
{
|
||||
const int total_player = race_manager->getNumPlayers();
|
||||
const int total_karts = race_manager->getNumberOfKarts();
|
||||
|
||||
// No AI
|
||||
if ((total_karts - total_player) == 0) return;
|
||||
|
||||
int red_player = 0;
|
||||
int blue_player = 0;
|
||||
for (int i = 0; i < total_player; i++)
|
||||
{
|
||||
KartTeam team = race_manager->getKartInfo(i).getKartTeam();
|
||||
|
||||
// Happen in profiling mode
|
||||
if (team == KART_TEAM_NONE)
|
||||
{
|
||||
race_manager->setKartTeam(i, KART_TEAM_BLUE);
|
||||
team = KART_TEAM_BLUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
team == KART_TEAM_BLUE ? blue_player++ : red_player++;
|
||||
}
|
||||
|
||||
int available_ai = total_karts - red_player - blue_player;
|
||||
while (available_ai > 0)
|
||||
{
|
||||
if ((m_red_ai + red_player) > (m_blue_ai + blue_player))
|
||||
{
|
||||
m_blue_ai++;
|
||||
available_ai--;
|
||||
}
|
||||
else if ((m_blue_ai + blue_player) > (m_red_ai + red_player))
|
||||
{
|
||||
m_red_ai++;
|
||||
available_ai--;
|
||||
}
|
||||
else if ((m_blue_ai + blue_player) == (m_red_ai + red_player))
|
||||
{
|
||||
blue_player > red_player ? m_red_ai++ : m_blue_ai++;
|
||||
available_ai--;
|
||||
}
|
||||
}
|
||||
Log::debug("World", "Blue AI: %d red AI: %d", m_blue_ai, m_red_ai);
|
||||
|
||||
} // setAITeam
|
||||
|
@ -25,6 +25,7 @@
|
||||
* battle, etc.)
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
@ -85,6 +86,13 @@ public:
|
||||
private:
|
||||
/** A pointer to the global world object for a race. */
|
||||
static World *m_world;
|
||||
// ------------------------------------------------------------------------
|
||||
void setAITeam();
|
||||
// ------------------------------------------------------------------------
|
||||
std::shared_ptr<AbstractKart> createKartWithTeam
|
||||
(const std::string &kart_ident, int index, int local_player_id,
|
||||
int global_player_id, RaceManager::KartType type,
|
||||
PerPlayerDifficulty difficulty);
|
||||
|
||||
protected:
|
||||
|
||||
@ -92,6 +100,12 @@ protected:
|
||||
unsigned int m_magic_number;
|
||||
#endif
|
||||
|
||||
/* Team related variables. */
|
||||
int m_red_ai;
|
||||
int m_blue_ai;
|
||||
std::map<int, KartTeam> m_kart_team_map;
|
||||
std::map<int, unsigned int> m_kart_position_map;
|
||||
|
||||
/** The list of all karts. */
|
||||
KartList m_karts;
|
||||
RandomGenerator m_random;
|
||||
@ -179,7 +193,8 @@ protected:
|
||||
*/
|
||||
virtual float estimateFinishTimeForKart(AbstractKart* kart)
|
||||
{return getTime(); }
|
||||
|
||||
/** Set the team arrow on karts if necessary*/
|
||||
void initTeamArrows();
|
||||
|
||||
public:
|
||||
World();
|
||||
@ -334,6 +349,11 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool hasTeam() const { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the team of kart in world (including AIs) */
|
||||
KartTeam getKartTeam(unsigned int kart_id) const;
|
||||
// ------------------------------------------------------------------------
|
||||
int getTeamNum(KartTeam team) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set the network mode (true if networked) */
|
||||
void setNetworkWorld(bool is_networked) { m_is_network_world = is_networked; }
|
||||
|
||||
|
@ -217,9 +217,9 @@ void GameSetup::sortPlayersForGrandPrix()
|
||||
} // sortPlayersForGrandPrix
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void GameSetup::sortPlayersForSoccer()
|
||||
void GameSetup::sortPlayersForTeamGame()
|
||||
{
|
||||
if (race_manager->getMinorMode() != RaceManager::MINOR_MODE_SOCCER ||
|
||||
if (!race_manager->teamEnabled() ||
|
||||
NetworkConfig::get()->hasTeamChoosing())
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(m_players_mutex);
|
||||
@ -229,4 +229,4 @@ void GameSetup::sortPlayersForSoccer()
|
||||
assert(player);
|
||||
player->setTeam((KartTeam)(i % 2));
|
||||
}
|
||||
} // sortPlayersForSoccer
|
||||
} // sortPlayersForTeamGame
|
||||
|
@ -164,7 +164,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
void sortPlayersForGrandPrix();
|
||||
// ------------------------------------------------------------------------
|
||||
void sortPlayersForSoccer();
|
||||
void sortPlayersForTeamGame();
|
||||
// ------------------------------------------------------------------------
|
||||
void setHitCaptureTime(int hc, float time)
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ void LobbyProtocol::configRemoteKart(
|
||||
rki.setDefaultKartColor(profile->getDefaultKartColor());
|
||||
rki.setPerPlayerDifficulty(profile->getPerPlayerDifficulty());
|
||||
rki.setOnlineId(profile->getOnlineId());
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
|
||||
if (race_manager->teamEnabled())
|
||||
rki.setKartTeam(profile->getTeam());
|
||||
// Inform the race manager about the data for this kart.
|
||||
race_manager->setPlayerKart(i, rki);
|
||||
|
@ -164,12 +164,25 @@ void ServerLobby::setup()
|
||||
while (it != m_available_kts.second.end())
|
||||
{
|
||||
Track* t = track_manager->getTrack(*it);
|
||||
if (!t->isArena() || t->isInternal())
|
||||
if (race_manager->getMajorMode() ==
|
||||
RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
|
||||
{
|
||||
it = m_available_kts.second.erase(it);
|
||||
if (!t->isCTF() || t->isInternal())
|
||||
{
|
||||
it = m_available_kts.second.erase(it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
else
|
||||
it++;
|
||||
{
|
||||
if (!t->isArena() || t->isInternal())
|
||||
{
|
||||
it = m_available_kts.second.erase(it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -480,7 +493,7 @@ void ServerLobby::asynchronousUpdate()
|
||||
// Remove disconnected player (if any) one last time
|
||||
m_game_setup->update(true);
|
||||
m_game_setup->sortPlayersForGrandPrix();
|
||||
m_game_setup->sortPlayersForSoccer();
|
||||
m_game_setup->sortPlayersForTeamGame();
|
||||
auto players = m_game_setup->getConnectedPlayers();
|
||||
NetworkString* load_world = getNetworkString();
|
||||
load_world->setSynchronous(true);
|
||||
|
@ -130,6 +130,7 @@ Track::Track(const std::string &filename)
|
||||
m_enable_push_back = true;
|
||||
m_reverse_available = false;
|
||||
m_is_arena = false;
|
||||
m_is_ctf = false;
|
||||
m_max_arena_players = 0;
|
||||
m_has_easter_eggs = false;
|
||||
m_has_navmesh = false;
|
||||
@ -160,6 +161,8 @@ Track::Track(const std::string &filename)
|
||||
m_minimap_y_scale = 1.0f;
|
||||
m_force_disable_fog = false;
|
||||
m_startup_run = false;
|
||||
m_red_flag = m_blue_flag =
|
||||
btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
m_default_number_of_laps = 3;
|
||||
m_all_nodes.clear();
|
||||
m_static_physics_only_nodes.clear();
|
||||
@ -545,6 +548,7 @@ void Track::loadTrackInfo()
|
||||
root->get("friction", &m_friction);
|
||||
root->get("soccer", &m_is_soccer);
|
||||
root->get("arena", &m_is_arena);
|
||||
root->get("ctf", &m_is_ctf);
|
||||
root->get("max-arena-players", &m_max_arena_players);
|
||||
root->get("cutscene", &m_is_cutscene);
|
||||
root->get("groups", &m_groups);
|
||||
@ -2075,6 +2079,19 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
}
|
||||
} // for i<root->getNumNodes()
|
||||
}
|
||||
if (m_is_ctf &&
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
|
||||
{
|
||||
for (unsigned int i=0; i<root->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode *node = root->getNode(i);
|
||||
const std::string &name = node->getName();
|
||||
if (name == "red-flag" || name == "blue-flag")
|
||||
{
|
||||
flagCommand(node);
|
||||
}
|
||||
} // for i<root->getNumNodes()
|
||||
}
|
||||
delete root;
|
||||
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
@ -2146,6 +2163,9 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
|
||||
unsigned int start_position_counter = 0;
|
||||
|
||||
unsigned int node_count = root->getNumNodes();
|
||||
const bool is_mode_ctf = m_is_ctf && race_manager->getMajorMode() ==
|
||||
RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG;
|
||||
|
||||
for (unsigned int i = 0; i < node_count; i++)
|
||||
{
|
||||
const XMLNode *node = root->getNode(i);
|
||||
@ -2168,12 +2188,16 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
|
||||
}
|
||||
else if (name == "banana" || name == "item" ||
|
||||
name == "small-nitro" || name == "big-nitro" ||
|
||||
name == "easter-egg" )
|
||||
name == "easter-egg" || name == "red-flag" ||
|
||||
name == "blue-flag")
|
||||
{
|
||||
// will be handled later
|
||||
}
|
||||
else if (name == "start")
|
||||
else if (name == "start" || name == "ctf-start")
|
||||
{
|
||||
if ((name == "start" && is_mode_ctf) ||
|
||||
(name == "ctf-start" && !is_mode_ctf))
|
||||
continue;
|
||||
unsigned int position = start_position_counter;
|
||||
start_position_counter++;
|
||||
node->get("position", &position);
|
||||
@ -2397,6 +2421,67 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
|
||||
} // if sky-box
|
||||
} // handleSky
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Track::flagCommand(const XMLNode *node)
|
||||
{
|
||||
Vec3 xyz;
|
||||
// Set some kind of default in case Y is not defined in the file
|
||||
// (with the new track exporter it always is defined anyway).
|
||||
// Y is the height from which the item is dropped on the track.
|
||||
xyz.setY(1000);
|
||||
node->getXYZ(&xyz);
|
||||
|
||||
Vec3 loc(xyz);
|
||||
|
||||
// Test if the item lies on a 3d node, if so adjust the normal
|
||||
// Also do a raycast if drop item is given
|
||||
Vec3 normal(0, 1, 0);
|
||||
Vec3 quad_normal = normal;
|
||||
Vec3 hit_point = loc;
|
||||
if (Graph::get())
|
||||
{
|
||||
int road_sector = Graph::UNKNOWN_SECTOR;
|
||||
Graph::get()->findRoadSector(xyz, &road_sector);
|
||||
// Only do custom direction of raycast if item is on quad graph
|
||||
if (road_sector != Graph::UNKNOWN_SECTOR)
|
||||
{
|
||||
quad_normal = Graph::get()->getQuad(road_sector)->getNormal();
|
||||
}
|
||||
}
|
||||
|
||||
const Material *m;
|
||||
// If raycast is used, increase the start position slightly
|
||||
// in case that the point is too close to the actual surface
|
||||
// (e.g. floating point errors can cause a problem here).
|
||||
loc += quad_normal * 0.1f;
|
||||
|
||||
#ifndef DEBUG
|
||||
m_track_mesh->castRay(loc, loc + (-10000 * quad_normal), &hit_point,
|
||||
&m, &normal);
|
||||
#else
|
||||
bool drop_success = m_track_mesh->castRay(loc, loc +
|
||||
(-10000 * quad_normal), &hit_point, &m, &normal);
|
||||
if (!drop_success)
|
||||
{
|
||||
Log::warn("track", "flag at position (%f,%f,%f) can not be dropped",
|
||||
loc.getX(), loc.getY(), loc.getZ());
|
||||
Log::warn("track", "onto terrain - position unchanged.");
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::string &name = node->getName();
|
||||
if (name == "red-flag")
|
||||
{
|
||||
m_red_flag = btTransform(shortestArcQuat(Vec3(0, 1, 0), normal),
|
||||
hit_point);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_blue_flag = btTransform(shortestArcQuat(Vec3(0, 1, 0), normal),
|
||||
hit_point);
|
||||
}
|
||||
} // flagCommand
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Handle creation and placement of an item.
|
||||
* \param xyz The position of the item.
|
||||
@ -2408,6 +2493,13 @@ void Track::itemCommand(const XMLNode *node)
|
||||
{
|
||||
const std::string &name = node->getName();
|
||||
|
||||
const bool is_mode_ctf = m_is_ctf &&
|
||||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG;
|
||||
bool ctf = false;
|
||||
node->get("ctf", &ctf);
|
||||
if ((is_mode_ctf && !ctf) || (!is_mode_ctf && ctf))
|
||||
return;
|
||||
|
||||
Item::ItemType type;
|
||||
if (name=="banana" ) type = Item::ITEM_BANANA;
|
||||
else if(name=="item" ) type = Item::ITEM_BONUS_BOX;
|
||||
|
@ -200,8 +200,11 @@ private:
|
||||
Vec3 m_aabb_min;
|
||||
/** Maximum coordinates of this track. */
|
||||
Vec3 m_aabb_max;
|
||||
btTransform m_red_flag;
|
||||
btTransform m_blue_flag;
|
||||
/** True if this track is an arena. */
|
||||
bool m_is_arena;
|
||||
bool m_is_ctf;
|
||||
/** Max players supported by an arena. */
|
||||
unsigned int m_max_arena_players;
|
||||
/** True if this track has easter eggs. */
|
||||
@ -427,6 +430,7 @@ public:
|
||||
void update(int ticks);
|
||||
void reset();
|
||||
void itemCommand(const XMLNode *node);
|
||||
void flagCommand(const XMLNode *node);
|
||||
core::stringw getName() const;
|
||||
core::stringw getSortName() const;
|
||||
bool isInGroup(const std::string &group_name);
|
||||
@ -447,6 +451,8 @@ public:
|
||||
/** Returns true if this track has an arena mode. */
|
||||
bool isArena() const { return m_is_arena; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool isCTF() const { return m_is_ctf; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this track is a racing track. This means it is not an
|
||||
* internal track (like cut scenes), arena, or soccer field. */
|
||||
bool isRaceTrack() const
|
||||
@ -681,6 +687,11 @@ public:
|
||||
/** Adds the parent of the meta library for correction later */
|
||||
void addMetaLibrary(TrackObject* parent, TrackObject* meta_library)
|
||||
{ m_meta_library.emplace_back(parent, meta_library); }
|
||||
// ------------------------------------------------------------------------
|
||||
const btTransform& getRedFlag() const { return m_red_flag; }
|
||||
// ------------------------------------------------------------------------
|
||||
const btTransform& getBlueFlag() const { return m_blue_flag; }
|
||||
|
||||
}; // class Track
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user