Add initial kart local state saving with correct attachment rewind
This commit is contained in:
parent
8515805d52
commit
11d9090039
@ -148,11 +148,6 @@ void Attachment::set(AttachmentType type, int ticks,
|
||||
case ATTACH_BOMB:
|
||||
m_node->setMesh(attachment_manager->getMesh(type));
|
||||
m_node->setAnimationSpeed(0);
|
||||
if (m_bomb_sound) m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = SFXManager::get()->createSoundSource("clock");
|
||||
m_bomb_sound->setLoop(true);
|
||||
m_bomb_sound->setPosition(m_kart->getXYZ());
|
||||
m_bomb_sound->play();
|
||||
break;
|
||||
default:
|
||||
m_node->setMesh(attachment_manager->getMesh(type));
|
||||
@ -229,23 +224,12 @@ void Attachment::clear()
|
||||
m_plugin = NULL;
|
||||
}
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
|
||||
m_type=ATTACH_NOTHING;
|
||||
|
||||
m_ticks_left = 0;
|
||||
m_node->setVisible(false);
|
||||
m_node->setPosition(core::vector3df());
|
||||
m_node->setRotation(core::vector3df());
|
||||
|
||||
// Resets the weight of the kart if the previous attachment affected it
|
||||
// (e.g. anvil). This must be done *after* setting m_type to
|
||||
// ATTACH_NOTHING in order to reset the physics parameters.
|
||||
m_kart->updateWeight();
|
||||
} // clear
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -300,14 +284,19 @@ void Attachment::rewindTo(BareNetworkString *buffer)
|
||||
|
||||
// Attaching an object can be expensive (loading new models, ...)
|
||||
// so avoid doing this if there is no change in attachment type
|
||||
if(new_type == m_type)
|
||||
// Don't use set to reset a model on local player if it's already cleared
|
||||
// (or m_initial_speed is redone / model is re-shown again when rewinding)
|
||||
if (m_type == new_type || m_type == ATTACH_NOTHING)
|
||||
{
|
||||
setTicksLeft(ticks_left);
|
||||
if (m_type != new_type)
|
||||
m_type = new_type;
|
||||
return;
|
||||
}
|
||||
|
||||
set(new_type, ticks_left, m_previous_owner);
|
||||
} // rewindTo
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Called when going forwards in time during a rewind.
|
||||
* \param buffer Buffer with the rewind information.
|
||||
@ -421,7 +410,6 @@ void Attachment::hitBanana(ItemState *item_state)
|
||||
// Reduce speed once (see description above), all other changes are
|
||||
// handled in Kart::updatePhysics
|
||||
m_kart->adjustSpeed(kp->getAnvilSpeedFactor());
|
||||
m_kart->updateWeight();
|
||||
break;
|
||||
case ATTACH_BOMB:
|
||||
set( ATTACH_BOMB, stk_config->time2Ticks(stk_config->m_bomb_time)
|
||||
@ -511,12 +499,10 @@ void Attachment::update(int ticks)
|
||||
|
||||
m_ticks_left -= ticks;
|
||||
|
||||
|
||||
bool is_shield = m_type == ATTACH_BUBBLEGUM_SHIELD ||
|
||||
m_type == ATTACH_NOLOK_BUBBLEGUM_SHIELD;
|
||||
float m_wanted_node_scale = is_shield
|
||||
? std::max(1.0f, m_kart->getHighestPoint()*1.1f)
|
||||
: 1.0f;
|
||||
float wanted_node_scale = is_shield ?
|
||||
std::max(1.0f, m_kart->getHighestPoint() * 1.1f) : 1.0f;
|
||||
int slow_flashes = stk_config->time2Ticks(3.0f);
|
||||
if (is_shield && m_ticks_left < slow_flashes)
|
||||
{
|
||||
@ -533,11 +519,11 @@ void Attachment::update(int ticks)
|
||||
}
|
||||
|
||||
float dt = stk_config->ticks2Time(ticks);
|
||||
if (m_node_scale < m_wanted_node_scale)
|
||||
if (m_node_scale < wanted_node_scale)
|
||||
{
|
||||
m_node_scale += dt*1.5f;
|
||||
if (m_node_scale > m_wanted_node_scale)
|
||||
m_node_scale = m_wanted_node_scale;
|
||||
if (m_node_scale > wanted_node_scale)
|
||||
m_node_scale = wanted_node_scale;
|
||||
m_node->setScale(core::vector3df(m_node_scale,m_node_scale,
|
||||
m_node_scale) );
|
||||
}
|
||||
@ -590,8 +576,6 @@ void Attachment::update(int ticks)
|
||||
break;
|
||||
case ATTACH_BOMB:
|
||||
{
|
||||
if (m_bomb_sound) m_bomb_sound->setPosition(m_kart->getXYZ());
|
||||
|
||||
// Mesh animation frames are 1 to 61 frames (60 steps)
|
||||
// The idea is change second by second, counterclockwise 60 to 0 secs
|
||||
// If longer times needed, it should be a surprise "oh! bomb activated!"
|
||||
@ -609,12 +593,6 @@ void Attachment::update(int ticks)
|
||||
he->setLocalPlayerKartHit();
|
||||
projectile_manager->addHitEffect(he);
|
||||
ExplosionAnimation::create(m_kart);
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -622,11 +600,14 @@ void Attachment::update(int ticks)
|
||||
case ATTACH_NOLOK_BUBBLEGUM_SHIELD:
|
||||
if (m_ticks_left <= 0)
|
||||
{
|
||||
if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX();
|
||||
m_bubble_explode_sound =
|
||||
SFXManager::get()->createSoundSource("bubblegum_explode");
|
||||
m_bubble_explode_sound->setPosition(m_kart->getXYZ());
|
||||
m_bubble_explode_sound->play();
|
||||
if (!RewindManager::get()->isRewinding())
|
||||
{
|
||||
if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX();
|
||||
m_bubble_explode_sound =
|
||||
SFXManager::get()->createSoundSource("bubblegum_explode");
|
||||
m_bubble_explode_sound->setPosition(m_kart->getXYZ());
|
||||
m_bubble_explode_sound->play();
|
||||
}
|
||||
|
||||
ItemManager::get()->dropNewItem(Item::ITEM_BUBBLEGUM, m_kart);
|
||||
}
|
||||
@ -634,10 +615,38 @@ void Attachment::update(int ticks)
|
||||
} // switch
|
||||
|
||||
// Detach attachment if its time is up.
|
||||
if ( m_ticks_left <= 0)
|
||||
if (m_ticks_left <= 0)
|
||||
clear();
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Attachment::updateGraphics(float dt)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case ATTACH_BOMB:
|
||||
{
|
||||
if (!m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound = SFXManager::get()->createSoundSource("clock");
|
||||
m_bomb_sound->setLoop(true);
|
||||
m_bomb_sound->play();
|
||||
}
|
||||
m_bomb_sound->setPosition(m_kart->getXYZ());
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
|
||||
} // updateGraphics
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Return the additional weight of the attachment (some attachments slow
|
||||
* karts down by also making them heavier).
|
||||
|
@ -116,6 +116,8 @@ public:
|
||||
~Attachment();
|
||||
void clear ();
|
||||
void hitBanana(ItemState *item);
|
||||
void updateGraphics(float dt);
|
||||
|
||||
void update(int ticks);
|
||||
void handleCollisionWithKart(AbstractKart *other);
|
||||
void set (AttachmentType type, int ticks,
|
||||
@ -154,6 +156,15 @@ public:
|
||||
/** Nothing to undo when going back during a rewind, the full state info
|
||||
* will take care of creating the right attachment. */
|
||||
virtual void undo(BareNetworkString *buffer) { }
|
||||
// ------------------------------------------------------------------------
|
||||
float getInitialSpeed() const { return m_initial_speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setInitialSpeed(float speed) { m_initial_speed = speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
float getNodeScale() const { return m_node_scale; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setNodeScale(float scale) { m_node_scale = scale; }
|
||||
|
||||
}; // Attachment
|
||||
|
||||
#endif
|
||||
|
@ -348,7 +348,6 @@ void Powerup::use()
|
||||
kart->getAttachment()->set(Attachment::ATTACH_ANVIL,
|
||||
stk_config->
|
||||
time2Ticks(kp->getAnvilDuration()) );
|
||||
kart->updateWeight();
|
||||
kart->adjustSpeed(kp->getAnvilSpeedFactor() * 0.5f);
|
||||
|
||||
// should we position the sound at the kart that is hit,
|
||||
|
@ -430,10 +430,6 @@ public:
|
||||
* over. */
|
||||
virtual void startEngineSFX() = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** This method is to be called every time the mass of the kart is updated,
|
||||
* which includes attaching an anvil to the kart (and detaching). */
|
||||
virtual void updateWeight() = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Multiplies the velocity of the kart by a factor f (both linear
|
||||
* and angular). This is used by anvils, which suddenly slow down the kart
|
||||
* when they are attached. */
|
||||
|
@ -59,9 +59,6 @@ public:
|
||||
virtual void updateGraphics(float dt) OVERRIDE;
|
||||
virtual void reset() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** No physics body for ghost kart, so nothing to adjust. */
|
||||
virtual void updateWeight() OVERRIDE {};
|
||||
// ------------------------------------------------------------------------
|
||||
/** No physics for ghost kart. */
|
||||
virtual void applyEngineForce (float force) OVERRIDE {};
|
||||
// ------------------------------------------------------------------------
|
||||
@ -93,7 +90,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time at which the kart was at a given distance.
|
||||
* Returns -1.0f if none */
|
||||
float getTimeForDistance(float distance);
|
||||
virtual float getTimeForDistance(float distance) OVERRIDE;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the smallest time at which the kart had the required number of eggs
|
||||
|
@ -351,6 +351,9 @@ void Kart::reset()
|
||||
m_kart_gfx->reset();
|
||||
m_skidding->reset();
|
||||
|
||||
m_weight = 0.0f;
|
||||
updateWeight();
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
if (m_collision_particles)
|
||||
m_collision_particles->setCreationRateAbsolute(0.0f);
|
||||
@ -856,10 +859,13 @@ void Kart::adjustSpeed(float f)
|
||||
void Kart::updateWeight()
|
||||
{
|
||||
float mass = m_kart_properties->getMass() + m_attachment->weightAdjust();
|
||||
|
||||
btVector3 inertia;
|
||||
m_kart_chassis.calculateLocalInertia(mass, inertia);
|
||||
m_body->setMassProps(mass, inertia);
|
||||
if (m_weight != mass)
|
||||
{
|
||||
m_weight = mass;
|
||||
btVector3 inertia;
|
||||
m_kart_chassis.calculateLocalInertia(mass, inertia);
|
||||
m_body->setMassProps(mass, inertia);
|
||||
}
|
||||
} // updateWeight
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -2524,6 +2530,7 @@ void Kart::updateEngineSFX(float dt)
|
||||
*/
|
||||
void Kart::updateEnginePowerAndBrakes(int ticks)
|
||||
{
|
||||
updateWeight();
|
||||
updateNitro(ticks);
|
||||
float engine_power = getActualWheelForce();
|
||||
|
||||
@ -2542,7 +2549,7 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
|
||||
{
|
||||
// For a short time after a collision disable the engine,
|
||||
// so that the karts can bounce back a bit from the obstacle.
|
||||
if(m_bounce_back_ticks>0.0f)
|
||||
if (m_bounce_back_ticks > 0)
|
||||
engine_power = 0.0f;
|
||||
// let a player going backwards accelerate quickly (e.g. if a player
|
||||
// hits a wall, he needs to be able to start again quickly after
|
||||
@ -2937,6 +2944,8 @@ void Kart::updateGraphics(float dt)
|
||||
m_skid_sound->setPosition(getXYZ());
|
||||
m_nitro_sound->setPosition(getXYZ());
|
||||
|
||||
m_attachment->updateGraphics(dt);
|
||||
|
||||
// update star effect (call will do nothing if stars are not activated)
|
||||
m_stars_effect->update(dt);
|
||||
|
||||
|
@ -214,6 +214,8 @@ protected:
|
||||
|
||||
float m_falling_time;
|
||||
|
||||
float m_weight;
|
||||
|
||||
/** When a kart has its view blocked by the plunger, this variable will be
|
||||
* > 0 the number it contains is the time left before removing plunger. */
|
||||
int m_view_blocked_by_plunger;
|
||||
@ -265,7 +267,7 @@ protected:
|
||||
float getActualWheelForce();
|
||||
void playCrashSFX(const Material* m, AbstractKart *k);
|
||||
void loadData(RaceManager::KartType type, bool animatedModel);
|
||||
|
||||
void updateWeight();
|
||||
public:
|
||||
Kart(const std::string& ident, unsigned int world_kart_id,
|
||||
int position, const btTransform& init_transform,
|
||||
@ -276,7 +278,6 @@ public:
|
||||
virtual void kartIsInRestNow() OVERRIDE;
|
||||
virtual void updateGraphics(float dt) OVERRIDE;
|
||||
virtual void createPhysics ();
|
||||
virtual void updateWeight () OVERRIDE;
|
||||
virtual float getSpeedForTurnRadius(float radius) const OVERRIDE;
|
||||
virtual float getMaxSteerAngle(float speed) const;
|
||||
virtual bool isInRest () const OVERRIDE;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "items/powerup.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/max_speed.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "modes/world.hpp"
|
||||
@ -191,6 +192,9 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
|
||||
// 3) Attachment, powerup, nitro
|
||||
// ------------------------------
|
||||
getAttachment()->rewindTo(buffer);
|
||||
// Required for going back to anvil when rewinding
|
||||
updateWeight();
|
||||
|
||||
getPowerup()->rewindTo(buffer);
|
||||
m_min_nitro_ticks = buffer->getUInt8();
|
||||
float nitro = buffer->getFloat();
|
||||
@ -203,6 +207,7 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
|
||||
// 6) Skidding
|
||||
// -----------
|
||||
m_skidding->rewindTo(buffer);
|
||||
|
||||
return;
|
||||
} // restoreState
|
||||
|
||||
@ -218,6 +223,33 @@ void KartRewinder::update(int ticks)
|
||||
// ----------------------------------------------------------------------------
|
||||
void KartRewinder::rewindToEvent(BareNetworkString *buffer)
|
||||
{
|
||||
}; // rewindToEvent
|
||||
} // rewindToEvent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
std::function<void()> KartRewinder::getLocalStateRestoreFunction()
|
||||
{
|
||||
// In theory all ticks / boolean related stuff can be saved locally
|
||||
int bubblegum_ticks = m_bubblegum_ticks;
|
||||
int bounce_back_ticks = m_bounce_back_ticks;
|
||||
int invulnerable_ticks = m_invulnerable_ticks;
|
||||
int squash_ticks = m_squash_ticks;
|
||||
bool fire_clicked = m_fire_clicked;
|
||||
int view_blocked_by_plunger = m_view_blocked_by_plunger;
|
||||
|
||||
// Attachment local state
|
||||
float initial_speed = getAttachment()->getInitialSpeed();
|
||||
float node_scale = getAttachment()->getNodeScale();
|
||||
return [bubblegum_ticks, bounce_back_ticks, invulnerable_ticks, squash_ticks,
|
||||
fire_clicked, view_blocked_by_plunger, initial_speed,
|
||||
node_scale, this]()
|
||||
{
|
||||
m_bubblegum_ticks = bubblegum_ticks;
|
||||
m_bounce_back_ticks = bounce_back_ticks;
|
||||
m_invulnerable_ticks = invulnerable_ticks;
|
||||
m_squash_ticks = squash_ticks;
|
||||
m_fire_clicked = fire_clicked;
|
||||
m_view_blocked_by_plunger = view_blocked_by_plunger;
|
||||
getAttachment()->setInitialSpeed(initial_speed);
|
||||
getAttachment()->setNodeScale(node_scale);
|
||||
};
|
||||
} // getLocalStateRestoreFunction
|
||||
|
@ -76,6 +76,9 @@ public:
|
||||
virtual void undoEvent(BareNetworkString *p) OVERRIDE {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool enableSmoothing() const OVERRIDE { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual std::function<void()> getLocalStateRestoreFunction() OVERRIDE;
|
||||
|
||||
|
||||
}; // Rewinder
|
||||
#endif
|
||||
|
@ -174,7 +174,6 @@ void addAttachment(Attachment::AttachmentType type)
|
||||
stk_config->time2Ticks(kart->getKartProperties()
|
||||
->getAnvilDuration()) );
|
||||
kart->adjustSpeed(kart->getKartProperties()->getAnvilSpeedFactor());
|
||||
kart->updateWeight();
|
||||
}
|
||||
else if (type == Attachment::ATTACH_PARACHUTE)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user