diff --git a/apps/openmw/mwmp/Cell.cpp b/apps/openmw/mwmp/Cell.cpp index 571e7fd2c..fbc6d836c 100644 --- a/apps/openmw/mwmp/Cell.cpp +++ b/apps/openmw/mwmp/Cell.cpp @@ -5,6 +5,7 @@ #include "Cell.hpp" #include "Main.hpp" +#include "Networking.hpp" #include "LocalPlayer.hpp" using namespace mwmp; @@ -21,8 +22,14 @@ mwmp::Cell::~Cell() } -void Cell::update() +void Cell::updateLocal() { + if (localActors.empty()) return; + + mwmp::WorldEvent *worldEvent = mwmp::Main::get().getNetworking()->getWorldEvent(); + worldEvent->reset(); + worldEvent->cell = *store->getCell(); + for (std::map::iterator it = localActors.begin(); it != localActors.end();) { LocalActor *actor = it->second; @@ -31,16 +38,29 @@ void Cell::update() if (actor->getPtr().getCell() && actor->getPtr().getCell() != store) { LOG_APPEND(Log::LOG_INFO, "- Removing LocalActor %s which is no longer in this cell", it->first.c_str()); + actor->getPtr().getBase()->isLocalActor = false; localActors.erase(it++); } else { - LOG_APPEND(Log::LOG_VERBOSE, "- Updating LocalActor %s", it->first.c_str()); - actor->update(); + //LOG_APPEND(Log::LOG_VERBOSE, "- Updating LocalActor %s", it->first.c_str()); + //actor->update(); + MWWorld::Ptr ptr = actor->getPtr(); + + mwmp::WorldObject worldObject; + worldObject.refId = ptr.getCellRef().getRefId(); + worldObject.refNumIndex = ptr.getCellRef().getRefNum().mIndex; + worldObject.mpNum = ptr.getCellRef().getMpNum(); + worldObject.pos = ptr.getRefData().getPosition(); + + worldEvent->addObject(worldObject); ++it; } } + + mwmp::Main::get().getNetworking()->getWorldPacket(ID_ACTOR_FRAME)->setEvent(worldEvent); + mwmp::Main::get().getNetworking()->getWorldPacket(ID_ACTOR_FRAME)->Send(); } void Cell::initializeLocalActors() @@ -73,6 +93,39 @@ void Cell::uninitializeLocalActors() localActors.clear(); } +void Cell::readCellFrame(mwmp::WorldEvent& worldEvent) +{ + WorldObject worldObject; + + for (unsigned int i = 0; i < worldEvent.objectChanges.count; i++) + { + worldObject = worldEvent.objectChanges.objects.at(i); + std::string mapIndex = generateMapIndex(worldObject); + + // If this key doesn't exist, create it + if (dedicatedActors.count(mapIndex) == 0) + { + MWWorld::Ptr ptrFound = store->searchExact(worldObject.refId, worldObject.refNumIndex, worldObject.mpNum); + + if (ptrFound) + { + dedicatedActors[mapIndex] = new DedicatedActor(); + dedicatedActors[mapIndex]->cell = worldEvent.cell; + dedicatedActors[mapIndex]->setPtr(ptrFound); + LOG_APPEND(Log::LOG_INFO, "- Initialized DedicatedActor %s", mapIndex.c_str()); + } + } + + // If this now exists, set its details + if (dedicatedActors.count(mapIndex) > 0) + { + DedicatedActor *actor = dedicatedActors[mapIndex]; + actor->position = worldObject.pos; + actor->move(); + } + } +} + std::string Cell::generateMapIndex(MWWorld::Ptr ptr) { std::string mapIndex = ""; @@ -82,6 +135,15 @@ std::string Cell::generateMapIndex(MWWorld::Ptr ptr) return mapIndex; } +std::string Cell::generateMapIndex(mwmp::WorldObject object) +{ + std::string mapIndex = ""; + mapIndex += object.refId; + mapIndex += "-" + Utils::toString(object.refNumIndex); + mapIndex += "-" + Utils::toString(object.mpNum); + return mapIndex; +} + MWWorld::CellStore *mwmp::Cell::getCellStore() { return store; diff --git a/apps/openmw/mwmp/Cell.hpp b/apps/openmw/mwmp/Cell.hpp index a7c110d7d..f867f4d77 100644 --- a/apps/openmw/mwmp/Cell.hpp +++ b/apps/openmw/mwmp/Cell.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_CELL_HPP #define OPENMW_CELL_HPP +#include "WorldEvent.hpp" #include "LocalActor.hpp" #include "DedicatedActor.hpp" #include "../mwworld/cellstore.hpp" @@ -14,11 +15,13 @@ namespace mwmp Cell(MWWorld::CellStore* cellStore); ~Cell(); - void update(); + void updateLocal(); void initializeLocalActors(); void uninitializeLocalActors(); + void readCellFrame(mwmp::WorldEvent& worldEvent); std::string generateMapIndex(MWWorld::Ptr ptr); + std::string generateMapIndex(mwmp::WorldObject object); MWWorld::CellStore* getCellStore(); std::string getDescription(); diff --git a/apps/openmw/mwmp/CellController.cpp b/apps/openmw/mwmp/CellController.cpp index af99ae19b..90fedcb78 100644 --- a/apps/openmw/mwmp/CellController.cpp +++ b/apps/openmw/mwmp/CellController.cpp @@ -22,7 +22,7 @@ mwmp::CellController::~CellController() } -void CellController::update() +void CellController::updateLocal() { for (std::deque::iterator it = cellsActive.begin(); it != cellsActive.end();) { @@ -36,15 +36,14 @@ void CellController::update() else { //LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Updating mwmp::Cell %s", mpCell->getDescription().c_str()); - mpCell->update(); + mpCell->updateLocal(); ++it; } } } -void CellController::initializeCell(const ESM::Cell& cell) +void CellController::initializeCellLocal(const ESM::Cell& cell) { - MWWorld::CellStore *cellStore = getCell(cell); if (!cellStore) return; @@ -57,6 +56,38 @@ void CellController::initializeCell(const ESM::Cell& cell) cellsActive.push_back(mpCell); } +void CellController::readCellFrame(mwmp::WorldEvent& worldEvent) +{ + bool cellExisted = false; + + // Check if this cell already exists + for (std::deque::iterator it = cellsActive.begin(); it != cellsActive.end(); ++it) + { + mwmp::Cell *mpCell = *it; + + if (worldEvent.cell.getDescription() == mpCell->getDescription()) + { + mpCell->readCellFrame(worldEvent); + cellExisted = true; + break; + } + } + + if (!cellExisted) + { + MWWorld::CellStore *cellStore = getCell(worldEvent.cell); + + if (!cellStore) return; + + mwmp::Cell *mpCell = new mwmp::Cell(cellStore); + + LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Initialized mwmp::Cell %s", mpCell->getDescription().c_str()); + + cellsActive.push_back(mpCell); + mpCell->readCellFrame(worldEvent); + } +} + int mwmp::CellController::getCellSize() const { return 8192; diff --git a/apps/openmw/mwmp/CellController.hpp b/apps/openmw/mwmp/CellController.hpp index 9077ca53c..517344927 100644 --- a/apps/openmw/mwmp/CellController.hpp +++ b/apps/openmw/mwmp/CellController.hpp @@ -2,6 +2,7 @@ #define OPENMW_CELLCONTROLLER_HPP #include "Cell.hpp" +#include "WorldEvent.hpp" #include "LocalActor.hpp" #include "DedicatedActor.hpp" #include "../mwworld/cellstore.hpp" @@ -15,8 +16,9 @@ namespace mwmp CellController(); ~CellController(); - void update(); - void initializeCell(const ESM::Cell& cell); + void updateLocal(); + void initializeCellLocal(const ESM::Cell& cell); + void readCellFrame(mwmp::WorldEvent& worldEvent); int getCellSize() const; virtual MWWorld::CellStore *getCell(const ESM::Cell& cell); diff --git a/apps/openmw/mwmp/DedicatedActor.cpp b/apps/openmw/mwmp/DedicatedActor.cpp index 94a0753bd..bf80ede70 100644 --- a/apps/openmw/mwmp/DedicatedActor.cpp +++ b/apps/openmw/mwmp/DedicatedActor.cpp @@ -1,3 +1,9 @@ +#include "../mwbase/environment.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/worldimp.hpp" + #include "DedicatedActor.hpp" using namespace mwmp; @@ -17,3 +23,21 @@ void DedicatedActor::update() { } + +void DedicatedActor::move() +{ + MWBase::World *world = MWBase::Environment::get().getWorld(); + + world->moveObject(ptr, position.pos[0], position.pos[1], position.pos[2]); + world->rotateObject(ptr, position.rot[0], position.rot[1], position.rot[2]); +} + +MWWorld::Ptr DedicatedActor::getPtr() +{ + return ptr; +} + +void DedicatedActor::setPtr(const MWWorld::Ptr& newPtr) +{ + ptr = newPtr; +} diff --git a/apps/openmw/mwmp/DedicatedActor.hpp b/apps/openmw/mwmp/DedicatedActor.hpp index 4b6a569fc..d92e48637 100644 --- a/apps/openmw/mwmp/DedicatedActor.hpp +++ b/apps/openmw/mwmp/DedicatedActor.hpp @@ -2,6 +2,7 @@ #define OPENMW_DEDICATEDACTOR_HPP #include +#include "../mwworld/manualref.hpp" namespace mwmp { @@ -13,6 +14,13 @@ namespace mwmp virtual ~DedicatedActor(); void update(); + void move(); + + MWWorld::Ptr getPtr(); + void setPtr(const MWWorld::Ptr& newPtr); + + private: + MWWorld::Ptr ptr; }; } diff --git a/apps/openmw/mwmp/Main.cpp b/apps/openmw/mwmp/Main.cpp index 0755340d2..c0ad4c85f 100644 --- a/apps/openmw/mwmp/Main.cpp +++ b/apps/openmw/mwmp/Main.cpp @@ -210,7 +210,7 @@ void Main::updateWorld(float dt) const else { mLocalPlayer->update(); - mCellController->update(); + mCellController->updateLocal(); } } diff --git a/apps/openmw/mwmp/Networking.cpp b/apps/openmw/mwmp/Networking.cpp index 3de347111..aecdafaa4 100644 --- a/apps/openmw/mwmp/Networking.cpp +++ b/apps/openmw/mwmp/Networking.cpp @@ -859,13 +859,14 @@ void Networking::processWorldPacket(RakNet::Packet *packet) { LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Received ID_ACTOR_AUTHORITY about %s", worldEvent.cell.getDescription().c_str()); - Main::get().getCellController()->initializeCell(worldEvent.cell); + Main::get().getCellController()->initializeCellLocal(worldEvent.cell); break; } case ID_ACTOR_FRAME: { - LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Received ID_ACTOR_FRAME about %s", worldEvent.cell.getDescription().c_str()); + Main::get().getCellController()->readCellFrame(worldEvent); + break; } case ID_CONTAINER: