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:
@@ -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
|
||||
|
||||
@@ -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"; }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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); }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user