Fixed item handling in battle modes by adding an additional 'position class'
to data/powerup.xml for battle modes. This makes it unnecessary that modes can select which powerup are available, therefore this code was cleaned up. Also added some minor code simplifications. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5374 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
d1ac9142a3
commit
56ebedd175
@ -25,11 +25,12 @@
|
||||
<!-- Distribution of the items depending on position of the
|
||||
kart. The order must correspond to powerup_manager.hpp -->
|
||||
<!-- bubble cake bowl zipper plunger switch para anvil -->
|
||||
<first w="1 0 0 0 0 1 0 0" />
|
||||
<top33 w="1 1 1 1 1 1 1 0" />
|
||||
<mid33 w="1 1 1 1 1 1 1 0" />
|
||||
<end33 w="0 1 1 1 1 1 1 1" />
|
||||
<last w="0 1 1 2 2 0 2 2" />
|
||||
<first w="1 0 0 0 0 1 0 0" />
|
||||
<top33 w="1 1 1 1 1 1 1 0" />
|
||||
<mid33 w="1 1 1 1 1 1 1 0" />
|
||||
<end33 w="0 1 1 1 1 1 1 1" />
|
||||
<last w="0 1 1 2 2 0 2 2" />
|
||||
<battle w="0 2 1 0 0 0 0 0" />
|
||||
|
||||
</powerup>
|
||||
|
||||
|
@ -89,7 +89,7 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_PLUNGER)
|
||||
|
||||
// pulling back makes no sense in battle mode, since this mode is not a race.
|
||||
// so in battle mode, always hide view
|
||||
if( m_reverse_mode || race_manager->isBattleMode(race_manager->getMinorMode()) )
|
||||
if( m_reverse_mode || race_manager->isBattleMode() )
|
||||
m_rubber_band = NULL;
|
||||
else
|
||||
{
|
||||
@ -151,7 +151,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
|
||||
|
||||
// pulling back makes no sense in battle mode, since this mode is not a race.
|
||||
// so in battle mode, always hide view
|
||||
if( m_reverse_mode || race_manager->isBattleMode(race_manager->getMinorMode()) )
|
||||
if( m_reverse_mode || race_manager->isBattleMode() )
|
||||
{
|
||||
if(kart) {
|
||||
kart->blockViewWithPlunger();
|
||||
|
@ -289,8 +289,9 @@ void Powerup::use()
|
||||
*/
|
||||
void Powerup::hitBonusBox(int n, const Item &item, int add_info)
|
||||
{
|
||||
// Position can be -1 in case of a battle mode (which doesn't have
|
||||
// positions), but this case is properly handled in getRandomPowerup.
|
||||
int position = m_owner->getPosition();
|
||||
assert(position != -1);
|
||||
|
||||
PowerupManager::PowerupType new_powerup =
|
||||
powerup_manager->getRandomPowerup(position);
|
||||
|
@ -88,7 +88,7 @@ PowerupManager::PowerupType PowerupManager::getPowerupType(const std::string &na
|
||||
} // getPowerupType
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loads all projectiles from the powerup.xml file.
|
||||
/** Loads all powerups from the powerup.xml file.
|
||||
*/
|
||||
void PowerupManager::loadAllPowerups()
|
||||
{
|
||||
@ -104,14 +104,21 @@ void PowerupManager::loadAllPowerups()
|
||||
if(type!=POWERUP_NOTHING)
|
||||
LoadPowerup(type, *node);
|
||||
}
|
||||
loadWeights(*root, "first", POSITION_FIRST);
|
||||
loadWeights(*root, "top33", POSITION_TOP33);
|
||||
loadWeights(*root, "mid33", POSITION_MID33);
|
||||
loadWeights(*root, "end33", POSITION_END33);
|
||||
loadWeights(*root, "last" , POSITION_LAST );
|
||||
loadWeights(*root, "first", POSITION_FIRST );
|
||||
loadWeights(*root, "top33", POSITION_TOP33 );
|
||||
loadWeights(*root, "mid33", POSITION_MID33 );
|
||||
loadWeights(*root, "end33", POSITION_END33 );
|
||||
loadWeights(*root, "last" , POSITION_LAST );
|
||||
loadWeights(*root, "battle" , POSITION_BATTLE_MODE);
|
||||
} // loadAllPowerups
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loads the data for one particular powerup. For bowling ball, plunger, and
|
||||
* cake static members in the appropriate classes are called to store
|
||||
* additional information for those objects.
|
||||
* \param type The type of the powerup.
|
||||
* \param node The XML node with the data for this powerup.
|
||||
*/
|
||||
void PowerupManager::LoadPowerup(PowerupType type, const XMLNode &node)
|
||||
{
|
||||
std::string icon_file("");
|
||||
@ -222,6 +229,8 @@ void PowerupManager::updateWeightsForRace(unsigned int num_karts)
|
||||
{
|
||||
m_position_to_class.clear();
|
||||
const World *world = World::getWorld();
|
||||
// In battle mode no positions exist, so use only position 1
|
||||
unsigned int end_position = (race_manager->isBattleMode()) ? 1 : num_karts;
|
||||
for(unsigned int position =1; position <= num_karts; position++)
|
||||
{
|
||||
// Set up the mapping of position to position class:
|
||||
@ -235,7 +244,6 @@ void PowerupManager::updateWeightsForRace(unsigned int num_karts)
|
||||
for(unsigned int i= POWERUP_FIRST; i<=POWERUP_LAST; i++)
|
||||
{
|
||||
PowerupType type=(PowerupType)i;
|
||||
if(!world->acceptPowerup(type)) continue;
|
||||
unsigned int w =m_weights[pos_class][i-POWERUP_FIRST];
|
||||
sum += w;
|
||||
for(unsigned int i=0; i<w; i++)
|
||||
@ -246,12 +254,18 @@ void PowerupManager::updateWeightsForRace(unsigned int num_karts)
|
||||
} // updateWeightsForRace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Determines the position class for a
|
||||
/** Determines the position class for a given position. If the race is a
|
||||
* battle mode (in which case we don't have a position), always return
|
||||
* 'POSITION_BATTLE_MODE' (and in this case only position 1 will be used
|
||||
* for all karts).
|
||||
* \param num_karts Number of karts in the race.
|
||||
* \param position The position for which to determine the position class.
|
||||
*/
|
||||
PowerupManager::PositionClass
|
||||
PowerupManager::convertPositionToClass(unsigned int num_karts,
|
||||
unsigned int position)
|
||||
{
|
||||
if(race_manager->isBattleMode()) return POSITION_BATTLE_MODE;
|
||||
if(position==1) return POSITION_FIRST;
|
||||
if(position==num_karts) return POSITION_LAST;
|
||||
|
||||
@ -268,10 +282,19 @@ PowerupManager::PositionClass
|
||||
} // convertPositionToClass
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a random powerup for a kart at a given position. If the race mode
|
||||
* is a battle, the position is actually not used and a randomly selected
|
||||
* item for POSITION_BATTLE_MODE is returned. This function takes the weights
|
||||
* specified for all items into account by using a list which contains all
|
||||
* items depending on the weights defined. See updateWeightsForRace()
|
||||
* \param pos Position of the kart (1<=pos<=number of karts) - ignored in
|
||||
* case of a battle mode.
|
||||
*/
|
||||
PowerupManager::PowerupType PowerupManager::getRandomPowerup(unsigned int pos)
|
||||
{
|
||||
// Positions start with 1, while the index starts with 0 - so subtract 1
|
||||
PositionClass pos_class = m_position_to_class[pos-1];
|
||||
PositionClass pos_class = race_manager->isBattleMode() ? POSITION_BATTLE_MODE
|
||||
: m_position_to_class[pos-1];
|
||||
|
||||
int random = rand()%m_powerups_for_position[pos_class].size();
|
||||
return m_powerups_for_position[pos_class][random];
|
||||
|
@ -82,12 +82,16 @@ public:
|
||||
};
|
||||
|
||||
/** The different position classes, used to map a kart's position to a
|
||||
* weight distribution for the different powerups. */
|
||||
* weight distribution for the different powerups. The battle mode is
|
||||
* listed as a separate 'position' - this way the same implementation
|
||||
* as used for normal racing can be used to define which items are
|
||||
* available in battle mode*/
|
||||
enum PositionClass {POSITION_FIRST,
|
||||
POSITION_TOP33,
|
||||
POSITION_MID33,
|
||||
POSITION_END33,
|
||||
POSITION_LAST,
|
||||
POSITION_BATTLE_MODE,
|
||||
POSITION_COUNT};
|
||||
|
||||
private:
|
||||
|
@ -334,21 +334,3 @@ void ThreeStrikesBattle::raceResultOrder( int* order )
|
||||
order[pos] = kart_id;
|
||||
}
|
||||
} // raceResultOrder
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ThreeStrikesBattle::acceptPowerup(const PowerupManager::PowerupType type) const
|
||||
{
|
||||
// these powerups don't make much sense in battle mode
|
||||
if (type == PowerupManager::POWERUP_PARACHUTE ||
|
||||
type == PowerupManager::POWERUP_ANVIL ||
|
||||
type == PowerupManager::POWERUP_BUBBLEGUM ||
|
||||
type == PowerupManager::POWERUP_ZIPPER ||
|
||||
type == PowerupManager::POWERUP_SWITCH ||
|
||||
type == PowerupManager::POWERUP_PLUNGER)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} // acceptPowerup
|
||||
|
||||
|
@ -70,7 +70,6 @@ public:
|
||||
virtual RaceGUI::KartIconDisplayInfo* getKartsDisplayInfo();
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
virtual void moveKartAfterRescue(Kart* kart);
|
||||
virtual bool acceptPowerup(const PowerupManager::PowerupType type) const;
|
||||
|
||||
virtual std::string getIdent() const;
|
||||
|
||||
|
@ -220,13 +220,7 @@ public:
|
||||
|
||||
/** \return whether this world can generate/have highscores */
|
||||
bool useHighScores() const { return m_use_highscores; }
|
||||
|
||||
/** called when a bonus box is hit, to determine which types of powerups are allowed
|
||||
in each game mode. By default all are accepted, override in child classes to get
|
||||
a different behaviour */
|
||||
virtual bool acceptPowerup(const PowerupManager::PowerupType type) const
|
||||
{ return true; }
|
||||
|
||||
|
||||
/** Called by the code that draws the list of karts on the race GUI
|
||||
* to know what needs to be drawn in the current mode
|
||||
*/
|
||||
|
@ -89,8 +89,7 @@ public:
|
||||
#define LINEAR_RACE(ID, COUNT_LAPSES) (1000+ID+100*COUNT_LAPSES)
|
||||
#define BATTLE_ARENA(ID) (2000+ID)
|
||||
/** Minor variants to the major types of race.
|
||||
* Make sure to use the 'LINEAR_RACE/BATTLE_ARENA' macros
|
||||
*/
|
||||
* Make sure to use the 'LINEAR_RACE/BATTLE_ARENA' macros. */
|
||||
enum MinorRaceModeType
|
||||
{
|
||||
MINOR_MODE_NONE = -1,
|
||||
@ -102,6 +101,9 @@ public:
|
||||
MINOR_MODE_3_STRIKES = BATTLE_ARENA(0)
|
||||
};
|
||||
|
||||
/** Returns a string identifier for each minor race mode.
|
||||
* \param mode Minor race mode.
|
||||
*/
|
||||
static const char* getIdentOf(const MinorRaceModeType mode)
|
||||
{
|
||||
switch (mode)
|
||||
@ -112,8 +114,12 @@ public:
|
||||
case MINOR_MODE_3_STRIKES: return STRIKES_IDENT;
|
||||
default: assert(false); return NULL;
|
||||
}
|
||||
}
|
||||
} // getIdentOf
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the icon for a minor race mode.
|
||||
* \param mode Minor race mode.
|
||||
*/
|
||||
static const char* getIconOf(const MinorRaceModeType mode)
|
||||
{
|
||||
switch (mode)
|
||||
@ -124,7 +130,12 @@ public:
|
||||
case MINOR_MODE_3_STRIKES: return "/gui/mode_3strikes.png";
|
||||
default: assert(false); return NULL;
|
||||
}
|
||||
}
|
||||
} // getIconOf
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a (translated) name of a minor race mode.
|
||||
* \param mode Minor race mode.
|
||||
*/
|
||||
static const wchar_t* getNameOf(const MinorRaceModeType mode)
|
||||
{
|
||||
switch (mode)
|
||||
@ -141,6 +152,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the minor mode id from a string identifier. This function is
|
||||
* used from challenge_data, which reads the mode from a challenge file.
|
||||
* \param name The name of the minor mode.
|
||||
*/
|
||||
static const MinorRaceModeType getModeIDFromInternalName(const char* name)
|
||||
{
|
||||
if (strcmp(name, IDENT_STD) == 0) return MINOR_MODE_NORMAL_RACE;
|
||||
@ -155,7 +171,7 @@ public:
|
||||
#undef LINEAR_RACE
|
||||
#undef BATTLE_ARENA
|
||||
|
||||
/** Difficulty. */
|
||||
/** Game difficulty. */
|
||||
enum Difficulty { RD_EASY, RD_MEDIUM, RD_HARD };
|
||||
|
||||
/** Different kart types: A local player, a player connected via network,
|
||||
@ -163,6 +179,9 @@ public:
|
||||
* (currently not used). */
|
||||
enum KartType { KT_PLAYER, KT_NETWORK_PLAYER, KT_AI, KT_LEADER, KT_GHOST };
|
||||
private:
|
||||
|
||||
/** This data structure accumulates kart data and race result data from
|
||||
* each race. */
|
||||
struct KartStatus
|
||||
{
|
||||
std::string m_ident; // The .tkkf filename without the .tkkf
|
||||
@ -188,9 +207,16 @@ private:
|
||||
|
||||
}; // KartStatus
|
||||
|
||||
/** The kart status data for each kart. */
|
||||
std::vector<KartStatus> m_kart_status;
|
||||
|
||||
/** The selected difficulty. */
|
||||
Difficulty m_difficulty;
|
||||
|
||||
/** The major mode (single race, GP). */
|
||||
MajorRaceModeType m_major_mode;
|
||||
|
||||
/** The minor mode (race, time trial, ftl, battle mode). */
|
||||
MinorRaceModeType m_minor_mode;
|
||||
/** Stores remote kart information about all player karts. */
|
||||
std::vector<RemoteKartInfo> m_player_karts;
|
||||
@ -281,52 +307,55 @@ public:
|
||||
void setRandomKartList(const std::vector<std::string>& rkl)
|
||||
{ m_random_kart_list = rkl; }
|
||||
void computeRandomKartList();
|
||||
|
||||
void setMirror() {/*FIXME*/}
|
||||
void setReverse(){/*FIXME*/}
|
||||
void startNew(); // start new race/GP/...
|
||||
void next(); // start the next race or go back to the start screen
|
||||
void rerunRace(); // Rerun the same race again
|
||||
void exitRace(); // exit a race (and don't start the next one)
|
||||
void startNew(); // start new race/GP/...
|
||||
void next(); // start the next race or go back to the start screen
|
||||
void rerunRace(); // Rerun the same race again
|
||||
void exitRace(); // exit a race (and don't start the next one)
|
||||
|
||||
/** get information about given mode (returns true if 'mode' is of linear races type)
|
||||
info is stored in its ID for conveniance, see the macros above for exact meaning
|
||||
*/
|
||||
static bool isLinearRaceMode(const MinorRaceModeType type)
|
||||
* info is stored in its ID for conveniance, see the macros LINEAR_RACE and
|
||||
* BATTLE_ARENA above for exact meaning.
|
||||
*/
|
||||
bool isLinearRaceMode()
|
||||
{
|
||||
const int id = (int)type;
|
||||
const int id = (int)m_minor_mode;
|
||||
if(id > 999 && id < 2000) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/** get information about given mode (returns true if 'mode' is of battle type)
|
||||
info is stored in its ID for conveniance, see the macros above for exact meaning
|
||||
*/
|
||||
static bool isBattleMode(const MinorRaceModeType type)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the current mode is a battle mode. This uses the
|
||||
* numerical id of the mode, see the macros LINEAR_RACE and BATTLE_ARENA
|
||||
* above for exact meaning.
|
||||
*/
|
||||
bool isBattleMode()
|
||||
{
|
||||
const int id = (int)type;
|
||||
const int id = (int)m_minor_mode;
|
||||
if (id >= 2000) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/** get information about given mode (returns true if 'mode' requires lap counting)
|
||||
info is stored in its ID for conveniance, see the macros above for exact meaning
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the current mode has laps. If uses the numeric id based
|
||||
* on the macros
|
||||
*/
|
||||
static bool modeHasLaps(const MinorRaceModeType type)
|
||||
bool modeHasLaps()
|
||||
{
|
||||
if (isBattleMode(type)) return false;
|
||||
const int id = (int)type;
|
||||
if (isBattleMode()) return false;
|
||||
const int id = (int)m_minor_mode;
|
||||
const int answer = (id-1000)/100;
|
||||
return answer!=0;
|
||||
}
|
||||
|
||||
static bool modeHasHighscores(const MinorRaceModeType type)
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the currently selected minor mode has highscores. */
|
||||
bool modeHasHighscores()
|
||||
{
|
||||
//FIXME: this information is duplicated. RaceManager knows about it, and
|
||||
// each World may set m_use_highscores to true or false. The reason
|
||||
// for this duplication is that we might want to know whether to
|
||||
// display highscores without creating a World.
|
||||
return type != MINOR_MODE_3_STRIKES && type != MINOR_MODE_FOLLOW_LEADER;
|
||||
return m_minor_mode != MINOR_MODE_3_STRIKES &&
|
||||
m_minor_mode != MINOR_MODE_FOLLOW_LEADER;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -45,8 +45,8 @@ using namespace GUIEngine;
|
||||
TrackInfoDialog::TrackInfoDialog(const std::string& trackIdent, const irr::core::stringw& trackName,
|
||||
ITexture* screenshot, const float w, const float h) : ModalDialog(w, h)
|
||||
{
|
||||
const bool has_laps = RaceManager::modeHasLaps (race_manager->getMinorMode());
|
||||
const bool has_highscores = RaceManager::modeHasHighscores(race_manager->getMinorMode());
|
||||
const bool has_laps = race_manager->modeHasLaps();
|
||||
const bool has_highscores = race_manager->modeHasHighscores();
|
||||
|
||||
const int y1 = m_area.getHeight()/7;
|
||||
const int y2 = m_area.getHeight()*5/7;
|
||||
|
Loading…
x
Reference in New Issue
Block a user