Make flyable to work with shared_ptr

This commit is contained in:
Benau 2018-07-24 15:43:31 +08:00
parent 60bfc1840b
commit 4a9a0fba0f
11 changed files with 205 additions and 73 deletions

View File

@ -37,6 +37,7 @@
#include "karts/explosion_animation.hpp"
#include "modes/linear_world.hpp"
#include "modes/soccer_world.hpp"
#include "network/network_string.hpp"
#include "physics/physics.hpp"
#include "tracks/track.hpp"
#include "utils/constants.hpp"
@ -378,7 +379,7 @@ void Flyable::setAnimation(AbstractKartAnimation *animation)
*/
void Flyable::updateGraphics(float dt)
{
updateSmoothedGraphics(dt);
Moveable::updateSmoothedGraphics(dt);
Moveable::updateGraphics();
} // updateGraphics
@ -573,5 +574,31 @@ HitEffect* Flyable::getHitEffect() const
unsigned int Flyable::getOwnerId()
{
return m_owner->getWorldKartId();
}
} // getOwnerId
// ----------------------------------------------------------------------------
BareNetworkString* Flyable::saveState(std::vector<std::string>* ru)
{
} // saveState
// ----------------------------------------------------------------------------
void Flyable::restoreState(BareNetworkString *buffer, int count)
{
} // restoreState
// ----------------------------------------------------------------------------
std::function<void()> Flyable::getLocalStateRestoreFunction()
{
} // getLocalStateRestoreFunction
// ----------------------------------------------------------------------------
void Flyable::addForRewind(const std::string& uid)
{
SmoothNetworkBody::setEnable(true);
SmoothNetworkBody::setSmoothRotation(false);
SmoothNetworkBody::setAdjustVerticalOffset(false);
Rewinder::setUniqueIdentity(uid);
Rewinder::rewinderAdd();
} // addForRewind
/* EOF */

View File

@ -24,6 +24,7 @@
#include "items/powerup_manager.hpp"
#include "karts/moveable.hpp"
#include "network/rewinder.hpp"
#include "tracks/terrain_info.hpp"
#include "utils/cpp2011.hpp"
@ -43,7 +44,8 @@ class XMLNode;
/**
* \ingroup items
*/
class Flyable : public Moveable, public TerrainInfo
class Flyable : public Moveable, public TerrainInfo,
public Rewinder
{
public:
private:
@ -128,7 +130,7 @@ protected:
/** Time since thrown. used so a kart can't hit himself when trying
* something, and also to put some time limit to some collectibles */
int m_ticks_since_thrown;
int16_t m_ticks_since_thrown;
/** Set to something > -1 if this flyable should auto-destrcut after
* that may ticks. */
@ -217,6 +219,24 @@ public:
/** Returns the size (extend) of the mesh. */
const Vec3 &getExtend() const { return m_extend; }
// ------------------------------------------------------------------------
void addForRewind(const std::string& uid);
// ------------------------------------------------------------------------
virtual void undoEvent(BareNetworkString *buffer) OVERRIDE {}
// ------------------------------------------------------------------------
virtual void rewindToEvent(BareNetworkString *buffer) OVERRIDE {}
// ------------------------------------------------------------------------
virtual void undoState(BareNetworkString *buffer) OVERRIDE {}
// ------------------------------------------------------------------------
virtual void saveTransform() OVERRIDE { Moveable::prepareSmoothing(); }
// ------------------------------------------------------------------------
virtual void computeError() OVERRIDE { Moveable::checkSmoothing(); }
// ------------------------------------------------------------------------
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
OVERRIDE;
// ------------------------------------------------------------------------
virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE;
// ------------------------------------------------------------------------
virtual std::function<void()> getLocalStateRestoreFunction() OVERRIDE;
}; // Flyable
#endif

View File

@ -211,6 +211,11 @@ void Powerup::adjustSound()
}
} // adjustSound
//-----------------------------------------------------------------------------
void Powerup::playSound()
{
} // playSound
//-----------------------------------------------------------------------------
/** Use (fire) this powerup.
*/

View File

@ -36,9 +36,6 @@ class SFXBase;
class Powerup : public NoCopy
{
private:
/** A synchronised random number generator for network games. */
RandomGenerator m_random;
/** Sound effect that is being played. */
SFXBase *m_sound_use;
@ -51,6 +48,7 @@ private:
/** The owner (kart) of this powerup. */
AbstractKart* m_kart;
void playSound();
public:
Powerup (AbstractKart* kart_);
~Powerup ();

View File

@ -27,6 +27,8 @@
#include "items/powerup.hpp"
#include "items/rubber_ball.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp"
#include "network/rewind_manager.hpp"
ProjectileManager *projectile_manager=0;
@ -45,12 +47,6 @@ void ProjectileManager::removeTextures()
//-----------------------------------------------------------------------------
void ProjectileManager::cleanup()
{
for(Projectiles::iterator i = m_active_projectiles.begin();
i != m_active_projectiles.end(); ++i)
{
delete *i;
}
m_active_projectiles.clear();
for(HitEffects::iterator i = m_active_hit_effects.begin();
i != m_active_hit_effects.end(); ++i)
@ -68,12 +64,8 @@ void ProjectileManager::cleanup()
*/
void ProjectileManager::updateGraphics(float dt)
{
for (auto p = m_active_projectiles.begin();
p != m_active_projectiles.end(); ++p)
{
(*p)->updateGraphics(dt);
}
for (auto& p : m_active_projectiles)
p.second->updateGraphics(dt);
} // updateGraphics
// -----------------------------------------------------------------------------
@ -107,24 +99,21 @@ void ProjectileManager::update(int ticks)
/** Updates all rockets on the server (or no networking). */
void ProjectileManager::updateServer(int ticks)
{
Projectiles::iterator p = m_active_projectiles.begin();
while(p!=m_active_projectiles.end())
auto p = m_active_projectiles.begin();
while (p != m_active_projectiles.end())
{
bool can_be_deleted = (*p)->updateAndDelete(ticks);
if(can_be_deleted)
bool can_be_deleted = p->second->updateAndDelete(ticks);
if (can_be_deleted)
{
HitEffect *he = (*p)->getHitEffect();
if(he)
HitEffect *he = p->second->getHitEffect();
if (he)
addHitEffect(he);
Flyable *f=*p;
Projectiles::iterator p_next=m_active_projectiles.erase(p);
delete f;
p=p_next;
p = m_active_projectiles.erase(p);
}
else
p++;
} // while p!=m_active_projectiles.end()
} // updateServer
// -----------------------------------------------------------------------------
@ -132,20 +121,30 @@ void ProjectileManager::updateServer(int ticks)
* \param kart The kart which shoots the projectile.
* \param type Type of projectile.
*/
Flyable *ProjectileManager::newProjectile(AbstractKart *kart,
PowerupManager::PowerupType type)
std::shared_ptr<Flyable>
ProjectileManager::newProjectile(AbstractKart *kart,
PowerupManager::PowerupType type)
{
Flyable *f;
std::shared_ptr<Flyable> f;
switch(type)
{
case PowerupManager::POWERUP_BOWLING: f = new Bowling(kart); break;
case PowerupManager::POWERUP_PLUNGER: f = new Plunger(kart); break;
case PowerupManager::POWERUP_CAKE: f = new Cake(kart); break;
case PowerupManager::POWERUP_RUBBERBALL: f = new RubberBall(kart);
break;
default: return NULL;
case PowerupManager::POWERUP_BOWLING:
f = std::make_shared<Bowling>(kart);
break;
case PowerupManager::POWERUP_PLUNGER:
f = std::make_shared<Plunger>(kart);
break;
case PowerupManager::POWERUP_CAKE:
f = std::make_shared<Cake>(kart);
break;
case PowerupManager::POWERUP_RUBBERBALL:
f = std::make_shared<RubberBall>(kart);
break;
default:
return nullptr;
}
m_active_projectiles.push_back(f);
const std::string& uid = getUniqueIdentity(kart, type);
m_active_projectiles[uid] = f;
return f;
} // newProjectile
@ -158,13 +157,13 @@ Flyable *ProjectileManager::newProjectile(AbstractKart *kart,
bool ProjectileManager::projectileIsClose(const AbstractKart * const kart,
float radius)
{
float r2 = radius*radius;
for(Projectiles::iterator i = m_active_projectiles.begin();
i != m_active_projectiles.end(); i++)
float r2 = radius * radius;
for (auto i = m_active_projectiles.begin(); i != m_active_projectiles.end();
i++)
{
float dist2 = (*i)->getXYZ().distance2(kart->getXYZ());
if(dist2<r2) return true;
float dist2 = i->second->getXYZ().distance2(kart->getXYZ());
if (dist2 < r2)
return true;
}
return false;
} // projectileIsClose
@ -179,21 +178,99 @@ bool ProjectileManager::projectileIsClose(const AbstractKart * const kart,
int ProjectileManager::getNearbyProjectileCount(const AbstractKart * const kart,
float radius, PowerupManager::PowerupType type)
{
float r2 = radius*radius;
int projectileCount = 0;
for(Projectiles::iterator i = m_active_projectiles.begin();
i != m_active_projectiles.end(); i++)
float r2 = radius * radius;
int projectile_count = 0;
for (auto i = m_active_projectiles.begin(); i != m_active_projectiles.end();
i++)
{
if ((*i)->getType() == type)
if (i->second->getType() == type)
{
float dist2 = (*i)->getXYZ().distance2(kart->getXYZ());
if(dist2<r2)
float dist2 = i->second->getXYZ().distance2(kart->getXYZ());
if (dist2 < r2)
{
projectileCount++;
projectile_count++;
}
}
}
return projectileCount;
return projectile_count;
} // getNearbyProjectileCount
// -----------------------------------------------------------------------------
std::string ProjectileManager::getUniqueIdentity(AbstractKart* kart,
PowerupManager::PowerupType t)
{
switch (t)
{
case PowerupManager::POWERUP_BOWLING:
return std::string("B_") +
StringUtils::toString(kart->getWorldKartId()) + "_" +
StringUtils::toString(World::getWorld()->getTicksSinceStart());
case PowerupManager::POWERUP_PLUNGER:
return std::string("P_") +
StringUtils::toString(kart->getWorldKartId()) + "_" +
StringUtils::toString(World::getWorld()->getTicksSinceStart());
case PowerupManager::POWERUP_CAKE:
return std::string("C_") +
StringUtils::toString(kart->getWorldKartId()) + "_" +
StringUtils::toString(World::getWorld()->getTicksSinceStart());
case PowerupManager::POWERUP_RUBBERBALL:
return std::string("R_") +
StringUtils::toString(kart->getWorldKartId()) + "_" +
StringUtils::toString(World::getWorld()->getTicksSinceStart());
default:
assert(false);
return "";
}
} // getUniqueIdentity
// -----------------------------------------------------------------------------
std::shared_ptr<Rewinder>
ProjectileManager::addRewinderFromNetworkState(const std::string& uid)
{
std::vector<std::string> id = StringUtils::split(uid, '_');
if (id.size() != 3)
return nullptr;
if (!(id[0] == "B" || id[0] == "P" || id[0] == "C" || id[0] == "R"))
return nullptr;
int world_id = -1;
if (!StringUtils::fromString(id[1], world_id))
return nullptr;
AbstractKart* kart = World::getWorld()->getKart(world_id);
char first_id = id[0][0];
Log::warn("ProjectileManager",
"Missed a firing event, add the flyable %s manually", uid.c_str());
switch (first_id)
{
case 'B':
{
auto f = std::make_shared<Bowling>(kart);
f->addForRewind(uid);
m_active_projectiles[uid] = f;
return f;
}
case 'P':
{
auto f = std::make_shared<Plunger>(kart);
f->addForRewind(uid);
m_active_projectiles[uid] = f;
return f;
}
case 'C':
{
auto f = std::make_shared<Cake>(kart);
f->addForRewind(uid);
m_active_projectiles[uid] = f;
return f;
}
case 'R':
{
auto f = std::make_shared<RubberBall>(kart);
f->addForRewind(uid);
m_active_projectiles[uid] = f;
return f;
}
default:
assert(false);
return nullptr;
}
} // addProjectileFromNetworkState

View File

@ -19,6 +19,8 @@
#ifndef HEADER_PROJECTILEMANAGER_HPP
#define HEADER_PROJECTILEMANAGER_HPP
#include <map>
#include <memory>
#include <vector>
namespace irr
@ -32,6 +34,7 @@ namespace irr
class AbstractKart;
class Flyable;
class HitEffect;
class Rewinder;
class Track;
class Vec3;
@ -41,17 +44,18 @@ class Vec3;
class ProjectileManager : public NoCopy
{
private:
typedef std::vector<Flyable*> Projectiles;
typedef std::vector<HitEffect*> HitEffects;
/** The list of all active projectiles, i.e. projectiles which are
* currently moving on the track. */
Projectiles m_active_projectiles;
std::map<std::string, std::shared_ptr<Flyable> > m_active_projectiles;
/** All active hit effects, i.e. hit effects which are currently
* being shown or have a sfx playing. */
HitEffects m_active_hit_effects;
std::string getUniqueIdentity(AbstractKart* kart,
PowerupManager::PowerupType type);
void updateServer(int ticks);
public:
ProjectileManager() {}
@ -60,9 +64,6 @@ public:
void cleanup ();
void update (int ticks);
void updateGraphics (float dt);
Flyable* newProjectile (AbstractKart *kart,
PowerupManager::PowerupType type);
void Deactivate (Flyable *p) {}
void removeTextures ();
bool projectileIsClose(const AbstractKart * const kart,
float radius);
@ -74,6 +75,13 @@ public:
* \param hit_effect The hit effect to be added. */
void addHitEffect(HitEffect *hit_effect)
{ m_active_hit_effects.push_back(hit_effect); }
// ------------------------------------------------------------------------
std::shared_ptr<Rewinder>
addRewinderFromNetworkState(const std::string& uid);
// ------------------------------------------------------------------------
std::shared_ptr<Flyable> newProjectile(AbstractKart *kart,
PowerupManager::PowerupType type);
};
extern ProjectileManager *projectile_manager;

View File

@ -222,11 +222,6 @@ void KartRewinder::update(int ticks)
Kart::update(ticks);
} // update
// ----------------------------------------------------------------------------
void KartRewinder::rewindToEvent(BareNetworkString *buffer)
{
} // rewindToEvent
// ----------------------------------------------------------------------------
std::function<void()> KartRewinder::getLocalStateRestoreFunction()
{

View File

@ -48,7 +48,7 @@ public:
OVERRIDE;
void reset() OVERRIDE;
virtual void restoreState(BareNetworkString *p, int count) OVERRIDE;
virtual void rewindToEvent(BareNetworkString *p) OVERRIDE;
virtual void rewindToEvent(BareNetworkString *p) OVERRIDE {}
virtual void update(int ticks) OVERRIDE;
// -------------------------------------------------------------------------
virtual float getSteerPercent() const OVERRIDE

View File

@ -64,7 +64,7 @@ void Moveable::updateSmoothedGraphics(float dt)
{
Vec3 velocity;
if (m_body)
velocity = m_body->getLinearVelocity();
velocity = getVelocity();
SmoothNetworkBody::updateSmoothedGraphics(m_transform, velocity, dt);
#undef DEBUG_SMOOTHING
#ifdef DEBUG_SMOOTHING

View File

@ -1055,13 +1055,13 @@ void World::update(int ticks)
}
PROFILER_POP_CPU_MARKER();
if(race_manager->isRecordingRace()) ReplayRecorder::get()->update(ticks);
Physics::getInstance()->update(ticks);
PROFILER_PUSH_CPU_MARKER("World::update (projectiles)", 0xa0, 0x7F, 0x00);
projectile_manager->update(ticks);
PROFILER_POP_CPU_MARKER();
if(race_manager->isRecordingRace()) ReplayRecorder::get()->update(ticks);
Physics::getInstance()->update(ticks);
PROFILER_POP_CPU_MARKER();
#ifdef DEBUG

View File

@ -31,7 +31,6 @@ class Rewinder : public std::enable_shared_from_this<Rewinder>
{
protected:
void setUniqueIdentity(const std::string& uid) { m_unique_identity = uid; }
private:
std::string m_unique_identity;
@ -92,6 +91,9 @@ public:
}
// -------------------------------------------------------------------------
bool rewinderAdd();
// -------------------------------------------------------------------------
template<typename T> std::shared_ptr<T> getShared()
{ return std::dynamic_pointer_cast<T>(shared_from_this()); }
}; // Rewinder
#endif