Make a better class for kart animation creation exception

This commit is contained in:
Benau 2019-04-03 10:25:38 +08:00
parent d990bcb2a1
commit 05fad217e3
5 changed files with 64 additions and 16 deletions

View File

@ -689,7 +689,19 @@ void Flyable::restoreState(BareNetworkString *buffer, int count)
{
// At the moment we only have cannon animation for rubber ball
if (!m_animation)
setAnimation(new CannonAnimation(this, buffer));
{
try
{
CannonAnimation* ca = new CannonAnimation(this, buffer);
setAnimation(ca);
}
catch (const KartAnimationCreationException& kace)
{
Log::error("Flyable", "Kart animation creation error: %s",
kace.what());
buffer->skip(kace.getSkippingOffset());
}
}
else
m_animation->restoreState(buffer);
}

View File

@ -25,6 +25,7 @@
#include "utils/no_copy.hpp"
#include "utils/vec3.hpp"
#include <exception>
#include <limits>
#include <string>
@ -38,6 +39,14 @@ enum KartAnimationType : uint8_t
KAT_CANNON = 2
};
/** Exception for kart animation creation in networking, so if thrown it will
* tell the num of bytes skipping in the game state. */
class KartAnimationCreationException : public std::exception
{
public:
virtual int getSkippingOffset() const = 0;
};
/** The base class for all kart animation, like rescue, explosion, or cannon.
* Kart animations are done by removing the physics body from the physics
* world, and instead modifying the rotation and position of the kart

View File

@ -380,18 +380,36 @@ void CannonAnimation::restoreState(BareNetworkString* buffer)
// ----------------------------------------------------------------------------
void CannonAnimation::restoreData(BareNetworkString* buffer)
{
// Kart cannon has 2 floats + 1 compressed quaternion
// Flyable has 1 float (delta)
const int skipping_offset = m_kart ? 12 : 4;
class CannonCreationException : public KartAnimationCreationException
{
private:
const std::string m_error;
const int m_skipping_offset;
public:
CannonCreationException(const std::string& error, int skipping_offset)
: m_error(error), m_skipping_offset(skipping_offset) {}
// --------------------------------------------------------------------
virtual int getSkippingOffset() const { return m_skipping_offset; }
// --------------------------------------------------------------------
virtual const char* what() const throw() { return m_error.c_str(); }
};
int cc_idx = buffer->getInt8();
if ((unsigned)cc_idx > CheckManager::get()->getCheckStructureCount())
{
throw std::invalid_argument(
"Server has different check structure size.");
throw CannonCreationException(
"Server has different check structure size.", skipping_offset);
}
CheckCannon* cc = dynamic_cast<CheckCannon*>
(CheckManager::get()->getCheckStructure(cc_idx));
if (!cc)
{
throw std::invalid_argument(
"Server has different check cannon index.");
throw CannonCreationException(
"Server has different check cannon index.", skipping_offset);
}
float skid_rot = 0.0f;
float fraction_of_line = 0.0f;

View File

@ -30,7 +30,6 @@ class CheckCannon;
class Flyable;
class Ipo;
/** This animation shoots the kart to a specified point on the track.
*
* \ingroup karts

View File

@ -330,17 +330,27 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
{
delete m_kart_animation;
m_kart_animation = NULL;
switch (kat)
try
{
case KAT_RESCUE:
new RescueAnimation(this, buffer);
break;
case KAT_EXPLOSION:
new ExplosionAnimation(this, buffer);
break;
case KAT_CANNON:
new CannonAnimation(this, buffer);
break;
switch (kat)
{
case KAT_RESCUE:
new RescueAnimation(this, buffer);
break;
case KAT_EXPLOSION:
new ExplosionAnimation(this, buffer);
break;
case KAT_CANNON:
new CannonAnimation(this, buffer);
break;
}
}
catch (const KartAnimationCreationException& kace)
{
Log::error("KartRewinder", "Kart animation creation error: %s",
kace.what());
buffer->skip(kace.getSkippingOffset());
m_kart_animation = NULL;
}
}
else