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

View File

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

View File

@ -19,6 +19,8 @@
#ifndef HEADER_KART_CONTROL_HPP #ifndef HEADER_KART_CONTROL_HPP
#define HEADER_KART_CONTROL_HPP #define HEADER_KART_CONTROL_HPP
#include "utils/types.hpp"
class BareNetworkString; class BareNetworkString;
/** /**
@ -33,10 +35,10 @@ public:
enum SkidControl {SC_NONE, SC_NO_DIRECTION, SC_LEFT, SC_RIGHT}; enum SkidControl {SC_NONE, SC_NO_DIRECTION, SC_LEFT, SC_RIGHT};
private: private:
/** The current steering value in [-1, 1]. */ /** The current steering value in [-32767, 32767]. */
float m_steer; int16_t m_steer;
/** Acceleration, in [0, 1]. */ /** Acceleration, in [0, 65535]. */
float m_accel; uint16_t m_accel;
/** True if the kart brakes. */ /** True if the kart brakes. */
bool m_brake; bool m_brake;
/** True if the kart activates nitro. */ /** True if the kart activates nitro. */
@ -126,11 +128,11 @@ public:
m_skid = (SkidControl)((c & 96) >> 5); m_skid = (SkidControl)((c & 96) >> 5);
} // setButtonsCompressed } // setButtonsCompressed
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the current steering value. */ /** Returns the current steering value in [-1, 1]. */
float getSteer() const { return m_steer; } float getSteer() const { return (float)m_steer / 32767.0f; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns current acceleration. */ /** Returns current acceleration in [0, 1]. */
float getAccel() const { return m_accel; } float getAccel() const { return (float)m_accel / 65535.0f; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns if the kart is braking. */ /** Returns if the kart is braking. */
bool getBrake() const { return m_brake; } 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 // NOTE: when the size changes, the AIBaseController::saveState and
// restore state MUST be adjusted!! // 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)); .addUInt8((m_prev_brake ? 1 : 0) | (m_prev_nitro ? 2 : 0));
} // copyToBuffer } // copyToBuffer
@ -384,7 +384,7 @@ void PlayerController::rewindTo(BareNetworkString *buffer)
{ {
// NOTE: when the size changes, the AIBaseController::saveState and // NOTE: when the size changes, the AIBaseController::saveState and
// restore state MUST be adjusted!! // restore state MUST be adjusted!!
m_steer_val = buffer->getUInt32(); m_steer_val = buffer->getInt24();
m_prev_accel = buffer->getUInt16(); m_prev_accel = buffer->getUInt16();
uint8_t c = buffer->getUInt8(); uint8_t c = buffer->getUInt8();
m_prev_brake = (c & 1) != 0; m_prev_brake = (c & 1) != 0;

View File

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

View File

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

View File

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