diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 63c553cf0..87574b00a 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -41,8 +41,6 @@ #include "network/rewind_manager.hpp" #include "physics/triangle_mesh.hpp" #include "tracks/track.hpp" -#include "physics/triangle_mesh.hpp" -#include "tracks/track.hpp" #include "utils/constants.hpp" #include "irrMath.h" @@ -543,7 +541,7 @@ void Attachment::update(int ticks) m_bubble_explode_sound->play(); } if (!m_kart->isGhostKart()) - ItemManager::get()->dropNewItem(Item::ITEM_BUBBLEGUM, m_kart); + Track::getCurrentTrack()->getItemManager()->dropNewItem(Item::ITEM_BUBBLEGUM, m_kart); } break; } // switch diff --git a/src/items/item.cpp b/src/items/item.cpp index ec6c9b28e..5f830aa24 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -32,7 +32,6 @@ #include "tracks/arena_graph.hpp" #include "tracks/drive_graph.hpp" #include "tracks/drive_node.hpp" -#include "tracks/track.hpp" #include "utils/constants.hpp" #include "utils/string_utils.hpp" @@ -350,13 +349,13 @@ void Item::handleNewMesh(ItemType type) #ifndef SERVER_ONLY if (m_node == NULL) return; - setMesh(ItemManager::get()->getItemModel(type), - ItemManager::get()->getItemLowResolutionModel(type)); + setMesh(ItemManager::getItemModel(type), + ItemManager::getItemLowResolutionModel(type)); for (auto* node : m_node->getAllNodes()) { SP::SPMeshNode* spmn = dynamic_cast(node); if (spmn) - spmn->setGlowColor(ItemManager::get()->getGlowColor(type)); + spmn->setGlowColor(ItemManager::getGlowColor(type)); } Vec3 hpr; hpr.setHPR(getOriginalRotation()); diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index e55947b02..531dd7735 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -48,27 +48,9 @@ std::vector ItemManager::m_item_mesh; std::vector ItemManager::m_item_lowres_mesh; std::vector ItemManager::m_glow_color; bool ItemManager::m_disable_item_collection = false; -std::shared_ptr ItemManager::m_item_manager; std::mt19937 ItemManager::m_random_engine; uint32_t ItemManager::m_random_seed = 0; -//----------------------------------------------------------------------------- -/** Creates one instance of the item manager. */ -void ItemManager::create() -{ - assert(!m_item_manager); - // Due to protected constructor use new instead of make_shared - m_item_manager = std::shared_ptr(new ItemManager()); -} // create - -//----------------------------------------------------------------------------- -/** Destroys the one instance of the item manager. */ -void ItemManager::destroy() -{ - assert(m_item_manager); - m_item_manager = nullptr; -} // destroy - //----------------------------------------------------------------------------- /** Loads the default item meshes (high- and low-resolution). */ diff --git a/src/items/item_manager.hpp b/src/items/item_manager.hpp index 10da49e05..e93b7fd8d 100644 --- a/src/items/item_manager.hpp +++ b/src/items/item_manager.hpp @@ -56,15 +56,9 @@ private: static std::mt19937 m_random_engine; static uint32_t m_random_seed; -protected: - /** The instance of ItemManager while a race is on. */ - static std::shared_ptr m_item_manager; - public: static void loadDefaultItemMeshes(); static void removeTextures(); - static void create(); - static void destroy(); static void updateRandomSeed(uint32_t seed_number) { m_random_engine.seed(seed_number); @@ -97,14 +91,6 @@ public: /** Returns the glow color for an item. */ static video::SColorf& getGlowColor(ItemState::ItemType type) { return m_glow_color[type]; } - // ------------------------------------------------------------------------ - /** Return an instance of the item manager (it does not automatically - * create one, call create for that). */ - static ItemManager *get() - { - assert(m_item_manager); - return m_item_manager.get(); - } // get // ======================================================================== protected: @@ -138,8 +124,8 @@ protected: void setSwitchItems(const std::vector &switch_items); void insertItemInQuad(Item *item); void deleteItemInQuad(ItemState *item); - ItemManager(); public: + ItemManager(); virtual ~ItemManager(); virtual Item* placeItem (ItemState::ItemType type, const Vec3& xyz, diff --git a/src/items/network_item_manager.cpp b/src/items/network_item_manager.cpp index 585f37aa1..2651007c2 100644 --- a/src/items/network_item_manager.cpp +++ b/src/items/network_item_manager.cpp @@ -28,17 +28,6 @@ #include "network/stk_peer.hpp" bool NetworkItemManager::m_network_item_debugging = false; - -//----------------------------------------------------------------------------- -/** Creates one instance of the item manager. */ -void NetworkItemManager::create() -{ - assert(!m_item_manager); - auto nim = std::shared_ptr(new NetworkItemManager()); - nim->rewinderAdd(); - m_item_manager = nim; -} // create - // ============================================================================ /** Creates a new instance of the item manager. This is done at startup * of each race. diff --git a/src/items/network_item_manager.hpp b/src/items/network_item_manager.hpp index 6bdfdc80e..730263808 100644 --- a/src/items/network_item_manager.hpp +++ b/src/items/network_item_manager.hpp @@ -66,14 +66,11 @@ private: Synchronised< std::vector > m_item_events; void forwardTime(int ticks); - - NetworkItemManager(); - public: static bool m_network_item_debugging; - static void create(); + NetworkItemManager(); virtual ~NetworkItemManager(); virtual void reset() OVERRIDE; virtual void setItemConfirmationTime(std::weak_ptr peer, diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index 94c089dff..32678b550 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -271,6 +271,7 @@ void Powerup::use() m_number--; World *world = World::getWorld(); + ItemManager* im = Track::getCurrentTrack()->getItemManager(); switch (m_type) { case PowerupManager::POWERUP_ZIPPER: @@ -278,7 +279,7 @@ void Powerup::use() break ; case PowerupManager::POWERUP_SWITCH: { - ItemManager::get()->switchItems(); + im->switchItems(); if (!has_played_sound) { m_sound_use->setPosition(m_kart->getXYZ()); @@ -310,8 +311,7 @@ void Powerup::use() // use the bubble gum the traditional way, if the kart is looking back if (m_kart->getControls().getLookBack()) { - Item *new_item = - ItemManager::get()->dropNewItem(Item::ITEM_BUBBLEGUM, m_kart); + Item *new_item = im->dropNewItem(Item::ITEM_BUBBLEGUM, m_kart); // E.g. ground not found in raycast. if(!new_item) return; diff --git a/src/karts/controller/arena_ai.cpp b/src/karts/controller/arena_ai.cpp index 6fd41844e..1ef3b2014 100644 --- a/src/karts/controller/arena_ai.cpp +++ b/src/karts/controller/arena_ai.cpp @@ -28,12 +28,14 @@ #include "karts/rescue_animation.hpp" #include "tracks/arena_graph.hpp" #include "tracks/arena_node.hpp" +#include "tracks/track.hpp" #include ArenaAI::ArenaAI(AbstractKart *kart) : AIBaseController(kart) { + m_item_manager = Track::getCurrentTrack()->getItemManager(); m_debug_sphere = NULL; m_debug_sphere_next = NULL; m_graph = ArenaGraph::get(); @@ -580,7 +582,7 @@ void ArenaAI::tryCollectItem(Vec3* aim_point, int* target_node) const { float distance = 999999.9f; Item* selected = (*target_node == Graph::UNKNOWN_SECTOR ? NULL : - ItemManager::get()->getFirstItemInQuad(*target_node)); + m_item_manager->getFirstItemInQuad(*target_node)); // Don't look for a new item unless it's collected or swapped if (selected && selected->isAvailable() && !selected->isNegativeItem()) @@ -591,7 +593,7 @@ void ArenaAI::tryCollectItem(Vec3* aim_point, int* target_node) const for (unsigned int i = 0; i < m_graph->getNumNodes(); i++) { - Item* cur_item = ItemManager::get()->getFirstItemInQuad(i); + Item* cur_item = m_item_manager->getFirstItemInQuad(i); if (cur_item == NULL) continue; if (!cur_item->isAvailable() || cur_item->isNegativeItem()) continue; @@ -661,7 +663,7 @@ void ArenaAI::determinePath(int forward, std::vector* path) // Only test few nodes ahead if (i == 6) break; const int node = (*path)[i]; - Item* selected = ItemManager::get()->getFirstItemInQuad(node); + Item* selected = m_item_manager->getFirstItemInQuad(node); if (selected && selected->isAvailable() && selected->isNegativeItem()) { diff --git a/src/karts/controller/arena_ai.hpp b/src/karts/controller/arena_ai.hpp index 71c49f85d..3347c7bf9 100644 --- a/src/karts/controller/arena_ai.hpp +++ b/src/karts/controller/arena_ai.hpp @@ -28,6 +28,7 @@ #endif class ArenaGraph; +class ItemManager; namespace irr { @@ -40,6 +41,8 @@ namespace irr class ArenaAI : public AIBaseController { protected: + ItemManager* m_item_manager; + /** Pointer to the \ref ArenaGraph. */ ArenaGraph* m_graph; diff --git a/src/karts/controller/skidding_ai.cpp b/src/karts/controller/skidding_ai.cpp index 1d5695d2e..f1b4a5c16 100644 --- a/src/karts/controller/skidding_ai.cpp +++ b/src/karts/controller/skidding_ai.cpp @@ -61,6 +61,7 @@ SkiddingAI::SkiddingAI(AbstractKart *kart) : AIBaseLapController(kart) { + m_item_manager = Track::getCurrentTrack()->getItemManager(); reset(); // Determine if this AI has superpowers, which happens e.g. // for the final race challenge against nolok. @@ -225,10 +226,10 @@ void SkiddingAI::update(int ticks) // Clear stored items if they were deleted (for example a switched nitro) if (m_item_to_collect && - !ItemManager::get()->itemExists(m_item_to_collect)) + !m_item_manager->itemExists(m_item_to_collect)) m_item_to_collect = NULL; if (m_last_item_random && - !ItemManager::get()->itemExists(m_last_item_random)) + !m_item_manager->itemExists(m_last_item_random)) m_last_item_random = NULL; m_controls->setRescue(false); @@ -573,7 +574,7 @@ void SkiddingAI::handleItemCollectionAndAvoidance(Vec3 *aim_point, { int n_index= DriveGraph::get()->getNode(node)->getIndex(); const std::vector &items_ahead = - ItemManager::get()->getItemsInQuads(n_index); + m_item_manager->getItemsInQuads(n_index); for(unsigned int i=0; igetNode(node)->getIndex(); const std::vector &items_ahead = - ItemManager::get()->getItemsInQuads(n_index); + m_item_manager->getItemsInQuads(n_index); for(unsigned int i=0; iareItemsSwitched() || item_skill < 4)) + (!m_item_manager->areItemsSwitched() || item_skill < 4)) { m_controls->setFire(true); m_controls->setLookBack(true); diff --git a/src/karts/controller/skidding_ai.hpp b/src/karts/controller/skidding_ai.hpp index cd8b30bbe..2528e624a 100644 --- a/src/karts/controller/skidding_ai.hpp +++ b/src/karts/controller/skidding_ai.hpp @@ -50,6 +50,7 @@ #include +class ItemManager; class ItemState; class LinearWorld; class Track; @@ -234,6 +235,7 @@ private: enum {PSA_DEFAULT, PSA_NEW} m_point_selection_algorithm; + ItemManager* m_item_manager; #ifdef AI_DEBUG /** For skidding debugging: shows the estimated turn shape. */ ShowCurve **m_curve; diff --git a/src/karts/controller/test_ai.cpp b/src/karts/controller/test_ai.cpp index 78135aaa1..80a76f0f8 100644 --- a/src/karts/controller/test_ai.cpp +++ b/src/karts/controller/test_ai.cpp @@ -637,11 +637,12 @@ void SkiddingAI::handleItemCollectionAndAvoidance(Vec3 *aim_point, // 1) Filter and sort all items close by // ------------------------------------- const float max_item_lookahead_distance = 30.f; + ItemManager* im = Track::getCurrentTrack()->getItemManager(); while(distance < max_item_lookahead_distance) { int n_index= DriveGraph::get()->getNode(node)->getIndex(); const std::vector &items_ahead = - ItemManager::get()->getItemsInQuads(n_index); + im->getItemsInQuads(n_index); for(unsigned int i=0; icheckItemHit(this); + Track::getCurrentTrack()->getItemManager()->checkItemHit(this); const bool emergency = has_animation_before; diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 42238cf01..f26645f09 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -961,8 +961,8 @@ void ClientLobby::startGame(Event* event) if (lw) lw->handleServerCheckStructureCount(check_structure_count); - NetworkItemManager* nim = - dynamic_cast(ItemManager::get()); + NetworkItemManager* nim = dynamic_cast + (Track::getCurrentTrack()->getItemManager()); assert(nim); nim->restoreCompleteState(event->data()); @@ -1234,8 +1234,8 @@ void ClientLobby::liveJoinAcknowledged(Event* event) k->setLiveJoinKart(m_last_live_join_util_ticks); } - NetworkItemManager* nim = - dynamic_cast(ItemManager::get()); + NetworkItemManager* nim = dynamic_cast + (Track::getCurrentTrack()->getItemManager()); assert(nim); nim->restoreCompleteState(data); w->restoreCompleteState(data); diff --git a/src/network/protocols/game_protocol.cpp b/src/network/protocols/game_protocol.cpp index 7dacf6b17..082251e33 100644 --- a/src/network/protocols/game_protocol.cpp +++ b/src/network/protocols/game_protocol.cpp @@ -34,6 +34,7 @@ #include "network/socket_address.hpp" #include "network/stk_host.hpp" #include "network/stk_peer.hpp" +#include "tracks/track.hpp" #include "utils/log.hpp" #include "utils/time.hpp" #include "main_loop.hpp" @@ -58,6 +59,8 @@ std::shared_ptr GameProtocol::createInstance() GameProtocol::GameProtocol() : Protocol(PROTOCOL_CONTROLLER_EVENTS) { + m_network_item_manager = static_cast + (Track::getCurrentTrack()->getItemManager()); m_data_to_send = getNetworkString(); } // GameProtocol @@ -271,8 +274,7 @@ void GameProtocol::handleItemEventConfirmation(Event *event) { assert(NetworkConfig::get()->isServer()); int ticks = event->data().getTime(); - NetworkItemManager::get()->setItemConfirmationTime(event->getPeerSP(), - ticks); + m_network_item_manager->setItemConfirmationTime(event->getPeerSP(), ticks); } // handleItemEventConfirmation // ---------------------------------------------------------------------------- diff --git a/src/network/protocols/game_protocol.hpp b/src/network/protocols/game_protocol.hpp index 92209069e..7f939fcfa 100644 --- a/src/network/protocols/game_protocol.hpp +++ b/src/network/protocols/game_protocol.hpp @@ -32,6 +32,7 @@ #include class BareNetworkString; +class NetworkItemManager; class NetworkString; class STKPeer; @@ -78,6 +79,7 @@ private: void handleAdjustTime(Event *event); void handleItemEventConfirmation(Event *event); static std::weak_ptr m_game_protocol; + NetworkItemManager* m_network_item_manager; // Maximum value of values are only 32768 std::tuple compressAction(const Action& a) @@ -139,7 +141,6 @@ public: // ------------------------------------------------------------------------ std::unique_lock acquireWorldDeletingMutex() const { return std::unique_lock(m_world_deleting_mutex); } - }; // class GameProtocol #endif // GAME_PROTOCOL_HPP diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 27a95c641..29d7d6ddd 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -1953,8 +1953,8 @@ void ServerLobby::finishedLoadingLiveJoinClient(Event* event) .addUInt8(cc).addUInt64(live_join_start_time) .addUInt32(m_last_live_join_util_ticks); - NetworkItemManager* nim = - dynamic_cast(ItemManager::get()); + NetworkItemManager* nim = dynamic_cast + (Track::getCurrentTrack()->getItemManager()); assert(nim); nim->saveCompleteState(ns); nim->addLiveJoinPeer(peer); @@ -5077,8 +5077,8 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event) peer->getAddress().toString().c_str()); } } - NetworkItemManager* nim = - dynamic_cast(ItemManager::get()); + NetworkItemManager* nim = dynamic_cast + (Track::getCurrentTrack()->getItemManager()); assert(nim); nim->erasePeerInGame(peer); m_peers_ready.erase(peer); @@ -5133,13 +5133,10 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) } // clientSelectingAssetsWantsToBackLobby //----------------------------------------------------------------------------- -void ServerLobby::saveInitialItems() +void ServerLobby::saveInitialItems(std::shared_ptr nim) { m_items_complete_state->getBuffer().clear(); m_items_complete_state->reset(); - NetworkItemManager* nim = - dynamic_cast(ItemManager::get()); - assert(nim); nim->saveCompleteState(m_items_complete_state); } // saveInitialItems diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 098abf4a4..8e7d05809 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -38,6 +38,7 @@ #endif class BareNetworkString; +class NetworkItemManager; class NetworkString; class NetworkPlayerProfile; class STKPeer; @@ -381,7 +382,7 @@ public: int getDifficulty() const { return m_difficulty.load(); } int getGameMode() const { return m_game_mode.load(); } int getLobbyPlayers() const { return m_lobby_players.load(); } - void saveInitialItems(); + void saveInitialItems(std::shared_ptr nim); void saveIPBanTable(const SocketAddress& addr); void listBanTable(); void initServerStatsTable(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 3177cd8db..1385ed2d8 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -60,6 +60,7 @@ #include "modes/linear_world.hpp" #include "modes/easter_egg_hunt.hpp" #include "network/network_config.hpp" +#include "network/protocols/game_protocol.hpp" #include "network/protocols/server_lobby.hpp" #include "physics/physical_object.hpp" #include "physics/physics.hpp" @@ -291,7 +292,7 @@ void Track::reset() { m_ambient_color = m_default_ambient_color; m_check_manager->reset(*this); - ItemManager::get()->reset(); + m_item_manager->reset(); m_track_object_manager->reset(); m_startup_run = false; } // reset @@ -314,7 +315,7 @@ void Track::cleanup() file_manager->popModelSearchPath(); Graph::destroy(); - ItemManager::destroy(); + m_item_manager = nullptr; #ifndef SERVER_ONLY if (CVS->isGLSL()) { @@ -1609,7 +1610,7 @@ void Track::updateGraphics(float dt) { m_animated_textures[i]->update(dt); } - ItemManager::get()->updateGraphics(dt); + m_item_manager->updateGraphics(dt); } // updateGraphics @@ -1626,7 +1627,7 @@ void Track::update(int ticks) } float dt = stk_config->ticks2Time(ticks); m_check_manager->update(dt); - ItemManager::get()->update(ticks); + m_item_manager->update(ticks); // TODO: enable onUpdate scripts if we ever find a compelling use for them //Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); @@ -1907,13 +1908,17 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) main_loop->renderGUI(3340); if (NetworkConfig::get()->isNetworking()) - NetworkItemManager::create(); + { + auto nim = std::make_shared(); + nim->rewinderAdd(); + m_item_manager = nim; + } else { // Seed random engine locally uint32_t seed = (uint32_t)StkTime::getTimeSinceEpoch(); ItemManager::updateRandomSeed(seed); - ItemManager::create(); + m_item_manager = std::make_shared(); powerup_manager->setRandomSeed(seed); } main_loop->renderGUI(3360); @@ -2181,7 +2186,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) freeCachedMeshVertexBuffer(); const bool arena_random_item_created = - ItemManager::get()->randomItemsForArena(m_start_transforms); + m_item_manager->randomItemsForArena(m_start_transforms); if (!arena_random_item_created) { @@ -2215,7 +2220,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) main_loop->renderGUI(5800); if (auto sl = LobbyProtocol::get()) - sl->saveInitialItems(); + { + sl->saveInitialItems( + std::dynamic_pointer_cast(m_item_manager)); + } main_loop->renderGUI(5900); @@ -2706,7 +2714,7 @@ void Track::itemCommand(const XMLNode *node) #endif } - ItemManager::get()->placeItem(type, drop ? hit_point : loc, normal); + m_item_manager->placeItem(type, drop ? hit_point : loc, normal); } // itemCommand // ---------------------------------------------------------------------------- diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 05fd85bf8..74fcb901a 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -26,9 +26,10 @@ * objects. */ +#include +#include #include #include -#include #include @@ -45,6 +46,7 @@ class AbstractKart; class AnimationManager; class BezierCurve; class CheckManager; +class ItemManager; class ModelDefinitionLoader; class MovingTexture; class MusicInformation; @@ -353,6 +355,7 @@ private: /** The render target for the mini map, which is displayed in the race gui. */ RenderTarget *m_render_target; CheckManager* m_check_manager; + std::shared_ptr m_item_manager; float m_minimap_x_scale; float m_minimap_y_scale; @@ -712,6 +715,8 @@ public: void convertTrackToBullet(scene::ISceneNode *node); // ------------------------------------------------------------------------ CheckManager* getCheckManager() const { return m_check_manager; } + // ------------------------------------------------------------------------ + ItemManager* getItemManager() const { return m_item_manager.get(); } }; // class Track #endif