Added support for multiple powerups to be collected with one item

box. Weights for these are set in powerup.xml. ATM a 'multi item'
gives three items (hardcoded, I'll change that to be configurable
later).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6079 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-09-20 14:48:05 +00:00
parent 1f348ac93f
commit 78346e3ddf
6 changed files with 57 additions and 42 deletions

View File

@ -25,12 +25,18 @@
<!-- Distribution of the items depending on position of the <!-- Distribution of the items depending on position of the
kart. The order must correspond to powerup_manager.hpp --> kart. The order must correspond to powerup_manager.hpp -->
<!-- bubble cake bowl zipper plunger switch para anvil --> <!-- bubble cake bowl zipper plunger switch para anvil -->
<first w="3 0 0 0 0 1 0 0" /> <first w="3 0 1 0 0 1 0 0"
<top33 w="3 3 3 3 3 1 3 0" /> w-multi="3 0 0 0 0 0 0 0" />
<mid33 w="3 3 3 3 3 1 3 0" /> <top33 w="3 3 3 3 3 1 3 0"
<end33 w="0 3 3 3 3 1 3 3" /> w-multi="0 1 1 0 1 0 0 0" />
<last w="0 3 3 6 6 0 6 6" /> <mid33 w="3 3 3 3 3 1 3 0"
<battle w="0 6 3 0 0 0 0 0" /> w-multi="1 2 2 2 2 0 1 0" />
<end33 w="0 3 3 3 3 1 3 3"
w-multi="0 3 3 3 3 0 3 0" />
<last w="0 3 3 6 6 0 6 6"
w-multi="0 3 3 6 6 0 6 0" />
<battle w="0 6 3 0 0 0 0 0"
w-multi="0 2 1 0 0 0 0 0" />
</powerup> </powerup>

View File

@ -48,9 +48,9 @@ const wchar_t* getAnchorString()
case 2: return _("%s is a mighty pirate!"); case 2: return _("%s is a mighty pirate!");
default: assert(false); return L""; // avoid compiler warning. default: assert(false); return L""; // avoid compiler warning.
} }
} } // getAnchorString
//-----------------------------------------------------------------------------
const wchar_t* getParachuteString() const wchar_t* getParachuteString()
{ {
const int PARACHUTE_STRINGS_COUNT = 3; const int PARACHUTE_STRINGS_COUNT = 3;
@ -65,9 +65,9 @@ const wchar_t* getParachuteString()
case 2: return _("Do you want to fly kites?"); case 2: return _("Do you want to fly kites?");
default: assert(false); return L""; // avoid compiler warning default: assert(false); return L""; // avoid compiler warning
} }
} } // getParachuteString
//-----------------------------------------------------------------------------
const wchar_t* getSwapperString() const wchar_t* getSwapperString()
{ {
const int SWAPPER_STRINGS_COUNT = 3; const int SWAPPER_STRINGS_COUNT = 3;
@ -82,7 +82,7 @@ const wchar_t* getSwapperString()
case 2: return _("Banana? Box? Banana? Box? Banana? Box?"); case 2: return _("Banana? Box? Banana? Box? Banana? Box?");
default: assert(false); return L""; // avoid compiler warning default: assert(false); return L""; // avoid compiler warning
} }
} } // getSwapperString
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Constructor, stores the kart to which this powerup belongs. /** Constructor, stores the kart to which this powerup belongs.
@ -145,30 +145,30 @@ void Powerup::set(PowerupManager::PowerupType type, int n)
break ; break ;
case PowerupManager::POWERUP_BOWLING: case PowerupManager::POWERUP_BOWLING:
m_sound_use = sfx_manager->createSoundSource("bowling_roll"); m_sound_use = sfx_manager->createSoundSource("bowling_roll");
break ; break ;
case PowerupManager::POWERUP_ANVIL: case PowerupManager::POWERUP_ANVIL:
m_sound_use = sfx_manager->createSoundSource("use_anvil"); m_sound_use = sfx_manager->createSoundSource("use_anvil");
break; break;
case PowerupManager::POWERUP_PARACHUTE: case PowerupManager::POWERUP_PARACHUTE:
m_sound_use = sfx_manager->createSoundSource("use_parachute"); m_sound_use = sfx_manager->createSoundSource("use_parachute");
break; break;
case PowerupManager::POWERUP_BUBBLEGUM: case PowerupManager::POWERUP_BUBBLEGUM:
m_sound_use = sfx_manager->createSoundSource("goo"); m_sound_use = sfx_manager->createSoundSource("goo");
break ; break ;
case PowerupManager::POWERUP_SWITCH: case PowerupManager::POWERUP_SWITCH:
m_sound_use = sfx_manager->createSoundSource("swap"); m_sound_use = sfx_manager->createSoundSource("swap");
break; break;
case PowerupManager::POWERUP_NOTHING: case PowerupManager::POWERUP_NOTHING:
case PowerupManager::POWERUP_CAKE: case PowerupManager::POWERUP_CAKE:
case PowerupManager::POWERUP_PLUNGER: case PowerupManager::POWERUP_PLUNGER:
default : default :
m_sound_use = sfx_manager->createSoundSource("shot"); m_sound_use = sfx_manager->createSoundSource("shot");
break ; break ;
} }
@ -208,7 +208,8 @@ void Powerup::use()
RaceGUIBase* gui = world->getRaceGUI(); RaceGUIBase* gui = world->getRaceGUI();
switch (m_type) switch (m_type)
{ {
case PowerupManager::POWERUP_ZIPPER: m_owner->handleZipper(); case PowerupManager::POWERUP_ZIPPER:
m_owner->handleZipper();
break ; break ;
case PowerupManager::POWERUP_SWITCH: case PowerupManager::POWERUP_SWITCH:
{ {
@ -339,15 +340,15 @@ void Powerup::use()
* so that the server can overwrite which item is collectted * so that the server can overwrite which item is collectted
* (otherwise a random choice is done). * (otherwise a random choice is done).
*/ */
void Powerup::hitBonusBox(int n, const Item &item, int add_info) void Powerup::hitBonusBox(const Item &item, int add_info)
{ {
// Position can be -1 in case of a battle mode (which doesn't have // Position can be -1 in case of a battle mode (which doesn't have
// positions), but this case is properly handled in getRandomPowerup. // positions), but this case is properly handled in getRandomPowerup.
int position = m_owner->getPosition(); int position = m_owner->getPosition();
unsigned int n=1;
PowerupManager::PowerupType new_powerup = PowerupManager::PowerupType new_powerup =
powerup_manager->getRandomPowerup(position); powerup_manager->getRandomPowerup(position, &n);
// Always add a new powerup in ITEM_MODE_NEW (or if the kart // Always add a new powerup in ITEM_MODE_NEW (or if the kart
// doesn't have a powerup atm). // doesn't have a powerup atm).

View File

@ -58,7 +58,7 @@ public:
void reset (); void reset ();
Material* getIcon () const; Material* getIcon () const;
void use (); void use ();
void hitBonusBox (int n, const Item &item, int newC=-1); void hitBonusBox (const Item &item, int newC=-1);
/** Returns the number of powerups. */ /** Returns the number of powerups. */
int getNum () const {return m_number;} int getNum () const {return m_number;}

View File

@ -79,7 +79,8 @@ void PowerupManager::unloadPowerups()
* \param name Name of the powerup to look up. * \param name Name of the powerup to look up.
* \return The type, or POWERUP_NOTHING if the name is not found * \return The type, or POWERUP_NOTHING if the name is not found
*/ */
PowerupManager::PowerupType PowerupManager::getPowerupType(const std::string &name) const PowerupManager::PowerupType
PowerupManager::getPowerupType(const std::string &name) const
{ {
// Must match the order of PowerupType in powerup_manager.hpp!! // Must match the order of PowerupType in powerup_manager.hpp!!
static std::string powerup_names[] = { static std::string powerup_names[] = {
@ -185,17 +186,18 @@ void PowerupManager::loadWeights(const XMLNode &root,
PositionClass position_class) PositionClass position_class)
{ {
const XMLNode *node = root.getNode(class_name); const XMLNode *node = root.getNode(class_name);
std::string s(""); std::string s(""), s_multi("");
if(node) node->get("w", &s); if(node) node->get("w", &s );
if(node) node->get("w-multi", &s_multi);
if(!node || s=="") if(!node || s=="" || s_multi=="")
{ {
printf("No weights found for class '%s' - probabilities will be incorrect.\n", printf("No weights found for class '%s' - probabilities will be incorrect.\n",
class_name.c_str()); class_name.c_str());
return; return;
} }
std::vector<std::string> weight_list = StringUtils::split(s, ' '); std::vector<std::string> weight_list = StringUtils::split(s+" "+s_multi,' ');
std::vector<std::string>::iterator i=weight_list.begin(); std::vector<std::string>::iterator i=weight_list.begin();
while(i!=weight_list.end()) while(i!=weight_list.end())
@ -209,10 +211,10 @@ void PowerupManager::loadWeights(const XMLNode &root,
i++; i++;
} }
// Fill missing entries with 0s // Fill missing entries with 0s
while(weight_list.size()<(int)POWERUP_LAST) while(weight_list.size()<2*(int)POWERUP_LAST)
weight_list.push_back(0); weight_list.push_back(0);
if(weight_list.size()!=(int)POWERUP_LAST) if(weight_list.size()!=2*(int)POWERUP_LAST)
{ {
printf("Incorrect number of weights found in class '%s':\n", printf("Incorrect number of weights found in class '%s':\n",
class_name.c_str()); class_name.c_str());
@ -251,13 +253,11 @@ void PowerupManager::updateWeightsForRace(unsigned int num_karts)
// Then determine which items are available: // Then determine which items are available:
m_powerups_for_position[pos_class].clear(); m_powerups_for_position[pos_class].clear();
unsigned int sum = 0; for(unsigned int i= POWERUP_FIRST; i<=2*POWERUP_LAST; i++)
for(unsigned int i= POWERUP_FIRST; i<=POWERUP_LAST; i++)
{ {
PowerupType type=(PowerupType)i; PowerupType type=(PowerupType)i;
unsigned int w =m_weights[pos_class][i-POWERUP_FIRST]; unsigned int w =m_weights[pos_class][i-POWERUP_FIRST];
sum += w; for(unsigned int j=0; j<w; j++)
for(unsigned int i=0; i<w; i++)
m_powerups_for_position[pos_class].push_back(type); m_powerups_for_position[pos_class].push_back(type);
} // for type in [POWERUP_FIRST, POWERUP_LAST] } // for type in [POWERUP_FIRST, POWERUP_LAST]
} }
@ -300,13 +300,24 @@ PowerupManager::PositionClass
* items depending on the weights defined. See updateWeightsForRace() * items depending on the weights defined. See updateWeightsForRace()
* \param pos Position of the kart (1<=pos<=number of karts) - ignored in * \param pos Position of the kart (1<=pos<=number of karts) - ignored in
* case of a battle mode. * case of a battle mode.
* \param n Number of times this item is given to the kart
*/ */
PowerupManager::PowerupType PowerupManager::getRandomPowerup(unsigned int pos) PowerupManager::PowerupType PowerupManager::getRandomPowerup(unsigned int pos,
unsigned int *n)
{ {
// Positions start with 1, while the index starts with 0 - so subtract 1 // Positions start with 1, while the index starts with 0 - so subtract 1
PositionClass pos_class = race_manager->isBattleMode() ? POSITION_BATTLE_MODE PositionClass pos_class =
: m_position_to_class[pos-1]; race_manager->isBattleMode() ? POSITION_BATTLE_MODE
: m_position_to_class[pos-1];
int random = rand()%m_powerups_for_position[pos_class].size(); int random = rand()%m_powerups_for_position[pos_class].size();
return m_powerups_for_position[pos_class][random]; int i=m_powerups_for_position[pos_class][random];
if(i>=POWERUP_MAX)
{
i -= POWERUP_MAX;
*n = 3;
}
else
*n=1;
return (PowerupType)i;
} // getRandomPowerup } // getRandomPowerup

View File

@ -147,7 +147,7 @@ public:
void updateWeightsForRace(unsigned int num_karts); void updateWeightsForRace(unsigned int num_karts);
Material* getIcon (int type) const {return m_all_icons [type];} Material* getIcon (int type) const {return m_all_icons [type];}
PowerupManager::PowerupType PowerupManager::PowerupType
getRandomPowerup(unsigned int pos); getRandomPowerup(unsigned int pos, unsigned int *n);
/** Returns the mesh for a certain powerup. /** Returns the mesh for a certain powerup.
* \param type Mesh type for which the model is returned. */ * \param type Mesh type for which the model is returned. */
irr::scene::IMesh irr::scene::IMesh

View File

@ -539,10 +539,7 @@ void Kart::collectedItem(Item *item, int add_info)
break; break;
case Item::ITEM_BONUS_BOX : case Item::ITEM_BONUS_BOX :
{ {
// In wheelie style, karts get more items depending on energy, m_powerup.hitBonusBox(*item, add_info);
// in nitro mode it's only one item.
int n = 1;
m_powerup.hitBonusBox(n, *item, add_info);
break; break;
} }
case Item::ITEM_BUBBLEGUM: case Item::ITEM_BUBBLEGUM: