Tutorial development incremental commit
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7095 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
a8ae299119
commit
2427aed571
data/grandprix
src
ide/vc9
modes
states_screens
tutorial
14
data/grandprix/basic_drive.tutorial
Normal file
14
data/grandprix/basic_drive.tutorial
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<tutorial
|
||||
id="basicdriving"
|
||||
name="Win the At World's End Grand Prix"
|
||||
description="Come first in the At World's End Grand Prix with 3 Expert AI karts."
|
||||
major="single"
|
||||
minor="normal"
|
||||
gp="canyon"
|
||||
difficulty="easy"
|
||||
karts="1"
|
||||
position="1"
|
||||
num_laps="99"
|
||||
num_players="1"
|
||||
/>
|
@ -502,6 +502,10 @@
|
||||
RelativePath="..\..\modes\three_strikes_battle.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\modes\tutorial_race.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\modes\world.cpp"
|
||||
>
|
||||
@ -1118,6 +1122,10 @@
|
||||
RelativePath="..\..\tutorial\tutorial.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tutorial\tutorial_data.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tutorial\tutorial_manager.cpp"
|
||||
>
|
||||
@ -1420,6 +1428,10 @@
|
||||
RelativePath="..\..\modes\three_strikes_battle.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\modes\tutorial_race.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\modes\world.hpp"
|
||||
>
|
||||
@ -2024,6 +2036,10 @@
|
||||
RelativePath="..\..\tutorial\tutorial.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tutorial\tutorial_data.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tutorial\tutorial_manager.hpp"
|
||||
>
|
||||
|
194
src/modes/tutorial_race.cpp
Normal file
194
src/modes/tutorial_race.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Alejandro Santiago
|
||||
//
|
||||
// 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/tutorial_race.hpp"
|
||||
|
||||
#include "audio/music_manager.hpp"
|
||||
#include "tutorial/tutorial_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "items/powerup_manager.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TutorialRace::TutorialRace() : LinearWorld()
|
||||
{
|
||||
// We have to make sure that no kart finished the set number of laps
|
||||
// in a FTL race (since otherwise its distance will not be computed
|
||||
// correctly, and as a result e.g. a leader might suddenly fall back
|
||||
// after crossing the start line
|
||||
race_manager->setNumLaps(99999);
|
||||
|
||||
m_leader_intervals = stk_config->m_leader_intervals;
|
||||
for(unsigned int i=0; i<m_leader_intervals.size(); i++)
|
||||
m_leader_intervals[i] +=
|
||||
stk_config->m_leader_time_per_kart*race_manager->getNumberOfKarts();
|
||||
m_use_highscores = false; // disable high scores
|
||||
setClockMode(WorldStatus::CLOCK_COUNTDOWN, m_leader_intervals[0]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TutorialRace::~TutorialRace()
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark clock events
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the original time at which the countdown timer started. This is
|
||||
* used by the race_gui to display the music credits in FTL mode correctly.
|
||||
*/
|
||||
float TutorialRace::getClockStartTime()
|
||||
{
|
||||
return m_leader_intervals[0];
|
||||
} // getClockStartTime
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when a kart must be eliminated.
|
||||
*/
|
||||
void TutorialRace::countdownReachedZero()
|
||||
{
|
||||
if(m_leader_intervals.size()>1)
|
||||
m_leader_intervals.erase(m_leader_intervals.begin());
|
||||
WorldStatus::setTime(m_leader_intervals[0]);
|
||||
|
||||
// If the leader kart is not the first kart, remove the first
|
||||
// kart, otherwise remove the last kart.
|
||||
int position_to_remove = m_karts[0]->getPosition()==1
|
||||
? getCurrentNumKarts() : 1;
|
||||
Kart *kart = getKartAtPosition(position_to_remove);
|
||||
if(!kart || kart->isEliminated())
|
||||
{
|
||||
fprintf(stderr,"Problem with removing leader: position %d not found\n",
|
||||
position_to_remove);
|
||||
for(unsigned int i=0; i<m_karts.size(); i++)
|
||||
{
|
||||
fprintf(stderr,"kart %d: eliminated %d position %d\n",
|
||||
i,m_karts[i]->isEliminated(), m_karts[i]->getPosition());
|
||||
} // for i
|
||||
} //
|
||||
else
|
||||
{
|
||||
removeKart(kart->getWorldKartId());
|
||||
|
||||
// In case that the kart on position 1 was removed, we have
|
||||
// to set the correct position (which equals the remaining
|
||||
// number of karts) for the removed kart, as well as recompute
|
||||
// the position for all other karts
|
||||
if(position_to_remove==1)
|
||||
{
|
||||
// We have to add 1 to the number of karts to get the correct
|
||||
// position, since the eliminated kart was already removed
|
||||
// from the value returned by getCurrentNumKarts (and we have
|
||||
// to remove the kart before we can call updateRacePosition).
|
||||
// Note that we can not call WorldWithRank::setKartPosition
|
||||
// here, since it would not properly support debugging kart
|
||||
// ranks (since this kart would get its position set again
|
||||
// in updateRacePosition). We only set the rank of the eliminated
|
||||
// kart, and updateRacePosition will then call setKartPosition
|
||||
// for the now eliminated kart.
|
||||
kart->setPosition(getCurrentNumKarts()+1);
|
||||
updateRacePosition();
|
||||
}
|
||||
}
|
||||
|
||||
// almost over, use fast music
|
||||
if(getCurrentNumKarts()==3)
|
||||
{
|
||||
music_manager->switchToFastMusic();
|
||||
}
|
||||
|
||||
if (isRaceOver())
|
||||
{
|
||||
// Handle special FTL situation: the leader is kart number 3 when
|
||||
// the last kart gets eliminated. In this case kart on position 1
|
||||
// is eliminated, and the kart formerly on position 2 is on
|
||||
// position 1, the leader now position 2. In this case the kart
|
||||
// on position 1 would get more points for this victory. So if
|
||||
// this is the case, change the position
|
||||
if(m_karts[0]->getPosition()!=1)
|
||||
{
|
||||
// Adjust the position of all still driving karts except
|
||||
// the leader by +1, and move the leader to position 1.
|
||||
for (unsigned int i=1; i<m_karts.size(); i++)
|
||||
{
|
||||
if(!m_karts[i]->hasFinishedRace() &&
|
||||
!m_karts[i]->isEliminated() )
|
||||
m_karts[i]->setPosition(m_karts[i]->getPosition()+1);
|
||||
}
|
||||
m_karts[0]->setPosition(1);
|
||||
}
|
||||
|
||||
// Mark all still racing karts to be finished.
|
||||
for (unsigned int n=0; n<m_karts.size(); n++)
|
||||
{
|
||||
if (!m_karts[n]->isEliminated() &&
|
||||
!m_karts[n]->hasFinishedRace())
|
||||
{
|
||||
m_karts[n]->finishedRace(getTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of race is detected from World::updateWorld()
|
||||
|
||||
} // countdownReachedZero
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** The follow the leader race is over if there is only one kart left (plus
|
||||
* the leader), or if all (human) players have been eliminated.
|
||||
*/
|
||||
bool TutorialRace::isRaceOver()
|
||||
{
|
||||
// FIXME : add the logic to detect if the user have ended the tutorial.
|
||||
return true;
|
||||
} // isRaceOver
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void TutorialRace::restartRace()
|
||||
{
|
||||
LinearWorld::restartRace();
|
||||
m_leader_intervals.clear();
|
||||
m_leader_intervals = stk_config->m_leader_intervals;
|
||||
for(unsigned int i=0; i<m_leader_intervals.size(); i++)
|
||||
m_leader_intervals[i] +=
|
||||
stk_config->m_leader_time_per_kart*race_manager->getNumberOfKarts();
|
||||
WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN,
|
||||
m_leader_intervals[0]);
|
||||
} // restartRace
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the internal identifier for this kind of race.
|
||||
*/
|
||||
std::string TutorialRace::getIdent() const
|
||||
{
|
||||
return FTL_IDENT;
|
||||
} // getIdent
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the title for all karts that is displayed in the icon list. In
|
||||
* this mode the title for the first kart is set to 'leader'.
|
||||
*/
|
||||
RaceGUIBase::KartIconDisplayInfo* TutorialRace::getKartsDisplayInfo()
|
||||
{
|
||||
LinearWorld::getKartsDisplayInfo();
|
||||
m_kart_display_info[0].special_title = _("Leader");
|
||||
return m_kart_display_info;
|
||||
} // getKartsDisplayInfo
|
55
src/modes/tutorial_race.hpp
Normal file
55
src/modes/tutorial_race.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Alejandro Santiago
|
||||
//
|
||||
// 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 HEADER_TUTORIAL_MODE_HPP
|
||||
#define HEADER_TUTORIAL_MODE_HPP
|
||||
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
|
||||
/**
|
||||
* \brief An implementation of World, based on LinearWorld, to provide the Follow-the-leader game mode
|
||||
* \ingroup modes
|
||||
*/
|
||||
class TutorialRace : public LinearWorld
|
||||
{
|
||||
private:
|
||||
|
||||
std::vector <float> m_leader_intervals; // time till elimination in follow leader
|
||||
|
||||
public:
|
||||
|
||||
TutorialRace();
|
||||
virtual ~TutorialRace();
|
||||
|
||||
// clock events
|
||||
virtual void countdownReachedZero();
|
||||
|
||||
// overriding World methods
|
||||
virtual void restartRace();
|
||||
virtual std::string getIdent() const;
|
||||
float getClockStartTime();
|
||||
virtual bool useFastMusicNearEnd() const { return false; }
|
||||
virtual RaceGUIBase::KartIconDisplayInfo* getKartsDisplayInfo();
|
||||
|
||||
virtual bool isRaceOver();
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //HEADER_TUTORIAL_MODE_HPP
|
@ -25,7 +25,7 @@
|
||||
|
||||
using namespace irr::core;
|
||||
|
||||
const std::string BASIC_DRIVING = "bd";
|
||||
const std::string BASIC_DRIVING = "basicdriving";
|
||||
const std::string SHARP_TURN = "st";
|
||||
const std::string NITRO = "nt";
|
||||
const std::string COLLECTIBLE_WEAPONS = "cw";
|
||||
|
@ -66,7 +66,7 @@ private:
|
||||
|
||||
std::string m_Id; // short, internal name for this tutorial
|
||||
irr::core::stringw m_Name; // name used in menu for this tutorial
|
||||
irr::core::stringw m_challenge_description; // Message the user gets when the feature is not yet unlocked
|
||||
irr::core::stringw m_tutorial_description; // Message the user gets when the feature is not yet unlocked
|
||||
// vector<UnlockableFeature> m_feature; // Features to unlock
|
||||
// vector<string> m_prerequisites; // what needs to be done before accessing this tutorial
|
||||
|
||||
@ -83,6 +83,8 @@ public:
|
||||
void addUnlockTrackReward(const std::string &track_name);
|
||||
void addUnlockModeReward(const std::string &internal_mode_name,
|
||||
const irr::core::stringw &user_mode_name);
|
||||
void setTutorialDescription(const irr::core::stringw& d)
|
||||
{m_tutorial_description=d; }
|
||||
/* void addUnlockGPReward(const std::string &gp_name);
|
||||
void addUnlockDifficultyReward(const std::string &internal_name,
|
||||
const irr::core::stringw &user_name);
|
||||
@ -91,8 +93,7 @@ public:
|
||||
|
||||
/*const vector<UnlockableFeature>&
|
||||
getFeatures() const { return m_feature; }
|
||||
void setChallengeDescription(const irr::core::stringw& d)
|
||||
{m_challenge_description=d; }
|
||||
|
||||
const irr::core::stringw&
|
||||
getChallengeDescription() const {return m_challenge_description; }
|
||||
void addDependency(const std::string id) {m_prerequisites.push_back(id); }
|
||||
|
339
src/tutorial/tutorial_data.cpp
Normal file
339
src/tutorial/tutorial_data.cpp
Normal file
@ -0,0 +1,339 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Alejandro Santiago
|
||||
//
|
||||
// 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 "tutorial/tutorial_data.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
#include "karts/kart.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "race/grand_prix_data.hpp"
|
||||
#include "race/grand_prix_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "tracks/track_manager.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
TutorialData::TutorialData(const std::string& filename)
|
||||
#ifndef WIN32
|
||||
throw(std::runtime_error)
|
||||
#endif
|
||||
{
|
||||
m_filename = filename;
|
||||
m_major = RaceManager::MAJOR_MODE_SINGLE;
|
||||
m_minor = RaceManager::MINOR_MODE_NORMAL_RACE;
|
||||
m_difficulty = RaceManager::RD_EASY;
|
||||
m_num_laps = -1;
|
||||
m_num_karts = -1;
|
||||
m_time = -1.0f;
|
||||
m_track_name = "";
|
||||
m_gp_id = "";
|
||||
m_energy = -1;
|
||||
|
||||
XMLNode *root = new XMLNode( filename );
|
||||
|
||||
// Check if the file have been correctly load
|
||||
if(!root || root->getName()!="tutorial")
|
||||
{
|
||||
delete root;
|
||||
std::ostringstream msg;
|
||||
msg << "Couldn't load tutorial '" << filename << "': no tutorial node.";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
|
||||
std::string s_property;
|
||||
int i_property;
|
||||
float f_property;
|
||||
|
||||
// Mode
|
||||
|
||||
root->get("major", &s_property);
|
||||
setMajor(s_property);
|
||||
|
||||
// Minor
|
||||
root->get("minor", &s_property);
|
||||
setMinor(s_property);
|
||||
|
||||
// Name
|
||||
if(!root->get("name", &s_property) )
|
||||
error("name");
|
||||
setName( _(s_property.c_str()) );
|
||||
|
||||
// ID
|
||||
if(!root->get("id", &s_property) )
|
||||
error("id");
|
||||
setId(s_property);
|
||||
|
||||
// Description
|
||||
if(!root->get("s_property", &s_property) )
|
||||
error("description");
|
||||
setTutorialDescription( _(s_property.c_str()) );
|
||||
|
||||
// Karts
|
||||
if(!root->get("karts", &i_property) )
|
||||
error("karts");
|
||||
setNumKarts(i_property);
|
||||
|
||||
// Difficulty
|
||||
root->get("difficulty", &s_property);
|
||||
setDifficulty(s_property);
|
||||
|
||||
// Time
|
||||
root->get("time", &f_property); // one of time/position
|
||||
setTime(f_property);
|
||||
|
||||
// Position
|
||||
root->get("position", &m_position ); // must be set
|
||||
if(m_time<0 && m_position<0)
|
||||
error("position/time");
|
||||
|
||||
// Energy
|
||||
root->get("energy", & i_property ); // This is optional
|
||||
setEnergy(i_property);
|
||||
|
||||
// FIXME do we need position for the tutorials???????
|
||||
// Position is optional except in GP and FTL
|
||||
/*if(!root->get("position", &s_property))
|
||||
error("position");
|
||||
set
|
||||
&&
|
||||
//RaceManager::getWorld()->areKartsOrdered() ) // FIXME - order and optional are not the same thing
|
||||
(m_minor==RaceManager::MINOR_MODE_FOLLOW_LEADER ||
|
||||
m_major==RaceManager::MAJOR_MODE_GRAND_PRIX))
|
||||
error("position");*/
|
||||
|
||||
if(m_major==RaceManager::MAJOR_MODE_SINGLE)
|
||||
{
|
||||
// Track
|
||||
if (!root->get("track", &s_property ))
|
||||
error("track");
|
||||
setTrack(s_property);
|
||||
|
||||
if (!root->get("laps", &i_property))
|
||||
error("laps");
|
||||
setLaps(i_property);
|
||||
}
|
||||
else // GP
|
||||
{
|
||||
if (!root->get("gp", &m_gp_id )) error("gp");
|
||||
if (grand_prix_manager->getGrandPrix(m_gp_id) == NULL) error("gp");
|
||||
}
|
||||
|
||||
|
||||
delete root;
|
||||
|
||||
} // TutorialData
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TutorialData::error(const char *id) const
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Undefined or incorrect value for '" << id
|
||||
<< "' in tutorial file '" << m_filename << "'.";
|
||||
|
||||
std::cerr << "TutorialData : " << msg.str() << std::endl;
|
||||
|
||||
throw std::runtime_error(msg.str());
|
||||
} // error
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Checks if this challenge is valid, i.e. contains a valid track or a valid
|
||||
* GP. If incorrect data are found, STK is aborted with an error message.
|
||||
* (otherwise STK aborts when trying to do this challenge, which is worse).
|
||||
*/
|
||||
void TutorialData::check() const
|
||||
{
|
||||
if(m_major==RaceManager::MAJOR_MODE_SINGLE)
|
||||
{
|
||||
try
|
||||
{
|
||||
track_manager->getTrack(m_track_name);
|
||||
}
|
||||
catch(std::exception&)
|
||||
{
|
||||
error("track");
|
||||
}
|
||||
}
|
||||
else if(m_major==RaceManager::MAJOR_MODE_GRAND_PRIX)
|
||||
{
|
||||
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(m_gp_id);
|
||||
|
||||
if (gp == NULL)
|
||||
{
|
||||
error("gp");
|
||||
}
|
||||
const bool gp_ok = gp->checkConsistency(false);
|
||||
if (!gp_ok)
|
||||
{
|
||||
error("gp");
|
||||
}
|
||||
}
|
||||
} // check
|
||||
|
||||
|
||||
void TutorialData::setRace() const
|
||||
{
|
||||
race_manager->setMajorMode(m_major);
|
||||
if(m_major==RaceManager::MAJOR_MODE_SINGLE)
|
||||
{
|
||||
race_manager->setMinorMode(m_minor);
|
||||
race_manager->setTrack(m_track_name);
|
||||
race_manager->setDifficulty(m_difficulty);
|
||||
race_manager->setNumLaps(m_num_laps);
|
||||
race_manager->setNumKarts(m_num_karts);
|
||||
race_manager->setNumPlayers(1);
|
||||
race_manager->setNumLocalPlayers(1);
|
||||
race_manager->setCoinTarget(m_energy);
|
||||
}
|
||||
else // GP
|
||||
{
|
||||
race_manager->setMinorMode(m_minor);
|
||||
const GrandPrixData *gp = grand_prix_manager->getGrandPrix(m_gp_id);
|
||||
race_manager->setGrandPrix(*gp);
|
||||
race_manager->setDifficulty(m_difficulty);
|
||||
race_manager->setNumKarts(m_num_karts);
|
||||
race_manager->setNumPlayers(1);
|
||||
race_manager->setNumLocalPlayers(1);
|
||||
}
|
||||
} // setRace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool TutorialData::raceFinished()
|
||||
{
|
||||
// GP's use the grandPrixFinished() function, so they can't be fulfilled here.
|
||||
if(m_major==RaceManager::MAJOR_MODE_GRAND_PRIX) return false;
|
||||
|
||||
// Single races
|
||||
// ------------
|
||||
World *world = World::getWorld();
|
||||
std::string track_name = world->getTrack()->getIdent();
|
||||
if(track_name!=m_track_name ) return false; // wrong track
|
||||
if((int)world->getNumKarts()<m_num_karts ) return false; // not enough AI karts
|
||||
|
||||
Kart* kart = world->getPlayerKart(0);
|
||||
if(m_energy>0 && kart->getEnergy() <m_energy ) return false; // not enough energy
|
||||
if(m_position>0 && kart->getPosition()>m_position) return false; // too far behind
|
||||
|
||||
// Follow the leader
|
||||
// -----------------
|
||||
if(m_minor==RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||
{
|
||||
// All possible conditions were already checked, so: must have been successful
|
||||
return true;
|
||||
}
|
||||
// Quickrace / Timetrial
|
||||
// ---------------------
|
||||
// FIXME - encapsulate this better, each race mode needs to be able to specify
|
||||
// its own challenges and deal with them
|
||||
LinearWorld* lworld = dynamic_cast<LinearWorld*>(world);
|
||||
if(lworld != NULL)
|
||||
{
|
||||
if(lworld->getLapForKart( kart->getWorldKartId() ) != m_num_laps) return false; // wrong number of laps
|
||||
}
|
||||
if(m_time>0.0f && kart->getFinishTime()>m_time) return false; // too slow
|
||||
return true;
|
||||
} // raceFinished
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool TutorialData::grandPrixFinished()
|
||||
{
|
||||
// Note that we have to call race_manager->getNumKarts, since there
|
||||
// is no world objects to query at this stage.
|
||||
if (race_manager->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX ||
|
||||
race_manager->getMinorMode() != m_minor ||
|
||||
race_manager->getGrandPrix()->getId() != m_gp_id ||
|
||||
race_manager->getDifficulty()!= m_difficulty ||
|
||||
race_manager->getNumberOfKarts() < (unsigned int)m_num_karts ||
|
||||
race_manager->getNumPlayers() > 1) return false;
|
||||
|
||||
// check if the player came first.
|
||||
//assert(World::getWorld() != NULL);
|
||||
// Kart* kart = World::getWorld()->getPlayerKart(0);
|
||||
//const int rank = race_manager->getKartGPRank(kart->getWorldKartId());
|
||||
const int rank = race_manager->getLocalPlayerGPRank(0);
|
||||
|
||||
//printf("getting rank for %s : %i \n", kart->getName().c_str(), rank );
|
||||
if (rank != 0) return false;
|
||||
|
||||
return true;
|
||||
} // grandPrixFinished
|
||||
|
||||
void TutorialData::setNumKarts(int num_karts)
|
||||
{
|
||||
this->m_num_karts= num_karts;
|
||||
}
|
||||
void TutorialData::setLaps(int num_laps)
|
||||
{
|
||||
this->m_num_laps = num_laps;
|
||||
}
|
||||
void TutorialData::setTrack(std::string track_name)
|
||||
{
|
||||
this->m_track_name == track_name;
|
||||
if (track_manager->getTrack(m_track_name) == NULL)
|
||||
error("track");
|
||||
}
|
||||
|
||||
void TutorialData::setDifficulty(std::string difficulty)
|
||||
{
|
||||
if(difficulty == "easy")
|
||||
this->m_difficulty = RaceManager::RD_EASY;
|
||||
else if(difficulty =="medium")
|
||||
this->m_difficulty = RaceManager::RD_MEDIUM;
|
||||
else if(difficulty =="hard")
|
||||
this->m_difficulty = RaceManager::RD_HARD;
|
||||
else
|
||||
error("difficulty");
|
||||
}
|
||||
|
||||
void TutorialData::setMinor(std::string minor)
|
||||
{
|
||||
if(minor=="timetrial")
|
||||
this->m_minor = RaceManager::MINOR_MODE_TIME_TRIAL;
|
||||
else if(minor=="quickrace")
|
||||
this->m_minor = RaceManager::MINOR_MODE_NORMAL_RACE;
|
||||
else if(minor=="followtheleader")
|
||||
this->m_minor = RaceManager::MINOR_MODE_FOLLOW_LEADER;
|
||||
else
|
||||
error("minor");
|
||||
}
|
||||
|
||||
void TutorialData::setMajor(std::string major)
|
||||
{
|
||||
if(major=="grandprix")
|
||||
this->m_major = RaceManager::MAJOR_MODE_GRAND_PRIX;
|
||||
else if(major=="single")
|
||||
this->m_major = RaceManager::MAJOR_MODE_SINGLE;
|
||||
else
|
||||
error("major");
|
||||
}
|
||||
|
||||
void TutorialData::setPosition(int position)
|
||||
{
|
||||
this->m_position = position;
|
||||
}
|
||||
|
||||
void TutorialData::setTime (float time)
|
||||
{
|
||||
this->m_time = time;
|
||||
}
|
||||
|
||||
void TutorialData::setEnergy(int energy)
|
||||
{
|
||||
m_energy = energy;
|
||||
}
|
76
src/tutorial/tutorial_data.hpp
Normal file
76
src/tutorial/tutorial_data.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Alejandro Santiago
|
||||
//
|
||||
// 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 HEADER_TUTORIAL_DATA_HPP
|
||||
#define HEADER_TUTORIAL_DATA_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "tutorial/tutorial.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
|
||||
/**
|
||||
* \ingroup tutorial
|
||||
*/
|
||||
class TutorialData : public Tutorial
|
||||
{
|
||||
private:
|
||||
RaceManager::MajorRaceModeType m_major;
|
||||
RaceManager::MinorRaceModeType m_minor;
|
||||
RaceManager::Difficulty m_difficulty;
|
||||
int m_num_laps;
|
||||
int m_position;
|
||||
int m_num_karts;
|
||||
float m_time;
|
||||
std::string m_gp_id;
|
||||
std::string m_track_name;
|
||||
int m_energy;
|
||||
std::string m_filename;
|
||||
|
||||
void getUnlocks(const XMLNode *root, const std:: string type, REWARD_TYPE reward);
|
||||
void error(const char *id) const;
|
||||
|
||||
public:
|
||||
#ifdef WIN32
|
||||
TutorialData(const std::string& filename);
|
||||
#else
|
||||
TutorialData(const std::string& filename) throw(std::runtime_error);
|
||||
#endif
|
||||
|
||||
/** sets the right parameters in RaceManager to try this tutorial */
|
||||
void setRace() const;
|
||||
|
||||
void setEnergy(int m_energy);
|
||||
void setTime(float m_time);
|
||||
void setPosition(int position);
|
||||
void setDifficulty(std::string difficulty);
|
||||
void setTrack(std::string track_name);
|
||||
void setLaps(int num_laps);
|
||||
void setMajor(std::string major);
|
||||
void setMinor(std::string minor);
|
||||
void setNumKarts(int num_karts);
|
||||
|
||||
virtual void check() const;
|
||||
virtual bool raceFinished();
|
||||
virtual bool grandPrixFinished();
|
||||
|
||||
}; // TutorialData
|
||||
|
||||
#endif // HEADER_TUTORIAL_DATA_HPP
|
Loading…
x
Reference in New Issue
Block a user