1) Bubble gums do not disappear when hit, instead they are disabled

for 0.5 seconds (enough time for the kart that hit it to drive
   away). This also fixes the bug that re-appearing bubble gums
   were not properly pitch/roll aligned anymore.
2) Bugfix: If a bubble gum was used in a race, a crash happened
   when exiting STK (during cleanup).
3) Bugfix: When restarting a race, bubble gums from the old race
   are now removed.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2446 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-11-11 22:21:25 +00:00
parent c1cb44dd81
commit c14ca10f81
6 changed files with 83 additions and 44 deletions

View File

@ -21,15 +21,25 @@
BubbleGumItem::BubbleGumItem(ItemType type, const Vec3& xyz, const Vec3 &normal,
ssgEntity* model, unsigned int item_id)
: Item(type, xyz, normal, model, item_id)
: Item(type, xyz, normal, model, item_id,
/* rotate */ false)
{
m_rotate = false;
} // BubbleGumItem
//-----------------------------------------------------------------------------
BubbleGumItem::~BubbleGumItem()
{
} // ~BubbleGumItem
//-----------------------------------------------------------------------------
/** Is called when the item is hit by a kart. The bubble gum item then
* inactivates itself for 0.5 seconds, but disables the reappearing of
* the bubble gum.
*/
void BubbleGumItem::isCollected(float t)
{
deactivate(0.5);
// Set the time till reappear to -1 seconds --> the item will
// reappear immediately.
Item::isCollected(-1);
} // isCollected

View File

@ -26,10 +26,11 @@
class BubbleGumItem : public Item
{
public:
BubbleGumItem (ItemType type, const Vec3& xyz,
const Vec3 &normal, ssgEntity* model,
unsigned int item_id);
~BubbleGumItem ();
BubbleGumItem(ItemType type, const Vec3& xyz,
const Vec3 &normal, ssgEntity* model,
unsigned int item_id);
~BubbleGumItem ();
virtual void isCollected(float t);
}
; // class Item

View File

@ -25,8 +25,11 @@
#include "karts/kart.hpp"
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
ssgEntity* model, unsigned int item_id)
ssgEntity* model, unsigned int item_id, bool rotate)
{
m_rotate = rotate;
m_parent = NULL;
m_deactive_time = 0;
// Sets heading to 0, and sets pitch and roll depending on the normal. */
Vec3 hpr = Vec3(0, normal);
m_coord = Coord(xyz, hpr);
@ -39,16 +42,12 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
m_root->setTransform(const_cast<sgCoord*>(&m_coord.toSgCoord()));
m_root->addKid(model);
scene->add(m_root);
m_rotate = true;
m_parent = NULL;
m_immunity_timer = 0;
} // Item
//-----------------------------------------------------------------------------
Item::~Item()
{
scene->remove(m_root);
ssgDeRefDelete(m_root);
} // ~Item
@ -57,26 +56,20 @@ void Item::reset()
{
m_collected = false;
m_time_till_return = 0.0f;
m_deactive_time = 0.0f;
m_root->setTransform(const_cast<sgCoord*>(&m_coord.toSgCoord()));
} // reset
//-----------------------------------------------------------------------------
void Item::setParent(Kart* parent)
{
m_parent = parent;
m_immunity_timer = 1.5f;
m_parent = parent;
m_deactive_time = 1.5f;
}
//-----------------------------------------------------------------------------
bool Item::hitKart(Kart* kart)
{
if(m_immunity_timer > 0) return false;
return (kart->getXYZ()-m_coord.getXYZ()).length2()<0.8f;
} // hitKart
//-----------------------------------------------------------------------------
void Item::update(float delta)
{
if(m_parent != NULL && m_immunity_timer > 0) m_immunity_timer -= delta;
if(m_parent != NULL && m_deactive_time > 0) m_deactive_time -= delta;
if(m_collected)
{
@ -92,7 +85,6 @@ void Item::update(float delta)
else
{
m_collected = false;
m_coord.setHPR(Vec3(0.0f));
m_root->setTransform(const_cast<sgCoord*>(&m_coord.toSgCoord()));
} // T>0
@ -109,9 +101,15 @@ void Item::update(float delta)
} // update
//-----------------------------------------------------------------------------
void Item::isCollected()
/** Is called when the item is hit by a kart. It sets the flag that the item
* has been collected, and the time to return to the parameter.
* \param t Time till the object reappears (defaults to 2 seconds).
*/
void Item::isCollected(float t)
{
m_collected = true;
m_time_till_return = 2.0f;
m_collected = true;
// Note if the time is negative, in update the m_collected flag will
// be automatically set to false again.
m_time_till_return = t;
}

View File

@ -24,8 +24,8 @@
#define _WINSOCKAPI_
#include <plib/sg.h>
#include "coord.hpp"
#include "karts/kart.hpp"
class Kart;
class ssgTransform;
class ssgEntity;
@ -45,7 +45,7 @@ enum ItemType
// -----------------------------------------------------------------------------
class Item
{
protected:
private:
ItemType m_type; // Item type
bool m_collected; // true if item was collected & is not displayed
float m_time_till_return; // time till a collected item reappears
@ -57,23 +57,40 @@ protected:
bool m_rotate; // set to false if item should not rotate
Kart* m_parent; // optional, if item was placed by a kart, a timer
float m_immunity_timer; // can be used so it's not hit by its own item
float m_deactive_time; // can be used so it's not hit by its own item
public:
Item (ItemType type, const Vec3& xyz, const Vec3& normal,
ssgEntity* model, unsigned int item_id);
ssgEntity* model, unsigned int item_id,
bool rotate=true);
~Item ();
unsigned int getItemId() const {return m_item_id; }
void update (float delta);
void isCollected ();
bool hitKart (Kart* kart );
void reset ();
ssgTransform* getRoot () const {return m_root;}
ItemType getType () const {return m_type;}
bool wasCollected() const {return m_collected;}
virtual void isCollected(float t=2.0f);
// ------------------------------------------------------------------------
/** Returns true if the Kart is close enough to hit this item, and
* the item is not deactivated anymore.
* \param kart Kart to test.
*/
bool hitKart (Kart* kart ) const
{
return m_deactive_time <=0 &&
(kart->getXYZ()-m_coord.getXYZ()).length2()<0.8f;
} // hitKart
// ------------------------------------------------------------------------
/** 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.
* \param t Time the item is deactivated.
*/
void deactivate(float t) { m_deactive_time=t; }
// ------------------------------------------------------------------------
unsigned int getItemId() const { return m_item_id; }
ssgTransform* getRoot() const { return m_root; }
ItemType getType() const { return m_type; }
bool wasCollected() const { return m_collected;}
void setParent(Kart* parent);
}
; // class Item
void reset();
}; // class Item
#endif

View File

@ -306,10 +306,22 @@ void ItemManager::cleanup()
*/
void ItemManager::reset()
{
for(AllItemTypes::iterator i =m_all_items.begin();
i!=m_all_items.end(); i++)
std::vector<AllItemTypes::iterator> to_delete;
AllItemTypes::iterator i=m_all_items.begin();
while(i!=m_all_items.end())
{
(*i)->reset();
if((*i)->getType()==ITEM_BUBBLEGUM)
{
BubbleGumItem *b=static_cast<BubbleGumItem*>(*i);
AllItemTypes::iterator i_next = m_all_items.erase(i);
delete b;
i = i_next;
}
else
{
(*i)->reset();
i++;
}
} // for i
} // reset

View File

@ -169,6 +169,7 @@ void World::init()
//-----------------------------------------------------------------------------
World::~World()
{
item_manager->cleanup();
delete race_state;
m_track->cleanup();
// Clear all callbacks