Further improve kart state saving

This commit is contained in:
Benau 2019-03-06 14:03:39 +08:00
parent 2e007d7883
commit 09a62747f6
11 changed files with 107 additions and 92 deletions

View File

@ -180,9 +180,9 @@ void Attachment::clear(bool update_graphical_now)
m_plugin = NULL;
}
m_type=ATTACH_NOTHING;
m_type = ATTACH_NOTHING;
m_ticks_left = 0;
m_initial_speed = 0;
if (update_graphical_now)
updateGraphicalTypeNow();
} // clear
@ -204,16 +204,13 @@ void Attachment::saveState(BareNetworkString *buffer) const
uint8_t type = m_type | (( (m_type==ATTACH_BOMB) && (m_previous_owner!=NULL) )
? (1 << 6) : 0 ) | bit_7;
buffer->addUInt8(type);
if(m_type!=ATTACH_NOTHING)
{
buffer->addUInt16(m_ticks_left);
if(m_type==ATTACH_BOMB && m_previous_owner)
buffer->addUInt8(m_previous_owner->getWorldKartId());
if (m_type == ATTACH_PARACHUTE)
buffer->addUInt16(m_initial_speed);
if (m_plugin)
m_plugin->saveState(buffer);
}
buffer->addUInt16(m_ticks_left);
if (m_type==ATTACH_BOMB && m_previous_owner)
buffer->addUInt8(m_previous_owner->getWorldKartId());
if (m_type == ATTACH_PARACHUTE)
buffer->addUInt16(m_initial_speed);
if (m_plugin)
m_plugin->saveState(buffer);
} // saveState
// -----------------------------------------------------------------------------
@ -229,19 +226,7 @@ void Attachment::rewindTo(BareNetworkString *buffer)
AttachmentType new_type = AttachmentType(type & 63);
type &= 127;
// If there is no attachment, clear the attachment if necessary and exit
if (new_type == ATTACH_NOTHING)
{
m_initial_speed = 0;
if (m_type != new_type)
clear();
return;
}
int16_t ticks_left = 0;
if (new_type != ATTACH_NOTHING)
ticks_left = buffer->getUInt16();
int16_t ticks_left = buffer->getUInt16();
// Now it is a new attachment:
if (type == (ATTACH_BOMB | 64)) // we have previous owner information
{

View File

@ -78,10 +78,7 @@ void Powerup::reset()
void Powerup::saveState(BareNetworkString *buffer) const
{
buffer->addUInt8(uint8_t(m_type));
if(m_type!=PowerupManager::POWERUP_NOTHING)
{
buffer->addUInt8(m_number); // number is <=255
}
buffer->addUInt8(m_number); // number is <=255
} // saveState
//-----------------------------------------------------------------------------

View File

@ -332,11 +332,12 @@ void AIBaseController::determineTurnRadius(const Vec3 &end, Vec3 *center,
} // determineTurnRadius
//-----------------------------------------------------------------------------
void AIBaseController::saveState(BareNetworkString *buffer) const
bool AIBaseController::saveState(BareNetworkString *buffer) const
{
// Endcontroller needs this for proper offset in kart rewinder
// Must match the number of bytes in Playercontroller.
buffer->addInt24(0).addUInt16(0).addUInt8(0);
buffer->addUInt16(0).addUInt16(0).addUInt8(0);
return false;
} // copyToBuffer
//-----------------------------------------------------------------------------
@ -344,5 +345,5 @@ void AIBaseController::rewindTo(BareNetworkString *buffer)
{
// Endcontroller needs this for proper offset in kart rewinder.
// Skip the same number of bytes as PlayerController.
buffer->skip(3 + 2 + 1);
buffer->skip(2 + 2 + 1);
} // rewindTo

View File

@ -104,7 +104,7 @@ public:
};
virtual void skidBonusTriggered() OVERRIDE {}
// ------------------------------------------------------------------------
virtual void saveState(BareNetworkString *buffer) const OVERRIDE;
virtual bool saveState(BareNetworkString *buffer) const OVERRIDE;
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE;
void setNetworkAI(bool val) { m_enabled_network_ai = val; }
// ------------------------------------------------------------------------

View File

@ -77,7 +77,7 @@ public:
* rubber-banding. */
virtual bool isPlayerController () const = 0;
virtual bool disableSlipstreamBonus() const = 0;
virtual void saveState(BareNetworkString *buffer) const = 0;
virtual bool saveState(BareNetworkString *buffer) const = 0;
virtual void rewindTo(BareNetworkString *buffer) = 0;
// ---------------------------------------------------------------------------

View File

@ -62,7 +62,8 @@ public:
bool dry_run=false) OVERRIDE;
virtual void skidBonusTriggered() OVERRIDE {}
virtual void newLap(int lap) OVERRIDE {}
virtual void saveState(BareNetworkString *buffer) const OVERRIDE {}
virtual bool saveState(BareNetworkString *buffer) const OVERRIDE
{ return false; }
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE {}
void addReplayTime(float time);

View File

@ -40,6 +40,8 @@
#include "utils/log.hpp"
#include "utils/translation.hpp"
#include <cstdlib>
PlayerController::PlayerController(AbstractKart *kart)
: Controller(kart)
{
@ -371,12 +373,14 @@ void PlayerController::handleZipper(bool play_sound)
} // handleZipper
//-----------------------------------------------------------------------------
void PlayerController::saveState(BareNetworkString *buffer) const
bool PlayerController::saveState(BareNetworkString *buffer) const
{
// NOTE: when the size changes, the AIBaseController::saveState and
// restore state MUST be adjusted!!
buffer->addInt24(m_steer_val).addUInt16(m_prev_accel)
int steer_abs = std::abs(m_steer_val);
buffer->addUInt16((uint16_t)steer_abs).addUInt16(m_prev_accel)
.addUInt8((m_prev_brake ? 1 : 0) | (m_prev_nitro ? 2 : 0));
return m_steer_val < 0;
} // copyToBuffer
//-----------------------------------------------------------------------------
@ -384,7 +388,7 @@ void PlayerController::rewindTo(BareNetworkString *buffer)
{
// NOTE: when the size changes, the AIBaseController::saveState and
// restore state MUST be adjusted!!
m_steer_val = buffer->getInt24();
m_steer_val = buffer->getUInt16();
m_prev_accel = buffer->getUInt16();
uint8_t c = buffer->getUInt8();
m_prev_brake = (c & 1) != 0;

View File

@ -49,7 +49,7 @@ public:
virtual void reset () OVERRIDE;
virtual void handleZipper(bool play_sound) OVERRIDE;
virtual void resetInputState();
virtual void saveState(BareNetworkString *buffer) const OVERRIDE;
virtual bool saveState(BareNetworkString *buffer) const OVERRIDE;
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE;
// ------------------------------------------------------------------------
virtual void collectedItem(const ItemState &item,

View File

@ -375,7 +375,7 @@ void Kart::reset()
m_eliminated = false;
m_finish_time = 0.0f;
m_bubblegum_ticks = 0;
m_bubblegum_torque = 0.0f;
m_bubblegum_torque_sign = true;
m_invulnerable_ticks = 0;
m_min_nitro_ticks = 0;
m_energy_to_min_ratio = 0;
@ -1145,10 +1145,9 @@ void Kart::collectedItem(ItemState *item_state)
// slow down
m_bubblegum_ticks = (int16_t)stk_config->time2Ticks(
m_kart_properties->getBubblegumDuration());
m_bubblegum_torque =
m_bubblegum_torque_sign =
((World::getWorld()->getTicksSinceStart() / 10) % 2 == 0) ?
m_kart_properties->getBubblegumTorque() :
-m_kart_properties->getBubblegumTorque();
true : false;
m_max_speed->setSlowdown(MaxSpeed::MS_DECREASE_BUBBLE,
m_kart_properties->getBubblegumSpeedFraction() ,
m_kart_properties->getBubblegumFadeInTicks(),
@ -1394,15 +1393,6 @@ void Kart::update(int ticks)
if (m_bubblegum_ticks > 0)
{
m_bubblegum_ticks -= ticks;
if (m_bubblegum_ticks <= 0)
{
m_bubblegum_torque = 0;
}
}
else
{
// Not strictly necessary, but makes sure torque has expected values
m_bubblegum_torque = 0;
}
// This is to avoid a rescue immediately after an explosion
@ -1702,7 +1692,7 @@ void Kart::update(int ticks)
"v(16-18) %f %f %f steerf(20) %f maxangle(22) %f speed(24) %f "
"steering(26-27) %f %f clock(29) %lf skidstate(31) %d factor(33) %f "
"maxspeed(35) %f engf(37) %f braketick(39) %d brakes(41) %d heading(43) %f "
"bubticks(45) %d bubtor(47) %f",
"bubticks(45) %d",
getIdent().c_str(),
World::getWorld()->getTime(), World::getWorld()->getTicksSinceStart(),
getXYZ().getX(), getXYZ().getY(), getXYZ().getZ(),
@ -1723,8 +1713,7 @@ void Kart::update(int ticks)
m_brake_ticks, //39
m_controls.getButtonsCompressed(), //41
getHeading(), //43
m_bubblegum_ticks, // 45
m_bubblegum_torque // 47
m_bubblegum_ticks // 45
);
#endif
@ -2420,7 +2409,7 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
else
impulse = Vec3(0, 0, -1); // Arbitrary
impulse *= m_kart_properties->getCollisionTerrainImpulse();
m_bounce_back_ticks = stk_config->time2Ticks(0.2f);
m_bounce_back_ticks = (uint8_t)stk_config->time2Ticks(0.2f);
m_vehicle->setTimedCentralImpulse(
(uint16_t)stk_config->time2Ticks(0.1f), impulse);
}
@ -2469,12 +2458,12 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
else if (m->getCollisionReaction() == Material::PUSH_BACK)
{
// This variable is set to 0.2 in case of a kart-terrain collision
if (m_bounce_back_ticks <= stk_config->time2Ticks(0.2f))
if (m_bounce_back_ticks <= (uint8_t)stk_config->time2Ticks(0.2f))
{
btVector3 push = m_body->getLinearVelocity().normalized();
push[1] = 0.1f;
m_body->applyCentralImpulse( -4000.0f*push );
m_bounce_back_ticks = stk_config->time2Ticks(2.0f);
m_bounce_back_ticks = (uint8_t)stk_config->time2Ticks(2.0f);
} // if m_bounce_back_ticks <= 0.2f
} // if (m->getCollisionReaction() == Material::PUSH_BACK)
} // if(m && m->getCollisionReaction() != Material::NORMAL &&
@ -2496,7 +2485,7 @@ void Kart::playCrashSFX(const Material* m, AbstractKart *k)
// After a collision disable the engine for a short time so that karts
// can 'bounce back' a bit (without this the engine force will prevent
// karts from bouncing back, they will instead stuck towards the obstable).
if(m_bounce_back_ticks <= 0)
if(m_bounce_back_ticks == 0)
{
if (getVelocity().length()> 0.555f)
{
@ -2540,7 +2529,7 @@ void Kart::playCrashSFX(const Material* m, AbstractKart *k)
crash_sound_emitter->play(getXYZ(), buffer);
}
} // if lin_vel > 0.555
} // if m_bounce_back_ticks <= 0
} // if m_bounce_back_ticks == 0
} // playCrashSFX
// -----------------------------------------------------------------------------
@ -2642,7 +2631,7 @@ void Kart::updatePhysics(int ticks)
/*fade_out_time*/stk_config->time2Ticks(5.0f));
}
}
if (m_bounce_back_ticks > std::numeric_limits<int16_t>::min())
if (m_bounce_back_ticks > 0)
m_bounce_back_ticks -= ticks;
updateEnginePowerAndBrakes(ticks);
@ -2803,7 +2792,9 @@ void Kart::updateEnginePowerAndBrakes(int ticks)
if (m_bubblegum_ticks > 0)
{
engine_power = 0.0f;
m_body->applyTorque(btVector3(0.0, m_bubblegum_torque, 0.0));
m_body->applyTorque(btVector3(0.0,
m_kart_properties->getBubblegumTorque() *
(m_bubblegum_torque_sign ? 1.0f : -1.0f), 0.0));
}
if(m_controls.getAccel()) // accelerating

View File

@ -99,6 +99,13 @@ protected:
bool m_enabled_network_spectator;
/** The sign of torque to apply after hitting a bubble gum. */
bool m_bubblegum_torque_sign;
/** A short time after a collision acceleration is disabled to allow
* the karts to bounce back*/
uint8_t m_bounce_back_ticks;
protected:
/** Handles speed increase and capping due to powerup, terrain, ... */
MaxSpeed *m_max_speed;
@ -190,10 +197,6 @@ protected:
* the kart will brake. */
int m_brake_ticks;
/** A short time after a collision acceleration is disabled to allow
* the karts to bounce back*/
int16_t m_bounce_back_ticks;
/** Time a kart is invulnerable. */
int16_t m_invulnerable_ticks;
@ -220,9 +223,6 @@ protected:
float m_finish_time;
/** The torque to apply after hitting a bubble gum. */
float m_bubblegum_torque;
/** The amount of energy collected with nitro cans. Note that it
* must be float, since dt is subtraced in each timestep. */
float m_collected_energy;

View File

@ -163,7 +163,12 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
BareNetworkString *buffer = new BareNetworkString(MEMSIZE);
// 1) Boolean handling to determine if need saving
// 1) Steering and other player controls
// -------------------------------------
getControls().saveState(buffer);
bool sign_neg = getController()->saveState(buffer);
// 2) Boolean handling to determine if need saving
const bool has_animation = m_kart_animation != NULL;
uint8_t bool_for_each_data = 0;
if (m_fire_clicked)
@ -184,6 +189,19 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
bool_for_each_data |= (1 << 7);
buffer->addUInt8(bool_for_each_data);
uint8_t bool_for_each_data_2 = 0;
if (sign_neg)
bool_for_each_data_2 |= 1;
if (m_bounce_back_ticks > 0)
bool_for_each_data_2 |= (1 << 1);
if (getAttachment()->getType() != Attachment::ATTACH_NOTHING)
bool_for_each_data_2 |= (1 << 2);
if (getPowerup()->getType() != PowerupManager::POWERUP_NOTHING)
bool_for_each_data_2 |= (1 << 3);
if (m_bubblegum_torque_sign)
bool_for_each_data_2 |= (1 << 4);
buffer->addUInt8(bool_for_each_data_2);
if (m_bubblegum_ticks > 0)
buffer->addUInt16(m_bubblegum_ticks);
if (m_view_blocked_by_plunger > 0)
@ -193,7 +211,7 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
if (getEnergy() > 0.0f)
buffer->addFloat(getEnergy());
// 2) Kart animation status or physics values (transform and velocities)
// 3) Kart animation status or physics values (transform and velocities)
// -------------------------------------------
if (has_animation)
{
@ -212,7 +230,8 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
}
// For collision rewind
buffer->addUInt16(m_bounce_back_ticks);
if (m_bounce_back_ticks > 0)
buffer->addUInt8(m_bounce_back_ticks);
if (m_vehicle->getCentralImpulseTicks() > 0)
{
buffer->addUInt16(m_vehicle->getCentralImpulseTicks());
@ -220,15 +239,12 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
}
}
// 3) Steering and other player controls
// -------------------------------------
getControls().saveState(buffer);
getController()->saveState(buffer);
// 4) Attachment, powerup, nitro
// -----------------------------
getAttachment()->saveState(buffer);
getPowerup()->saveState(buffer);
if (getAttachment()->getType() != Attachment::ATTACH_NOTHING)
getAttachment()->saveState(buffer);
if (getPowerup()->getType() != PowerupManager::POWERUP_NOTHING)
getPowerup()->saveState(buffer);
// 5) Max speed info
// ------------------
@ -251,7 +267,12 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
{
m_has_server_state = true;
// 1) Boolean handling to determine if need saving
// 1) Steering and other controls
// ------------------------------
getControls().rewindTo(buffer);
getController()->rewindTo(buffer);
// 2) Boolean handling to determine if need saving
// -----------
uint8_t bool_for_each_data = buffer->getUInt8();
m_fire_clicked = (bool_for_each_data & 1) == 1;
@ -263,6 +284,19 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
bool read_timed_rotation = ((bool_for_each_data >> 6) & 1) == 1;
bool read_impulse = ((bool_for_each_data >> 7) & 1) == 1;
uint8_t bool_for_each_data_2 = buffer->getUInt8();
bool controller_steer_sign = (bool_for_each_data_2 & 1) == 1;
if (controller_steer_sign)
{
PlayerController* pc = dynamic_cast<PlayerController*>(m_controller);
if (pc)
pc->m_steer_val = pc->m_steer_val * -1;
}
bool read_bounce_back = ((bool_for_each_data_2 >> 1) & 1) == 1;
bool read_attachment = ((bool_for_each_data_2 >> 2) & 1) == 1;
bool read_powerup = ((bool_for_each_data_2 >> 3) & 1) == 1;
m_bubblegum_torque_sign = ((bool_for_each_data_2 >> 4) & 1) == 1;
if (read_bubblegum)
m_bubblegum_ticks = buffer->getUInt16();
else
@ -286,7 +320,7 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
else
setEnergy(0.0f);
// 2) Kart animation status or transform and velocities
// 3) Kart animation status or transform and velocities
// -----------
if (has_animation_in_state)
{
@ -341,7 +375,10 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
m_vehicle->setTimedRotation(0, 0.0f);
// Collision rewind
m_bounce_back_ticks = buffer->getUInt16();
if (read_bounce_back)
m_bounce_back_ticks = buffer->getUInt8();
else
m_bounce_back_ticks = 0;
if (read_impulse)
{
uint16_t central_impulse_ticks = buffer->getUInt16();
@ -360,18 +397,19 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
m_vehicle->updateAllWheelTransformsWS();
}
// 3) Steering and other controls
// ------------------------------
getControls().rewindTo(buffer);
getController()->rewindTo(buffer);
// 4) Attachment, powerup, nitro
// ------------------------------
getAttachment()->rewindTo(buffer);
if (read_attachment)
getAttachment()->rewindTo(buffer);
else
getAttachment()->clear();
// Required for going back to anvil when rewinding
updateWeight();
getPowerup()->rewindTo(buffer);
if (read_powerup)
getPowerup()->rewindTo(buffer);
else
getPowerup()->set(PowerupManager::POWERUP_NOTHING, 0);
// 5) Max speed info
// ------------------
@ -402,7 +440,6 @@ std::function<void()> KartRewinder::getLocalStateRestoreFunction()
// itself
int brake_ticks = m_brake_ticks;
int8_t min_nitro_ticks = m_min_nitro_ticks;
float bubblegum_torque = m_bubblegum_torque;
// Controller local state
int steer_val_l = 0;
@ -423,13 +460,12 @@ std::function<void()> KartRewinder::getLocalStateRestoreFunction()
// Skidding local state
float remaining_jump_time = m_skidding->m_remaining_jump_time;
return [brake_ticks, min_nitro_ticks, bubblegum_torque,
return [brake_ticks, min_nitro_ticks,
steer_val_l, steer_val_r, current_fraction,
max_speed_fraction, remaining_jump_time, this]()
{
m_brake_ticks = brake_ticks;
m_min_nitro_ticks = min_nitro_ticks;
m_bubblegum_torque = bubblegum_torque;
PlayerController* pc = dynamic_cast<PlayerController*>(m_controller);
if (pc)
{