Made bubble gum disappear (after a certain number of hits, set in

stk_config.xml).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5294 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-04-27 22:43:44 +00:00
parent e6e23021bc
commit 10ea91e758
9 changed files with 125 additions and 33 deletions

View File

@ -68,6 +68,9 @@
Order: item, banana, big-nitro, small-nitro, bubble-bum -->
<switch time="5" items="1 0 4 4 2"/>
<!-- How often bubble gum get driven over before it disappears. -->
<bubble-gum disappear-counter="1"/>
<!-- impulse is the push from explosions when karts aren't hit directly.
explosion-impulse-objects is the impulse for physics objects (smaller
ones like the cone, will be pushed way too far with normal impulse). -->

View File

@ -103,6 +103,7 @@ void STKConfig::load(const std::string &filename)
CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" );
CHECK_NEG(m_zipper_max_speed_fraction, "zipper-max-speed-fraction" );
CHECK_NEG(m_item_switch_time, "item-switch-time" );
CHECK_NEG(m_bubble_gum_counter, "bubblegum disappear counter");
CHECK_NEG(m_explosion_impulse, "explosion-impulse" );
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
CHECK_NEG(m_max_history, "max-history" );
@ -137,6 +138,7 @@ void STKConfig::init_defaults()
m_explosion_impulse = m_explosion_impulse_objects =
m_delay_finish_time = m_skid_fadeout_time =
m_near_ground = m_item_switch_time = UNDEFINED;
m_bubble_gum_counter = -100;
m_max_karts = -100;
m_gp_order = -100;
m_max_history = -100;
@ -248,6 +250,11 @@ void STKConfig::getAllData(const XMLNode * root)
switch_node->get("time", &m_item_switch_time);
}
if(const XMLNode *bubble_gum_node= root->getNode("bubble-gum"))
{
bubble_gum_node->get("disappear-counter", &m_bubble_gum_counter);
}
if(const XMLNode *explosion_node= root->getNode("explosion"))
{
explosion_node->get("impulse", &m_explosion_impulse );

View File

@ -63,6 +63,8 @@ public:
float m_zipper_max_speed_fraction;/**<Fraction of max speed allowed past
regular max speed */
float m_item_switch_time; /**< Time items will be switched. */
int m_bubble_gum_counter; /**< How many times bananas must be eaten
before they disappear. */
float m_explosion_impulse; /**<Impulse affecting each non-hit kart.*/
float m_explosion_impulse_objects;/**<Impulse of explosion on moving
objects, e.g. road cones, ... */

View File

@ -28,15 +28,18 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
scene::IMesh* mesh, unsigned int item_id)
{
setType(type);
m_event_handler = NULL;
m_xyz = xyz;
m_deactive_time = 0;
m_event_handler = NULL;
m_xyz = xyz;
m_deactive_time = 0;
// Sets heading to 0, and sets pitch and roll depending on the normal. */
Vec3 hpr = Vec3(0, normal);
m_item_id = item_id;
m_original_type = ITEM_NONE;
m_collected = false;
m_time_till_return = 0.0f; // not strictly necessary, see isCollected()
Vec3 hpr = Vec3(0, normal);
m_item_id = item_id;
m_original_type = ITEM_NONE;
m_collected = false;
m_time_till_return = 0.0f; // not strictly necessary, see isCollected()
m_disappear_counter = m_type==ITEM_BUBBLEGUM
? stk_config->m_bubble_gum_counter
: -1 ;
m_original_mesh = mesh;
m_node = irr_driver->addMesh(mesh);
m_node->setPosition(xyz.toIrrVector());
@ -62,7 +65,7 @@ void Item::setType(ItemType type)
*/
void Item::switchTo(ItemType type, scene::IMesh *mesh)
{
m_original_type = m_type;
m_original_type = m_type;
setType(type);
m_node->setMesh(mesh);
} // switchTo
@ -97,9 +100,12 @@ Item::~Item()
*/
void Item::reset()
{
m_collected = false;
m_time_till_return = 0.0f;
m_deactive_time = 0.0f;
m_collected = false;
m_time_till_return = 0.0f;
m_deactive_time = 0.0f;
m_disappear_counter = m_type==ITEM_BUBBLEGUM
? stk_config->m_bubble_gum_counter
: -1 ;
if(m_original_type!=ITEM_NONE)
{
setType(m_original_type);
@ -168,8 +174,9 @@ void Item::collected(const Kart *kart, float t)
{
m_collected = true;
m_event_handler = kart;
if(m_type==ITEM_BUBBLEGUM)
if(m_type==ITEM_BUBBLEGUM && m_disappear_counter>0)
{
m_disappear_counter --;
// Deactivates the item for a certain amount of time. It is used to
// prevent bubble gum from hitting a kart over and over again (in each
// frame) by giving it time to drive away.

View File

@ -92,7 +92,13 @@ private:
/** Optionally if item was placed by a kart, a timer can be used to
* temporarly deactivate collision so a kart is not hit by its own item */
float m_deactive_time;
/** Counts how often an item is used before it disappears. Used for
* bubble gum to make them disappear after a while. A value >0
* indicates that the item still exists, =0 that the item can be
* deleted, and <0 that the item will never be deleted. */
int m_disappear_counter;
void setType(ItemType type);
public:
Item (ItemType type, const Vec3& xyz, const Vec3& normal,
@ -113,9 +119,22 @@ public:
} // hitKart
// ------------------------------------------------------------------------
/** Returns the index of this item in the item manager list. */
unsigned int getItemId() const { return m_item_id; }
// ------------------------------------------------------------------------
/** Returns the type of this item. */
ItemType getType() const { return m_type; }
// ------------------------------------------------------------------------
/** Returns true if this item is currently collected. */
bool wasCollected() const { return m_collected;}
// ------------------------------------------------------------------------
/** Returns true if this item is used up and can be removed. */
bool isUsedUp() const {return m_disappear_counter==0; }
// ------------------------------------------------------------------------
/** Returns true if this item can be used up, and therefore needs to
* be removed when the game is reset. */
bool canBeUsedUp() const {return m_disappear_counter>-1; }
// ------------------------------------------------------------------------
void setParent(Kart* parent);
void reset();
void switchTo(ItemType type, scene::IMesh *mesh);

View File

@ -138,15 +138,25 @@ void ItemManager::loadDefaultItems()
Item* ItemManager::newItem(Item::ItemType type, const Vec3& xyz,
const Vec3 &normal, Kart *parent)
{
// Find where the item can be stored in the index list: either in a
// previously deleted entry, otherwise at the end.
int index = -1;
for(index=m_all_items.size()-1; index>=0 && m_all_items[index]; index--) {}
if(index==-1) index = m_all_items.size();
Item* item;
item = new Item(type, xyz, normal, m_item_mesh[type], m_all_items.size());
item = new Item(type, xyz, normal, m_item_mesh[type], index);
if(parent != NULL) item->setParent(parent);
if(m_switch_time>=0)
{
Item::ItemType new_type = m_switch_to[item->getType()];
item->switchTo(new_type, m_item_mesh[(int)new_type]);
}
m_all_items.push_back(item);
if(index<(int)m_all_items.size())
m_all_items[index] = item;
else
m_all_items.push_back(item);
return item;
} // newItem
@ -157,12 +167,17 @@ Item* ItemManager::newItem(Item::ItemType type, const Vec3& xyz,
void ItemManager::collectedItem(int item_id, Kart *kart, int add_info)
{
Item *item=m_all_items[item_id];
assert(item);
item->collected(kart);
kart->collectedItem(*item, add_info);
} // collectedItem
//-----------------------------------------------------------------------------
void ItemManager::hitItem(Kart* kart)
/** Checks if any item was collected by the given kart. This function calls
* collectedItem if an item was collected.
* \param kart Pointer to the kart.
*/
void ItemManager::checkItemHit(Kart* kart)
{
// Only do this on the server
if(network_manager->getMode()==NetworkManager::NW_CLIENT) return;
@ -170,13 +185,13 @@ void ItemManager::hitItem(Kart* kart)
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
if((*i)->wasCollected()) continue;
if((!*i) || (*i)->wasCollected()) continue;
if((*i)->hitKart(kart))
{
collectedItem(i-m_all_items.begin(), kart);
} // if hit
} // for m_all_items
} // hitItem
} // checkItemHit
//-----------------------------------------------------------------------------
/** Remove all item instances, and the track specific models. This is used
@ -187,7 +202,8 @@ void ItemManager::cleanup()
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
delete *i;
if(*i)
delete *i;
}
m_all_items.clear();
} // cleanup
@ -203,14 +219,17 @@ void ItemManager::reset()
{
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
(*i)->switchBack();
{
if(*i) (*i)->switchBack();
}
m_switch_time = -1.0f;
}
AllItemTypes::iterator i=m_all_items.begin();
while(i!=m_all_items.end())
{
if((*i)->getType()==Item::ITEM_BUBBLEGUM)
if(!*i) continue;
if((*i)->canBeUsedUp() || (*i)->getType()==Item::ITEM_BUBBLEGUM)
{
Item *b=*i;
AllItemTypes::iterator i_next = m_all_items.erase(i);
@ -239,7 +258,7 @@ void ItemManager::update(float dt)
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
(*i)->switchBack();
if(*i) (*i)->switchBack();
} // for m_all_items
} // m_switch_time < 0
} // m_switch_time>=0
@ -247,7 +266,15 @@ void ItemManager::update(float dt)
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
(*i)->update(dt);
if(*i)
{
(*i)->update(dt);
if( (*i)->isUsedUp())
{
delete *i;
m_all_items[i-m_all_items.begin()] = NULL;
} // if usedUp
} // if *i
} // for m_all_items
} // update
@ -260,12 +287,11 @@ void ItemManager::switchItems()
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
{
if(!*i) continue;
Item::ItemType new_type = m_switch_to[(*i)->getType()];
if(m_switch_time<0)
(*i)->switchTo(new_type, m_item_mesh[(int)new_type]);
// FIXME: if switch is used while items are switched:
// switch back - but that doesn't work properly yet
else
(*i)->switchBack();
} // for m_all_items

View File

@ -60,7 +60,7 @@ public:
Item* newItem (Item::ItemType type, const Vec3& xyz,
const Vec3 &normal, Kart* parent=NULL);
void update (float delta);
void hitItem (Kart* kart);
void checkItemHit (Kart* kart);
void cleanup ();
void reset ();
void removeTextures ();

View File

@ -34,9 +34,12 @@
//-----------------------------------------------------------------------------
Powerup::Powerup(Kart* kart_)
/** Constructor, stores the kart to which this powerup belongs.
* \param kart The kart to which this powerup belongs.
*/
Powerup::Powerup(Kart* kart)
{
m_owner = kart_;
m_owner = kart;
m_sound_use = NULL;
reset();
} // Powerup
@ -50,6 +53,8 @@ Powerup::~Powerup()
} // ~Powerup
//-----------------------------------------------------------------------------
/** Resets the powerup, called at begin of a race.
*/
void Powerup::reset()
{
m_type = POWERUP_NOTHING;
@ -61,6 +66,12 @@ void Powerup::reset()
} // reset
//-----------------------------------------------------------------------------
/** Sets the collected items. The number of items is increased if the same
* item is currently collected, otherwise replaces the existing item. It also
* sets item specific sounds.
* \param type Thew new type.
* \param n Number of items of the given type.
*/
void Powerup::set(PowerupType type, int n)
{
if (m_type==type)
@ -113,6 +124,9 @@ void Powerup::set(PowerupType type, int n)
} // set
//-----------------------------------------------------------------------------
/** Returns the icon for the currently collected powerup. Used in the
* race_gui to display the collected item.
*/
Material *Powerup::getIcon() const
{
// Check if it's one of the types which have a separate
@ -121,6 +135,8 @@ Material *Powerup::getIcon() const
}
//-----------------------------------------------------------------------------
/** Use (fire) this powerup.
*/
void Powerup::use()
{
// Play custom kart sound when collectible is used
@ -136,7 +152,7 @@ void Powerup::use()
m_number--;
World *world = World::getWorld();
RaceGUI* gui = World::getWorld()->getRaceGUI();
RaceGUI* gui = world->getRaceGUI();
switch (m_type)
{
case POWERUP_ZIPPER: m_owner->handleZipper();
@ -214,7 +230,7 @@ void Powerup::use()
case POWERUP_PARACHUTE:
{
Kart* player_kart = NULL;
//Attach a parachutte(that last as twice as the
//Attach a parachutte(that last twice as long as the
//one from the bananas) to all the karts that
//are in front of this one.
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
@ -257,6 +273,18 @@ void Powerup::use()
} // use
//-----------------------------------------------------------------------------
/** This function is called when a bnous box is it. This function can be
* called on a server (in which case item and add_info are not used),
* or on a client, in which case the item and additional info is used
* to make sure server and clients are synched correctly.
* \param n
* \param item The item (bonux box) that was hit. This is necessary
* for servers so that the clients can be informed which item
* was collected.
* \param add_info Additional information. This is used for network games
* so that the server can overwrite which item is collectted
* (otherwise a random choice is done).
*/
void Powerup::hitBonusBox(int n, const Item &item, int add_info)
{
World *world = World::getWorld();

View File

@ -537,7 +537,7 @@ void Kart::collectedItem(const Item &item, int add_info)
// In wheelie style, karts get more items depending on energy,
// in nitro mode it's only one item.
int n = 1;
m_powerup.hitBonusBox(n, item,add_info);
m_powerup.hitBonusBox(n, item, add_info);
break;
}
case Item::ITEM_BUBBLEGUM:
@ -769,7 +769,7 @@ void Kart::update(float dt)
} // if there is material
// Check if any item was hit.
item_manager->hitItem(this);
item_manager->checkItemHit(this);
if(m_kart_properties->hasSkidmarks())
m_skidmarks->update(dt);