Improve kart state saving

This commit is contained in:
Benau 2019-02-27 11:05:47 +08:00
parent c00cf66b26
commit 813934bdba
7 changed files with 116 additions and 59 deletions

View File

@ -336,7 +336,7 @@ void AIBaseController::saveState(BareNetworkString *buffer) const
{
// Endcontroller needs this for proper offset in kart rewinder
// Must match the number of bytes in Playercontroller.
buffer->addUInt32(0).addUInt16(0).addUInt8(0);
buffer->addInt24(0).addUInt16(0).addUInt8(0);
} // copyToBuffer
//-----------------------------------------------------------------------------
@ -344,5 +344,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(4 + 2 + 1);
buffer->skip(3 + 2 + 1);
} // rewindTo

View File

@ -19,18 +19,23 @@
#include "karts/controller/kart_control.hpp"
#include "network/network_string.hpp"
#include "irrMath.h"
#include <algorithm>
// ------------------------------------------------------------------------
/** Sets the current steering value. */
void KartControl::setSteer(float f)
{
m_steer = f;
int steer = irr::core::clamp((int)(f * 32767.0f), -32767, 32767);
m_steer = (int16_t)steer;
} // setSteer
// ----------------------------------------------------------------------------
/** Sets the acceleration. */
void KartControl::setAccel(float f)
{
m_accel = f;
int accel = std::min((int)(f * 65535.0f), 65535);
m_accel = (uint16_t)accel;
} // setAccel
// ----------------------------------------------------------------------------
@ -78,8 +83,8 @@ void KartControl::setLookBack(bool b)
/** Copies the important data from this objects into a memory buffer. */
void KartControl::saveState(BareNetworkString *buffer) const
{
buffer->add(m_steer);
buffer->add(m_accel);
buffer->addUInt16(m_steer);
buffer->addUInt16(m_accel);
buffer->addChar(getButtonsCompressed());
} // saveState
@ -87,7 +92,7 @@ void KartControl::saveState(BareNetworkString *buffer) const
/** Restores this object from a previously saved memory buffer. */
void KartControl::rewindTo(BareNetworkString *buffer)
{
m_steer = buffer->getFloat();
m_accel = buffer->getFloat();
m_steer = buffer->getUInt16();
m_accel = buffer->getUInt16();
setButtonsCompressed(buffer->getUInt8());
} // setFromMemory

View File

@ -19,6 +19,8 @@
#ifndef HEADER_KART_CONTROL_HPP
#define HEADER_KART_CONTROL_HPP
#include "utils/types.hpp"
class BareNetworkString;
/**
@ -33,10 +35,10 @@ public:
enum SkidControl {SC_NONE, SC_NO_DIRECTION, SC_LEFT, SC_RIGHT};
private:
/** The current steering value in [-1, 1]. */
float m_steer;
/** Acceleration, in [0, 1]. */
float m_accel;
/** The current steering value in [-32767, 32767]. */
int16_t m_steer;
/** Acceleration, in [0, 65535]. */
uint16_t m_accel;
/** True if the kart brakes. */
bool m_brake;
/** True if the kart activates nitro. */
@ -126,11 +128,11 @@ public:
m_skid = (SkidControl)((c & 96) >> 5);
} // setButtonsCompressed
// ------------------------------------------------------------------------
/** Returns the current steering value. */
float getSteer() const { return m_steer; }
/** Returns the current steering value in [-1, 1]. */
float getSteer() const { return (float)m_steer / 32767.0f; }
// ------------------------------------------------------------------------
/** Returns current acceleration. */
float getAccel() const { return m_accel; }
/** Returns current acceleration in [0, 1]. */
float getAccel() const { return (float)m_accel / 65535.0f; }
// ------------------------------------------------------------------------
/** Returns if the kart is braking. */
bool getBrake() const { return m_brake; }

View File

@ -375,7 +375,7 @@ void PlayerController::saveState(BareNetworkString *buffer) const
{
// NOTE: when the size changes, the AIBaseController::saveState and
// restore state MUST be adjusted!!
buffer->addUInt32(m_steer_val).addUInt16(m_prev_accel)
buffer->addInt24(m_steer_val).addUInt16(m_prev_accel)
.addUInt8((m_prev_brake ? 1 : 0) | (m_prev_nitro ? 2 : 0));
} // copyToBuffer
@ -384,7 +384,7 @@ void PlayerController::rewindTo(BareNetworkString *buffer)
{
// NOTE: when the size changes, the AIBaseController::saveState and
// restore state MUST be adjusted!!
m_steer_val = buffer->getUInt32();
m_steer_val = buffer->getInt24();
m_prev_accel = buffer->getUInt16();
uint8_t c = buffer->getUInt8();
m_prev_brake = (c & 1) != 0;

View File

@ -1142,8 +1142,8 @@ void Kart::collectedItem(ItemState *item_state)
item_state->getPreviousOwner()->getIdent() == "nolok");
// slow down
m_bubblegum_ticks =
stk_config->time2Ticks(m_kart_properties->getBubblegumDuration());
m_bubblegum_ticks = (int16_t)stk_config->time2Ticks(
m_kart_properties->getBubblegumDuration());
m_bubblegum_torque =
((World::getWorld()->getTicksSinceStart() / 10) % 2 == 0) ?
m_kart_properties->getBubblegumTorque() :

View File

@ -494,10 +494,9 @@ public:
/** Makes a kart invulnerable for a certain amount of time. */
virtual void setInvulnerableTicks(int ticks) OVERRIDE
{
// The last 3 bits are saving fire clicked, kart animation status and
// plunger state for rewind
if (ticks > 8191)
ticks = 8191;
// int16_t max
if (ticks > 32767)
ticks = 32767;
m_invulnerable_ticks = ticks;
} // setInvulnerableTicks
// ------------------------------------------------------------------------

View File

@ -157,18 +157,35 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
BareNetworkString *buffer = new BareNetworkString(MEMSIZE);
// 1) Firing and related handling
// -----------
buffer->addUInt16(m_bubblegum_ticks);
bool plunger_on = m_view_blocked_by_plunger != 0;
// m_invulnerable_ticks will not be negative
bool has_animation = m_kart_animation != NULL;
uint16_t fire_and_invulnerable = (m_fire_clicked ? 1 << 15 : 0) |
(has_animation ? 1 << 14 : 0) | (plunger_on ? 1 << 13 : 0) |
m_invulnerable_ticks;
buffer->addUInt16(fire_and_invulnerable);
if (plunger_on)
// 1) 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)
bool_for_each_data |= 1;
if (m_bubblegum_ticks > 0)
bool_for_each_data |= (1 << 1);
if (m_view_blocked_by_plunger > 0)
bool_for_each_data |= (1 << 2);
if (m_invulnerable_ticks > 0)
bool_for_each_data |= (1 << 3);
if (getEnergy() > 0.0f)
bool_for_each_data |= (1 << 4);
if (has_animation)
bool_for_each_data |= (1 << 5);
if (m_vehicle->getTimedRotationTicks() > 0)
bool_for_each_data |= (1 << 6);
if (m_vehicle->getCentralImpulseTicks() > 0)
bool_for_each_data |= (1 << 7);
buffer->addUInt8(bool_for_each_data);
if (m_bubblegum_ticks > 0)
buffer->addUInt16(m_bubblegum_ticks);
if (m_view_blocked_by_plunger > 0)
buffer->addUInt16(m_view_blocked_by_plunger);
if (m_invulnerable_ticks > 0)
buffer->addUInt16(m_invulnerable_ticks);
if (getEnergy() > 0.0f)
buffer->addFloat(getEnergy());
// 2) Kart animation status or physics values (transform and velocities)
// -------------------------------------------
@ -186,13 +203,19 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
buffer->add(q);
buffer->add(body->getLinearVelocity());
buffer->add(body->getAngularVelocity());
buffer->addUInt16(m_vehicle->getTimedRotationTicks());
buffer->addFloat(m_vehicle->getTimedRotation());
if (m_vehicle->getTimedRotationTicks() > 0)
{
buffer->addUInt16(m_vehicle->getTimedRotationTicks());
buffer->addFloat(m_vehicle->getTimedRotation());
}
// For collision rewind
buffer->addUInt16(m_bounce_back_ticks);
buffer->addUInt16(m_vehicle->getCentralImpulseTicks());
buffer->add(m_vehicle->getAdditionalImpulse());
if (m_vehicle->getCentralImpulseTicks() > 0)
{
buffer->addUInt16(m_vehicle->getCentralImpulseTicks());
buffer->add(m_vehicle->getAdditionalImpulse());
}
}
// 3) Steering and other player controls
@ -204,7 +227,6 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
// -----------------------------
getAttachment()->saveState(buffer);
getPowerup()->saveState(buffer);
buffer->addFloat(getEnergy());
// 5) Max speed info
// ------------------
@ -227,19 +249,40 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
{
m_has_server_state = true;
// 1) Firing and related handling
// 1) Boolean handling to determine if need saving
// -----------
m_bubblegum_ticks = buffer->getUInt16();
uint16_t fire_and_invulnerable = buffer->getUInt16();
m_fire_clicked = ((fire_and_invulnerable >> 15) & 1) == 1;
bool has_animation_in_state = ((fire_and_invulnerable >> 14) & 1) == 1;
bool has_plunger = ((fire_and_invulnerable >> 13) & 1) == 1;
if (has_plunger)
uint8_t bool_for_each_data = buffer->getUInt8();
m_fire_clicked = (bool_for_each_data & 1) == 1;
bool read_bubblegum = ((bool_for_each_data >> 1) & 1) == 1;
bool read_plunger = ((bool_for_each_data >> 2) & 1) == 1;
bool read_invulnerable = ((bool_for_each_data >> 3) & 1) == 1;
bool read_energy = ((bool_for_each_data >> 4) & 1) == 1;
bool has_animation_in_state = ((bool_for_each_data >> 5) & 1) == 1;
bool read_timed_rotation = ((bool_for_each_data >> 6) & 1) == 1;
bool read_impulse = ((bool_for_each_data >> 7) & 1) == 1;
if (read_bubblegum)
m_bubblegum_ticks = buffer->getUInt16();
else
m_bubblegum_ticks = 0;
if (read_plunger)
m_view_blocked_by_plunger = buffer->getUInt16();
else
m_view_blocked_by_plunger = 0;
m_invulnerable_ticks = fire_and_invulnerable & ~(1 << 13);
if (read_invulnerable)
m_invulnerable_ticks = buffer->getUInt16();
else
m_invulnerable_ticks = 0;
if (read_energy)
{
float nitro = buffer->getFloat();
setEnergy(nitro);
}
else
setEnergy(0.0f);
// 2) Kart animation status or transform and velocities
// -----------
@ -294,18 +337,28 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
// before Moveable::update() is called (which updates the transform)
setTrans(kart_trans);
uint16_t time_rot = buffer->getUInt16();
float timed_rotation_y = buffer->getFloat();
// Set timed rotation divides by time_rot
m_vehicle->setTimedRotation(time_rot,
stk_config->ticks2Time(time_rot) * timed_rotation_y);
if (read_timed_rotation)
{
uint16_t time_rot = buffer->getUInt16();
float timed_rotation_y = buffer->getFloat();
// Set timed rotation divides by time_rot
m_vehicle->setTimedRotation(time_rot,
stk_config->ticks2Time(time_rot) * timed_rotation_y);
}
else
m_vehicle->setTimedRotation(0, 0.0f);
// Collision rewind
m_bounce_back_ticks = buffer->getUInt16();
uint16_t central_impulse_ticks = buffer->getUInt16();
Vec3 additional_impulse = buffer->getVec3();
m_vehicle->setTimedCentralImpulse(central_impulse_ticks,
additional_impulse, true/*rewind*/);
if (read_impulse)
{
uint16_t central_impulse_ticks = buffer->getUInt16();
Vec3 additional_impulse = buffer->getVec3();
m_vehicle->setTimedCentralImpulse(central_impulse_ticks,
additional_impulse, true/*rewind*/);
}
else
m_vehicle->setTimedCentralImpulse(0, Vec3(0.0f), true/*rewind*/);
// For the raycast to determine the current material under the kart
// the m_hardPointWS of the wheels is used. So after a rewind we
@ -327,8 +380,6 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
updateWeight();
getPowerup()->rewindTo(buffer);
float nitro = buffer->getFloat();
setEnergy(nitro);
// 5) Max speed info
// ------------------