Fixed #399: explode was called by cake and bowling,

even if the kart was immune. Now Flyable::hit()
returns true/false if the hit was a real hit.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9712 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2011-09-02 01:36:23 +00:00
parent 4b2929097d
commit fca446b974
10 changed files with 66 additions and 49 deletions

View File

@@ -202,9 +202,13 @@ bool Bowling::updateAndDelete(float dt)
* The bowling ball triggers an explosion when hit.
* \param kart The kart hit (NULL if no kart was hit).
* \param object The object that was hit (NULL if none).
* \returns True if there was actually a hit (i.e. not owner, and target is
* not immune), false otherwise.
*/
void Bowling::hit(Kart* kart, PhysicalObject* obj)
bool Bowling::hit(Kart* kart, PhysicalObject* obj)
{
Flyable::hit(kart, obj);
explode(kart, obj);
bool was_real_hit = Flyable::hit(kart, obj);
if(was_real_hit)
explode(kart, obj);
return was_real_hit;
} // hit

View File

@@ -46,7 +46,7 @@ public:
static void init(const XMLNode &node, scene::IMesh *bowling);
virtual bool updateAndDelete(float dt);
virtual const core::stringw getHitString(const Kart *kart) const;
virtual void hit(Kart* kart, PhysicalObject* obj=NULL);
virtual bool hit(Kart* kart, PhysicalObject* obj=NULL);
/** Returns the sfx to use when the bowling ball explodes. */
const char* getExplosionSound() const { return "strike"; }

View File

@@ -159,10 +159,14 @@ const core::stringw Cake::getHitString(const Kart *kart) const
* The cake triggers an explosion when hit.
* \param kart The kart hit (NULL if no kart was hit).
* \param object The object that was hit (NULL if none).
* \returns True if there was actually a hit (i.e. not owner, and target is
* not immune), false otherwise.
*/
void Cake::hit(Kart* kart, PhysicalObject* obj)
bool Cake::hit(Kart* kart, PhysicalObject* obj)
{
Flyable::hit(kart, obj);
explode(kart, obj);
} // hit
bool was_real_hit = Flyable::hit(kart, obj);
if(was_real_hit)
explode(kart, obj);
return was_real_hit;
} // hit

View File

@@ -49,8 +49,9 @@ private:
public:
Cake (Kart *kart);
static void init (const XMLNode &node, scene::IMesh *cake_model);
virtual const core::stringw getHitString(const Kart *kart) const;
virtual void hit(Kart* kart, PhysicalObject* obj=NULL);
virtual const core::stringw
getHitString(const Kart *kart) const;
virtual bool hit(Kart* kart, PhysicalObject* obj=NULL);
// ------------------------------------------------------------------------
virtual void hitTrack () { hit(NULL); }
// ------------------------------------------------------------------------

View File

@@ -65,7 +65,6 @@ Flyable::Flyable(Kart *kart, PowerupManager::PowerupType type, float mass)
m_owner = kart;
m_type = type;
m_has_hit_something = false;
m_exploded = false;
m_shape = NULL;
m_mass = mass;
m_adjust_up_velocity = true;
@@ -327,7 +326,7 @@ bool Flyable::updateAndDelete(float dt)
if(m_max_lifespan > -1 && m_time_since_thrown > m_max_lifespan)
hit(NULL);
if(m_exploded) return true;
if(m_has_hit_something) return true;
Vec3 xyz=getBody()->getWorldTransform().getOrigin();
// Check if the flyable is outside of the track. If so, explode it.
@@ -400,8 +399,7 @@ void Flyable::updateFromServer(const FlyableInfo &f, float dt)
{
setXYZ(f.m_xyz);
setRotation(f.m_rotation);
// m_exploded is not set here, since otherwise when explode() is called,
// the rocket is considered to be already exploded.
// Update the graphical position
Moveable::update(dt);
} // updateFromServer
@@ -420,13 +418,15 @@ bool Flyable::isOwnerImmunity(const Kart* kart_hit) const
// ----------------------------------------------------------------------------
/** Callback from the physics in case that a kart or physical object is hit.
* kart The kart hit (NULL if no kart was hit).
* object The object that was hit (NULL if none).
* \param kart The kart hit (NULL if no kart was hit).
* \param object The object that was hit (NULL if none).
* \return True if there was actually a hit (i.e. not owner, and target is
* not immune), false otherwise.
*/
void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
bool Flyable::hit(Kart *kart_hit, PhysicalObject* object)
{
// the owner of this flyable should not be hit by his own flyable
if(m_exploded || isOwnerImmunity(kart_hit)) return;
if(isOwnerImmunity(kart_hit)) return false;
if (kart_hit != NULL)
{
@@ -442,10 +442,8 @@ void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
}
m_has_hit_something=true;
m_exploded=true;
return;
return true;
} // hit

View File

@@ -119,19 +119,22 @@ protected:
/** Size of the model. */
static Vec3 m_st_extend[PowerupManager::POWERUP_MAX];
/** time since thrown. used so a kart can't hit himself when trying something,
and also to put some time limit to some collectibles */
/** Time since thrown. used so a kart can't hit himself when trying
* something, and also to put some time limit to some collectibles */
float m_time_since_thrown;
/** set to something > -1 if this flyable should auto-destrcut after a while */
/** Set to something > -1 if this flyable should auto-destrcut after
* a while. */
float m_max_lifespan;
/** if set to true, the kart that throwns this flyable can't collide with it
for a short time */
/** If set to true, the kart that throwns this flyable can't collide
* with it for a short time. */
bool m_owner_has_temporary_immunity;
void getClosestKart(const Kart **minKart, float *minDistSquared,
Vec3 *minDelta, const Kart* inFrontOf=NULL,
void getClosestKart(const Kart **minKart,
float *minDistSquared,
Vec3 *minDelta,
const Kart* inFrontOf=NULL,
const bool backwards=false) const;
void getLinearKartItemIntersection(const Vec3 &origin,
@@ -144,8 +147,10 @@ protected:
/** init bullet for moving objects like projectiles */
void createPhysics(float y_offset,
const Vec3 &velocity,
btCollisionShape *shape, const float gravity=0.0f,
const bool rotates=false, const bool turn_around=false,
btCollisionShape *shape,
const float gravity=0.0f,
const bool rotates=false,
const bool turn_around=false,
const btTransform* customDirection=NULL);
public:
@@ -154,13 +159,13 @@ public:
virtual ~Flyable ();
static void init (const XMLNode &node, scene::IMesh *model,
PowerupManager::PowerupType type);
virtual bool updateAndDelete(float);
virtual bool updateAndDelete(float);
virtual const core::stringw getHitString(const Kart *kart) const = 0;
virtual HitEffect* getHitEffect() const;
void updateFromServer(const FlyableInfo &f, float dt);
bool isOwnerImmunity(const Kart *kart_hit) const;
virtual void hit(Kart* kart, PhysicalObject* obj=NULL);
void explode(Kart* kart, PhysicalObject* obj=NULL);
virtual HitEffect* getHitEffect() const;
void updateFromServer(const FlyableInfo &f, float dt);
bool isOwnerImmunity(const Kart *kart_hit) const;
virtual bool hit(Kart* kart, PhysicalObject* obj=NULL);
void explode(Kart* kart, PhysicalObject* obj=NULL);
// ------------------------------------------------------------------------
/** If true the up velocity of the flyable will be adjust so that the
* flyable stays at a height close to the average height.

View File

@@ -169,10 +169,12 @@ bool Plunger::updateAndDelete(float dt)
* till the rubber band expires.
* \param kart Pointer to the kart hit (NULL if not a kart).
* \param obj Pointer to PhysicalObject object if hit (NULL otherwise).
* \returns True if there was actually a hit (i.e. not owner, and target is
* not immune), false otherwise.
*/
void Plunger::hit(Kart *kart, PhysicalObject *obj)
bool Plunger::hit(Kart *kart, PhysicalObject *obj)
{
if(isOwnerImmunity(kart)) return;
if(isOwnerImmunity(kart)) return false;
RaceGUIBase* gui = World::getWorld()->getRaceGUI();
irr::core::stringw hit_message;
@@ -193,9 +195,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
}
m_keep_alive = 0;
// Make this object invisible by placing it faaar down. Note that if this
// objects is simply removed from the scene graph, it might be auto-deleted
// because the ref count reaches zero.
// Make this object invisible.
getNode()->setVisible(false);
World::getWorld()->getPhysics()->removeBody(getBody());
}
@@ -216,7 +216,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
if(kart)
{
m_rubber_band->hit(kart);
return;
return false;
}
else if(obj)
{
@@ -228,6 +228,9 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
m_rubber_band->hit(NULL, &(getXYZ()));
}
}
// Rubber band attached.
return false;
} // hit
// -----------------------------------------------------------------------------

View File

@@ -53,7 +53,7 @@ public:
virtual bool updateAndDelete(float dt);
virtual void hitTrack ();
virtual const core::stringw getHitString(const Kart *kart) const;
virtual void hit (Kart *kart, PhysicalObject *obj=NULL);
virtual bool hit (Kart *kart, PhysicalObject *obj=NULL);
// ------------------------------------------------------------------------
/** Sets the keep-alive value. Setting it to 0 will remove the plunger

View File

@@ -465,10 +465,11 @@ float RubberBall::getMaxTerrainHeight() const
/** Callback from the physics in case that a kart or object is hit. The rubber
* ball will only be removed if it hits it target, all other karts it might
* hit earlier will only be flattened.
* kart The kart hit (NULL if no kart was hit).
* object The object that was hit (NULL if none).
* \params kart The kart hit (NULL if no kart was hit).
* \params object The object that was hit (NULL if none).
* \returns True if
*/
void RubberBall::hit(Kart* kart, PhysicalObject* object)
bool RubberBall::hit(Kart* kart, PhysicalObject* object)
{
if(kart)
{
@@ -476,14 +477,15 @@ void RubberBall::hit(Kart* kart, PhysicalObject* object)
if(kart!=m_target)
{
kart->setSquash(m_st_squash_duration, m_st_squash_slowdown);
return false;
}
else
{
// Else trigger the full explosion animation
kart->handleExplosion(kart->getXYZ(), /*direct hit*/true);
setHasHit();
return true;
}
return;
}
Flyable::hit(kart, object);
return Flyable::hit(kart, object);
} // hit

View File

@@ -129,7 +129,7 @@ public:
virtual ~RubberBall();
static void init(const XMLNode &node, scene::IMesh *bowling);
virtual bool updateAndDelete(float dt);
virtual void hit(Kart* kart, PhysicalObject* obj=NULL);
virtual bool hit(Kart* kart, PhysicalObject* obj=NULL);
virtual const core::stringw getHitString(const Kart *kart) const;
// ------------------------------------------------------------------------
/** This object does not create an explosion, all affects on