Fix plunger in network

This commit is contained in:
Benau
2018-07-28 16:02:46 +08:00
parent fa4c640dae
commit 3f27a04bd1
7 changed files with 127 additions and 35 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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