Added preliminary easter-egg mode. It still needs a icon (battle mode
used atm), and a better easter egg model (atm bunny from snow mountain, ... whith turns out has lost the black nose). One track has easter eggs added (math class). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@12281 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
8202eb8f9e
commit
29be45b198
BIN
data/gui/mode_easter.png
Normal file
BIN
data/gui/mode_easter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
@ -9,5 +9,7 @@
|
|||||||
handled as one, so list it here -->
|
handled as one, so list it here -->
|
||||||
<bubblegum model="bubblegum.b3d" lowmodel="bubblegum-low.b3d" />
|
<bubblegum model="bubblegum.b3d" lowmodel="bubblegum-low.b3d" />
|
||||||
<bubblegum-nolok model="bubblegum-nolok.b3d" lowmodel="bubblegum-nolok-low.b3d"/>
|
<bubblegum-nolok model="bubblegum-nolok.b3d" lowmodel="bubblegum-nolok-low.b3d"/>
|
||||||
|
<!-- <easter-egg model="easter_egg.b3d" /> -->
|
||||||
|
<easter-egg model="easter_egg.b3d" />
|
||||||
</items>
|
</items>
|
||||||
|
|
||||||
|
BIN
data/models/easter_egg-icon.png
Normal file
BIN
data/models/easter_egg-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
data/models/easter_egg.b3d
Normal file
BIN
data/models/easter_egg.b3d
Normal file
Binary file not shown.
@ -110,8 +110,9 @@
|
|||||||
<powerup collect-mode="new"/>
|
<powerup collect-mode="new"/>
|
||||||
<!-- time: How long a switch is being effective.
|
<!-- time: How long a switch is being effective.
|
||||||
items for each item list the index of the item it is switched with.
|
items for each item list the index of the item it is switched with.
|
||||||
Order: giftbox, banana, big-nitro, small-nitro, bubble-gum, trigger, nolok-bubble-gum -->
|
Order: giftbox, banana, big-nitro, small-nitro, bubble-gum, trigger,
|
||||||
<switch time="5" items="1 0 4 4 2 5 2"/>
|
nolok-bubble-gum, easter egg -->
|
||||||
|
<switch time="5" items="1 0 4 4 2 5 2 7"/>
|
||||||
|
|
||||||
<!-- How often bubble gum get driven over before it disappears. -->
|
<!-- How often bubble gum get driven over before it disappears. -->
|
||||||
<bubble-gum disappear-counter="1"/>
|
<bubble-gum disappear-counter="1"/>
|
||||||
|
@ -121,6 +121,7 @@ src/main.cpp
|
|||||||
src/main_loop.cpp
|
src/main_loop.cpp
|
||||||
src/modes/cutscene_world.cpp
|
src/modes/cutscene_world.cpp
|
||||||
src/modes/demo_world.cpp
|
src/modes/demo_world.cpp
|
||||||
|
src/modes/easter_egg_hunt.cpp
|
||||||
src/modes/follow_the_leader.cpp
|
src/modes/follow_the_leader.cpp
|
||||||
src/modes/game_tutorial.cpp
|
src/modes/game_tutorial.cpp
|
||||||
src/modes/linear_world.cpp
|
src/modes/linear_world.cpp
|
||||||
@ -367,6 +368,7 @@ src/karts/skidding_properties.hpp
|
|||||||
src/main_loop.hpp
|
src/main_loop.hpp
|
||||||
src/modes/cutscene_world.hpp
|
src/modes/cutscene_world.hpp
|
||||||
src/modes/demo_world.hpp
|
src/modes/demo_world.hpp
|
||||||
|
src/modes/easter_egg_hunt.hpp
|
||||||
src/modes/follow_the_leader.hpp
|
src/modes/follow_the_leader.hpp
|
||||||
src/modes/game_tutorial.hpp
|
src/modes/game_tutorial.hpp
|
||||||
src/modes/linear_world.hpp
|
src/modes/linear_world.hpp
|
||||||
|
@ -700,6 +700,10 @@
|
|||||||
RelativePath="..\..\modes\demo_world.cpp"
|
RelativePath="..\..\modes\demo_world.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\modes\easter_egg_hunt.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\modes\follow_the_leader.cpp"
|
RelativePath="..\..\modes\follow_the_leader.cpp"
|
||||||
>
|
>
|
||||||
@ -1886,6 +1890,10 @@
|
|||||||
RelativePath="..\..\modes\demo_world.hpp"
|
RelativePath="..\..\modes\demo_world.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\modes\easter_egg_hunt.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\modes\follow_the_leader.hpp"
|
RelativePath="..\..\modes\follow_the_leader.hpp"
|
||||||
>
|
>
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "graphics/lod_node.hpp"
|
#include "graphics/lod_node.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
|
#include "modes/easter_egg_hunt.hpp"
|
||||||
#include "modes/three_strikes_battle.hpp"
|
#include "modes/three_strikes_battle.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
@ -109,10 +110,17 @@ void Item::initItem(ItemType type, const Vec3 &xyz)
|
|||||||
m_deactive_time = 0;
|
m_deactive_time = 0;
|
||||||
m_time_till_return = 0.0f; // not strictly necessary, see isCollected()
|
m_time_till_return = 0.0f; // not strictly necessary, see isCollected()
|
||||||
m_emitter = NULL;
|
m_emitter = NULL;
|
||||||
m_rotate = (type!=ITEM_BUBBLEGUM) && (type!=ITEM_TRIGGER);
|
m_rotate = (type!=ITEM_BUBBLEGUM) && (type!=ITEM_TRIGGER) &&
|
||||||
m_disappear_counter = m_type==ITEM_BUBBLEGUM
|
(type!=ITEM_EASTER_EGG);
|
||||||
? stk_config->m_bubble_gum_counter
|
switch(m_type)
|
||||||
: -1 ;
|
{
|
||||||
|
case ITEM_BUBBLEGUM:
|
||||||
|
m_disappear_counter = stk_config->m_bubble_gum_counter; break;
|
||||||
|
case ITEM_EASTER_EGG:
|
||||||
|
m_disappear_counter = -1; break;
|
||||||
|
default:
|
||||||
|
m_disappear_counter = -1;
|
||||||
|
}
|
||||||
// Now determine in which quad this item is, and its distance
|
// Now determine in which quad this item is, and its distance
|
||||||
// from the center within this quad.
|
// from the center within this quad.
|
||||||
m_graph_node = QuadGraph::UNKNOWN_SECTOR;
|
m_graph_node = QuadGraph::UNKNOWN_SECTOR;
|
||||||
@ -236,9 +244,15 @@ void Item::reset()
|
|||||||
m_collected = false;
|
m_collected = false;
|
||||||
m_time_till_return = 0.0f;
|
m_time_till_return = 0.0f;
|
||||||
m_deactive_time = 0.0f;
|
m_deactive_time = 0.0f;
|
||||||
m_disappear_counter = m_type==ITEM_BUBBLEGUM
|
switch(m_type)
|
||||||
? stk_config->m_bubble_gum_counter
|
{
|
||||||
: -1 ;
|
case ITEM_BUBBLEGUM:
|
||||||
|
m_disappear_counter = stk_config->m_bubble_gum_counter; break;
|
||||||
|
case ITEM_EASTER_EGG:
|
||||||
|
m_disappear_counter = -1; break;
|
||||||
|
default:
|
||||||
|
m_disappear_counter = -1;
|
||||||
|
}
|
||||||
if(m_original_type!=ITEM_NONE)
|
if(m_original_type!=ITEM_NONE)
|
||||||
{
|
{
|
||||||
setType(m_original_type);
|
setType(m_original_type);
|
||||||
@ -319,7 +333,18 @@ void Item::collected(const AbstractKart *kart, float t)
|
|||||||
{
|
{
|
||||||
m_collected = true;
|
m_collected = true;
|
||||||
m_event_handler = kart;
|
m_event_handler = kart;
|
||||||
if(m_type==ITEM_BUBBLEGUM && m_disappear_counter>0)
|
if(m_type==ITEM_EASTER_EGG)
|
||||||
|
{
|
||||||
|
m_time_till_return=99999;
|
||||||
|
EasterEggHunt *world = dynamic_cast<EasterEggHunt*>(World::getWorld());
|
||||||
|
assert(world);
|
||||||
|
world->collectedEasterEgg(kart);
|
||||||
|
if (m_node != NULL)
|
||||||
|
{
|
||||||
|
m_node->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(m_type==ITEM_BUBBLEGUM && m_disappear_counter>0)
|
||||||
{
|
{
|
||||||
m_disappear_counter --;
|
m_disappear_counter --;
|
||||||
// Deactivates the item for a certain amount of time. It is used to
|
// Deactivates the item for a certain amount of time. It is used to
|
||||||
|
@ -74,6 +74,8 @@ public:
|
|||||||
ITEM_BUBBLEGUM,
|
ITEM_BUBBLEGUM,
|
||||||
ITEM_BUBBLEGUM_NOLOK,
|
ITEM_BUBBLEGUM_NOLOK,
|
||||||
|
|
||||||
|
/** For easter egg mode only. */
|
||||||
|
ITEM_EASTER_EGG,
|
||||||
/** An invisible item that can be used to trigger some behavior when
|
/** An invisible item that can be used to trigger some behavior when
|
||||||
* approaching a point
|
* approaching a point
|
||||||
*/
|
*/
|
||||||
|
@ -77,8 +77,8 @@ void ItemManager::loadDefaultItemMeshes()
|
|||||||
item_names[Item::ITEM_NITRO_BIG ] = "nitro-big";
|
item_names[Item::ITEM_NITRO_BIG ] = "nitro-big";
|
||||||
item_names[Item::ITEM_NITRO_SMALL] = "nitro-small";
|
item_names[Item::ITEM_NITRO_SMALL] = "nitro-small";
|
||||||
item_names[Item::ITEM_TRIGGER ] = "trigger";
|
item_names[Item::ITEM_TRIGGER ] = "trigger";
|
||||||
|
|
||||||
item_names[Item::ITEM_BUBBLEGUM_NOLOK] = "bubblegum-nolok";
|
item_names[Item::ITEM_BUBBLEGUM_NOLOK] = "bubblegum-nolok";
|
||||||
|
item_names[Item::ITEM_EASTER_EGG ] = "easter-egg";
|
||||||
|
|
||||||
const std::string file_name = file_manager->getDataFile("items.xml");
|
const std::string file_name = file_manager->getDataFile("items.xml");
|
||||||
const XMLNode *root = file_manager->createXMLTree(file_name);
|
const XMLNode *root = file_manager->createXMLTree(file_name);
|
||||||
|
@ -85,7 +85,7 @@ void ProjectileManager::update(float dt)
|
|||||||
he = next;
|
he = next;
|
||||||
}
|
}
|
||||||
// Update this hit effect. If it can be removed, remove it.
|
// Update this hit effect. If it can be removed, remove it.
|
||||||
if((*he)->updateAndDelete(dt))
|
else if((*he)->updateAndDelete(dt))
|
||||||
{
|
{
|
||||||
delete *he;
|
delete *he;
|
||||||
HitEffects::iterator next = m_active_hit_effects.erase(he);
|
HitEffects::iterator next = m_active_hit_effects.erase(he);
|
||||||
|
@ -27,13 +27,7 @@ float AIProperties::UNDEFINED = -99.9f;
|
|||||||
*/
|
*/
|
||||||
AIProperties::AIProperties(RaceManager::Difficulty difficulty)
|
AIProperties::AIProperties(RaceManager::Difficulty difficulty)
|
||||||
{
|
{
|
||||||
switch(difficulty)
|
m_ident = race_manager->getDifficultyAsString(difficulty);
|
||||||
{
|
|
||||||
case RaceManager::DIFFICULTY_EASY: m_ident="easy"; break;
|
|
||||||
case RaceManager::DIFFICULTY_MEDIUM: m_ident="medium"; break;
|
|
||||||
case RaceManager::DIFFICULTY_HARD: m_ident="hard"; break;
|
|
||||||
default: m_ident=""; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_max_item_angle = UNDEFINED;
|
m_max_item_angle = UNDEFINED;
|
||||||
m_max_item_angle_high_speed = UNDEFINED;
|
m_max_item_angle_high_speed = UNDEFINED;
|
||||||
|
@ -69,6 +69,9 @@ void Moveable::updateGraphics(float dt, const Vec3& offset_xyz,
|
|||||||
Vec3 xyz=getXYZ()+offset_xyz;
|
Vec3 xyz=getXYZ()+offset_xyz;
|
||||||
m_node->setPosition(xyz.toIrrVector());
|
m_node->setPosition(xyz.toIrrVector());
|
||||||
btQuaternion r_all = getRotation()*rotation;
|
btQuaternion r_all = getRotation()*rotation;
|
||||||
|
if(btFuzzyZero(r_all.getX()) && btFuzzyZero(r_all.getY()-0.70710677f) &&
|
||||||
|
btFuzzyZero(r_all.getZ()) && btFuzzyZero(r_all.getW()-0.70710677f) )
|
||||||
|
r_all.setX(0.000001f);
|
||||||
Vec3 hpr;
|
Vec3 hpr;
|
||||||
hpr.setHPR(r_all);
|
hpr.setHPR(r_all);
|
||||||
m_node->setRotation(hpr.toIrrHPR());
|
m_node->setRotation(hpr.toIrrHPR());
|
||||||
|
203
src/modes/easter_egg_hunt.cpp
Normal file
203
src/modes/easter_egg_hunt.cpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2012 Joerg Henrichs
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 3
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#include "modes/easter_egg_hunt.hpp"
|
||||||
|
|
||||||
|
#include "io/file_manager.hpp"
|
||||||
|
#include "karts/abstract_kart.hpp"
|
||||||
|
#include "tracks/track.hpp"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Constructor. Sets up the clock mode etc.
|
||||||
|
*/
|
||||||
|
EasterEggHunt::EasterEggHunt() : WorldWithRank()
|
||||||
|
{
|
||||||
|
WorldStatus::setClockMode(CLOCK_CHRONO);
|
||||||
|
m_use_highscores = false;
|
||||||
|
m_eggs_found = 0;
|
||||||
|
} // EasterEggHunt
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Initialises the easer egg hunt.
|
||||||
|
*/
|
||||||
|
void EasterEggHunt::init()
|
||||||
|
{
|
||||||
|
WorldWithRank::init();
|
||||||
|
m_display_rank = false;
|
||||||
|
|
||||||
|
// check for possible problems if AI karts were incorrectly added
|
||||||
|
if(getNumKarts() > race_manager->getNumPlayers())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No AI exists for this game mode\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int kart_amount = m_karts.size();
|
||||||
|
m_eggs_collected.resize(m_karts.size(), 0);
|
||||||
|
|
||||||
|
} // EasterEggHunt
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Destructor. Clears all internal data structures, and removes the tire mesh
|
||||||
|
* from the mesh cache.
|
||||||
|
*/
|
||||||
|
EasterEggHunt::~EasterEggHunt()
|
||||||
|
{
|
||||||
|
} // ~EasterEggHunt
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Check if a file easter_eggs.xml exists in the track directory, and if so
|
||||||
|
* loads that file and makes the easter egg mode available for this track.
|
||||||
|
*/
|
||||||
|
void EasterEggHunt::readData(const std::string &filename)
|
||||||
|
{
|
||||||
|
XMLNode *easter = file_manager->createXMLTree(filename);
|
||||||
|
if(!easter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(easter->getName()!="EasterEggHunt")
|
||||||
|
{
|
||||||
|
printf("Can't load easter egg file '%s' - no EasterEggHunt element.",
|
||||||
|
filename);
|
||||||
|
delete easter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XMLNode *data = NULL;
|
||||||
|
std::string difficulty_name;
|
||||||
|
RaceManager::Difficulty diff = race_manager->getDifficulty();
|
||||||
|
for(unsigned int i=0; i<RaceManager::DIFFICULTY_COUNT; i++)
|
||||||
|
{
|
||||||
|
difficulty_name = race_manager->getDifficultyAsString(diff);
|
||||||
|
data = easter->getNode(difficulty_name);
|
||||||
|
if(data) break;
|
||||||
|
diff = (RaceManager::Difficulty)(diff+1);
|
||||||
|
if(diff==RaceManager::DIFFICULTY_LAST)
|
||||||
|
diff = RaceManager::DIFFICULTY_FIRST;
|
||||||
|
}
|
||||||
|
if(!data)
|
||||||
|
{
|
||||||
|
delete easter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_time_limit = 9999;
|
||||||
|
data->get("time-limit", &m_time_limit);
|
||||||
|
|
||||||
|
m_number_of_eggs = 0;
|
||||||
|
for(unsigned int i=0; i<data->getNumNodes(); i++)
|
||||||
|
{
|
||||||
|
const XMLNode *egg = data->getNode(i);
|
||||||
|
if(egg->getName()!="easter-egg")
|
||||||
|
{
|
||||||
|
printf("Unknown node '%s' in easter egg level '%s' - ignored.\n",
|
||||||
|
egg->getName().c_str(), difficulty_name.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
World::getTrack()->itemCommand(egg);
|
||||||
|
m_number_of_eggs++;
|
||||||
|
} // for i <num_nodes
|
||||||
|
|
||||||
|
delete easter;
|
||||||
|
|
||||||
|
WorldStatus::setClockMode(CLOCK_CHRONO, m_time_limit);
|
||||||
|
|
||||||
|
} // readEasterEggInfo
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns the internal identifier for this race.
|
||||||
|
*/
|
||||||
|
const std::string& EasterEggHunt::getIdent() const
|
||||||
|
{
|
||||||
|
return IDENT_EASTER;
|
||||||
|
} // getIdent
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Called when a kart has collected an egg.
|
||||||
|
* \param kart The kart that collected an egg.
|
||||||
|
*/
|
||||||
|
void EasterEggHunt::collectedEasterEgg(const AbstractKart *kart)
|
||||||
|
{
|
||||||
|
m_eggs_collected[kart->getWorldKartId()]++;
|
||||||
|
m_eggs_found++;
|
||||||
|
} // collectedEasterEgg
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Update the world and the track.
|
||||||
|
* \param dt Time step size.
|
||||||
|
*/
|
||||||
|
void EasterEggHunt::update(float dt)
|
||||||
|
{
|
||||||
|
WorldWithRank::update(dt);
|
||||||
|
WorldWithRank::updateTrack(dt);
|
||||||
|
} // update
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** The hunt is over once all eggs are found.
|
||||||
|
*/
|
||||||
|
bool EasterEggHunt::isRaceOver()
|
||||||
|
{
|
||||||
|
if(m_eggs_found == m_number_of_eggs)
|
||||||
|
return true;
|
||||||
|
if(m_time<0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
} // isRaceOver
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Called then a battle is restarted.
|
||||||
|
*/
|
||||||
|
void EasterEggHunt::restartRace()
|
||||||
|
{
|
||||||
|
WorldWithRank::restartRace();
|
||||||
|
|
||||||
|
for(unsigned int i=0; i<m_eggs_collected.size(); i++)
|
||||||
|
m_eggs_collected[i] = 0;
|
||||||
|
m_eggs_found = 0;
|
||||||
|
} // restartRace
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns the data to display in the race gui.
|
||||||
|
*/
|
||||||
|
void EasterEggHunt::getKartsDisplayInfo(
|
||||||
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info)
|
||||||
|
{
|
||||||
|
const unsigned int kart_amount = getNumKarts();
|
||||||
|
for(unsigned int i = 0; i < kart_amount ; i++)
|
||||||
|
{
|
||||||
|
RaceGUIBase::KartIconDisplayInfo& rank_info = (*info)[i];
|
||||||
|
std::ostringstream o;
|
||||||
|
//I18n: number of collected eggs / overall number of eggs
|
||||||
|
rank_info.m_text = StringUtils::insertValues(_("Eggs: %d / %d"),
|
||||||
|
m_eggs_collected[i],
|
||||||
|
m_number_of_eggs);
|
||||||
|
rank_info.m_color = video::SColor(255, 255, 255, 255);
|
||||||
|
}
|
||||||
|
} // getKartDisplayInfo
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Moves a kart to its rescue position.
|
||||||
|
* \param kart The kart that was rescued.
|
||||||
|
*/
|
||||||
|
void EasterEggHunt::moveKartAfterRescue(AbstractKart* kart)
|
||||||
|
{
|
||||||
|
int start_position = kart->getInitialPosition();
|
||||||
|
btTransform start_pos = getTrack()->getStartTransform(start_position-1);
|
||||||
|
|
||||||
|
kart->getBody()->setCenterOfMassTransform(start_pos);
|
||||||
|
|
||||||
|
} // moveKartAfterRescue
|
74
src/modes/easter_egg_hunt.hpp
Executable file
74
src/modes/easter_egg_hunt.hpp
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2012 Joerg Henrichs
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 3
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#ifndef EASTER_EGG_HUNT_HPP
|
||||||
|
#define EASTER_EGG_HUNT_HPP
|
||||||
|
|
||||||
|
#include "modes/world_with_rank.hpp"
|
||||||
|
#include "states_screens/race_gui_base.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class AbstractKart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief An implementation of World to provide an easter egg hunt like mode
|
||||||
|
* \ingroup modes
|
||||||
|
*/
|
||||||
|
class EasterEggHunt: public WorldWithRank
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/** Keeps track of how many eggs each kart has found. */
|
||||||
|
std::vector<int> m_eggs_collected;
|
||||||
|
|
||||||
|
/** A time limit for the hunt. */
|
||||||
|
float m_time_limit;
|
||||||
|
|
||||||
|
/** Overall number of easter eggs. */
|
||||||
|
int m_number_of_eggs;
|
||||||
|
|
||||||
|
/** Number of eggs found so far. */
|
||||||
|
int m_eggs_found;
|
||||||
|
public:
|
||||||
|
EasterEggHunt();
|
||||||
|
virtual ~EasterEggHunt();
|
||||||
|
|
||||||
|
virtual void init();
|
||||||
|
|
||||||
|
virtual bool isRaceOver();
|
||||||
|
|
||||||
|
// overriding World methods
|
||||||
|
virtual void restartRace();
|
||||||
|
|
||||||
|
virtual bool raceHasLaps(){ return false; }
|
||||||
|
virtual void moveKartAfterRescue(AbstractKart* kart);
|
||||||
|
|
||||||
|
virtual const std::string& getIdent() const;
|
||||||
|
|
||||||
|
virtual void update(float dt);
|
||||||
|
virtual void getKartsDisplayInfo(
|
||||||
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
||||||
|
|
||||||
|
void updateKartRanks();
|
||||||
|
void collectedEasterEgg(const AbstractKart *kart);
|
||||||
|
void readData(const std::string &filename);
|
||||||
|
}; // EasterEggHunt
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -422,9 +422,7 @@ void LinearWorld::getKartsDisplayInfo(
|
|||||||
AbstractKart* kart = m_karts[i];
|
AbstractKart* kart = m_karts[i];
|
||||||
|
|
||||||
// reset color
|
// reset color
|
||||||
rank_info.r = 1.0;
|
rank_info.m_color = video::SColor(255, 255, 255, 255);
|
||||||
rank_info.g = 1.0;
|
|
||||||
rank_info.b = 1.0;
|
|
||||||
rank_info.lap = -1;
|
rank_info.lap = -1;
|
||||||
|
|
||||||
if(kart->isEliminated()) continue;
|
if(kart->isEliminated()) continue;
|
||||||
@ -486,12 +484,15 @@ void LinearWorld::getKartsDisplayInfo(
|
|||||||
|
|
||||||
if(kart_info.m_race_lap>=numLaps)
|
if(kart_info.m_race_lap>=numLaps)
|
||||||
{ // kart is finished, display in green
|
{ // kart is finished, display in green
|
||||||
rank_info.g = rank_info.b = 0;
|
rank_info.m_color.setGreen(0);
|
||||||
|
rank_info.m_color.setBlue(0);
|
||||||
}
|
}
|
||||||
else if(kart_info.m_race_lap>=0 && numLaps>1)
|
else if(kart_info.m_race_lap>=0 && numLaps>1)
|
||||||
{
|
{
|
||||||
rank_info.g = rank_info.b =
|
int col = (int)(255*(1.0f-(float)kart_info.m_race_lap
|
||||||
1.0f-(float)kart_info.m_race_lap/((float)numLaps-1.0f);
|
/((float)numLaps-1.0f) ));
|
||||||
|
rank_info.m_color.setBlue(col);
|
||||||
|
rank_info.m_color.setGreen(col);
|
||||||
}
|
}
|
||||||
} // next kart
|
} // next kart
|
||||||
|
|
||||||
@ -561,22 +562,15 @@ void LinearWorld::moveKartAfterRescue(AbstractKart* kart)
|
|||||||
|
|
||||||
info.getSector()->rescue();
|
info.getSector()->rescue();
|
||||||
int sector = info.getSector()->getCurrentGraphNode();
|
int sector = info.getSector()->getCurrentGraphNode();
|
||||||
kart->setXYZ( QuadGraph::get()
|
|
||||||
->getQuadOfNode(sector).getCenter());
|
|
||||||
|
|
||||||
btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f),
|
|
||||||
m_track->getAngle(sector) );
|
|
||||||
kart->setRotation(heading);
|
|
||||||
|
|
||||||
// A certain epsilon is added here to the Z coordinate, in case
|
// A certain epsilon is added here to the Z coordinate, in case
|
||||||
// that the drivelines are somewhat under the track. Otherwise, the
|
// that the drivelines are somewhat under the track. Otherwise, the
|
||||||
// kart might be placed a little bit under the track, triggering
|
// kart might be placed a little bit under the track, triggering
|
||||||
// a rescue, ... (experimentally found value)
|
// a rescue, ... (experimentally found value)
|
||||||
float epsilon = 0.5f * kart->getKartHeight();
|
float epsilon = 0.5f * kart->getKartHeight();
|
||||||
|
const Vec3 &xyz = QuadGraph::get()->getQuadOfNode(sector).getCenter();
|
||||||
btTransform pos;
|
btTransform pos;
|
||||||
pos.setOrigin(kart->getXYZ()+btVector3(0, kart->getKartHeight() + epsilon,
|
pos.setOrigin(xyz+btVector3(0, kart->getKartHeight() + epsilon,0));
|
||||||
0));
|
|
||||||
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
|
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
|
||||||
m_track->getAngle(sector)));
|
m_track->getAngle(sector)));
|
||||||
|
|
||||||
|
@ -438,24 +438,16 @@ void ThreeStrikesBattle::getKartsDisplayInfo(
|
|||||||
switch(m_kart_info[i].m_lives)
|
switch(m_kart_info[i].m_lives)
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
rank_info.r = 0.0;
|
rank_info.m_color = video::SColor(255, 0, 255, 0);
|
||||||
rank_info.g = 1.0;
|
|
||||||
rank_info.b = 0.0;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
rank_info.r = 1.0;
|
rank_info.m_color = video::SColor(255, 255, 229, 0);
|
||||||
rank_info.g = 0.9f;
|
|
||||||
rank_info.b = 0.0;
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
rank_info.r = 1.0;
|
rank_info.m_color = video::SColor(255, 255, 0, 0);
|
||||||
rank_info.g = 0.0;
|
|
||||||
rank_info.b = 0.0;
|
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
rank_info.r = 0.5;
|
rank_info.m_color = video::SColor(128, 128, 128, 0);
|
||||||
rank_info.g = 0.5;
|
|
||||||
rank_info.b = 0.5;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ void World::init()
|
|||||||
|
|
||||||
// Load the track models - this must be done before the karts so that the
|
// Load the track models - this must be done before the karts so that the
|
||||||
// karts can be positioned properly on (and not in) the tracks.
|
// karts can be positioned properly on (and not in) the tracks.
|
||||||
m_track->loadTrackModel(this, race_manager->getReverseTrack());
|
m_track->loadTrackModel(race_manager->getReverseTrack());
|
||||||
|
|
||||||
for(unsigned int i=0; i<num_karts; i++)
|
for(unsigned int i=0; i<num_karts; i++)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "karts/kart_properties_manager.hpp"
|
#include "karts/kart_properties_manager.hpp"
|
||||||
#include "modes/cutscene_world.hpp"
|
#include "modes/cutscene_world.hpp"
|
||||||
#include "modes/demo_world.hpp"
|
#include "modes/demo_world.hpp"
|
||||||
|
#include "modes/easter_egg_hunt.hpp"
|
||||||
#include "modes/follow_the_leader.hpp"
|
#include "modes/follow_the_leader.hpp"
|
||||||
#include "modes/overworld.hpp"
|
#include "modes/overworld.hpp"
|
||||||
#include "modes/profile_world.hpp"
|
#include "modes/profile_world.hpp"
|
||||||
@ -394,6 +395,8 @@ void RaceManager::startNextRace()
|
|||||||
World::setWorld(new OverWorld());
|
World::setWorld(new OverWorld());
|
||||||
else if(m_minor_mode==MINOR_MODE_CUTSCENE)
|
else if(m_minor_mode==MINOR_MODE_CUTSCENE)
|
||||||
World::setWorld(new CutsceneWorld());
|
World::setWorld(new CutsceneWorld());
|
||||||
|
else if(m_minor_mode==MINOR_MODE_EASTER_EGG)
|
||||||
|
World::setWorld(new EasterEggHunt());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Could not create given race mode\n");
|
fprintf(stderr,"Could not create given race mode\n");
|
||||||
|
@ -42,6 +42,7 @@ static const std::string IDENT_STD ("STANDARD" );
|
|||||||
static const std::string IDENT_TTRIAL ("STD_TIMETRIAL" );
|
static const std::string IDENT_TTRIAL ("STD_TIMETRIAL" );
|
||||||
static const std::string IDENT_FTL ("FOLLOW_LEADER" );
|
static const std::string IDENT_FTL ("FOLLOW_LEADER" );
|
||||||
static const std::string IDENT_STRIKES ("BATTLE_3_STRIKES");
|
static const std::string IDENT_STRIKES ("BATTLE_3_STRIKES");
|
||||||
|
static const std::string IDENT_EASTER ("EASTER_EGG_HUNT");
|
||||||
static const std::string IDENT_OVERWORLD("OVERWORLD" );
|
static const std::string IDENT_OVERWORLD("OVERWORLD" );
|
||||||
static const std::string IDENT_CUSTSCENE("CUTSCENE" );
|
static const std::string IDENT_CUSTSCENE("CUTSCENE" );
|
||||||
|
|
||||||
@ -94,6 +95,7 @@ public:
|
|||||||
// issues
|
// issues
|
||||||
#define LINEAR_RACE(ID, COUNT_LAPSES) (1000+ID+100*COUNT_LAPSES)
|
#define LINEAR_RACE(ID, COUNT_LAPSES) (1000+ID+100*COUNT_LAPSES)
|
||||||
#define BATTLE_ARENA(ID) (2000+ID)
|
#define BATTLE_ARENA(ID) (2000+ID)
|
||||||
|
#define EASTER_EGG(ID) (3000+ID)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Minor variants to the major types of race.
|
/** Minor variants to the major types of race.
|
||||||
@ -108,7 +110,9 @@ public:
|
|||||||
MINOR_MODE_OVERWORLD = LINEAR_RACE(3, false),
|
MINOR_MODE_OVERWORLD = LINEAR_RACE(3, false),
|
||||||
|
|
||||||
MINOR_MODE_3_STRIKES = BATTLE_ARENA(0),
|
MINOR_MODE_3_STRIKES = BATTLE_ARENA(0),
|
||||||
MINOR_MODE_CUTSCENE = BATTLE_ARENA(1)
|
MINOR_MODE_CUTSCENE = BATTLE_ARENA(1),
|
||||||
|
|
||||||
|
MINOR_MODE_EASTER_EGG = EASTER_EGG(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -132,6 +136,7 @@ public:
|
|||||||
case MINOR_MODE_TIME_TRIAL: return IDENT_TTRIAL;
|
case MINOR_MODE_TIME_TRIAL: return IDENT_TTRIAL;
|
||||||
case MINOR_MODE_FOLLOW_LEADER: return IDENT_FTL;
|
case MINOR_MODE_FOLLOW_LEADER: return IDENT_FTL;
|
||||||
case MINOR_MODE_3_STRIKES: return IDENT_STRIKES;
|
case MINOR_MODE_3_STRIKES: return IDENT_STRIKES;
|
||||||
|
case MINOR_MODE_EASTER_EGG: return IDENT_EASTER;
|
||||||
default: assert(false);
|
default: assert(false);
|
||||||
return IDENT_STD; // stop compiler warning
|
return IDENT_STD; // stop compiler warning
|
||||||
}
|
}
|
||||||
@ -149,6 +154,7 @@ public:
|
|||||||
case MINOR_MODE_TIME_TRIAL: return "/gui/mode_tt.png";
|
case MINOR_MODE_TIME_TRIAL: return "/gui/mode_tt.png";
|
||||||
case MINOR_MODE_FOLLOW_LEADER: return "/gui/mode_ftl.png";
|
case MINOR_MODE_FOLLOW_LEADER: return "/gui/mode_ftl.png";
|
||||||
case MINOR_MODE_3_STRIKES: return "/gui/mode_3strikes.png";
|
case MINOR_MODE_3_STRIKES: return "/gui/mode_3strikes.png";
|
||||||
|
case MINOR_MODE_EASTER_EGG: return "/gui/mode_easter.png";
|
||||||
default: assert(false); return NULL;
|
default: assert(false); return NULL;
|
||||||
}
|
}
|
||||||
} // getIconOf
|
} // getIconOf
|
||||||
@ -169,6 +175,7 @@ public:
|
|||||||
case MINOR_MODE_FOLLOW_LEADER: return _("Follow the Leader");
|
case MINOR_MODE_FOLLOW_LEADER: return _("Follow the Leader");
|
||||||
//I18N: Game mode
|
//I18N: Game mode
|
||||||
case MINOR_MODE_3_STRIKES: return _("3 Strikes Battle");
|
case MINOR_MODE_3_STRIKES: return _("3 Strikes Battle");
|
||||||
|
case MINOR_MODE_EASTER_EGG: return _("Easter Egg Hunt");
|
||||||
default: assert(false); return NULL;
|
default: assert(false); return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,6 +189,7 @@ public:
|
|||||||
case MINOR_MODE_TIME_TRIAL: return true;
|
case MINOR_MODE_TIME_TRIAL: return true;
|
||||||
case MINOR_MODE_FOLLOW_LEADER: return true;
|
case MINOR_MODE_FOLLOW_LEADER: return true;
|
||||||
case MINOR_MODE_3_STRIKES: return false;
|
case MINOR_MODE_3_STRIKES: return false;
|
||||||
|
case MINOR_MODE_EASTER_EGG: return false;
|
||||||
default: assert(false); return NULL;
|
default: assert(false); return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,6 +207,7 @@ public:
|
|||||||
else if (name==IDENT_TTRIAL ) return MINOR_MODE_TIME_TRIAL;
|
else if (name==IDENT_TTRIAL ) return MINOR_MODE_TIME_TRIAL;
|
||||||
else if (name==IDENT_FTL ) return MINOR_MODE_FOLLOW_LEADER;
|
else if (name==IDENT_FTL ) return MINOR_MODE_FOLLOW_LEADER;
|
||||||
else if (name==IDENT_STRIKES) return MINOR_MODE_3_STRIKES;
|
else if (name==IDENT_STRIKES) return MINOR_MODE_3_STRIKES;
|
||||||
|
else if (name==IDENT_EASTER ) return MINOR_MODE_EASTER_EGG;
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
return MINOR_MODE_NONE;
|
return MINOR_MODE_NONE;
|
||||||
@ -209,8 +218,10 @@ public:
|
|||||||
|
|
||||||
/** Game difficulty. */
|
/** Game difficulty. */
|
||||||
enum Difficulty { DIFFICULTY_EASY,
|
enum Difficulty { DIFFICULTY_EASY,
|
||||||
|
DIFFICULTY_FIRST = DIFFICULTY_EASY,
|
||||||
DIFFICULTY_MEDIUM,
|
DIFFICULTY_MEDIUM,
|
||||||
DIFFICULTY_HARD,
|
DIFFICULTY_HARD,
|
||||||
|
DIFFICULTY_LAST = DIFFICULTY_HARD,
|
||||||
DIFFICULTY_COUNT};
|
DIFFICULTY_COUNT};
|
||||||
|
|
||||||
/** Different kart types: A local player, a player connected via network,
|
/** Different kart types: A local player, a player connected via network,
|
||||||
@ -467,8 +478,21 @@ public:
|
|||||||
/** \return whether the track should be reversed */
|
/** \return whether the track should be reversed */
|
||||||
bool getReverseTrack() const { return m_reverse_track[m_track_number]; }
|
bool getReverseTrack() const { return m_reverse_track[m_track_number]; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns the difficulty. */
|
||||||
Difficulty getDifficulty() const { return m_difficulty; }
|
Difficulty getDifficulty() const { return m_difficulty; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns the specified difficulty as a string. */
|
||||||
|
std::string getDifficultyAsString(Difficulty diff) const
|
||||||
|
{
|
||||||
|
switch(diff)
|
||||||
|
{
|
||||||
|
case RaceManager::DIFFICULTY_EASY: return "easy"; break;
|
||||||
|
case RaceManager::DIFFICULTY_MEDIUM: return "medium"; break;
|
||||||
|
case RaceManager::DIFFICULTY_HARD: return "hard"; break;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
} // getDifficultyAsString
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
const std::string& getTrackName() const { return m_tracks[m_track_number];}
|
const std::string& getTrackName() const { return m_tracks[m_track_number];}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const GrandPrixData *getGrandPrix() const { return &m_grand_prix; }
|
const GrandPrixData *getGrandPrix() const { return &m_grand_prix; }
|
||||||
|
@ -72,7 +72,7 @@ RacePausedDialog::~RacePausedDialog()
|
|||||||
void RacePausedDialog::loadedFromFile()
|
void RacePausedDialog::loadedFromFile()
|
||||||
{
|
{
|
||||||
// disable the "restart" button in GPs
|
// disable the "restart" button in GPs
|
||||||
if (race_manager->getMajorMode() != RaceManager::MAJOR_MODE_SINGLE)
|
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
|
||||||
{
|
{
|
||||||
GUIEngine::RibbonWidget* choice_ribbon =
|
GUIEngine::RibbonWidget* choice_ribbon =
|
||||||
getWidget<GUIEngine::RibbonWidget>("choiceribbon");
|
getWidget<GUIEngine::RibbonWidget>("choiceribbon");
|
||||||
|
@ -807,7 +807,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
|||||||
int lap = info.lap;
|
int lap = info.lap;
|
||||||
|
|
||||||
// In battle mode there is no distance along track etc.
|
// In battle mode there is no distance along track etc.
|
||||||
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES)
|
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES ||
|
||||||
|
race_manager->getMinorMode()==RaceManager::MINOR_MODE_EASTER_EGG)
|
||||||
{
|
{
|
||||||
x = x_base;
|
x = x_base;
|
||||||
y = previous_y+ICON_PLAYER_WIDTH+2;
|
y = previous_y+ICON_PLAYER_WIDTH+2;
|
||||||
@ -870,15 +871,12 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
|||||||
|
|
||||||
if (m_kart_display_infos[kart_id].m_text.size() > 0)
|
if (m_kart_display_infos[kart_id].m_text.size() > 0)
|
||||||
{
|
{
|
||||||
video::SColor color = video::SColor(255,
|
|
||||||
(int)(255*info.r),
|
|
||||||
(int)(255*info.g),
|
|
||||||
(int)(255*info.b) );
|
|
||||||
core::rect<s32> pos(x+ICON_PLAYER_WIDTH, y+5,
|
core::rect<s32> pos(x+ICON_PLAYER_WIDTH, y+5,
|
||||||
x+ICON_PLAYER_WIDTH, y+5);
|
x+ICON_PLAYER_WIDTH, y+5);
|
||||||
core::stringw s=info.m_text.c_str();
|
core::stringw s=info.m_text.c_str();
|
||||||
|
|
||||||
font->draw(s.c_str(), pos, color, false, false, NULL, true /* ignore RTL */);
|
font->draw(s.c_str(), pos, info.m_color, false, false, NULL,
|
||||||
|
true /* ignore RTL */);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.special_title.size() > 0)
|
if (info.special_title.size() > 0)
|
||||||
@ -887,7 +885,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
|||||||
core::rect<s32> pos(x+ICON_PLAYER_WIDTH, y+5,
|
core::rect<s32> pos(x+ICON_PLAYER_WIDTH, y+5,
|
||||||
x+ICON_PLAYER_WIDTH, y+5);
|
x+ICON_PLAYER_WIDTH, y+5);
|
||||||
core::stringw s(info.special_title.c_str());
|
core::stringw s(info.special_title.c_str());
|
||||||
font->draw(s.c_str(), pos, color, false, false, NULL, true /* ignore RTL */);
|
font->draw(s.c_str(), pos, info.m_color, false, false, NULL,
|
||||||
|
true /* ignore RTL */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw icon
|
// draw icon
|
||||||
|
@ -53,16 +53,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
struct KartIconDisplayInfo
|
struct KartIconDisplayInfo
|
||||||
{
|
{
|
||||||
/** text to display next to icon, if any */
|
/** Text to display next to icon, if any. */
|
||||||
core::stringw m_text;
|
core::stringw m_text;
|
||||||
|
|
||||||
/** text color, if any text */
|
/** Text color, if any text. */
|
||||||
float r, g, b;
|
video::SColor m_color;
|
||||||
|
|
||||||
/** if this kart has a special title, e.g. "leader" in follow-the-leader */
|
/** If this kart has a special title, e.g. "leader" in follow-the-leader. */
|
||||||
core::stringw special_title;
|
core::stringw special_title;
|
||||||
|
|
||||||
/** Current lap of this kart, or -1 if irrelevant */
|
/** Current lap of this kart, or -1 if irrelevant. */
|
||||||
int lap;
|
int lap;
|
||||||
}; // KartIconDisplayInfo
|
}; // KartIconDisplayInfo
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ const int CONFIG_CODE_NORMAL = 0;
|
|||||||
const int CONFIG_CODE_TIMETRIAL = 1;
|
const int CONFIG_CODE_TIMETRIAL = 1;
|
||||||
const int CONFIG_CODE_FTL = 2;
|
const int CONFIG_CODE_FTL = 2;
|
||||||
const int CONFIG_CODE_3STRIKES = 3;
|
const int CONFIG_CODE_3STRIKES = 3;
|
||||||
|
const int CONFIG_CODE_EASTER = 4;
|
||||||
|
|
||||||
using namespace GUIEngine;
|
using namespace GUIEngine;
|
||||||
DEFINE_SCREEN_SINGLETON( RaceSetupScreen );
|
DEFINE_SCREEN_SINGLETON( RaceSetupScreen );
|
||||||
@ -53,19 +54,19 @@ public:
|
|||||||
// game mode changed!!
|
// game mode changed!!
|
||||||
m_parent->onGameModeChanged();
|
m_parent->onGameModeChanged();
|
||||||
}
|
}
|
||||||
};
|
}; // GameModeRibbonListener
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
RaceSetupScreen::RaceSetupScreen() : Screen("racesetup.stkgui")
|
RaceSetupScreen::RaceSetupScreen() : Screen("racesetup.stkgui")
|
||||||
{
|
{
|
||||||
}
|
} // RaceSetupScreen
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RaceSetupScreen::loadedFromFile()
|
void RaceSetupScreen::loadedFromFile()
|
||||||
{
|
{
|
||||||
}
|
} // loadedFromFile
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -127,6 +128,13 @@ void RaceSetupScreen::eventCallback(Widget* widget, const std::string& name, con
|
|||||||
race_manager->setNumKarts( race_manager->getNumLocalPlayers() ); // no AI karts;
|
race_manager->setNumKarts( race_manager->getNumLocalPlayers() ); // no AI karts;
|
||||||
StateManager::get()->pushScreen( ArenasScreen::getInstance() );
|
StateManager::get()->pushScreen( ArenasScreen::getInstance() );
|
||||||
}
|
}
|
||||||
|
else if (selectedMode == IDENT_EASTER)
|
||||||
|
{
|
||||||
|
race_manager->setMinorMode(RaceManager::MINOR_MODE_EASTER_EGG);
|
||||||
|
UserConfigParams::m_game_mode = CONFIG_CODE_EASTER;
|
||||||
|
race_manager->setNumKarts( race_manager->getNumLocalPlayers() ); // no AI karts;
|
||||||
|
StateManager::get()->pushScreen( TracksScreen::getInstance() );
|
||||||
|
}
|
||||||
else if (selectedMode == "locked")
|
else if (selectedMode == "locked")
|
||||||
{
|
{
|
||||||
unlock_manager->playLockSound();
|
unlock_manager->playLockSound();
|
||||||
@ -142,7 +150,7 @@ void RaceSetupScreen::eventCallback(Widget* widget, const std::string& name, con
|
|||||||
{
|
{
|
||||||
StateManager::get()->escapePressed();
|
StateManager::get()->escapePressed();
|
||||||
}
|
}
|
||||||
}
|
} // eventCallback
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -167,7 +175,7 @@ void RaceSetupScreen::onGameModeChanged()
|
|||||||
{
|
{
|
||||||
kartamount->setActivated();
|
kartamount->setActivated();
|
||||||
}
|
}
|
||||||
}
|
} // onGameModeChanged
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -228,7 +236,15 @@ void RaceSetupScreen::init()
|
|||||||
name4 += _("Hit others with weapons until they lose all their lives. (Only in multiplayer games)");
|
name4 += _("Hit others with weapons until they lose all their lives. (Only in multiplayer games)");
|
||||||
w2->addItem( name4, IDENT_STRIKES, RaceManager::getIconOf(RaceManager::MINOR_MODE_3_STRIKES));
|
w2->addItem( name4, IDENT_STRIKES, RaceManager::getIconOf(RaceManager::MINOR_MODE_3_STRIKES));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
irr::core::stringw name1 = irr::core::stringw(
|
||||||
|
RaceManager::getNameOf(RaceManager::MINOR_MODE_EASTER_EGG)) + L"\n";
|
||||||
|
//FIXME: avoid duplicating descriptions from the help menu!
|
||||||
|
name1 += _("Find all Easter Eggs");
|
||||||
|
|
||||||
|
w2->addItem( name1, IDENT_EASTER,
|
||||||
|
RaceManager::getIconOf(RaceManager::MINOR_MODE_EASTER_EGG));
|
||||||
|
}
|
||||||
|
|
||||||
w2->updateItemDisplay();
|
w2->updateItemDisplay();
|
||||||
|
|
||||||
@ -247,10 +263,13 @@ void RaceSetupScreen::init()
|
|||||||
case CONFIG_CODE_3STRIKES :
|
case CONFIG_CODE_3STRIKES :
|
||||||
w2->setSelection(IDENT_STRIKES, PLAYER_ID_GAME_MASTER, true);
|
w2->setSelection(IDENT_STRIKES, PLAYER_ID_GAME_MASTER, true);
|
||||||
break;
|
break;
|
||||||
|
case CONFIG_CODE_EASTER :
|
||||||
|
w2->setSelection(IDENT_EASTER, PLAYER_ID_GAME_MASTER, true);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mode_listener = new GameModeRibbonListener(this);
|
m_mode_listener = new GameModeRibbonListener(this);
|
||||||
w2->registerHoverListener(m_mode_listener);
|
w2->registerHoverListener(m_mode_listener);
|
||||||
}
|
} // init
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -286,6 +286,9 @@ void TracksScreen::buildTrackList()
|
|||||||
for (int n=0; n<trackAmount; n++)
|
for (int n=0; n<trackAmount; n++)
|
||||||
{
|
{
|
||||||
Track* curr = track_manager->getTrack( n );
|
Track* curr = track_manager->getTrack( n );
|
||||||
|
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_EASTER_EGG
|
||||||
|
&& !curr->hasEasterEggs())
|
||||||
|
continue;
|
||||||
if (curr->isArena()) continue;
|
if (curr->isArena()) continue;
|
||||||
if (curr->isInternal()) continue;
|
if (curr->isInternal()) continue;
|
||||||
|
|
||||||
@ -313,6 +316,9 @@ void TracksScreen::buildTrackList()
|
|||||||
for (int n=0; n<trackAmount; n++)
|
for (int n=0; n<trackAmount; n++)
|
||||||
{
|
{
|
||||||
Track* curr = track_manager->getTrack( curr_group[n] );
|
Track* curr = track_manager->getTrack( curr_group[n] );
|
||||||
|
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_EASTER_EGG
|
||||||
|
&& !curr->hasEasterEggs())
|
||||||
|
continue;
|
||||||
if (curr->isArena()) continue;
|
if (curr->isArena()) continue;
|
||||||
if (curr->isInternal()) continue;
|
if (curr->isInternal()) continue;
|
||||||
|
|
||||||
|
@ -60,8 +60,12 @@ void CheckLap::reset(const Track &track)
|
|||||||
bool CheckLap::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, int indx)
|
bool CheckLap::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, int indx)
|
||||||
{
|
{
|
||||||
float track_length = World::getWorld()->getTrack()->getTrackLength();
|
float track_length = World::getWorld()->getTrack()->getTrackLength();
|
||||||
float current_distance =
|
LinearWorld *lin_world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||||
((LinearWorld*)World::getWorld())->getDistanceDownTrackForKart(indx);
|
// Can happen if a non-lap based race mode is used with a scene file that
|
||||||
|
// has check defined.
|
||||||
|
if(!lin_world)
|
||||||
|
return false;
|
||||||
|
float current_distance = lin_world->getDistanceDownTrackForKart(indx);
|
||||||
bool result =(m_previous_distance[indx]>0.95f*track_length &&
|
bool result =(m_previous_distance[indx]>0.95f*track_length &&
|
||||||
current_distance<7.0f);
|
current_distance<7.0f);
|
||||||
if(UserConfigParams::m_check_debug && result)
|
if(UserConfigParams::m_check_debug && result)
|
||||||
|
@ -47,6 +47,7 @@ using namespace irr;
|
|||||||
#include "items/item.hpp"
|
#include "items/item.hpp"
|
||||||
#include "items/item_manager.hpp"
|
#include "items/item_manager.hpp"
|
||||||
#include "modes/linear_world.hpp"
|
#include "modes/linear_world.hpp"
|
||||||
|
#include "modes/easter_egg_hunt.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
#include "physics/physical_object.hpp"
|
#include "physics/physical_object.hpp"
|
||||||
#include "physics/physics.hpp"
|
#include "physics/physics.hpp"
|
||||||
@ -92,6 +93,7 @@ Track::Track(const std::string &filename)
|
|||||||
m_enable_push_back = true;
|
m_enable_push_back = true;
|
||||||
m_reverse_available = false;
|
m_reverse_available = false;
|
||||||
m_is_arena = false;
|
m_is_arena = false;
|
||||||
|
m_has_easter_eggs = false;
|
||||||
m_is_cutscene = false;
|
m_is_cutscene = false;
|
||||||
m_camera_far = 1000.0f;
|
m_camera_far = 1000.0f;
|
||||||
m_mini_map = NULL;
|
m_mini_map = NULL;
|
||||||
@ -354,6 +356,9 @@ void Track::loadTrackInfo()
|
|||||||
m_screenshot = m_root+"/"+m_screenshot;
|
m_screenshot = m_root+"/"+m_screenshot;
|
||||||
delete root;
|
delete root;
|
||||||
|
|
||||||
|
std::string dir = StringUtils::getPath(m_filename);
|
||||||
|
std::string easter_name = dir+"/easter_eggs.xml";
|
||||||
|
m_has_easter_eggs = file_manager->fileExists(easter_name);
|
||||||
} // loadTrackInfo
|
} // loadTrackInfo
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1238,9 +1243,7 @@ void Track::createWater(const XMLNode &node)
|
|||||||
* \param mode_id Which of the modes of a track to use. This determines which
|
* \param mode_id Which of the modes of a track to use. This determines which
|
||||||
* scene, quad, and graph file to load.
|
* scene, quad, and graph file to load.
|
||||||
*/
|
*/
|
||||||
|
void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||||
void Track::loadTrackModel(World* parent, bool reverse_track,
|
|
||||||
unsigned int mode_id )
|
|
||||||
{
|
{
|
||||||
if(!m_reverse_available)
|
if(!m_reverse_available)
|
||||||
{
|
{
|
||||||
@ -1390,7 +1393,8 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
|
|||||||
createWater(*node);
|
createWater(*node);
|
||||||
}
|
}
|
||||||
else if(name=="banana" || name=="item" ||
|
else if(name=="banana" || name=="item" ||
|
||||||
name=="small-nitro" || name=="big-nitro")
|
name=="small-nitro" || name=="big-nitro" ||
|
||||||
|
name=="easter-egg" )
|
||||||
{
|
{
|
||||||
// will be handled later
|
// will be handled later
|
||||||
}
|
}
|
||||||
@ -1420,6 +1424,8 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
|
|||||||
}
|
}
|
||||||
else if(name=="checks")
|
else if(name=="checks")
|
||||||
{
|
{
|
||||||
|
// Easter egg hunts don't have laps.
|
||||||
|
if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_EASTER_EGG)
|
||||||
CheckManager::get()->load(*node);
|
CheckManager::get()->load(*node);
|
||||||
}
|
}
|
||||||
else if (name=="particle-emitter")
|
else if (name=="particle-emitter")
|
||||||
@ -1573,8 +1579,8 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
|
|||||||
}
|
}
|
||||||
else if(m_sky_type==SKY_COLOR)
|
else if(m_sky_type==SKY_COLOR)
|
||||||
{
|
{
|
||||||
parent->setClearBackBuffer(true);
|
World::getWorld()->setClearBackBuffer(true);
|
||||||
parent->setClearbackBufferColor(m_sky_color);
|
World::getWorld()->setClearbackBufferColor(m_sky_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1609,25 +1615,12 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
|
|||||||
for(unsigned int i=0; i<root->getNumNodes(); i++)
|
for(unsigned int i=0; i<root->getNumNodes(); i++)
|
||||||
{
|
{
|
||||||
const XMLNode *node = root->getNode(i);
|
const XMLNode *node = root->getNode(i);
|
||||||
const std::string name = node->getName();
|
const std::string &name = node->getName();
|
||||||
if (name=="banana" || name=="item" ||
|
if (name=="banana" || name=="item" ||
|
||||||
name=="small-nitro" || name=="big-nitro")
|
name=="small-nitro" || name=="big-nitro" ||
|
||||||
|
name=="easter-egg" )
|
||||||
{
|
{
|
||||||
Item::ItemType type;
|
itemCommand(node);
|
||||||
if (name=="banana" ) type = Item::ITEM_BANANA;
|
|
||||||
else if(name=="item" ) type = Item::ITEM_BONUS_BOX;
|
|
||||||
else if(name=="small-nitro") type = Item::ITEM_NITRO_SMALL;
|
|
||||||
else type = Item::ITEM_NITRO_BIG;
|
|
||||||
Vec3 xyz;
|
|
||||||
// Set some kind of default in case Z is not defined in the file
|
|
||||||
// (with the new track exporter it always is defined anyway).
|
|
||||||
// Z is the height from which the item is dropped on the track.
|
|
||||||
xyz.setY(1000);
|
|
||||||
node->getXYZ(&xyz);
|
|
||||||
bool drop=true;
|
|
||||||
node->get("drop", &drop);
|
|
||||||
// Height is needed if bit 2 (for z) is not set
|
|
||||||
itemCommand(xyz, type, drop);
|
|
||||||
}
|
}
|
||||||
} // for i<root->getNumNodes()
|
} // for i<root->getNumNodes()
|
||||||
|
|
||||||
@ -1645,7 +1638,8 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
|
|||||||
{
|
{
|
||||||
printf("WARNING: no check lines found in track '%s'.\n",
|
printf("WARNING: no check lines found in track '%s'.\n",
|
||||||
m_ident.c_str());
|
m_ident.c_str());
|
||||||
printf("Lap counting will not work, and start positions might be incorrect.\n");
|
printf("Lap counting will not work, and start positions might be "
|
||||||
|
"incorrect.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UserConfigParams::logMemory())
|
if(UserConfigParams::logMemory())
|
||||||
@ -1654,10 +1648,18 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
|
|||||||
irr_driver->getSceneManager()->getMeshCache()->getMeshCount(),
|
irr_driver->getSceneManager()->getMeshCache()->getMeshCount(),
|
||||||
irr_driver->getVideoDriver()->getTextureCount());
|
irr_driver->getVideoDriver()->getTextureCount());
|
||||||
|
|
||||||
if (World::getWorld()->useChecklineRequirements())
|
World *world = World::getWorld();
|
||||||
|
if (world->useChecklineRequirements())
|
||||||
{
|
{
|
||||||
QuadGraph::get()->computeChecklineRequirements();
|
QuadGraph::get()->computeChecklineRequirements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EasterEggHunt *easter_world = dynamic_cast<EasterEggHunt*>(world);
|
||||||
|
if(easter_world)
|
||||||
|
{
|
||||||
|
std::string dir = StringUtils::getPath(m_filename);
|
||||||
|
easter_world->readData(dir+"/easter_eggs.xml");
|
||||||
|
}
|
||||||
} // loadTrackModel
|
} // loadTrackModel
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1804,14 +1806,38 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
|
|||||||
* \param drop True if the item Z position should be determined based on
|
* \param drop True if the item Z position should be determined based on
|
||||||
* the track topology.
|
* the track topology.
|
||||||
*/
|
*/
|
||||||
void Track::itemCommand(const Vec3 &xyz, Item::ItemType type,
|
void Track::itemCommand(const XMLNode *node)
|
||||||
bool drop)
|
|
||||||
{
|
{
|
||||||
|
const std::string &name = node->getName();
|
||||||
|
|
||||||
|
Item::ItemType type;
|
||||||
|
if (name=="banana" ) type = Item::ITEM_BANANA;
|
||||||
|
else if(name=="item" ) type = Item::ITEM_BONUS_BOX;
|
||||||
|
else if(name=="small-nitro") type = Item::ITEM_NITRO_SMALL;
|
||||||
|
else if(name=="easter-egg" ) type = Item::ITEM_EASTER_EGG;
|
||||||
|
else type = Item::ITEM_NITRO_BIG;
|
||||||
|
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);
|
||||||
|
bool drop=true;
|
||||||
|
node->get("drop", &drop);
|
||||||
|
|
||||||
// Some modes (e.g. time trial) don't have any bonus boxes
|
// Some modes (e.g. time trial) don't have any bonus boxes
|
||||||
if(type==Item::ITEM_BONUS_BOX &&
|
if(type==Item::ITEM_BONUS_BOX &&
|
||||||
!World::getWorld()->haveBonusBoxes())
|
!World::getWorld()->haveBonusBoxes())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Only do easter eggs in easter egg mode.
|
||||||
|
if(type==Item::ITEM_EASTER_EGG &&
|
||||||
|
!(race_manager->getMinorMode()==RaceManager::MINOR_MODE_EASTER_EGG))
|
||||||
|
{
|
||||||
|
printf("Found easter egg in non-easter-egg mode - ignored.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3 loc(xyz);
|
Vec3 loc(xyz);
|
||||||
// if only 2d coordinates are given, let the item fall from very high
|
// if only 2d coordinates are given, let the item fall from very high
|
||||||
if(drop)
|
if(drop)
|
||||||
|
@ -228,6 +228,9 @@ private:
|
|||||||
/** True if this track is an arena. */
|
/** True if this track is an arena. */
|
||||||
bool m_is_arena;
|
bool m_is_arena;
|
||||||
|
|
||||||
|
/** True if this track has easter eggs. */
|
||||||
|
bool m_has_easter_eggs;
|
||||||
|
|
||||||
bool m_is_cutscene;
|
bool m_is_cutscene;
|
||||||
|
|
||||||
/** The version of this track. A certain STK version will only support
|
/** The version of this track. A certain STK version will only support
|
||||||
@ -358,8 +361,6 @@ private:
|
|||||||
std::vector<BezierCurve*> m_all_curves;
|
std::vector<BezierCurve*> m_all_curves;
|
||||||
|
|
||||||
void loadTrackInfo();
|
void loadTrackInfo();
|
||||||
void itemCommand(const Vec3 &xyz, Item::ItemType item_type,
|
|
||||||
bool drop);
|
|
||||||
void loadQuadGraph(unsigned int mode_id, const bool reverse);
|
void loadQuadGraph(unsigned int mode_id, const bool reverse);
|
||||||
void convertTrackToBullet(scene::ISceneNode *node);
|
void convertTrackToBullet(scene::ISceneNode *node);
|
||||||
bool loadMainTrack(const XMLNode &node);
|
bool loadMainTrack(const XMLNode &node);
|
||||||
@ -386,7 +387,9 @@ public:
|
|||||||
void update(float dt);
|
void update(float dt);
|
||||||
void reset();
|
void reset();
|
||||||
void adjustForFog(scene::ISceneNode *node);
|
void adjustForFog(scene::ISceneNode *node);
|
||||||
void adjustForFog(scene::IMesh* mesh, scene::ISceneNode* parent_scene_node);
|
void adjustForFog(scene::IMesh* mesh,
|
||||||
|
scene::ISceneNode* parent_scene_node);
|
||||||
|
void itemCommand(const XMLNode *node);
|
||||||
const core::vector3df& getSunRotation();
|
const core::vector3df& getSunRotation();
|
||||||
/** Sets the current ambient color for a kart with index k. */
|
/** Sets the current ambient color for a kart with index k. */
|
||||||
void setAmbientColor(const video::SColor &color,
|
void setAmbientColor(const video::SColor &color,
|
||||||
@ -394,6 +397,8 @@ public:
|
|||||||
void handleExplosion(const Vec3 &pos,
|
void handleExplosion(const Vec3 &pos,
|
||||||
const PhysicalObject *mp,
|
const PhysicalObject *mp,
|
||||||
bool secondary_hits=true) const;
|
bool secondary_hits=true) const;
|
||||||
|
void loadTrackModel (bool reverse_track = false,
|
||||||
|
unsigned int mode_id=0);
|
||||||
std::vector< std::vector<float> >
|
std::vector< std::vector<float> >
|
||||||
buildHeightMap();
|
buildHeightMap();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -402,11 +407,11 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const core::dimension2du& getMiniMapSize() const { return m_mini_map_size; }
|
const core::dimension2du& getMiniMapSize() const { return m_mini_map_size; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns true if this track has an arena mode. */
|
||||||
bool isArena() const { return m_is_arena; }
|
bool isArena() const { return m_is_arena; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void loadTrackModel (World* parent,
|
/** Returns true if this track has easter eggs. */
|
||||||
bool reverse_track = false,
|
bool hasEasterEggs() const { return m_has_easter_eggs; }
|
||||||
unsigned int mode_id=0);
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void addMusic (MusicInformation* mi)
|
void addMusic (MusicInformation* mi)
|
||||||
{m_music.push_back(mi); }
|
{m_music.push_back(mi); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user