From c14ca10f815baa94dcd85901a11ba6689cafad40 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Tue, 11 Nov 2008 22:21:25 +0000 Subject: [PATCH] 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 --- src/items/bubblegumitem.cpp | 16 ++++++++++--- src/items/bubblegumitem.hpp | 9 ++++---- src/items/item.cpp | 38 +++++++++++++++---------------- src/items/item.hpp | 45 +++++++++++++++++++++++++------------ src/items/item_manager.cpp | 18 ++++++++++++--- src/modes/world.cpp | 1 + 6 files changed, 83 insertions(+), 44 deletions(-) diff --git a/src/items/bubblegumitem.cpp b/src/items/bubblegumitem.cpp index 48a898951..1c5cbd561 100644 --- a/src/items/bubblegumitem.cpp +++ b/src/items/bubblegumitem.cpp @@ -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 diff --git a/src/items/bubblegumitem.hpp b/src/items/bubblegumitem.hpp index 869904824..5fa914832 100644 --- a/src/items/bubblegumitem.hpp +++ b/src/items/bubblegumitem.hpp @@ -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 diff --git a/src/items/item.cpp b/src/items/item.cpp index 81eb0d3f1..4a6c8c995 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -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(&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(&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(&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; } diff --git a/src/items/item.hpp b/src/items/item.hpp index 2fc20cc08..bca16b47e 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -24,8 +24,8 @@ #define _WINSOCKAPI_ #include #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 diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index 9527ff0cc..58d8c28b9 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -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 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(*i); + AllItemTypes::iterator i_next = m_all_items.erase(i); + delete b; + i = i_next; + } + else + { + (*i)->reset(); + i++; + } } // for i } // reset diff --git a/src/modes/world.cpp b/src/modes/world.cpp index c9fa8ff56..3cac76fb5 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -169,6 +169,7 @@ void World::init() //----------------------------------------------------------------------------- World::~World() { + item_manager->cleanup(); delete race_state; m_track->cleanup(); // Clear all callbacks