From 56ebedd17596d9534c4ad8568f906d53fa3601a0 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Tue, 4 May 2010 13:54:49 +0000 Subject: [PATCH] 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 --- data/powerup.xml | 11 +-- src/items/plunger.cpp | 4 +- src/items/powerup.cpp | 3 +- src/items/powerup_manager.cpp | 41 +++++++-- src/items/powerup_manager.hpp | 6 +- src/modes/three_strikes_battle.cpp | 18 ---- src/modes/three_strikes_battle.hpp | 1 - src/modes/world.hpp | 8 +- src/race/race_manager.hpp | 89 ++++++++++++------- .../dialogs/track_info_dialog.cpp | 4 +- 10 files changed, 109 insertions(+), 76 deletions(-) diff --git a/data/powerup.xml b/data/powerup.xml index 972a9ead8..a3c4ea13a 100644 --- a/data/powerup.xml +++ b/data/powerup.xml @@ -25,11 +25,12 @@ - - - - - + + + + + + diff --git a/src/items/plunger.cpp b/src/items/plunger.cpp index 939da87ea..921e7a454 100644 --- a/src/items/plunger.cpp +++ b/src/items/plunger.cpp @@ -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(); diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index 6a0021cbf..882005383 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -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); diff --git a/src/items/powerup_manager.cpp b/src/items/powerup_manager.cpp index 1fe43c9bd..1927647aa 100644 --- a/src/items/powerup_manager.cpp +++ b/src/items/powerup_manager.cpp @@ -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; iisBattleMode()) 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]; diff --git a/src/items/powerup_manager.hpp b/src/items/powerup_manager.hpp index b1898a482..8413d3082 100644 --- a/src/items/powerup_manager.hpp +++ b/src/items/powerup_manager.hpp @@ -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: diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index 3ad70b03b..2ac3b1c35 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -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 - diff --git a/src/modes/three_strikes_battle.hpp b/src/modes/three_strikes_battle.hpp index ad883438a..03263d12a 100644 --- a/src/modes/three_strikes_battle.hpp +++ b/src/modes/three_strikes_battle.hpp @@ -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; diff --git a/src/modes/world.hpp b/src/modes/world.hpp index ca5332abe..dca944852 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -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 */ diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 65291e9a0..48b84977a 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -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 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 m_player_karts; @@ -281,52 +307,55 @@ public: void setRandomKartList(const std::vector& 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; } }; diff --git a/src/states_screens/dialogs/track_info_dialog.cpp b/src/states_screens/dialogs/track_info_dialog.cpp index 36c5ff986..a3056eebc 100644 --- a/src/states_screens/dialogs/track_info_dialog.cpp +++ b/src/states_screens/dialogs/track_info_dialog.cpp @@ -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;