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:
parent
e6e23021bc
commit
10ea91e758
@ -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). -->
|
||||
|
@ -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 );
|
||||
|
@ -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, ... */
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user