From 4a9a0fba0f2af97236e0c6596cb1aaf20489d95f Mon Sep 17 00:00:00 2001 From: Benau Date: Tue, 24 Jul 2018 15:43:31 +0800 Subject: [PATCH] Make flyable to work with shared_ptr --- src/items/flyable.cpp | 31 +++++- src/items/flyable.hpp | 24 ++++- src/items/powerup.cpp | 5 + src/items/powerup.hpp | 4 +- src/items/projectile_manager.cpp | 177 ++++++++++++++++++++++--------- src/items/projectile_manager.hpp | 18 +++- src/karts/kart_rewinder.cpp | 5 - src/karts/kart_rewinder.hpp | 2 +- src/karts/moveable.cpp | 2 +- src/modes/world.cpp | 6 +- src/network/rewinder.hpp | 4 +- 11 files changed, 205 insertions(+), 73 deletions(-) diff --git a/src/items/flyable.cpp b/src/items/flyable.cpp index 63e2d2127..474e3a384 100644 --- a/src/items/flyable.cpp +++ b/src/items/flyable.cpp @@ -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* ru) +{ +} // saveState + +// ---------------------------------------------------------------------------- +void Flyable::restoreState(BareNetworkString *buffer, int count) +{ +} // restoreState + +// ---------------------------------------------------------------------------- +std::function 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 */ diff --git a/src/items/flyable.hpp b/src/items/flyable.hpp index 8eba2bc6e..c9e22a951 100644 --- a/src/items/flyable.hpp +++ b/src/items/flyable.hpp @@ -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* ru) + OVERRIDE; + // ------------------------------------------------------------------------ + virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE; + // ------------------------------------------------------------------------ + virtual std::function getLocalStateRestoreFunction() OVERRIDE; }; // Flyable #endif diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index fc3f0895c..99c7b8f42 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -211,6 +211,11 @@ void Powerup::adjustSound() } } // adjustSound +//----------------------------------------------------------------------------- +void Powerup::playSound() +{ +} // playSound + //----------------------------------------------------------------------------- /** Use (fire) this powerup. */ diff --git a/src/items/powerup.hpp b/src/items/powerup.hpp index 9077495da..4e4965f80 100644 --- a/src/items/powerup.hpp +++ b/src/items/powerup.hpp @@ -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 (); diff --git a/src/items/projectile_manager.cpp b/src/items/projectile_manager.cpp index 907c77ca4..8b088f204 100644 --- a/src/items/projectile_manager.cpp +++ b/src/items/projectile_manager.cpp @@ -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 + ProjectileManager::newProjectile(AbstractKart *kart, + PowerupManager::PowerupType type) { - Flyable *f; + std::shared_ptr 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(kart); + break; + case PowerupManager::POWERUP_PLUNGER: + f = std::make_shared(kart); + break; + case PowerupManager::POWERUP_CAKE: + f = std::make_shared(kart); + break; + case PowerupManager::POWERUP_RUBBERBALL: + f = std::make_shared(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(dist2second->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(dist2second->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 + ProjectileManager::addRewinderFromNetworkState(const std::string& uid) +{ + std::vector 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(kart); + f->addForRewind(uid); + m_active_projectiles[uid] = f; + return f; + } + case 'P': + { + auto f = std::make_shared(kart); + f->addForRewind(uid); + m_active_projectiles[uid] = f; + return f; + } + case 'C': + { + auto f = std::make_shared(kart); + f->addForRewind(uid); + m_active_projectiles[uid] = f; + return f; + } + case 'R': + { + auto f = std::make_shared(kart); + f->addForRewind(uid); + m_active_projectiles[uid] = f; + return f; + } + default: + assert(false); + return nullptr; + } +} // addProjectileFromNetworkState diff --git a/src/items/projectile_manager.hpp b/src/items/projectile_manager.hpp index 9518ccec2..236026570 100644 --- a/src/items/projectile_manager.hpp +++ b/src/items/projectile_manager.hpp @@ -19,6 +19,8 @@ #ifndef HEADER_PROJECTILEMANAGER_HPP #define HEADER_PROJECTILEMANAGER_HPP +#include +#include #include 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 Projectiles; typedef std::vector HitEffects; /** The list of all active projectiles, i.e. projectiles which are * currently moving on the track. */ - Projectiles m_active_projectiles; + std::map > 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 + addRewinderFromNetworkState(const std::string& uid); + // ------------------------------------------------------------------------ + std::shared_ptr newProjectile(AbstractKart *kart, + PowerupManager::PowerupType type); + }; extern ProjectileManager *projectile_manager; diff --git a/src/karts/kart_rewinder.cpp b/src/karts/kart_rewinder.cpp index 1d4de3f1a..8b80c30b7 100644 --- a/src/karts/kart_rewinder.cpp +++ b/src/karts/kart_rewinder.cpp @@ -222,11 +222,6 @@ void KartRewinder::update(int ticks) Kart::update(ticks); } // update -// ---------------------------------------------------------------------------- -void KartRewinder::rewindToEvent(BareNetworkString *buffer) -{ -} // rewindToEvent - // ---------------------------------------------------------------------------- std::function KartRewinder::getLocalStateRestoreFunction() { diff --git a/src/karts/kart_rewinder.hpp b/src/karts/kart_rewinder.hpp index ebdd39b35..1c9beb254 100644 --- a/src/karts/kart_rewinder.hpp +++ b/src/karts/kart_rewinder.hpp @@ -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 diff --git a/src/karts/moveable.cpp b/src/karts/moveable.cpp index cf16491fe..492315f36 100644 --- a/src/karts/moveable.cpp +++ b/src/karts/moveable.cpp @@ -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 diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 7685bc81b..94381a06a 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -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 diff --git a/src/network/rewinder.hpp b/src/network/rewinder.hpp index 045eb7413..e314152dd 100644 --- a/src/network/rewinder.hpp +++ b/src/network/rewinder.hpp @@ -31,7 +31,6 @@ class Rewinder : public std::enable_shared_from_this { 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 std::shared_ptr getShared() + { return std::dynamic_pointer_cast(shared_from_this()); } }; // Rewinder #endif