Fix plunger in network
This commit is contained in:
@@ -593,6 +593,18 @@ unsigned int Flyable::getOwnerId()
|
||||
return m_owner->getWorldKartId();
|
||||
} // getOwnerId
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Flyable::moveToInfinity()
|
||||
{
|
||||
const Vec3 *min, *max;
|
||||
Track::getCurrentTrack()->getAABB(&min, &max);
|
||||
btTransform t = m_body->getWorldTransform();
|
||||
t.setOrigin(*max * 2.0f);
|
||||
m_body->setWorldTransform(t);
|
||||
m_motion_state->setWorldTransform(t);
|
||||
m_body->setInterpolationWorldTransform(t);
|
||||
} // moveToInfinity
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
BareNetworkString* Flyable::saveState(std::vector<std::string>* ru)
|
||||
{
|
||||
@@ -651,15 +663,8 @@ void Flyable::addRewindInfoEventFunctionAfterFiring()
|
||||
/*undo_function*/[f]()
|
||||
{
|
||||
f->m_undo_creation = true;
|
||||
const Vec3 *min, *max;
|
||||
Track::getCurrentTrack()->getAABB(&min, &max);
|
||||
btTransform t = f->m_body->getWorldTransform();
|
||||
// Move it to (almost infinity), avoiding affecting current
|
||||
// rewinding
|
||||
t.setOrigin(*max * 2.0f);
|
||||
f->m_body->setWorldTransform(t);
|
||||
f->m_motion_state->setWorldTransform(t);
|
||||
f->m_body->setInterpolationWorldTransform(t);
|
||||
// Move it to infinity, avoiding affecting current rewinding
|
||||
f->moveToInfinity();
|
||||
f->m_body->setGravity(Vec3(0.0f));
|
||||
},
|
||||
/*replay_function*/[f]()
|
||||
@@ -683,6 +688,14 @@ void Flyable::addRewindInfoEventFunctionAfterFiring()
|
||||
}));
|
||||
} // addRewindInfoEventFunctionAfterFiring
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Flyable::hideNodeWhenUndoDestruction()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
m_node->setVisible(false);
|
||||
#endif
|
||||
} // hideNodeWhenUndoDestruction
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Flyable::handleUndoDestruction()
|
||||
{
|
||||
@@ -699,7 +712,7 @@ void Flyable::handleUndoDestruction()
|
||||
return;
|
||||
|
||||
// We don't bother seeing the mesh during rewinding
|
||||
m_node->setVisible(false);
|
||||
hideNodeWhenUndoDestruction();
|
||||
std::shared_ptr<Flyable> f = getShared<Flyable>();
|
||||
std::string uid = f->getUniqueIdentity();
|
||||
RewindManager::get()->addRewindInfoEventFunction(new
|
||||
|
||||
@@ -168,11 +168,13 @@ protected:
|
||||
const bool turn_around=false,
|
||||
const btTransform* customDirection=NULL);
|
||||
|
||||
void moveToInfinity();
|
||||
/** Used when undoing creation or destruction. */
|
||||
btTransform m_saved_transform;
|
||||
Vec3 m_saved_lv, m_saved_av, m_saved_gravity;
|
||||
|
||||
virtual void additionalPhysicsProperties() {}
|
||||
virtual void hideNodeWhenUndoDestruction();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
Plunger::Plunger(AbstractKart *kart)
|
||||
: Flyable(kart, PowerupManager::POWERUP_PLUNGER)
|
||||
{
|
||||
m_has_locally_played_sound = false;
|
||||
m_moved_to_infinity = false;
|
||||
const float gravity = 0.0f;
|
||||
|
||||
setDoTerrainInfo(false);
|
||||
@@ -117,7 +119,15 @@ void Plunger::init(const XMLNode &node, scene::IMesh *plunger_model)
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates the bowling ball ineach frame. If this function returns true, the
|
||||
void Plunger::updateGraphics(float dt)
|
||||
{
|
||||
Flyable::updateGraphics(dt);
|
||||
if (m_rubber_band)
|
||||
m_rubber_band->updateGraphics(dt);
|
||||
} // updateGraphics
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates the plunger in each 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.
|
||||
@@ -157,7 +167,7 @@ bool Plunger::updateAndDelete(int ticks)
|
||||
*/
|
||||
bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
||||
{
|
||||
if(isOwnerImmunity(kart)) return false;
|
||||
if (isOwnerImmunity(kart) || m_moved_to_infinity) return false;
|
||||
|
||||
// pulling back makes no sense in battle mode, since this mode is not a race.
|
||||
// so in battle mode, always hide view
|
||||
@@ -166,8 +176,12 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
||||
if(kart)
|
||||
{
|
||||
kart->blockViewWithPlunger();
|
||||
if (kart->getController()->isLocalPlayerController())
|
||||
if (kart->getController()->isLocalPlayerController() &&
|
||||
!m_has_locally_played_sound)
|
||||
{
|
||||
m_has_locally_played_sound = true;
|
||||
SFXManager::get()->quickSound("plunger");
|
||||
}
|
||||
}
|
||||
|
||||
m_keep_alive = 0;
|
||||
@@ -175,13 +189,16 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
||||
#ifndef SERVER_ONLY
|
||||
getNode()->setVisible(false);
|
||||
#endif
|
||||
Physics::getInstance()->removeBody(getBody());
|
||||
// Previously removeBody will break rewind
|
||||
moveToInfinity();
|
||||
m_moved_to_infinity = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keep_alive = stk_config->time2Ticks(m_owner->getKartProperties()
|
||||
->getPlungerBandDuration() );
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
// Make this object invisible by placing it faaar down. Not that if
|
||||
// this objects is simply removed from the scene graph, it might be
|
||||
// auto-deleted because the ref count reaches zero.
|
||||
@@ -190,7 +207,10 @@ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj)
|
||||
{
|
||||
node->setVisible(false);
|
||||
}
|
||||
Physics::getInstance()->removeBody(getBody());
|
||||
#endif
|
||||
// Previously removeBody will break rewind
|
||||
moveToInfinity();
|
||||
m_moved_to_infinity = true;
|
||||
|
||||
if(kart)
|
||||
{
|
||||
@@ -221,4 +241,33 @@ void Plunger::hitTrack()
|
||||
hit(NULL, NULL);
|
||||
} // hitTrack
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
void Plunger::hideNodeWhenUndoDestruction()
|
||||
{
|
||||
Flyable::hideNodeWhenUndoDestruction();
|
||||
if (m_rubber_band)
|
||||
m_rubber_band->remove();
|
||||
} // hideNodeWhenUndoDestruction
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
BareNetworkString* Plunger::saveState(std::vector<std::string>* ru)
|
||||
{
|
||||
BareNetworkString* buffer = Flyable::saveState(ru);
|
||||
buffer->addUInt16(m_keep_alive).addUInt8(m_moved_to_infinity ? 1 : 0);
|
||||
if (m_rubber_band)
|
||||
buffer->addUInt8(m_rubber_band->getRubberBandTo());
|
||||
else
|
||||
buffer->addUInt8(255);
|
||||
return buffer;
|
||||
} // saveState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Plunger::restoreState(BareNetworkString *buffer, int count)
|
||||
{
|
||||
Flyable::restoreState(buffer, count);
|
||||
m_keep_alive = buffer->getUInt16();
|
||||
m_moved_to_infinity = buffer->getUInt8() == 1;
|
||||
int8_t rbt = buffer->getUInt8();
|
||||
if (rbt != -1 && m_rubber_band)
|
||||
m_rubber_band->setRubberBandTo((RubberBand::RubberBandTo)rbt);
|
||||
} // restoreState
|
||||
|
||||
@@ -42,14 +42,14 @@ private:
|
||||
RubberBand *m_rubber_band;
|
||||
|
||||
/** Ticks to keep the plunger alive while the rubber band is working. */
|
||||
int m_keep_alive;
|
||||
int16_t m_keep_alive;
|
||||
|
||||
btVector3 m_initial_velocity;
|
||||
|
||||
bool m_reverse_mode;
|
||||
bool m_reverse_mode, m_has_locally_played_sound, m_moved_to_infinity;
|
||||
|
||||
virtual void additionalPhysicsProperties() OVERRIDE { m_keep_alive = -1; }
|
||||
|
||||
virtual void hideNodeWhenUndoDestruction() OVERRIDE;
|
||||
public:
|
||||
Plunger(AbstractKart *kart);
|
||||
~Plunger();
|
||||
@@ -58,16 +58,22 @@ public:
|
||||
virtual void hitTrack () OVERRIDE;
|
||||
virtual bool hit (AbstractKart *kart, PhysicalObject *obj=NULL)
|
||||
OVERRIDE;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void updateGraphics(float dt) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** 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.
|
||||
*/
|
||||
void setKeepAlive(int ticks) {m_keep_alive = ticks;}
|
||||
void setKeepAlive(int16_t ticks) { m_keep_alive = ticks; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** No hit effect when it ends. */
|
||||
virtual HitEffect *getHitEffect() const OVERRIDE { return NULL; }
|
||||
virtual HitEffect *getHitEffect() const OVERRIDE { return NULL; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
||||
OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE;
|
||||
|
||||
}; // Plunger
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,8 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
||||
: m_plunger(plunger), m_owner(kart)
|
||||
{
|
||||
m_attached_state = RB_TO_PLUNGER;
|
||||
updatePosition();
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
if (ProfileWorld::isNoGraphics() || !CVS->isGLSL())
|
||||
{
|
||||
@@ -68,7 +70,6 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
||||
{
|
||||
m_dy_dc->getSPMVertex()[i].m_color = color;
|
||||
}
|
||||
updatePosition();
|
||||
SP::addDynamicDrawCall(m_dy_dc);
|
||||
#endif
|
||||
} // RubberBand
|
||||
@@ -76,12 +77,7 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
||||
// ----------------------------------------------------------------------------
|
||||
RubberBand::~RubberBand()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_dy_dc)
|
||||
{
|
||||
m_dy_dc->removeFromSP();
|
||||
}
|
||||
#endif
|
||||
remove();
|
||||
} // RubberBand
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -102,16 +98,22 @@ void RubberBand::updatePosition()
|
||||
case RB_TO_PLUNGER: m_end_position = m_plunger->getXYZ();
|
||||
checkForHit(k, m_end_position); break;
|
||||
} // switch(m_attached_state);
|
||||
} // updatePosition
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void RubberBand::updateGraphics(float dt)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (!m_dy_dc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the rubber band positions
|
||||
// --------------------------------
|
||||
// Todo: make height dependent on length (i.e. rubber band gets
|
||||
// thinner). And call explosion if the band is too long.
|
||||
const Vec3 &k = m_owner->getXYZ();
|
||||
const float hh=.1f; // half height of the band
|
||||
const Vec3 &p=m_end_position; // for shorter typing
|
||||
auto& v = m_dy_dc->getVerticesVector();
|
||||
@@ -137,7 +139,7 @@ void RubberBand::updatePosition()
|
||||
m_dy_dc->setUpdateOffset(0);
|
||||
m_dy_dc->recalculateBoundingBox();
|
||||
#endif
|
||||
} // updatePosition
|
||||
} // updateGraphics
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates the rubber band. It takes the new position of the kart and the
|
||||
@@ -277,3 +279,13 @@ void RubberBand::hit(AbstractKart *kart_hit, const Vec3 *track_xyz)
|
||||
} // hit
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void RubberBand::remove()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_dy_dc)
|
||||
{
|
||||
m_dy_dc->removeFromSP();
|
||||
m_dy_dc = nullptr;
|
||||
}
|
||||
#endif
|
||||
} // remove
|
||||
|
||||
@@ -38,12 +38,14 @@ class Plunger;
|
||||
*/
|
||||
class RubberBand : public NoCopy
|
||||
{
|
||||
public:
|
||||
enum RubberBandTo : uint8_t
|
||||
{
|
||||
RB_TO_PLUNGER = 0, /**< Rubber band is attached to plunger. */
|
||||
RB_TO_KART, /**< Rubber band is attached to a kart hit. */
|
||||
RB_TO_TRACK /**< Rubber band is attached to track. */
|
||||
};
|
||||
private:
|
||||
enum {RB_TO_PLUNGER, /**< Rubber band is attached to plunger. */
|
||||
RB_TO_KART, /**< Rubber band is attached to a kart hit. */
|
||||
RB_TO_TRACK} /**< Rubber band is attached to track. */
|
||||
m_attached_state;
|
||||
|
||||
/** If rubber band is attached to track, the coordinates. */
|
||||
Vec3 m_hit_position;
|
||||
/** The plunger the rubber band is attached to. */
|
||||
@@ -51,6 +53,8 @@ private:
|
||||
/** The kart who shot this plunger. */
|
||||
AbstractKart *m_owner;
|
||||
|
||||
RubberBandTo m_attached_state;
|
||||
|
||||
/** The dynamic draw call of the rubber band. */
|
||||
std::shared_ptr<SP::SPDynamicDrawCall> m_dy_dc;
|
||||
|
||||
@@ -66,7 +70,11 @@ private:
|
||||
public:
|
||||
RubberBand(Plunger *plunger, AbstractKart *kart);
|
||||
~RubberBand();
|
||||
void updateGraphics(float dt);
|
||||
void update(int ticks);
|
||||
void hit(AbstractKart *kart_hit, const Vec3 *track_xyz=NULL);
|
||||
RubberBandTo getRubberBandTo() const { return m_attached_state; }
|
||||
void setRubberBandTo(RubberBandTo rbt) { m_attached_state = rbt; }
|
||||
void remove();
|
||||
}; // RubberBand
|
||||
#endif
|
||||
|
||||
@@ -176,6 +176,8 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
|
||||
// Don't restore to phyics position if showing kart animation
|
||||
if (!getKartAnimation())
|
||||
{
|
||||
// Clear any forces applied (like by plunger or bubble gum torque)
|
||||
body->clearForces();
|
||||
body->setLinearVelocity(lv);
|
||||
body->setAngularVelocity(av);
|
||||
// This function also reads the velocity, so it must be called
|
||||
|
||||
Reference in New Issue
Block a user