Fix rubber ball in network

This commit is contained in:
Benau 2018-07-29 15:59:34 +08:00
parent 3f27a04bd1
commit 982220daf8
5 changed files with 155 additions and 24 deletions

View File

@ -408,8 +408,11 @@ bool Flyable::updateAndDelete(int ticks)
if (hasAnimation())
{
m_animation->update(stk_config->ticks2Time(ticks));
Moveable::update(ticks);
if (!RewindManager::get()->isRewinding())
{
m_animation->update(stk_config->ticks2Time(ticks));
Moveable::update(ticks);
}
return false;
} // if animation
@ -626,13 +629,16 @@ void Flyable::restoreState(BareNetworkString *buffer, int count)
Vec3 lv, av;
CompressNetworkBody::decompress(buffer, &t, &lv, &av);
m_body->setWorldTransform(t);
m_motion_state->setWorldTransform(t);
m_body->setInterpolationWorldTransform(t);
m_body->setLinearVelocity(lv);
m_body->setAngularVelocity(av);
m_body->setInterpolationLinearVelocity(lv);
m_body->setInterpolationAngularVelocity(av);
if (!hasAnimation())
{
m_body->setWorldTransform(t);
m_motion_state->setWorldTransform(t);
m_body->setInterpolationWorldTransform(t);
m_body->setLinearVelocity(lv);
m_body->setAngularVelocity(av);
m_body->setInterpolationLinearVelocity(lv);
m_body->setInterpolationAngularVelocity(av);
}
uint16_t hit_and_ticks = buffer->getUInt16();
m_has_hit_something = (hit_and_ticks >> 15) == 1;
m_ticks_since_thrown = hit_and_ticks & ~(1 << 15);

View File

@ -27,6 +27,7 @@
#include "items/projectile_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/linear_world.hpp"
#include "network/rewind_manager.hpp"
#include "physics/btKart.hpp"
#include "physics/triangle_mesh.hpp"
#include "tracks/check_manager.hpp"
@ -77,6 +78,17 @@ RubberBall::RubberBall(AbstractKart *kart)
setAdjustUpVelocity(false);
m_max_lifespan = stk_config->time2Ticks(9999);
m_target = NULL;
m_ping_sfx = SFXManager::get()->createSoundSource("ball_bounce");
m_owner_init_pos = m_owner->getXYZ();
m_init_pos = getXYZ();
additionalPhysicsProperties();
CheckManager::get()->addFlyableToCannons(this);
} // RubberBall
// ----------------------------------------------------------------------------
void RubberBall::additionalPhysicsProperties()
{
setXYZ(m_init_pos);
m_aiming_at_target = false;
m_fast_ping = false;
// At the start the ball aims at quads till it gets close enough to the
@ -84,9 +96,8 @@ RubberBall::RubberBall(AbstractKart *kart)
m_height_timer = 0.0f;
m_interval = m_st_interval;
m_current_max_height = m_max_height;
m_ping_sfx = SFXManager::get()->createSoundSource("ball_bounce");
// Just init the previoux coordinates with some value that's not getXYZ()
m_previous_xyz = m_owner->getXYZ();
m_previous_xyz = m_owner_init_pos;
m_previous_height = 2.0f; //
// A negative value indicates that the timer is not active
m_delete_ticks = -1;
@ -103,9 +114,8 @@ RubberBall::RubberBall(AbstractKart *kart)
const Vec3& normal =
DriveGraph::get()->getNode(getCurrentGraphNode())->getNormal();
TerrainInfo::update(getXYZ(), -normal);
initializeControlPoints(m_owner->getXYZ());
CheckManager::get()->addFlyableToCannons(this);
} // RubberBall
initializeControlPoints(m_owner_init_pos);
} // additionalPhysicsProperties
// ----------------------------------------------------------------------------
/** Destructor, removes any playing sfx.
@ -154,6 +164,29 @@ void RubberBall::setAnimation(AbstractKartAnimation *animation)
{
initializeControlPoints(getXYZ());
m_height_timer = 0;
if (RewindManager::get()->useLocalEvent())
{
std::shared_ptr<RubberBall> rb = getShared<RubberBall>();
btTransform cur_trans = getTrans();
Vec3 cur_previous_xyz = m_previous_xyz;
RewindManager::get()->addRewindInfoEventFunction(new
RewindInfoEventFunction(World::getWorld()->getTicksSinceStart(),
/*undo_function*/[rb]()
{
rb->m_undo_creation = true;
rb->moveToInfinity();
},
/*replay_function*/[rb, cur_trans, cur_previous_xyz]()
{
rb->m_undo_creation = false;
rb->m_body->setWorldTransform(cur_trans);
rb->m_motion_state->setWorldTransform(cur_trans);
rb->m_body->setInterpolationWorldTransform(cur_trans);
rb->m_previous_xyz = cur_previous_xyz;
rb->initializeControlPoints(cur_trans.getOrigin());
rb->m_height_timer = 0;
}));
}
}
Flyable::setAnimation(animation);
} // setAnimation
@ -326,7 +359,6 @@ bool RubberBall::updateAndDelete(int ticks)
// FIXME: what does the rubber ball do in case of battle mode??
if(!world) return true;
if(m_delete_ticks>0)
{
m_delete_ticks -= 1;
@ -408,16 +440,16 @@ bool RubberBall::updateAndDelete(int ticks)
// Ball squashing:
// ===============
#ifndef SERVER_ONLY
if (height<1.0f*m_extend.getY())
m_node->setScale(core::vector3df(1.0f, height / m_extend.getY(), 1.0f));
else
m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));
next_xyz = getHitPoint() + getNormal()*(height*m_node->getScale().Y);
float scale = 1.0f;
if (height < 1.0f * m_extend.getY())
scale = height / m_extend.getY();
#else
next_xyz = getHitPoint() + getNormal()*(height);
#ifndef SERVER_ONLY
if (!RewindManager::get()->isRewinding())
m_node->setScale(core::vector3df(1.0f, scale, 1.0f));
#endif
next_xyz = getHitPoint() + getNormal() * (height * scale);
m_previous_xyz = getXYZ();
m_previous_height = (getXYZ() - getHitPoint()).length();
setXYZ(next_xyz);
@ -567,7 +599,8 @@ float RubberBall::updateHeight()
if(m_height_timer>m_interval)
{
m_height_timer -= m_interval;
if(m_ping_sfx->getStatus()!=SFXBase::SFX_PLAYING)
if (m_ping_sfx->getStatus()!=SFXBase::SFX_PLAYING &&
!RewindManager::get()->isRewinding())
{
m_ping_sfx->setPosition(getXYZ());
m_ping_sfx->play();
@ -741,3 +774,56 @@ bool RubberBall::hit(AbstractKart* kart, PhysicalObject* object)
}
return was_real_hit;
} // hit
// ----------------------------------------------------------------------------
BareNetworkString* RubberBall::saveState(std::vector<std::string>* ru)
{
BareNetworkString* buffer = Flyable::saveState(ru);
buffer->addUInt32(m_last_aimed_graph_node);
buffer->add(m_control_points[0]);
buffer->add(m_control_points[1]);
buffer->add(m_control_points[2]);
buffer->add(m_control_points[3]);
buffer->add(m_previous_xyz);
buffer->addFloat(m_previous_height);
buffer->addFloat(m_length_cp_1_2);
buffer->addFloat(m_length_cp_2_3);
buffer->addFloat(m_t);
buffer->addFloat(m_t_increase);
buffer->addFloat(m_interval);
buffer->addUInt8(m_fast_ping ? 1 : 0);
buffer->addFloat(m_distance_to_target);
buffer->addFloat(m_height_timer);
buffer->addUInt32(m_delete_ticks);
buffer->addFloat(m_current_max_height);
buffer->addUInt8(m_aiming_at_target ? 1 : 0);
buffer->addUInt32(m_tunnel_count);
TrackSector::saveState(buffer);
return buffer;
} // saveState
// ----------------------------------------------------------------------------
void RubberBall::restoreState(BareNetworkString *buffer, int count)
{
Flyable::restoreState(buffer, count);
m_last_aimed_graph_node = buffer->getUInt32();
m_control_points[0] = buffer->getVec3();
m_control_points[1] = buffer->getVec3();
m_control_points[2] = buffer->getVec3();
m_control_points[3] = buffer->getVec3();
m_previous_xyz = buffer->getVec3();
m_previous_height = buffer->getFloat();
m_length_cp_1_2 = buffer->getFloat();
m_length_cp_2_3 = buffer->getFloat();
m_t = buffer->getFloat();
m_t_increase = buffer->getFloat();
m_interval = buffer->getFloat();
m_fast_ping = buffer->getUInt8() == 1;
m_distance_to_target = buffer->getFloat();
m_height_timer = buffer->getFloat();
m_delete_ticks = buffer->getUInt32();
m_current_max_height = buffer->getFloat();
m_aiming_at_target = buffer->getUInt8() == 1;
m_tunnel_count = buffer->getUInt32();
TrackSector::rewindTo(buffer);
} // restoreState

View File

@ -187,6 +187,9 @@ private:
/** A 'ping' sound effect to be played when the ball hits the ground. */
SFXBase *m_ping_sfx;
/* Used by undo and redo the firing when rewind */
Vec3 m_owner_init_pos, m_init_pos;
void computeTarget();
void updateDistanceToTarget();
unsigned int getSuccessorToHitTarget(unsigned int node_index,
@ -199,6 +202,8 @@ private:
float getTunnelHeight(const Vec3 &next_xyz,
const float vertical_offset) const;
bool checkTunneling();
virtual void additionalPhysicsProperties() OVERRIDE;
public:
RubberBall (AbstractKart* kart);
virtual ~RubberBall();
@ -214,6 +219,12 @@ public:
/** This object does not create an explosion, all affects on
* karts are handled by this hit() function. */
//virtual HitEffect *getHitEffect() const {return NULL; }
// ------------------------------------------------------------------------
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
OVERRIDE;
// ------------------------------------------------------------------------
virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE;
// ------------------------------------------------------------------------
}; // RubberBall

View File

@ -20,6 +20,7 @@
#include "modes/linear_world.hpp"
#include "modes/world.hpp"
#include "network/network_string.hpp"
#include "tracks/check_manager.hpp"
#include "tracks/check_structure.hpp"
#include "tracks/arena_graph.hpp"
@ -157,3 +158,25 @@ float TrackSector::getRelativeDistanceToCenter() const
ratio=-1.0f;
return ratio;
} // getRelativeDistanceToCenter
// ----------------------------------------------------------------------------
void TrackSector::saveState(BareNetworkString* buffer) const
{
buffer->addUInt32(m_current_graph_node);
buffer->addUInt32(m_last_valid_graph_node);
buffer->add(m_current_track_coords);
buffer->add(m_latest_valid_track_coords);
buffer->addUInt8(m_on_road ? 1 : 0);
buffer->addUInt32(m_last_triggered_checkline);
} // saveState
// ----------------------------------------------------------------------------
void TrackSector::rewindTo(BareNetworkString* buffer)
{
m_current_graph_node = buffer->getUInt32();
m_last_valid_graph_node = buffer->getUInt32();
m_current_track_coords = buffer->getVec3();
m_latest_valid_track_coords = buffer->getVec3();
m_on_road = buffer->getUInt8() == 1;
m_last_triggered_checkline = buffer->getUInt32();
} // rewindTo

View File

@ -21,6 +21,7 @@
#include "utils/vec3.hpp"
class BareNetworkString;
class Track;
/** This object keeps track of which sector an object is on. A sector is
@ -83,6 +84,10 @@ public:
void setLastTriggeredCheckline(int i) { m_last_triggered_checkline = i; }
// ------------------------------------------------------------------------
int getLastValidGraphNode() const { return m_last_valid_graph_node; }
// ------------------------------------------------------------------------
void saveState(BareNetworkString* buffer) const;
// ------------------------------------------------------------------------
void rewindTo(BareNetworkString* buffer);
}; // TrackSector