Refactoring: flyable and hit effects now call
updateAndDelete instead of update. The return value indicates if the flyable/hit effect needs to be deleted. That removes callbacks to the projectile manager to indicate that something needs to be deleted. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9619 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
8d8601655d
commit
771cf47339
@ -85,11 +85,11 @@ Explosion::~Explosion()
|
|||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
* \return true If the explosion is finished.
|
* \return true If the explosion is finished.
|
||||||
*/
|
*/
|
||||||
bool Explosion::update(float dt)
|
bool Explosion::updateAndDelete(float dt)
|
||||||
{
|
{
|
||||||
// The explosion sfx is shorter than the particle effect,
|
// The explosion sfx is shorter than the particle effect,
|
||||||
// so no need to save the result of the update call.
|
// so no need to save the result of the update call.
|
||||||
HitSFX::update(dt);
|
HitSFX::updateAndDelete(dt);
|
||||||
|
|
||||||
m_remaining_time -= dt;
|
m_remaining_time -= dt;
|
||||||
|
|
||||||
@ -133,4 +133,4 @@ bool Explosion::update(float dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false; // not finished
|
return false; // not finished
|
||||||
} // update
|
} // updateAndDelete
|
||||||
|
@ -46,7 +46,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
Explosion(const Vec3& coord, const char* explosion_sound);
|
Explosion(const Vec3& coord, const char* explosion_sound);
|
||||||
~Explosion();
|
~Explosion();
|
||||||
bool update (float delta_t);
|
bool updateAndDelete(float delta_t);
|
||||||
bool hasEnded () { return m_remaining_time <= -explosion_time; }
|
bool hasEnded () { return m_remaining_time <= -explosion_time; }
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
/** Updates a hit effect. Called once per frame.
|
/** Updates a hit effect. Called once per frame.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
* \return True if the hit effect is finished and can be removed. */
|
* \return True if the hit effect is finished and can be removed. */
|
||||||
virtual bool update (float dt) = 0;
|
virtual bool updateAndDelete(float dt) = 0;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets that this SFX affects a player kart, which can be used to
|
/** Sets that this SFX affects a player kart, which can be used to
|
||||||
|
@ -61,11 +61,12 @@ void HitSFX::setPlayerKartHit()
|
|||||||
} // setPlayerKartHit
|
} // setPlayerKartHit
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Updates the hit sfx, called one per time step.
|
/** Updates the hit sfx, called one per time step. If this function returns
|
||||||
|
* true, the effect will be deleted.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
* \return true If the explosion is finished.
|
* \return true If the explosion is finished.
|
||||||
*/
|
*/
|
||||||
bool HitSFX::update(float dt)
|
bool HitSFX::updateAndDelete(float dt)
|
||||||
{
|
{
|
||||||
return m_sfx->getStatus() != SFXManager::SFX_PLAYING;
|
return m_sfx->getStatus() != SFXManager::SFX_PLAYING;
|
||||||
} // update
|
} // updateAndDelete
|
||||||
|
@ -36,7 +36,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
HitSFX(const Vec3& coord, const char* explosion_sound);
|
HitSFX(const Vec3& coord, const char* explosion_sound);
|
||||||
~HitSFX();
|
~HitSFX();
|
||||||
virtual bool update (float dt);
|
virtual bool updateAndDelete(float dt);
|
||||||
virtual void setPlayerKartHit();
|
virtual void setPlayerKartHit();
|
||||||
|
|
||||||
}; // HitSFX
|
}; // HitSFX
|
||||||
|
@ -90,9 +90,17 @@ void Bowling::init(const XMLNode &node, scene::IMesh *bowling)
|
|||||||
} // init
|
} // init
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
void Bowling::update(float dt)
|
/** Updates the bowling ball ineach frame. If this function returns true, the
|
||||||
|
* object will be removed by the projectile manager.
|
||||||
|
* \param dt Time step size.
|
||||||
|
* \returns True of this object should be removed.
|
||||||
|
*/
|
||||||
|
bool Bowling::updateAndDelete(float dt)
|
||||||
{
|
{
|
||||||
Flyable::update(dt);
|
bool can_be_deleted = Flyable::updateAndDelete(dt);
|
||||||
|
if(can_be_deleted)
|
||||||
|
return true;
|
||||||
|
|
||||||
const Kart *kart=0;
|
const Kart *kart=0;
|
||||||
Vec3 direction;
|
Vec3 direction;
|
||||||
float minDistance;
|
float minDistance;
|
||||||
@ -121,7 +129,7 @@ void Bowling::update(float dt)
|
|||||||
if(!material || material->isDriveReset())
|
if(!material || material->isDriveReset())
|
||||||
{
|
{
|
||||||
hit(NULL);
|
hit(NULL);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
btVector3 v = m_body->getLinearVelocity();
|
btVector3 v = m_body->getLinearVelocity();
|
||||||
@ -131,13 +139,17 @@ void Bowling::update(float dt)
|
|||||||
if(vlen<0.8*m_speed*m_speed)
|
if(vlen<0.8*m_speed*m_speed)
|
||||||
{ // bowling lost energy (less than 80%), i.e. it's too slow - speed it up:
|
{ // bowling lost energy (less than 80%), i.e. it's too slow - speed it up:
|
||||||
if(vlen==0.0f) {
|
if(vlen==0.0f) {
|
||||||
v = btVector3(.5f, .0, 0.5f); // avoid 0 div.
|
v = btVector3(.5f, .0, 0.5f); // avoid 0 div.
|
||||||
}
|
}
|
||||||
m_body->setLinearVelocity(v*m_speed/sqrt(vlen));
|
m_body->setLinearVelocity(v*m_speed/sqrt(vlen));
|
||||||
} // vlen < 0.8*m_speed*m_speed
|
} // vlen < 0.8*m_speed*m_speed
|
||||||
} // hat< m_max_height
|
} // hat< m_max_height
|
||||||
|
|
||||||
if(vlen<0.1)
|
if(vlen<0.1)
|
||||||
|
{
|
||||||
hit(NULL);
|
hit(NULL);
|
||||||
} // update
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} // updateAndDelete
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -43,7 +43,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
Bowling(Kart* kart);
|
Bowling(Kart* kart);
|
||||||
static void init(const XMLNode &node, scene::IMesh *bowling);
|
static void init(const XMLNode &node, scene::IMesh *bowling);
|
||||||
virtual void update(float dt);
|
virtual bool updateAndDelete(float dt);
|
||||||
|
|
||||||
const char* getExplosionSound() const { return "strike"; }
|
const char* getExplosionSound() const { return "strike"; }
|
||||||
|
|
||||||
|
@ -254,8 +254,8 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
|||||||
Vec3 *minDelta, const Kart* inFrontOf,
|
Vec3 *minDelta, const Kart* inFrontOf,
|
||||||
const bool backwards) const
|
const bool backwards) const
|
||||||
{
|
{
|
||||||
btTransform tProjectile = (inFrontOf != NULL ? inFrontOf->getTrans()
|
btTransform trans_projectile = (inFrontOf != NULL ? inFrontOf->getTrans()
|
||||||
: getTrans());
|
: getTrans());
|
||||||
|
|
||||||
*minDistSquared = 999999.9f;
|
*minDistSquared = 999999.9f;
|
||||||
*minKart = NULL;
|
*minKart = NULL;
|
||||||
@ -271,9 +271,11 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
|||||||
kart->playingEmergencyAnimation() ) continue;
|
kart->playingEmergencyAnimation() ) continue;
|
||||||
btTransform t=kart->getTrans();
|
btTransform t=kart->getTrans();
|
||||||
|
|
||||||
Vec3 delta = t.getOrigin()-tProjectile.getOrigin();
|
Vec3 delta = t.getOrigin()-trans_projectile.getOrigin();
|
||||||
// the Y distance is added again because karts above or below should not be prioritized when aiming
|
// the Y distance is added again because karts above or below should//
|
||||||
float distance2 = delta.length2() + abs(t.getOrigin().getY() - tProjectile.getOrigin().getY())*2;
|
// not be prioritized when aiming
|
||||||
|
float distance2 = delta.length2() + abs(t.getOrigin().getY()
|
||||||
|
- trans_projectile.getOrigin().getY())*2;
|
||||||
|
|
||||||
if(inFrontOf != NULL)
|
if(inFrontOf != NULL)
|
||||||
{
|
{
|
||||||
@ -338,19 +340,25 @@ void Flyable::getLinearKartItemIntersection (const Vec3 &origin,
|
|||||||
float gy = target_direction.getY();
|
float gy = target_direction.getY();
|
||||||
|
|
||||||
//Projected onto X-Z plane
|
//Projected onto X-Z plane
|
||||||
float target_kart_speed = target_direction.length_2d() * target_kart->getSpeed();
|
float target_kart_speed = target_direction.length_2d()
|
||||||
|
* target_kart->getSpeed();
|
||||||
|
|
||||||
float target_kart_heading = target_kart->getHeading();
|
float target_kart_heading = target_kart->getHeading();
|
||||||
|
|
||||||
float dist = -(target_kart_speed / item_XZ_speed) * (dx * cosf(target_kart_heading) -
|
float dist = -(target_kart_speed / item_XZ_speed)
|
||||||
dz * sinf(target_kart_heading));
|
* (dx * cosf(target_kart_heading) -
|
||||||
|
dz * sinf(target_kart_heading) );
|
||||||
|
|
||||||
float fire_th = (dx*dist - dz * sqrtf(dx*dx + dz*dz - dist*dist)) / (dx*dx + dz*dz);
|
float fire_th = (dx*dist - dz * sqrtf(dx*dx + dz*dz - dist*dist))
|
||||||
fire_th = (((dist - dx*fire_th) / dz > 0) ? -acosf(fire_th): acosf(fire_th));
|
/ (dx*dx + dz*dz);
|
||||||
|
fire_th = (((dist - dx*fire_th) / dz > 0) ? -acosf(fire_th)
|
||||||
|
: acosf(fire_th));
|
||||||
|
|
||||||
float time = 0.0f;
|
float time = 0.0f;
|
||||||
float a = item_XZ_speed * sinf (fire_th) + target_kart_speed * sinf (target_kart_heading);
|
float a = item_XZ_speed * sinf (fire_th)
|
||||||
float b = item_XZ_speed * cosf (fire_th) + target_kart_speed * cosf (target_kart_heading);
|
+ target_kart_speed * sinf (target_kart_heading);
|
||||||
|
float b = item_XZ_speed * cosf (fire_th)
|
||||||
|
+ target_kart_speed * cosf (target_kart_heading);
|
||||||
|
|
||||||
if (fabsf(a) > fabsf(b)) time = fabsf (dx / a);
|
if (fabsf(a) > fabsf(b)) time = fabsf (dx / a);
|
||||||
else if (b != 0.0f) time = fabsf(dz / b);
|
else if (b != 0.0f) time = fabsf(dz / b);
|
||||||
@ -364,16 +372,23 @@ void Flyable::getLinearKartItemIntersection (const Vec3 &origin,
|
|||||||
time -= forw_offset / sqrt(a*a+b*b);
|
time -= forw_offset / sqrt(a*a+b*b);
|
||||||
|
|
||||||
*fire_angle = fire_th;
|
*fire_angle = fire_th;
|
||||||
*up_velocity = (0.5f * time * gravity) + (dy / time) + (gy * target_kart->getSpeed());
|
*up_velocity = (0.5f * time * gravity) + (dy / time)
|
||||||
|
+ (gy * target_kart->getSpeed());
|
||||||
} // getLinearKartItemIntersection
|
} // getLinearKartItemIntersection
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Flyable::update(float dt)
|
/** Updates this flyable. It calls Moveable::update. If this function returns
|
||||||
|
* true, the flyable will be deleted by the projectile manager.
|
||||||
|
* \param dt Time step size.
|
||||||
|
* \returns True if this object can be deleted.
|
||||||
|
*/
|
||||||
|
bool Flyable::updateAndDelete(float dt)
|
||||||
{
|
{
|
||||||
m_time_since_thrown += dt;
|
m_time_since_thrown += dt;
|
||||||
if(m_max_lifespan > -1 && m_time_since_thrown > m_max_lifespan) hit(NULL);
|
if(m_max_lifespan > -1 && m_time_since_thrown > m_max_lifespan)
|
||||||
|
hit(NULL);
|
||||||
|
|
||||||
if(m_exploded) return;
|
if(m_exploded) return true;
|
||||||
|
|
||||||
Vec3 xyz=getBody()->getWorldTransform().getOrigin();
|
Vec3 xyz=getBody()->getWorldTransform().getOrigin();
|
||||||
// Check if the flyable is outside of the track. If so, explode it.
|
// Check if the flyable is outside of the track. If so, explode it.
|
||||||
@ -396,7 +411,7 @@ void Flyable::update(float dt)
|
|||||||
xyz[0]>(*max)[0]-eps || xyz[2]>(*max)[2]-eps || xyz[1]>(*max)[1]-eps )
|
xyz[0]>(*max)[0]-eps || xyz[2]>(*max)[2]-eps || xyz[1]>(*max)[1]-eps )
|
||||||
{
|
{
|
||||||
hit(NULL); // flyable out of track boundary
|
hit(NULL); // flyable out of track boundary
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the position offset so that the flyable can adjust its position
|
// Add the position offset so that the flyable can adjust its position
|
||||||
@ -404,6 +419,10 @@ void Flyable::update(float dt)
|
|||||||
// problems finding the terrain in steep uphill sections).
|
// problems finding the terrain in steep uphill sections).
|
||||||
TerrainInfo::update(xyz+m_position_offset);
|
TerrainInfo::update(xyz+m_position_offset);
|
||||||
|
|
||||||
|
// Remove flyable if its
|
||||||
|
if(TerrainInfo::getMaterial()==NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
if(m_adjust_up_velocity)
|
if(m_adjust_up_velocity)
|
||||||
{
|
{
|
||||||
float hat = xyz.getY()-getHoT();
|
float hat = xyz.getY()-getHoT();
|
||||||
@ -412,7 +431,8 @@ void Flyable::update(float dt)
|
|||||||
// HAT is clamped by min/max height. This might be somewhat
|
// HAT is clamped by min/max height. This might be somewhat
|
||||||
// unphysical, but feels right in the game.
|
// unphysical, but feels right in the game.
|
||||||
|
|
||||||
float delta = m_average_height - std::max(std::min(hat, m_max_height), m_min_height);
|
float delta = m_average_height - std::max(std::min(hat, m_max_height),
|
||||||
|
m_min_height);
|
||||||
Vec3 v = getVelocity();
|
Vec3 v = getVelocity();
|
||||||
assert(!isnan(v.getX()));
|
assert(!isnan(v.getX()));
|
||||||
assert(!isnan(v.getX()));
|
assert(!isnan(v.getX()));
|
||||||
@ -429,9 +449,11 @@ void Flyable::update(float dt)
|
|||||||
} // if m_adjust_up_velocity
|
} // if m_adjust_up_velocity
|
||||||
|
|
||||||
Moveable::update(dt);
|
Moveable::update(dt);
|
||||||
} // update
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
return false;
|
||||||
|
} // updateAmdDelete
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
/** Updates the position of a projectile based on information received frmo the
|
/** Updates the position of a projectile based on information received frmo the
|
||||||
* server.
|
* server.
|
||||||
*/
|
*/
|
||||||
@ -445,7 +467,7 @@ void Flyable::updateFromServer(const FlyableInfo &f, float dt)
|
|||||||
Moveable::update(dt);
|
Moveable::update(dt);
|
||||||
} // updateFromServer
|
} // updateFromServer
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Returns true if the item hit the kart who shot it (to avoid that an item
|
/** Returns true if the item hit the kart who shot it (to avoid that an item
|
||||||
* that's too close to the shoter hits the shoter).
|
* that's too close to the shoter hits the shoter).
|
||||||
* \param kart Kart who was hit.
|
* \param kart Kart who was hit.
|
||||||
@ -457,8 +479,8 @@ bool Flyable::isOwnerImmunity(const Kart* kart_hit) const
|
|||||||
m_time_since_thrown < 2.0f;
|
m_time_since_thrown < 2.0f;
|
||||||
} // isOwnerImmunity
|
} // isOwnerImmunity
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Callback from the phycis in case that a kart or object is hit.
|
/** Callback from the phycis in case that a kart or physical object is hit.
|
||||||
* kart The kart hit (NULL if no kart was hit).
|
* kart The kart hit (NULL if no kart was hit).
|
||||||
* object The object that was hit (NULL if none).
|
* object The object that was hit (NULL if none).
|
||||||
*/
|
*/
|
||||||
@ -475,10 +497,11 @@ void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
|
|||||||
{
|
{
|
||||||
case PowerupManager::POWERUP_CAKE:
|
case PowerupManager::POWERUP_CAKE:
|
||||||
{
|
{
|
||||||
hit_message += StringUtils::insertValues(getCakeString(),
|
hit_message =
|
||||||
core::stringw(kart_hit->getName()),
|
StringUtils::insertValues(getCakeString(),
|
||||||
core::stringw(m_owner->getName())
|
core::stringw(kart_hit->getName()),
|
||||||
).c_str();
|
core::stringw(m_owner->getName())
|
||||||
|
).c_str();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PowerupManager::POWERUP_PLUNGER:
|
case PowerupManager::POWERUP_PLUNGER:
|
||||||
@ -490,16 +513,18 @@ void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
|
|||||||
{
|
{
|
||||||
if (kart_hit == m_owner)
|
if (kart_hit == m_owner)
|
||||||
{
|
{
|
||||||
hit_message += StringUtils::insertValues(getSelfBowlingString(),
|
hit_message =
|
||||||
core::stringw(m_owner->getName())
|
StringUtils::insertValues(getSelfBowlingString(),
|
||||||
).c_str();
|
core::stringw(m_owner->getName())
|
||||||
|
).c_str();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hit_message += StringUtils::insertValues(getBowlingString(),
|
hit_message =
|
||||||
core::stringw(kart_hit->getName()),
|
StringUtils::insertValues(getBowlingString(),
|
||||||
core::stringw(m_owner->getName())
|
core::stringw(kart_hit->getName()),
|
||||||
).c_str();
|
core::stringw(m_owner->getName())
|
||||||
|
).c_str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -507,18 +532,29 @@ void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
|
|||||||
printf("Failed message for %i\n", m_type);
|
printf("Failed message for %i\n", m_type);
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
gui->addMessage(translations->fribidize(hit_message), NULL, 3.0f, 40, video::SColor(255, 255, 255, 255), false);
|
gui->addMessage(translations->fribidize(hit_message), NULL, 3.0f, 40,
|
||||||
|
video::SColor(255, 255, 255, 255), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_has_hit_something=true;
|
m_has_hit_something=true;
|
||||||
// Notify the projectile manager that this rocket has hit something.
|
// Notify the projectile manager that this rocket has hit something.
|
||||||
// The manager will create the appropriate explosion object.
|
// The manager will create the appropriate explosion object.
|
||||||
projectile_manager->notifyRemove();
|
|
||||||
|
|
||||||
m_exploded=true;
|
m_exploded=true;
|
||||||
|
|
||||||
if(!needsExplosion()) return;
|
if(needsExplosion())
|
||||||
|
explode(kart_hit, object);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
} // hit
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Creates the explosion physical effect, i.e. pushes the karts and ph
|
||||||
|
* appropriately. The corresponding visual/sfx needs to be added manually!
|
||||||
|
*/
|
||||||
|
void Flyable::explode(Kart *kart_hit, PhysicalObject *object)
|
||||||
|
{
|
||||||
// Apply explosion effect
|
// Apply explosion effect
|
||||||
// ----------------------
|
// ----------------------
|
||||||
World *world = World::getWorld();
|
World *world = World::getWorld();
|
||||||
|
@ -154,11 +154,12 @@ public:
|
|||||||
virtual ~Flyable ();
|
virtual ~Flyable ();
|
||||||
static void init (const XMLNode &node, scene::IMesh *model,
|
static void init (const XMLNode &node, scene::IMesh *model,
|
||||||
PowerupManager::PowerupType type);
|
PowerupManager::PowerupType type);
|
||||||
virtual void update (float);
|
virtual bool updateAndDelete(float);
|
||||||
|
virtual HitEffect *getHitEffect() const;
|
||||||
void updateFromServer(const FlyableInfo &f, float dt);
|
void updateFromServer(const FlyableInfo &f, float dt);
|
||||||
HitEffect *getHitEffect() const;
|
|
||||||
bool isOwnerImmunity(const Kart *kart_hit) const;
|
bool isOwnerImmunity(const Kart *kart_hit) const;
|
||||||
|
virtual void 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
|
/** If true the up velocity of the flyable will be adjust so that the
|
||||||
* flyable stays at a height close to the average height.
|
* flyable stays at a height close to the average height.
|
||||||
@ -173,11 +174,6 @@ public:
|
|||||||
/** Called when this flyable hits the track. */
|
/** Called when this flyable hits the track. */
|
||||||
virtual void hitTrack () {};
|
virtual void hitTrack () {};
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Called when this flyable hit a kart or physical object.
|
|
||||||
* \param kart Pointer to the kart hit (NULL if no kart was hit).
|
|
||||||
* \param obj Pointer to the object hit (NULL if no object was hit). */
|
|
||||||
virtual void hit (Kart* kart, PhysicalObject* obj=NULL);
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
/** Enables/disables adjusting ov velocity depending on height above
|
/** Enables/disables adjusting ov velocity depending on height above
|
||||||
* terrain. Missiles can 'follow the terrain' with this adjustment,
|
* terrain. Missiles can 'follow the terrain' with this adjustment,
|
||||||
* but gravity will basically be disabled. */
|
* but gravity will basically be disabled. */
|
||||||
@ -197,9 +193,8 @@ public:
|
|||||||
/** Returns the sfx that should be played in case of an explosion. */
|
/** Returns the sfx that should be played in case of an explosion. */
|
||||||
virtual const char* getExplosionSound() const { return "explosion"; }
|
virtual const char* getExplosionSound() const { return "explosion"; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Indicates if an explosion needs to be added if this flyable
|
/** Default is that each flyable needs an explosion effect. */
|
||||||
* is removed. */
|
virtual bool needsExplosion() const { return true; }
|
||||||
virtual bool needsExplosion() const {return true;}
|
|
||||||
}; // Flyable
|
}; // Flyable
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -118,21 +118,21 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_PLUNGER)
|
|||||||
m_keep_alive = -1;
|
m_keep_alive = -1;
|
||||||
} // Plunger
|
} // Plunger
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
Plunger::~Plunger()
|
Plunger::~Plunger()
|
||||||
{
|
{
|
||||||
if(m_rubber_band)
|
if(m_rubber_band)
|
||||||
delete m_rubber_band;
|
delete m_rubber_band;
|
||||||
} // ~Plunger
|
} // ~Plunger
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void Plunger::init(const XMLNode &node, scene::IMesh *plunger_model)
|
void Plunger::init(const XMLNode &node, scene::IMesh *plunger_model)
|
||||||
{
|
{
|
||||||
Flyable::init(node, plunger_model, PowerupManager::POWERUP_PLUNGER);
|
Flyable::init(node, plunger_model, PowerupManager::POWERUP_PLUNGER);
|
||||||
} // init
|
} // init
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void Plunger::update(float dt)
|
bool Plunger::updateAndDelete(float dt)
|
||||||
{
|
{
|
||||||
// In keep-alive mode, just update the rubber band
|
// In keep-alive mode, just update the rubber band
|
||||||
if(m_keep_alive >= 0)
|
if(m_keep_alive >= 0)
|
||||||
@ -141,18 +141,19 @@ void Plunger::update(float dt)
|
|||||||
if(m_keep_alive<=0)
|
if(m_keep_alive<=0)
|
||||||
{
|
{
|
||||||
setHasHit();
|
setHasHit();
|
||||||
projectile_manager->notifyRemove();
|
return true;
|
||||||
}
|
}
|
||||||
if(m_rubber_band != NULL) m_rubber_band->update(dt);
|
if(m_rubber_band != NULL) m_rubber_band->update(dt);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else: update the flyable and rubber band
|
// Else: update the flyable and rubber band
|
||||||
Flyable::update(dt);
|
bool ret = Flyable::updateAndDelete(dt);
|
||||||
if(m_rubber_band != NULL) m_rubber_band->update(dt);
|
if(m_rubber_band != NULL) m_rubber_band->update(dt);
|
||||||
|
|
||||||
if(getHoT()==Track::NOHIT) return;
|
return ret;
|
||||||
} // update
|
|
||||||
|
} // updateAndDelete
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
/** Virtual function called when the plunger hits something.
|
/** Virtual function called when the plunger hits something.
|
||||||
|
@ -47,16 +47,21 @@ public:
|
|||||||
Plunger(Kart *kart);
|
Plunger(Kart *kart);
|
||||||
~Plunger();
|
~Plunger();
|
||||||
static void init(const XMLNode &node, scene::IMesh* missile);
|
static void init(const XMLNode &node, scene::IMesh* missile);
|
||||||
|
virtual bool updateAndDelete(float dt);
|
||||||
|
virtual void hitTrack ();
|
||||||
|
virtual void hit (Kart *kart, PhysicalObject *obj=NULL);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** Sets the keep-alive value. Setting it to 0 will remove the plunger
|
/** Sets the keep-alive value. Setting it to 0 will remove the plunger
|
||||||
* at the next update - which is used if the rubber band snaps.
|
* at the next update - which is used if the rubber band snaps.
|
||||||
*/
|
*/
|
||||||
void setKeepAlive(float t) {m_keep_alive = t;}
|
void setKeepAlive(float t) {m_keep_alive = t;}
|
||||||
virtual void update (float dt);
|
// ------------------------------------------------------------------------
|
||||||
virtual void hitTrack ();
|
/** No hit effect when it ends. */
|
||||||
virtual void hit (Kart *kart, PhysicalObject *obj=NULL);
|
virtual HitEffect *getHitEffect() const {return NULL; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** A plunger does not explode if it is removed. */
|
/** Plunger does not need an explosion effect. */
|
||||||
virtual bool needsExplosion() const {return false;}
|
virtual bool needsExplosion() const { return false; }
|
||||||
}; // Plunger
|
}; // Plunger
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -76,30 +76,11 @@ void ProjectileManager::update(float dt)
|
|||||||
updateServer(dt);
|
updateServer(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then check if any projectile hit something
|
|
||||||
if(m_something_was_hit)
|
|
||||||
{
|
|
||||||
Projectiles::iterator p = m_active_projectiles.begin();
|
|
||||||
while(p!=m_active_projectiles.end())
|
|
||||||
{
|
|
||||||
if(! (*p)->hasHit()) { p++; continue; }
|
|
||||||
if((*p)->needsExplosion())
|
|
||||||
{
|
|
||||||
HitEffect *he = (*p)->getHitEffect();
|
|
||||||
addHitEffect(he);
|
|
||||||
}
|
|
||||||
Flyable *f=*p;
|
|
||||||
Projectiles::iterator pNext=m_active_projectiles.erase(p); // returns the next element
|
|
||||||
delete f;
|
|
||||||
p=pNext;
|
|
||||||
} // while p!=m_active_projectiles.end()
|
|
||||||
}
|
|
||||||
|
|
||||||
HitEffects::iterator he = m_active_hit_effects.begin();
|
HitEffects::iterator he = m_active_hit_effects.begin();
|
||||||
while(he!=m_active_hit_effects.end())
|
while(he!=m_active_hit_effects.end())
|
||||||
{
|
{
|
||||||
// Update this hit effect. If it can be removed, remove it.
|
// Update this hit effect. If it can be removed, remove it.
|
||||||
if((*he)->update(dt))
|
if((*he)->updateAndDelete(dt))
|
||||||
{
|
{
|
||||||
delete *he;
|
delete *he;
|
||||||
HitEffects::iterator next = m_active_hit_effects.erase(he);
|
HitEffects::iterator next = m_active_hit_effects.erase(he);
|
||||||
@ -119,19 +100,31 @@ void ProjectileManager::updateServer(float dt)
|
|||||||
{
|
{
|
||||||
race_state->setNumFlyables(m_active_projectiles.size());
|
race_state->setNumFlyables(m_active_projectiles.size());
|
||||||
}
|
}
|
||||||
for(Projectiles::iterator i = m_active_projectiles.begin();
|
|
||||||
i != m_active_projectiles.end(); ++i)
|
Projectiles::iterator p = m_active_projectiles.begin();
|
||||||
|
while(p!=m_active_projectiles.end())
|
||||||
{
|
{
|
||||||
(*i)->update(dt);
|
bool can_be_deleted = (*p)->updateAndDelete(dt);
|
||||||
// Store the state information on the server
|
|
||||||
if(network_manager->getMode()!=NetworkManager::NW_NONE)
|
if(network_manager->getMode()!=NetworkManager::NW_NONE)
|
||||||
{
|
{
|
||||||
race_state->setFlyableInfo(i-m_active_projectiles.begin(),
|
race_state->setFlyableInfo(p-m_active_projectiles.begin(),
|
||||||
FlyableInfo((*i)->getXYZ(),
|
FlyableInfo((*p)->getXYZ(),
|
||||||
(*i)->getRotation(),
|
(*p)->getRotation(),
|
||||||
(*i)->hasHit()) );
|
can_be_deleted) );
|
||||||
}
|
}
|
||||||
}
|
if(can_be_deleted)
|
||||||
|
{
|
||||||
|
HitEffect *he = (*p)->getHitEffect();
|
||||||
|
if(he)
|
||||||
|
addHitEffect(he);
|
||||||
|
Flyable *f=*p;
|
||||||
|
Projectiles::iterator p_next=m_active_projectiles.erase(p);
|
||||||
|
delete f;
|
||||||
|
p=p_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p++;
|
||||||
|
} // while p!=m_active_projectiles.end()
|
||||||
} // updateServer
|
} // updateServer
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -140,7 +133,6 @@ void ProjectileManager::updateServer(float dt)
|
|||||||
* (i.e. position, hit effects etc) */
|
* (i.e. position, hit effects etc) */
|
||||||
void ProjectileManager::updateClient(float dt)
|
void ProjectileManager::updateClient(float dt)
|
||||||
{
|
{
|
||||||
m_something_was_hit = false;
|
|
||||||
unsigned int num_projectiles = race_state->getNumFlyables();
|
unsigned int num_projectiles = race_state->getNumFlyables();
|
||||||
if(num_projectiles != m_active_projectiles.size())
|
if(num_projectiles != m_active_projectiles.size())
|
||||||
fprintf(stderr, "Warning: num_projectiles %d active %d\n",num_projectiles,
|
fprintf(stderr, "Warning: num_projectiles %d active %d\n",num_projectiles,
|
||||||
@ -154,7 +146,6 @@ void ProjectileManager::updateClient(float dt)
|
|||||||
(*i)->updateFromServer(f, dt);
|
(*i)->updateFromServer(f, dt);
|
||||||
if(f.m_exploded)
|
if(f.m_exploded)
|
||||||
{
|
{
|
||||||
m_something_was_hit = true;
|
|
||||||
(*i)->hit(NULL);
|
(*i)->hit(NULL);
|
||||||
}
|
}
|
||||||
} // for i in m_active_projectiles
|
} // for i in m_active_projectiles
|
||||||
|
@ -53,14 +53,11 @@ private:
|
|||||||
* being shown or have a sfx playing. */
|
* being shown or have a sfx playing. */
|
||||||
HitEffects m_active_hit_effects;
|
HitEffects m_active_hit_effects;
|
||||||
|
|
||||||
bool m_something_was_hit;
|
|
||||||
void updateClient(float dt);
|
void updateClient(float dt);
|
||||||
void updateServer(float dt);
|
void updateServer(float dt);
|
||||||
public:
|
public:
|
||||||
ProjectileManager() {m_something_was_hit=false;}
|
ProjectileManager() {}
|
||||||
~ProjectileManager() {}
|
~ProjectileManager() {}
|
||||||
/** Notifies the projectile manager that something needs to be removed. */
|
|
||||||
void notifyRemove () {m_something_was_hit=true; }
|
|
||||||
void loadData ();
|
void loadData ();
|
||||||
void cleanup ();
|
void cleanup ();
|
||||||
void update (float dt);
|
void update (float dt);
|
||||||
|
@ -214,13 +214,15 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *bowling)
|
|||||||
Flyable::init(node, bowling, PowerupManager::POWERUP_RUBBERBALL);
|
Flyable::init(node, bowling, PowerupManager::POWERUP_RUBBERBALL);
|
||||||
} // init
|
} // init
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Updates the rubber ball.
|
/** Updates the rubber ball.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
|
* \returns True if the rubber ball should be removed.
|
||||||
*/
|
*/
|
||||||
void RubberBall::update(float dt)
|
bool RubberBall::updateAndDelete(float dt)
|
||||||
{
|
{
|
||||||
Flyable::update(dt);
|
if(Flyable::updateAndDelete(dt))
|
||||||
|
return true;
|
||||||
|
|
||||||
// Update the target in case that the first kart was overtaken (or has
|
// Update the target in case that the first kart was overtaken (or has
|
||||||
// finished the race).
|
// finished the race).
|
||||||
@ -229,7 +231,7 @@ void RubberBall::update(float dt)
|
|||||||
if(!m_target) // Remove this item from the game
|
if(!m_target) // Remove this item from the game
|
||||||
{
|
{
|
||||||
hit(NULL);
|
hit(NULL);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDistanceToTarget();
|
checkDistanceToTarget();
|
||||||
@ -271,7 +273,9 @@ void RubberBall::update(float dt)
|
|||||||
m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));
|
m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
setXYZ(next_xyz);
|
setXYZ(next_xyz);
|
||||||
} // update
|
|
||||||
|
return false;
|
||||||
|
} // updateAndDelete
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Uses Hermite splines (Catmull-Rom) to interpolate the position of the
|
/** Uses Hermite splines (Catmull-Rom) to interpolate the position of the
|
||||||
@ -430,7 +434,6 @@ void RubberBall::hit(Kart* kart, PhysicalObject* object)
|
|||||||
{
|
{
|
||||||
// Else trigger the full explosion animation
|
// Else trigger the full explosion animation
|
||||||
kart->handleExplosion(kart->getXYZ(), /*direct hit*/true);
|
kart->handleExplosion(kart->getXYZ(), /*direct hit*/true);
|
||||||
projectile_manager->notifyRemove();
|
|
||||||
setHasHit();
|
setHasHit();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -125,11 +125,15 @@ public:
|
|||||||
RubberBall (Kart* kart);
|
RubberBall (Kart* kart);
|
||||||
virtual ~RubberBall();
|
virtual ~RubberBall();
|
||||||
static void init(const XMLNode &node, scene::IMesh *bowling);
|
static void init(const XMLNode &node, scene::IMesh *bowling);
|
||||||
virtual void update (float dt);
|
virtual bool updateAndDelete(float dt);
|
||||||
virtual void hit (Kart* kart, PhysicalObject* obj=NULL);
|
virtual void hit (Kart* kart, PhysicalObject* obj=NULL);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** This object does not create an explosion, all affects on
|
/** This object does not create an explosion, all affects on
|
||||||
* karts are handled by this hit() function. */
|
* karts are handled by this hit() function. */
|
||||||
virtual bool needsExplosion() const {return false;}
|
virtual HitEffect *getHitEffect() const {return NULL; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Plunger does not need an explosion effect. */
|
||||||
|
virtual bool needsExplosion() const { return false; }
|
||||||
|
|
||||||
}; // RubberBall
|
}; // RubberBall
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user