diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 0113fed02..260e7f302 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -95,6 +95,8 @@ add_openmw_dir (mwbase inputmanager windowmanager statemanager ) +add_openmw_dir (mwmp Networking Player) + # Main executable if (NOT ANDROID) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 3fcd46f7c..01d370efc 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -55,6 +55,8 @@ #include "mwstate/statemanagerimp.hpp" +#include "mwmp/Networking.hpp" + namespace { void checkSDLError(int ret) @@ -102,6 +104,8 @@ void OMW::Engine::frame(float frametime) if (mUseSound) mEnvironment.getSoundManager()->update(frametime); + mwmp::Main::Frame(frametime); + // Main menu opened? Then scripts are also paused. bool paused = mEnvironment.getWindowManager()->containsMode(MWGui::GM_MainMenu); @@ -645,7 +649,10 @@ void OMW::Engine::go() ToUTF8::Utf8Encoder encoder (mEncoding); mEncoder = &encoder; + prepareEngine (settings); + mwmp::Main::Create(); + mSkipMenu = true; if (!mSaveGameFile.empty()) { @@ -715,6 +722,7 @@ void OMW::Engine::go() // Save user settings settings.saveUser(settingspath); + mwmp::Main::Destroy(); std::cout << "Quitting peacefully." << std::endl; } diff --git a/apps/openmw/mwmp/Networking.cpp b/apps/openmw/mwmp/Networking.cpp new file mode 100644 index 000000000..43c5979e0 --- /dev/null +++ b/apps/openmw/mwmp/Networking.cpp @@ -0,0 +1,117 @@ +// +// Created by koncord on 01.01.16. +// + +#include "Networking.hpp" +#include +#include +#include +#include "../mwbase/environment.hpp" +#include "../mwstate/statemanagerimp.hpp" +#include "../mwinput/inputmanagerimp.hpp" +#include "../mwscript/scriptmanagerimp.hpp" +#include "../mwgui/windowmanagerimp.hpp" +#include "../mwworld/worldimp.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwworld/player.hpp" +#include "../mwworld/customdata.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" +#include "../mwclass/npc.hpp" +#include "../mwclass/creature.hpp" +#include "../mwmechanics/mechanicsmanagerimp.hpp" + +#include "../mwmechanics/aistate.hpp" +#include "Player.hpp" + +using namespace mwmp; +using namespace std; + +Main *Main::pMain = 0; + +Main::Main() +{ + std::cout << "Main::Main" << std::endl; +} + +Main::~Main() +{ + std::cout << "Main::~Main" << std::endl; +} + +void Main::Create() +{ + assert(!pMain); + pMain = new Main(); + const MWBase::Environment &environment = MWBase::Environment::get(); + environment.getStateManager()->newGame(true); + +} + +void Main::Destroy() +{ + Player::CleanUp(); + delete pMain; +} + +void Main::Frame(float dt) +{ + const MWBase::Environment &environment = MWBase::Environment::get(); + if (environment.getWindowManager()->containsMode(MWGui::GM_MainMenu)) + { + //environment.getWindowManager()->exitCurrentGuiMode(); + } + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::ScriptManager *script = MWBase::Environment::get().getScriptManager(); + MWWorld::Ptr player = world->getPlayerPtr(); + + float x = player.getRefData().getPosition().pos[0]; + float y = player.getRefData().getPosition().pos[1]; + float z = player.getRefData().getPosition().pos[2]; + float rot_x = player.getRefData().getPosition().rot[0]; + float rot_y = player.getRefData().getPosition().rot[1]; + float rot_z = player.getRefData().getPosition().rot[2]; + + static bool connected = true; + if (connected) + { + connected = false; + world->toggleGodMode(); + // create item + MWWorld::CellStore* store = player.getCell(); + + Player::CreatePlayer(1, "Ashot the Orc", "Orc", "b_n_orc_m_head_01", "b_n_orc_m_hair_01"); + Player *ref = Player::GetPlayer(1); + + ref->getPtr().getCellRef().setPosition(player.getRefData().getPosition()); + world->moveObject(ref->getPtr(),player.getCell(), x, y, z); // move to player + } + Player *ref = Player::GetPlayer(1); + + ref->Move(player.getRefData().getPosition(), player.getCell()); + + //cout << "x:\t" << x << "\ty:\t" << y << "\tz:\t" << z<< endl; + + //ref->getPtr().getRefData(). + //loc.getRefData().setPosition(player.getRefData().getPosition()); + MWMechanics::NpcStats *npcStats = &ref->getPtr().getClass().getNpcStats(ref->getPtr()); + npcStats->setHealth(1000); + npcStats->setMagicka(1000); + npcStats->setFatigue(1000); + if(npcStats->isDead()) + npcStats->resurrect(); + npcStats->setAttacked(false); + + npcStats->setBaseDisposition(255); + + if(player.getClass().getNpcStats(ref->getPtr()).getHealth().getCurrent() <= 0) + { + + } + +} + +void Main::UpdateWorld(float dt) +{ + +} diff --git a/apps/openmw/mwmp/Networking.hpp b/apps/openmw/mwmp/Networking.hpp new file mode 100644 index 000000000..c79bf1b75 --- /dev/null +++ b/apps/openmw/mwmp/Networking.hpp @@ -0,0 +1,17 @@ + +namespace mwmp +{ + class Main + { + public: + Main(); + ~Main(); + + static void Create(); + static void Destroy(); + static void Frame(float dt); + static void UpdateWorld(float dt); + private: + static Main *pMain; + }; +} diff --git a/apps/openmw/mwmp/Player.cpp b/apps/openmw/mwmp/Player.cpp index 59734df38..8f9b912e9 100644 --- a/apps/openmw/mwmp/Player.cpp +++ b/apps/openmw/mwmp/Player.cpp @@ -2,4 +2,151 @@ // Created by koncord on 02.01.16. // +#include +#include +#include "../mwbase/environment.hpp" +#include "../mwstate/statemanagerimp.hpp" +#include "../mwinput/inputmanagerimp.hpp" +#include "../mwgui/windowmanagerimp.hpp" +#include "../mwworld/worldimp.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwworld/player.hpp" +#include "../mwworld/customdata.hpp" +#include "../mwclass/npc.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "Player.hpp" + +using namespace mwmp; + +std::map Player::players; + +Player::~Player() +{ + delete reference; +} + +MWWorld::Ptr Player::getPtr() +{ + MWBase::World *world = MWBase::Environment::get().getWorld(); + return world->getPtr(reference->getPtr().get()->mBase->mId, false); +} + +Player::Player() +{ + +} + +void Player::CreatePlayer(int id, const std::string &name, const std::string &race, const std::string &head, + const std::string &hair) +{ + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayerPtr(); + + ESM::NPC dedic_pl = *player.get()->mBase; + dedic_pl.mRace = race; + dedic_pl.mHead = head; + dedic_pl.mHair = hair; + dedic_pl.mName = name; + + + if (players[id] == 0) + { + dedic_pl.mId = "Dedicated Player"; + + std::string recid = world->createRecord(dedic_pl)->mId; + + players[id] = new Player(); + Player *_player = players[id]; + + _player->reference = new MWWorld::ManualRef(world->getStore(), recid, 1); + + // temporary spawn character in ToddTest cell + ESM::Position pos; + world->findInteriorPosition("ToddTest", pos); + MWWorld::CellStore *store = world->getInterior("ToddTest"); + + MWWorld::Ptr tmp = world->safePlaceObject(_player->reference->getPtr(), store, pos); + _player->ptr = world->getPtr(tmp.get()->mBase->mId, false); + + } + else + { + dedic_pl.mId = players[id]->reference->getPtr().get()->mBase->mId; + + MWWorld::ESMStore *store = const_cast(&world->getStore()); + MWWorld::Store *esm_store = const_cast *> (&store->get()); + + esm_store->insert(dedic_pl); + + } + + players[id]->active = true; + + world->enable(players[id]->reference->getPtr()); +} + + +void Player::CleanUp() +{ + for(std::map ::iterator it = players.begin(); it != players.end(); it++) + delete it->second; +} + +void Player::DestroyPlayer(int id) +{ + if (players[id]->active) + { + players[id]->active = false; + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->disable(players[id]->getPtr()); + + //move player to toddTest + ESM::Position pos; + world->findInteriorPosition("ToddTest", pos); + MWWorld::CellStore *store = world->getInterior("ToddTest"); + + players[id]->ptr = world->moveObject(players[id]->getPtr(), store, pos.pos[0], pos.pos[1], pos.pos[2]); + } +} + +Player *Player::GetPlayer(int id) +{ + return players[id]; +} + +MWWorld::Ptr Player::getLiveCellPtr() +{ + return reference->getPtr(); +} + +MWWorld::ManualRef *Player::getRef() +{ + return reference; +} + +void Player::Move(ESM::Position pos, MWWorld::CellStore *cell) +{ + if (!active) return; + MWWorld::Ptr myPtr = getPtr(); + ESM::Position ref_pos = myPtr.getRefData().getPosition(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + float xx = pos.pos[0] - ref_pos.pos[0]; + float yy = pos.pos[1] - ref_pos.pos[1]; + double d = sqrt((xx * xx) + (yy * yy)); + + MWMechanics::AiSequence *aiSequence = &myPtr.getClass().getCreatureStats(myPtr).getAiSequence(); + + if (d > 10.0 && d < 150.0) + { + MWMechanics::AiTravel travelPackage(pos.pos[0], pos.pos[1], pos.pos[2]); + aiSequence->clear(); + aiSequence->stack(travelPackage, myPtr); + } + else if (d == 0.0) + aiSequence->clear(); + else if (d >= 150.0) + world->moveObject(myPtr, cell, pos.pos[0], pos.pos[1], pos.pos[2]); + + world->rotateObject(myPtr, pos.rot[0], pos.rot[1], pos.rot[2]); +} diff --git a/apps/openmw/mwmp/Player.hpp b/apps/openmw/mwmp/Player.hpp index d702ac3e2..6709df1d4 100644 --- a/apps/openmw/mwmp/Player.hpp +++ b/apps/openmw/mwmp/Player.hpp @@ -5,11 +5,36 @@ #ifndef OPENMW_PLAYER_HPP #define OPENMW_PLAYER_HPP +#include +#include +#include +#include -class Player +namespace mwmp { + class Player + { + public: + MWWorld::Ptr getPtr(); + MWWorld::Ptr getLiveCellPtr(); + MWWorld::ManualRef* getRef(); + void Move(ESM::Position pos, MWWorld::CellStore* cell); -}; + static void CreatePlayer(int id, const std::string& name, const std::string &race, const std::string &head, const std::string &hair); + static void DestroyPlayer(int id); + static void CleanUp(); + static Player *GetPlayer(int id); + private: + Player(); + ~Player(); + int id; + bool active; + MWWorld::ManualRef* reference; + MWWorld::Ptr ptr; + private: + static std::map players; + }; +} #endif //OPENMW_PLAYER_HPP diff --git a/cmake/FindRakNet.cmake b/cmake/FindRakNet.cmake new file mode 100644 index 000000000..9ce071cd1 --- /dev/null +++ b/cmake/FindRakNet.cmake @@ -0,0 +1,74 @@ +# Comes form project edunetgames +# - Try to find RakNet +# Once done this will define +# +# RakNet_FOUND - system has RakNet +# RakNet_INCLUDES - the RakNet include directory +# RakNet_LIBRARY - Link these to use RakNet + +if(Win32) +SET(RakNet_LIBRARY_Name RakNetLibStatic) +SET(RakNet_LIBRARY_Name_Debug RakNetLibStaticDebug) +else(Win32) +SET(RakNet_LIBRARY_Name RakNetStatic) +SET(RakNet_LIBRARY_Name_Debug RakNetStatic_Debug) +endif(Win32) + +FIND_LIBRARY (RakNet_LIBRARY_RELEASE NAMES ${RakNet_LIBRARY_Name} + PATHS + ENV LD_LIBRARY_PATH + ENV LIBRARY_PATH + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /opt/local/lib + ${RAKNET_ROOT}/lib + ) + +FIND_LIBRARY (RakNet_LIBRARY_DEBUG NAMES ${RakNet_LIBRARY_Name_Debug} + PATHS + ENV LD_LIBRARY_PATH + ENV LIBRARY_PATH + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /opt/local/lib + ${RAKNET_ROOT}/lib + ) + + + +FIND_PATH (RakNet_INCLUDES raknet/RakPeer.h + ENV CPATH + /usr/include + /usr/local/include + /opt/local/include + ${RAKNET_ROOT}/include + ) + +IF(RakNet_INCLUDES AND RakNet_LIBRARY_RELEASE) + SET(RakNet_FOUND TRUE) +ENDIF(RakNet_INCLUDES AND RakNet_LIBRARY_RELEASE) + +IF(RakNet_FOUND) + SET(RakNet_INCLUDES ${RakNet_INCLUDES}) + + + IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + SET(RakNet_LIBRARY optimized ${RakNet_LIBRARY_RELEASE} debug ${RakNet_LIBRARY_DEBUG}) + ELSE() + # if there are no configuration types and CMAKE_BUILD_TYPE has no value + # then just use the release libraries + SET(RakNet_LIBRARY ${RakNet_LIBRARY_RELEASE} ) + ENDIF() + IF(NOT RakNet_FIND_QUIETLY) + MESSAGE(STATUS "Found RakNet: ${RakNet_LIBRARIES}") + ENDIF(NOT RakNet_FIND_QUIETLY) +ELSE(RakNet_FOUND) + IF(RakNet_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find RakNet") + ENDIF(RakNet_FIND_REQUIRED) +ENDIF(RakNet_FOUND) +