Improve swatter in network by locally add a swat event

This commit is contained in:
Benau 2018-08-02 16:37:56 +08:00
parent b164a35d91
commit 9a8d5fc667
5 changed files with 52 additions and 58 deletions

View File

@ -47,7 +47,6 @@
/** Initialises the attachment each kart has.
*/
Attachment::Attachment(AbstractKart* kart)
: EventRewinder()
{
m_type = ATTACH_NOTHING;
m_ticks_left = 0;
@ -148,7 +147,7 @@ void Attachment::set(AttachmentType type, int ticks,
m_node->setMesh(attachment_manager->getMesh(ATTACH_NOLOKS_SWATTER));
else
m_node->setMesh(attachment_manager->getMesh(type));
m_plugin = new Swatter(m_kart, was_bomb, bomb_scene_node);
m_plugin = new Swatter(m_kart, was_bomb, bomb_scene_node, ticks);
break;
case ATTACH_BOMB:
m_node->setMesh(attachment_manager->getMesh(type));
@ -208,17 +207,6 @@ void Attachment::set(AttachmentType type, int ticks,
}
}
m_node->setVisible(true);
#ifndef SERVER_ONLY
// Save event about the new attachment
RewindManager *rwm = RewindManager::get();
if(rwm->isEnabled() && !rwm->isRewinding())
{
// FIXME!!!! For now commented out
//BareNetworkString *buffer = new BareNetworkString(2);
//saveState(buffer);
//rwm->addEvent(this, buffer, /*confirmed*/true);
}
#endif
} // set
// -----------------------------------------------------------------------------
@ -311,7 +299,7 @@ void Attachment::rewindTo(BareNetworkString *buffer)
}
// If playing kart animation, don't rewind to any attacment
if (is_removing_bomb)
if (is_removing_bomb || m_kart->getKartAnimation())
return;
// Attaching an object can be expensive (loading new models, ...)
@ -331,16 +319,6 @@ void Attachment::rewindTo(BareNetworkString *buffer)
/*disable_swatter_animation*/);
} // rewindTo
// -----------------------------------------------------------------------------
/** Called when going forwards in time during a rewind.
* \param buffer Buffer with the rewind information.
*/
void Attachment::rewind(BareNetworkString *buffer)
{
// Event has same info as a state, so re-use the restore function
rewindTo(buffer);
} // rewind
// -----------------------------------------------------------------------------
/** Selects the new attachment. In order to simplify synchronisation with the
* server, the new item is based on the current world time.

View File

@ -21,9 +21,7 @@
#include "config/stk_config.hpp"
#include "items/attachment_plugin.hpp"
#include "network/event_rewinder.hpp"
#include "utils/no_copy.hpp"
#include "utils/random_generator.hpp"
#include <IAnimatedMeshSceneNode.h>
using namespace irr;
@ -46,8 +44,7 @@ class SFXBase;
* a scene node).
* \ingroup items
*/
class Attachment: public NoCopy, public scene::IAnimationEndCallBack,
public EventRewinder
class Attachment: public NoCopy, public scene::IAnimationEndCallBack
{
public:
// Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX.
@ -102,15 +99,12 @@ private:
* for certain attachments. */
AttachmentPlugin *m_plugin;
/** Pseudo random number generator. */
RandomGenerator m_random;
/** Ticking sound for the bomb */
SFXBase *m_bomb_sound;
/** Soung for exploding bubble gum shield */
SFXBase *m_bubble_explode_sound;
public:
Attachment(AbstractKart* kart);
~Attachment();
@ -123,7 +117,6 @@ public:
void set (AttachmentType type, int ticks,
AbstractKart *previous_kart=NULL,
bool disable_swatter_animation = false);
virtual void rewind(BareNetworkString *buffer);
void rewindTo(BareNetworkString *buffer);
void saveState(BareNetworkString *buffer) const;

View File

@ -40,6 +40,8 @@
#include "karts/kart_properties.hpp"
#include "modes/world.hpp"
#include "modes/soccer_world.hpp"
#include "network/network_config.hpp"
#include "network/rewind_manager.hpp"
#define SWAT_POS_OFFSET core::vector3df(0.0, 0.2f, -0.4f)
#define SWAT_ANGLE_MIN 45
@ -56,14 +58,15 @@
* attachment scene node).
*/
Swatter::Swatter(AbstractKart *kart, bool was_bomb,
scene::ISceneNode* bomb_scene_node)
: AttachmentPlugin(kart)
scene::ISceneNode* bomb_scene_node, int ticks)
: AttachmentPlugin(kart),
m_swatter_start_ticks(World::getWorld()->getTicksSinceStart()),
m_swatter_end_ticks(World::getWorld()->getTicksSinceStart() + ticks)
{
m_animation_phase = SWATTER_AIMING;
m_discard_now = false;
m_target = NULL;
m_closest_kart = NULL;
m_bomb_scene_node = bomb_scene_node;
m_swat_bomb_frame = 0.0f;
@ -162,19 +165,29 @@ void Swatter::updateGrahpics(float dt)
*/
bool Swatter::updateAndTestFinished(int ticks)
{
const int ticks_start = World::getWorld()->getTicksSinceStart();
if (m_removed_bomb_ticks != std::numeric_limits<int>::max())
{
if (World::getWorld()->getTicksSinceStart() >= m_removed_bomb_ticks)
if (ticks_start >= m_removed_bomb_ticks)
return true;
return false;
} // if removing bomb
if (RewindManager::get()->isRewinding())
return false;
if (!m_discard_now)
{
switch (m_animation_phase)
{
case SWATTER_AIMING:
{
// Avoid swatter near the start and the end lifetime of swatter
// to make sure all clients know the existence of swatter each other
if (ticks_start - m_swatter_start_ticks < 60 ||
m_swatter_end_ticks - ticks_start < 60)
return false;
chooseTarget();
pointToTarget();
if(!m_target || !m_closest_kart) break;
@ -198,8 +211,7 @@ bool Swatter::updateAndTestFinished(int ticks)
{
// Start squashing
m_animation_phase = SWATTER_TO_TARGET;
m_start_swat_ticks =
World::getWorld()->getTicksSinceStart() + 20;
m_start_swat_ticks = ticks_start + 20;
// Setup the animation
m_scene_node->setCurrentFrame(0.0f);
m_scene_node->setLoopMode(false);
@ -207,14 +219,8 @@ bool Swatter::updateAndTestFinished(int ticks)
#ifndef SERVER_ONLY
// Play swat sound
const int wt = World::getWorld()->getTicksSinceStart();
auto it = m_swat_sound_ticks.find(wt);
if (it == m_swat_sound_ticks.end())
{
m_swat_sound->setPosition(swatter_pos);
m_swat_sound->play();
m_swat_sound_ticks.insert(wt);
}
m_swat_sound->setPosition(swatter_pos);
m_swat_sound->play();
#endif
}
}
@ -223,15 +229,14 @@ bool Swatter::updateAndTestFinished(int ticks)
{
pointToTarget();
// Did we just finish the first part of the movement?
if (World::getWorld()->getTicksSinceStart() > m_start_swat_ticks)
if (ticks_start > m_start_swat_ticks)
{
m_start_swat_ticks = std::numeric_limits<int>::max();
// Squash the karts and items around and
// change the current phase
squashThingsAround();
m_animation_phase = SWATTER_FROM_TARGET;
const int end_ticks =
World::getWorld()->getTicksSinceStart() + 60;
const int end_ticks = ticks_start + 60;
if (race_manager
->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES ||
race_manager
@ -253,9 +258,9 @@ bool Swatter::updateAndTestFinished(int ticks)
if (m_discard_now)
{
return World::getWorld()->getTicksSinceStart() > m_end_swat_ticks;
return ticks_start > m_end_swat_ticks;
}
else if (World::getWorld()->getTicksSinceStart() > m_end_swat_ticks)
else if (ticks_start > m_end_swat_ticks)
{
m_animation_phase = SWATTER_AIMING;
m_end_swat_ticks = std::numeric_limits<int>::max();
@ -335,8 +340,23 @@ void Swatter::squashThingsAround()
{
const KartProperties *kp = m_kart->getKartProperties();
m_closest_kart->setSquash(kp->getSwatterSquashDuration(),
kp->getSwatterSquashSlowdown());
AbstractKart* closest_kart = m_closest_kart;
float duration = kp->getSwatterSquashDuration();
float slowdown = kp->getSwatterSquashSlowdown();
closest_kart->setSquash(duration, slowdown);
// Locally add a event to replay the squash during rewind
if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isClient())
{
RewindManager::get()->addRewindInfoEventFunction(new
RewindInfoEventFunction(World::getWorld()->getTicksSinceStart(),
/*undo_function*/[](){},
/*replay_function*/[closest_kart, duration, slowdown]()
{
closest_kart->setSquash(duration, slowdown);
}));
}
// Handle achievement if the swatter is used by the current player
if (m_kart->getController()->canGetAchievements())

View File

@ -74,14 +74,17 @@ private:
/** For some reason the built-in animation system doesn't work correctly here?? */
float m_swat_bomb_frame;
std::set<int> m_swat_sound_ticks;
int m_start_swat_ticks;
int m_end_swat_ticks;
const int m_swatter_start_ticks;
const int m_swatter_end_ticks;
public:
Swatter(AbstractKart *kart, bool was_bomb,
scene::ISceneNode* bomb_scene_node);
scene::ISceneNode* bomb_scene_node, int ticks);
virtual ~Swatter();
void updateGrahpics(float dt) OVERRIDE;
bool updateAndTestFinished(int ticks) OVERRIDE;

View File

@ -2953,7 +2953,7 @@ void Kart::updateGraphics(float dt)
{
m_squash_time -= dt;
// If squasing time ends, reset the model
if (m_squash_time <= 0.0f)
if (m_squash_time <= 0.0f || !isSquashed())
{
m_squash_time = std::numeric_limits<float>::max();
m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));