Improve swatter in network by locally add a swat event
This commit is contained in:
parent
b164a35d91
commit
9a8d5fc667
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user