diff --git a/.gitmodules b/.gitmodules index 9ad6c4012..9dc4364d0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "extern/breakpad"] path = extern/breakpad url = https://chromium.googlesource.com/breakpad/breakpad +[submodule "extern/sol"] + path = extern/sol + url = https://github.com/ThePhD/sol2 diff --git a/apps/openmw-mp/Actors.cpp b/apps/openmw-mp/Actors.cpp new file mode 100644 index 000000000..ad09edf23 --- /dev/null +++ b/apps/openmw-mp/Actors.cpp @@ -0,0 +1,270 @@ +// +// Created by koncord on 25.08.17. +// + +#include +#include "Actors.hpp" +#include "Script/LuaState.hpp" +#include "Networking.hpp" +#include "Cell.hpp" +#include "CellController.hpp" +#include "Player.hpp" + +using namespace std; + +void Actor::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Actor", + "getPosition", &NetActor::getPosition, + "setPosition", &NetActor::setPosition, + "getRotation", &NetActor::getRotation, + "setRotation", &NetActor::setRotation, + + "getHealth", &NetActor::getHealth, + "setHealth", &NetActor::setHealth, + "getMagicka", &NetActor::getMagicka, + "setMagicka", &NetActor::setMagicka, + "getFatigue", &NetActor::getFatigue, + "setFatigue", &NetActor::setFatigue, + + "getCell", &NetActor::getCell, + "getInventory", &NetActor::getInventory, + + "refId", sol::property(&Actor::getRefId, &Actor::setRefId), + "refNumIndex", sol::property(&Actor::getRefNumIndex, &Actor::setRefNumIndex), + "mpNum", sol::property(&Actor::getMpNum, &Actor::setMpNum) + + ); +} + +Actor::Actor() : NetActor() +{ + +} + +std::string Actor::getRefId() const +{ + return actor->refId; +} + +void Actor::setRefId(const std::string &refId) +{ + actor->refId = refId; +} + +int Actor::getRefNumIndex() const +{ + return actor->refNumIndex; +} + +void Actor::setRefNumIndex(int refNumIndex) +{ + actor->refNumIndex = refNumIndex; +} + +int Actor::getMpNum() const +{ + return actor->mpNum; +} + +void Actor::setMpNum(int mpNum) +{ + actor->mpNum = mpNum; +} + +bool Actor::doesHavePosition() const +{ + return actor->hasPositionData; +} + +bool Actor::doesHaveStatsDynamic() const +{ + return actor->hasStatsDynamicData; +} + +void ActorController::Init(LuaState &lua) +{ + sol::table playersTable = lua.getState()->create_named_table("Actors"); + + playersTable.set_function("createActor", [&lua](){ + lua.getActorCtrl().createActor(); + }); + + playersTable.set_function("sendActors", [&lua](shared_ptr player, vector> actors, + bool sendToAll) { + lua.getActorCtrl().sendActors(player, actors, sendToAll); + }); + + playersTable.set_function("sendList", [&lua](shared_ptr player, vector> actors, + bool sendToAll) { + lua.getActorCtrl().sendList(player, actors, sendToAll); + }); + + playersTable.set_function("requestList", [&lua](shared_ptr player){ + lua.getActorCtrl().requestList(player); + }); + + playersTable.set_function("getActors", [&lua](shared_ptr player){ + lua.getActorCtrl().getActors(player); + }); +} + +ActorController::ActorController() +{ + +} + +ActorController::~ActorController() +{ + +} + +std::shared_ptr ActorController::createActor() +{ + Actor *actor = new Actor(); + actor->actor.reset(new mwmp::BaseActor); + + return shared_ptr(actor); +} + +void ActorController::sendActors(std::shared_ptr player, std::vector> actors, bool sendToAll) +{ + actorList.cell = player->cell; + actorList.guid = player->guid; + + bool positionChanged = false; + bool statsChanged = false; + bool attributesChanged = false; + bool skillsChanged = false; + bool baseInfoChanged = false; + bool equipmentChanged = false; + bool changedCell = false; + + actorList.baseActors.clear(); + for (auto &actor : actors) + { + actorList.baseActors.push_back(actor->actor); + + if (actor->positionChanged) + positionChanged = true; + if (actor->statsChanged) + statsChanged = true; + if (actor->attributesChanged) + attributesChanged = true; + if (actor->skillsChanged) + skillsChanged = true; + if (actor->baseInfoChanged) + baseInfoChanged = true; + if (actor->inventory.isEquipmentChanged()) + { + equipmentChanged = true; + actor->inventory.resetEquipmentFlag(); + } + if (actor->cellAPI.isChangedCell()) + { + changedCell = true; + actor->cellAPI.resetChangedCell(); + } + actor->resetUpdateFlags(); + } + + auto actorCtrl = mwmp::Networking::get().getActorPacketController(); + Cell *serverCell = nullptr; + + if (sendToAll) + serverCell = CellController::get()->getCell(&actorList.cell); + + if (positionChanged) + { + auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION); + + packet->setActorList(&actorList); + packet->Send(actorList.guid); + + if (sendToAll) + serverCell->sendToLoaded(packet, &actorList); + } + if (statsChanged) + { + auto packet = actorCtrl->GetPacket(ID_ACTOR_STATS_DYNAMIC); + + packet->setActorList(&actorList); + packet->Send(actorList.guid); + + if (sendToAll) + serverCell->sendToLoaded(packet, &actorList); + + } + /*if (attributesChanged) + { + auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION); + + } + if (skillsChanged) + { + auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION); + + } + if (baseInfoChanged) + { + auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION); + + }*/ + + if (equipmentChanged) + { + auto packet = actorCtrl->GetPacket(ID_ACTOR_EQUIPMENT); + packet->setActorList(&actorList); + packet->Send(actorList.guid); + + if (sendToAll) + serverCell->sendToLoaded(packet, &actorList); + } + if (changedCell) + { + auto packet = actorCtrl->GetPacket(ID_ACTOR_CELL_CHANGE); + packet->setActorList(&actorList); + packet->Send(actorList.guid); + + if (sendToAll) + serverCell->sendToLoaded(packet, &actorList); + } +} + +void ActorController::sendList(std::shared_ptr player, std::vector> actors, bool sendToAll) +{ + actorList.cell = player->cell; + actorList.guid = player->guid; + actorList.action = mwmp::BaseActorList::SET; + + auto packet = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST); + packet->setActorList(&actorList); + packet->Send(actorList.guid); +} + +void ActorController::requestList(std::shared_ptr player) +{ + actorList.cell = player->cell; + actorList.guid = player->guid; + actorList.action = mwmp::BaseActorList::REQUEST; + + auto packet = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST); + packet->setActorList(&actorList); + packet->Send(actorList.guid); +} + +std::vector> ActorController::getActors(std::shared_ptr player) +{ + Cell *serverCell = CellController::get()->getCell(&player->cell); + + std::vector> actorList; + + for (auto actor : serverCell->getActorList()->baseActors) + { + Actor *a = new Actor; + a->actor = actor; + actorList.emplace_back(a); + } + + return actorList; +} diff --git a/apps/openmw-mp/Actors.hpp b/apps/openmw-mp/Actors.hpp new file mode 100644 index 000000000..7df6db56e --- /dev/null +++ b/apps/openmw-mp/Actors.hpp @@ -0,0 +1,55 @@ +// +// Created by koncord on 25.08.17. +// + +#pragma once + +#include +#include +#include "NetActor.hpp" + +class LuaState; +class Player; + +class Actor: public NetActor +{ + friend class ActorController; +public: + static void Init(LuaState &lua); +public: + Actor(); + std::string getRefId() const; + void setRefId(const std::string &refId); + + int getRefNumIndex() const; + void setRefNumIndex(int refNumIndex); + int getMpNum() const; + void setMpNum(int mpNum); + bool doesHavePosition() const; // ???? + bool doesHaveStatsDynamic() const; // ???? + + std::shared_ptr actor; +}; + +class ActorController +{ +public: + static void Init(LuaState &lua); +public: + + ActorController(); + ~ActorController(); + + std::shared_ptr createActor(); + void sendActors(std::shared_ptr player, std::vector> actors, bool sendToAll = false); + void sendList(std::shared_ptr player, std::vector> actors, bool sendToAll = false); + + void requestList(std::shared_ptr player); + + std::vector> getActors(std::shared_ptr player); + +private: + mwmp::BaseActorList actorList; +}; + + diff --git a/apps/openmw-mp/Books.cpp b/apps/openmw-mp/Books.cpp new file mode 100644 index 000000000..04ec2391a --- /dev/null +++ b/apps/openmw-mp/Books.cpp @@ -0,0 +1,68 @@ +// +// Created by koncord on 15.08.17. +// + +#include "Books.hpp" + +#include +#include "Script/LuaState.hpp" +#include "Player.hpp" +#include "Networking.hpp" + +void Books::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Books", + "addBook", &Books::addBook, + "getBookId", &Books::getBookId, + "getChanges", &Books::getChanges, + "reset", &Books::reset + ); +} + +Books::Books(Player *player) : player(player), changed(false) +{ + +} + +Books::~Books() +{ + +} + +void Books::addBook(const std::string &bookId) +{ + if (!changed) + reset(); + player->bookChanges.books.push_back({bookId}); + changed = true; +} + +std::string Books::getBookId(unsigned i) const +{ + if (i >= player->bookChanges.count) + return "invalid"; + + return player->bookChanges.books.at(i).bookId; +} + +unsigned Books::getChanges() const +{ + return player->bookChanges.count; +} + +void Books::reset() +{ + player->bookChanges.books.clear(); +} + +void Books::update() +{ + if (!changed) + return; + changed = false; + + auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK); + + packet->setPlayer(player); + packet->Send(/*toOthers*/ false); +} \ No newline at end of file diff --git a/apps/openmw-mp/Books.hpp b/apps/openmw-mp/Books.hpp new file mode 100644 index 000000000..ba351fdd6 --- /dev/null +++ b/apps/openmw-mp/Books.hpp @@ -0,0 +1,32 @@ +// +// Created by koncord on 15.08.17. +// + +#pragma once + +#include + +class LuaState; +class Player; + +class Books +{ +public: + static void Init(LuaState &lua); +public: + + explicit Books(Player *player); + ~Books(); + + void addBook(const std::string &bookId); + std::string getBookId(unsigned i) const; + unsigned getChanges() const; + void reset(); + + void update(); +private: + Player *player; + bool changed; +}; + + diff --git a/apps/openmw-mp/CMakeLists.txt b/apps/openmw-mp/CMakeLists.txt index fc9ee0527..f99b2a8e6 100644 --- a/apps/openmw-mp/CMakeLists.txt +++ b/apps/openmw-mp/CMakeLists.txt @@ -1,12 +1,5 @@ project(tes3mp-server) -if(UNIX) #temporarily disabled for non-unix - if(NOT (${CMAKE_CXX_COMPILER} MATCHES "aarch64" OR ${CMAKE_CXX_COMPILER} MATCHES "arm")) #temporarily disabled for arm - find_package(CallFF REQUIRED) - include_directories(${CallFF_INCLUDES}) - endif(NOT (${CMAKE_CXX_COMPILER} MATCHES "aarch64" OR ${CMAKE_CXX_COMPILER} MATCHES "arm")) -endif(UNIX) - option(BUILD_WITH_PAWN "Enable Pawn language" OFF) option(ENABLE_BREAKPAD "Enable Google Breakpad for Crash reporting" OFF) @@ -22,89 +15,52 @@ if(ENABLE_BREAKPAD) include_directories(${CMAKE_SOURCE_DIR}/extern/breakpad/src ${Breakpad_Headers}) endif(ENABLE_BREAKPAD) -if(BUILD_WITH_PAWN) +option(BUILD_WITH_LUA "Enable Terra/Lua language" ON) +option(FORCE_LUA "Use Lua instead Terra" OFF) - add_subdirectory(amx) - #set(Pawn_ROOT ${CMAKE_SOURCE_DIR}/external/pawn/) - set(Pawn_INCLUDES ${Pawn_ROOT}/include) - set(Pawn_LIBRARY ${Pawn_ROOT}/lib/libamx.a) - set(PawnScript_Sources - Script/LangPawn/LangPAWN.cpp - Script/LangPawn/PawnFunc.cpp) - set(PawnScript_Headers ${Pawn_INCLUDES} - Script/LangPawn/LangPAWN.hpp - ) +#set(Terra_ROOT ${CMAKE_SOURCE_DIR}/external/terra/) +#if(WIN32 OR FORCE_LUA) + find_package(LuaJit REQUIRED) +#[[else() + find_package(Terra REQUIRED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_TERRA")]] +#endif() +set(LuaScript_Headers ${Terra_INCLUDES} ${LUA_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/extern/sol/sol.hpp) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_PAWN -DPAWN_CELL_SIZE=64") - #include_directories(${Pawn_INCLUDES}) - include_directories("./amx/linux") -endif(BUILD_WITH_PAWN) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_LUA") +include_directories(${Terra_INCLUDES} ${LUA_INCLUDE_DIR} ${LUAJIT_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/extern/sol) -option(BUILD_WITH_LUA "Enable Terra/Lua language" ON) -option(FORCE_LUA "Use Lua instead Terra" OFF) -if(BUILD_WITH_LUA) - #set(Terra_ROOT ${CMAKE_SOURCE_DIR}/external/terra/) - if(WIN32 OR FORCE_LUA) - find_package(Lua51 REQUIRED) - MESSAGE(STATUS "Found LUA_LIBRARY: ${LUA_LIBRARY}") - MESSAGE(STATUS "Found LUA_INCLUDE_DIR: ${LUA_INCLUDE_DIR}") - else() - find_package(Terra REQUIRED) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_TERRA") - endif() - set(LuaScript_Sources - Script/LangLua/LangLua.cpp - Script/LangLua/LuaFunc.cpp) - set(LuaScript_Headers ${Terra_INCLUDES} ${LUA_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/extern/LuaBridge ${CMAKE_SOURCE_DIR}/extern/LuaBridge/detail - Script/LangLua/LangLua.hpp) - - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_LUA") - include_directories(${Terra_INCLUDES} ${LUA_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/extern/LuaBridge) -endif(BUILD_WITH_LUA) - -set(NativeScript_Sources - Script/LangNative/LangNative.cpp - ) -set(NativeScript_Headers - Script/LangNative/LangNative.hpp - ) # local files set(SERVER main.cpp - Player.cpp + Player.cpp Players.cpp Networking.cpp MasterClient.cpp Cell.cpp CellController.cpp Utils.cpp - Script/Script.cpp Script/ScriptFunction.cpp - Script/ScriptFunctions.cpp - - Script/Functions/Actors.cpp Script/Functions/World.cpp Script/Functions/Miscellaneous.cpp - - Script/Functions/Books.cpp Script/Functions/Cells.cpp Script/Functions/CharClass.cpp - Script/Functions/Chat.cpp Script/Functions/Dialogue.cpp Script/Functions/Factions.cpp - Script/Functions/GUI.cpp Script/Functions/Items.cpp Script/Functions/Mechanics.cpp - Script/Functions/Positions.cpp Script/Functions/Quests.cpp Script/Functions/Settings.cpp - Script/Functions/Spells.cpp Script/Functions/Stats.cpp Script/Functions/Timer.cpp - - Script/API/TimerAPI.cpp Script/API/PublicFnAPI.cpp - ${PawnScript_Sources} - ${LuaScript_Sources} - ${NativeScript_Sources} - + CharClass.cpp + Inventory.cpp + Settings.cpp + Timer.cpp + Books.cpp + GUI.cpp + Dialogue.cpp + Factions.cpp + Cells.cpp + Quests.cpp + Spells.cpp + Actors.cpp + NetActor.cpp + CellState.cpp + Object.cpp + Script/CommandController.cpp Script/EventController.cpp Script/LuaState.cpp Script/luaUtils.cpp ) set(SERVER_HEADER - Script/Types.hpp Script/Script.hpp Script/SystemInterface.hpp - Script/ScriptFunction.hpp Script/Platform.hpp Script/Language.hpp - Script/ScriptFunctions.hpp Script/API/TimerAPI.hpp Script/API/PublicFnAPI.hpp - ${PawnScript_Headers} - ${LuaScript_Headers} - ${NativeScript_Headers} - ${CallFF_INCLUDES} + ) source_group(tes3mp-server FILES ${SERVER} ${SERVER_HEADER}) @@ -171,7 +127,13 @@ add_executable(tes3mp-server ${PROCESSORS_ACTOR} ${PROCESSORS_PLAYER} ${PROCESSORS_WORLD} ${PROCESSORS} ${APPLE_BUNDLE_RESOURCES} ) -add_definitions(-std=gnu++14 -Wno-ignored-qualifiers) + +target_compile_definitions(tes3mp-server PRIVATE $<$:SOL_SAFE_FUNCTIONS>) # for lua debuging +target_compile_definitions(tes3mp-server PRIVATE $<$:SERVER_DEBUG>) # for lua debuging + +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options(tes3mp-server PRIVATE -std=gnu++14 -Wno-ignored-qualifiers -ftemplate-depth=2048) +endif() target_link_libraries(tes3mp-server #${Boost_SYSTEM_LIBRARY} @@ -182,9 +144,8 @@ target_link_libraries(tes3mp-server components ${Terra_LIBRARY} ${LUA_LIBRARIES} - ${Pawn_LIBRARY} + ${LUAJIT_LIBRARY} ${Breakpad_Library} - ${CallFF_LIBRARY} ) if (UNIX) diff --git a/apps/openmw-mp/Cell.cpp b/apps/openmw-mp/Cell.cpp index 05ce084ac..4bd24d4a4 100644 --- a/apps/openmw-mp/Cell.cpp +++ b/apps/openmw-mp/Cell.cpp @@ -7,8 +7,9 @@ #include #include +#include "Script/EventController.hpp" #include "Player.hpp" -#include "Script/Script.hpp" +#include "Networking.hpp" using namespace std; @@ -39,7 +40,8 @@ void Cell::addPlayer(Player *player) LOG_APPEND(Log::LOG_INFO, "- Adding %s to Cell %s", player->npc.mName.c_str(), getDescription().c_str()); - Script::Call(player->getId(), getDescription().c_str()); + + mwmp::Networking::get().getState().getEventCtrl().Call(player, getDescription()); players.push_back(player); } @@ -60,7 +62,8 @@ void Cell::removePlayer(Player *player) LOG_APPEND(Log::LOG_INFO, "- Removing %s from Cell %s", player->npc.mName.c_str(), getDescription().c_str()); - Script::Call(player->getId(), getDescription().c_str()); + + mwmp::Networking::get().getState().getEventCtrl().Call(player, getDescription()); players.erase(it); return; @@ -72,27 +75,27 @@ void Cell::readActorList(unsigned char packetID, const mwmp::BaseActorList *newA { for (unsigned int i = 0; i < newActorList->count; i++) { - mwmp::BaseActor newActor = newActorList->baseActors.at(i); + auto &newActor = newActorList->baseActors.at(i); mwmp::BaseActor *cellActor; - if (containsActor(newActor.refNumIndex, newActor.mpNum)) + if (containsActor(newActor->refNumIndex, newActor->mpNum)) { - cellActor = getActor(newActor.refNumIndex, newActor.mpNum); + cellActor = getActor(newActor->refNumIndex, newActor->mpNum); switch (packetID) { case ID_ACTOR_POSITION: cellActor->hasPositionData = true; - cellActor->position = newActor.position; + cellActor->position = newActor->position; break; case ID_ACTOR_STATS_DYNAMIC: cellActor->hasStatsDynamicData = true; - cellActor->creatureStats.mDynamic[0] = newActor.creatureStats.mDynamic[0]; - cellActor->creatureStats.mDynamic[1] = newActor.creatureStats.mDynamic[1]; - cellActor->creatureStats.mDynamic[2] = newActor.creatureStats.mDynamic[2]; + cellActor->creatureStats.mDynamic[0] = newActor->creatureStats.mDynamic[0]; + cellActor->creatureStats.mDynamic[1] = newActor->creatureStats.mDynamic[1]; + cellActor->creatureStats.mDynamic[2] = newActor->creatureStats.mDynamic[2]; break; } } @@ -107,9 +110,9 @@ bool Cell::containsActor(int refNumIndex, int mpNum) { for (unsigned int i = 0; i < cellActorList.baseActors.size(); i++) { - mwmp::BaseActor actor = cellActorList.baseActors.at(i); + auto &actor = cellActorList.baseActors.at(i); - if (actor.refNumIndex == refNumIndex && actor.mpNum == mpNum) + if (actor->refNumIndex == refNumIndex && actor->mpNum == mpNum) return true; } return false; @@ -119,28 +122,28 @@ mwmp::BaseActor *Cell::getActor(int refNumIndex, int mpNum) { for (unsigned int i = 0; i < cellActorList.baseActors.size(); i++) { - mwmp::BaseActor *actor = &cellActorList.baseActors.at(i); + auto &actor = cellActorList.baseActors.at(i); if (actor->refNumIndex == refNumIndex && actor->mpNum == mpNum) - return actor; + return actor.get(); } return 0; } void Cell::removeActors(const mwmp::BaseActorList *newActorList) { - for (std::vector::iterator it = cellActorList.baseActors.begin(); it != cellActorList.baseActors.end();) + for (auto it = cellActorList.baseActors.begin(); it != cellActorList.baseActors.end();) { - int refNumIndex = (*it).refNumIndex; - int mpNum = (*it).mpNum; + int refNumIndex = (*it)->refNumIndex; + int mpNum = (*it)->mpNum; bool foundActor = false; for (unsigned int i = 0; i < newActorList->count; i++) { - mwmp::BaseActor newActor = newActorList->baseActors.at(i); + auto &newActor = newActorList->baseActors.at(i); - if (newActor.refNumIndex == refNumIndex && newActor.mpNum == mpNum) + if (newActor->refNumIndex == refNumIndex && newActor->mpNum == mpNum) { it = cellActorList.baseActors.erase(it); foundActor = true; diff --git a/apps/openmw-mp/CellController.cpp b/apps/openmw-mp/CellController.cpp index 48330c53e..9cbad8dd2 100644 --- a/apps/openmw-mp/CellController.cpp +++ b/apps/openmw-mp/CellController.cpp @@ -1,9 +1,10 @@ #include "CellController.hpp" #include +#include #include "Cell.hpp" #include "Player.hpp" -#include "Script/Script.hpp" +#include "Networking.hpp" using namespace std; @@ -50,7 +51,7 @@ Cell *CellController::getCell(ESM::Cell *esmCell) Cell *CellController::getCellByXY(int x, int y) { - auto it = find_if(cells.begin(), cells.end(), [x, y](const Cell *c) + auto it = find_if (cells.begin(), cells.end(), [x, y](const Cell *c) { return c->cell.mData.mX == x && c->cell.mData.mY == y; }); @@ -66,7 +67,7 @@ Cell *CellController::getCellByXY(int x, int y) Cell *CellController::getCellByName(std::string cellName) { - auto it = find_if(cells.begin(), cells.end(), [cellName](const Cell *c) + auto it = find_if (cells.begin(), cells.end(), [cellName](const Cell *c) { return c->cell.mName == cellName; }); @@ -83,7 +84,7 @@ Cell *CellController::getCellByName(std::string cellName) Cell *CellController::addCell(ESM::Cell cellData) { LOG_APPEND(Log::LOG_INFO, "- Loaded cells: %d", cells.size()); - auto it = find_if(cells.begin(), cells.end(), [cellData](const Cell *c) { + auto it = find_if (cells.begin(), cells.end(), [cellData](const Cell *c) { // Currently we cannot compare because plugin lists can be loaded in different order //return c->cell.sRecordId == cellData.sRecordId; return c->cell.isExterior() ? (c->cell.mData.mX == cellData.mData.mX && c->cell.mData.mY == cellData.mData.mY) : @@ -116,7 +117,8 @@ void CellController::removeCell(Cell *cell) { if (*it != nullptr && *it == cell) { - Script::Call(cell->getDescription().c_str()); + mwmp::Networking::get().getState().getEventCtrl().Call(cell->getDescription()); + LOG_APPEND(Log::LOG_INFO, "- Removing %s from CellController", cell->getDescription().c_str()); delete *it; diff --git a/apps/openmw-mp/CellState.cpp b/apps/openmw-mp/CellState.cpp new file mode 100644 index 000000000..a240b5955 --- /dev/null +++ b/apps/openmw-mp/CellState.cpp @@ -0,0 +1,30 @@ +// +// Created by koncord on 25.08.17. +// + +#include "CellState.hpp" + +#include "Script/LuaState.hpp" + +void CellState::Init(LuaState &lua) +{ + lua.getState()->new_usertype("CellState", + "type", sol::property(&CellState::getStateType), + "description", sol::property(&CellState::getDescription) + ); +} + +CellState::CellState(mwmp::CellState state) : state(state) +{ + +} + +int CellState::getStateType() const +{ + return state.type; +} + +std::string CellState::getDescription() const +{ + return state.cell.getDescription(); +} \ No newline at end of file diff --git a/apps/openmw-mp/CellState.hpp b/apps/openmw-mp/CellState.hpp new file mode 100644 index 000000000..8e11a81a2 --- /dev/null +++ b/apps/openmw-mp/CellState.hpp @@ -0,0 +1,24 @@ +// +// Created by koncord on 25.08.17. +// + +#pragma once + +#include +#include + +class LuaState; + +class CellState +{ +public: + static void Init(LuaState &lua); + + explicit CellState(mwmp::CellState state); +public: + int getStateType() const; + std::string getDescription() const; + +private: + mwmp::CellState state; +}; diff --git a/apps/openmw-mp/Cells.cpp b/apps/openmw-mp/Cells.cpp new file mode 100644 index 000000000..1a399f0fe --- /dev/null +++ b/apps/openmw-mp/Cells.cpp @@ -0,0 +1,99 @@ +// +// Created by koncord on 25.08.17. +// + +#include "Cells.hpp" + +#include +#include "Script/LuaState.hpp" +#include "NetActor.hpp" +#include "Networking.hpp" + +using namespace std; + +void Cells::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Cells", + "cell", sol::property(&Cells::getCell, &Cells::setCell), + "getExterior", &Cells::getExterior, + "setExterior", &Cells::setExterior, + "getRegion", &Cells::getRegion, + + "isExterior", &Cells::isExterior, + "isChangingRegion", &Cells::isChangingRegion + ); +} + +Cells::Cells(NetActor *netActor) : netActor(netActor), changedCell(false) +{ + +} + +Cells::~Cells() +{ + +} + +void Cells::update() +{ + +} + +std::string Cells::getCell() const +{ + return netActor->getNetCreature()->cell.getDescription(); +} + +void Cells::setCell(const std::string &cellDescription) +{ + /*LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %s", netActor->getNetCreature()->npc.mName.c_str(), + netActor->getNetCreature()->cell.getDescription().c_str(), cellDescription.c_str());*/ + + netActor->getNetCreature()->cell = Utils::getCellFromDescription(cellDescription); + changedCell = true; +} + +std::tuple Cells::getExterior() const +{ + return make_tuple(netActor->getNetCreature()->cell.mData.mX, netActor->getNetCreature()->cell.mData.mY); +} + +void Cells::setExterior(int x, int y) +{ + /*LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %i,%i", netActor->getNetCreature()->npc.mName.c_str(), + netActor->getNetCreature()->cell.getDescription().c_str(), x, y);*/ + + // If the player is currently in an interior, turn off the interior flag from the cell + if (!netActor->getNetCreature()->cell.isExterior()) + netActor->getNetCreature()->cell.mData.mFlags &= ~ESM::Cell::Interior; + + netActor->getNetCreature()->cell.mData.mX = x; + netActor->getNetCreature()->cell.mData.mY = y; + changedCell = true; +} + +bool Cells::isExterior() const +{ + return netActor->getNetCreature()->cell.isExterior(); +} + +bool Cells::isChangingRegion() const +{ + return netActor->getNetCreature()->isChangingRegion; +} + +std::string Cells::getRegion() const +{ + return netActor->getNetCreature()->cell.mRegion; +} + +bool Cells::isChangedCell() const +{ + return changedCell; +} + +void Cells::resetChangedCell() +{ + changedCell = false; +} + diff --git a/apps/openmw-mp/Cells.hpp b/apps/openmw-mp/Cells.hpp new file mode 100644 index 000000000..72dd6c305 --- /dev/null +++ b/apps/openmw-mp/Cells.hpp @@ -0,0 +1,43 @@ +// +// Created by koncord on 25.08.17. +// + +#pragma once + +#include +#include +#include + +class LuaState; +class NetActor; + +class Cells +{ +public: + static void Init(LuaState &lua); +public: + explicit Cells(NetActor *netActor); + ~Cells(); + + void update(); + + std::string getCell() const; + void setCell(const std::string &cellDescription); + + std::tuple getExterior() const; + void setExterior(int x, int y); + + bool isExterior() const; + bool isChangingRegion() const; + + std::string getRegion() const; + + bool isChangedCell() const; + void resetChangedCell(); + +private: + NetActor *netActor; + bool changedCell; +}; + + diff --git a/apps/openmw-mp/CharClass.cpp b/apps/openmw-mp/CharClass.cpp new file mode 100644 index 000000000..49e7a1b51 --- /dev/null +++ b/apps/openmw-mp/CharClass.cpp @@ -0,0 +1,153 @@ +// +// Created by koncord on 12.08.17. +// + +#include "CharClass.hpp" + +#include +#include +#include "Player.hpp" +#include "Networking.hpp" + +using namespace std; + +void CharClass::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Class", + //"__gc", sol::destructor(deleter), + "default", sol::property(&CharClass::getDefault, &CharClass::setDefault), + "isDefault", &CharClass::isDefault, + + "name", sol::property(&CharClass::getName, &CharClass::setName), + "description", sol::property(&CharClass::getDesc, &CharClass::setDesc), + "specialization", + sol::property(&CharClass::getSpecialization, &CharClass::setSpecialization), + + "getMajorAttributes", &CharClass::getMajorAttributes, + "setMajorAttributes", &CharClass::setMajorAttributes, + + "getMinorSkills", &CharClass::getMinorSkills, + "setMinorSkills", &CharClass::setMinorSkills, + + "getMajorSkills", &CharClass::getMajorSkills, + "setMajorSkills", &CharClass::setMajorSkills + ); +} + +CharClass::CharClass(Player *player) : player(player), changed(false) +{ + printf("CharClass::CharClass()\n"); +} + +CharClass::~CharClass() +{ + printf("CharClass::~CharClass()\n"); +} + +string CharClass::getDefault() const +{ + return player->charClass.mId; +} + +void CharClass::setDefault(const string &className) +{ + player->charClass.mId = className; + changed = true; + printf("CharClass::setDefault()\n"); +} + +bool CharClass::isDefault() const +{ + return player->charClass.mId.empty(); +} + +void CharClass::setName(const string &className) +{ + player->charClass.mName = className; + changed = true; +} + +string CharClass::getName() const +{ + return player->charClass.mName; +} + +std::string CharClass::getDesc() const +{ + return player->charClass.mDescription; +} + +void CharClass::setDesc(const string &desc) +{ + player->charClass.mDescription = desc; + changed = true; +} + +std::tuple CharClass::getMajorAttributes() const +{ + const auto &data = player->charClass.mData; + return make_tuple(data.mAttribute[0], data.mAttribute[1]); +} + +void CharClass::setMajorAttributes(int first, int second) +{ + auto &data = player->charClass.mData; + data.mAttribute[0] = first; + data.mAttribute[1] = second; + changed = true; +} + +int CharClass::getSpecialization() const +{ + return player->charClass.mData.mSpecialization; +} + +void CharClass::setSpecialization(int spec) +{ + auto &data = player->charClass.mData; + data.mSpecialization = spec; + changed = true; +} + +std::tuple CharClass::getMinorSkills() const +{ + const auto &data = player->charClass.mData; + return make_tuple( data.mSkills[0][0], data.mSkills[1][0], data.mSkills[2][0], data.mSkills[3][0]); +} + +void CharClass::setMinorSkills(int fisrt, int second, int third, int fourth) +{ + auto &data = player->charClass.mData; + data.mSkills[0][0] = fisrt; + data.mSkills[1][0] = second; + data.mSkills[2][0] = third; + data.mSkills[3][0] = fourth; + changed = true; +} + +std::tuple CharClass::getMajorSkills() const +{ + const auto &data = player->charClass.mData; + return make_tuple( data.mSkills[0][1], data.mSkills[1][1], data.mSkills[2][1], data.mSkills[3][1]); +} + +void CharClass::setMajorSkills(int fisrt, int second, int third, int fourth) +{ + auto &data = player->charClass.mData; + data.mSkills[0][1] = fisrt; + data.mSkills[1][1] = second; + data.mSkills[2][1] = third; + data.mSkills[3][1] = fourth; + changed = true; +} + +void CharClass::update() +{ + if (!changed) + return; + changed = false; + printf("CharClass::update()\n"); + auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARCLASS); + packet->setPlayer(player); + packet->Send(false); +} diff --git a/apps/openmw-mp/CharClass.hpp b/apps/openmw-mp/CharClass.hpp new file mode 100644 index 000000000..65c8bc33b --- /dev/null +++ b/apps/openmw-mp/CharClass.hpp @@ -0,0 +1,50 @@ +// +// Created by koncord on 12.08.17. +// + +#pragma once + +#include +#include + +class LuaState; +class Player; + +class CharClass +{ +public: + static void Init(LuaState &lua); + +public: + explicit CharClass(Player *player); + ~CharClass(); + void update(); + + std::string getDefault() const; + void setDefault(const std::string &className); + bool isDefault() const; + + std::string getName() const; + void setName(const std::string &className); + + std::string getDesc() const; + void setDesc(const std::string &desc); + + std::tuple getMajorAttributes() const; + void setMajorAttributes(int first, int second); + + int getSpecialization() const; + void setSpecialization(int spec); + + std::tuple getMinorSkills() const; + void setMinorSkills(int fisrt, int second, int third, int fourth); + + std::tuple getMajorSkills() const; + void setMajorSkills(int fisrt, int second, int third, int fourth); +private: + // not controlled pointer + Player *player; + bool changed; +}; + + diff --git a/apps/openmw-mp/Dialogue.cpp b/apps/openmw-mp/Dialogue.cpp new file mode 100644 index 000000000..af9a85c77 --- /dev/null +++ b/apps/openmw-mp/Dialogue.cpp @@ -0,0 +1,62 @@ +// +// Created by koncord on 15.08.17. +// + +#include "Dialogue.hpp" + +#include +#include "Script/LuaState.hpp" +#include "Player.hpp" +#include "Networking.hpp" + +void Dialogue::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Dialogue", + "addTopic", &Dialogue::addTopic, + "getTopicId", &Dialogue::getTopicId, + "getChanges", &Dialogue::getChanges, + "reset", &Dialogue::reset); +} + + + +Dialogue::Dialogue(Player *player) : player(player), changed(false) +{ + +} + + +void Dialogue::reset() +{ + player->topicChanges.topics.clear(); +} + +void Dialogue::update() +{ + if (!changed) + return; + changed = false; + + auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TOPIC); + + packet->setPlayer(player); + packet->Send(/*toOthers*/ false); +} + +void Dialogue::addTopic(const std::string &topicId) +{ + if (!changed) + reset(); + changed = true; + player->topicChanges.topics.push_back({topicId}); +} + +std::string Dialogue::getTopicId(unsigned int i) const +{ + return player->topicChanges.topics.at(i).topicId; +} + +unsigned int Dialogue::getChanges() const +{ + return player->topicChanges.count; +} diff --git a/apps/openmw-mp/Dialogue.hpp b/apps/openmw-mp/Dialogue.hpp new file mode 100644 index 000000000..a43a30b19 --- /dev/null +++ b/apps/openmw-mp/Dialogue.hpp @@ -0,0 +1,30 @@ +// +// Created by koncord on 15.08.17. +// + +#pragma once + +#include + +class LuaState; +class Player; + +class Dialogue +{ +public: + static void Init(LuaState &lua); +public: + explicit Dialogue(Player *player); + + void addTopic(const std::string &topicId); + std::string getTopicId(unsigned int i) const; + unsigned int getChanges() const; + + void reset(); + void update(); +private: + Player *player; + bool changed; +}; + + diff --git a/apps/openmw-mp/Factions.cpp b/apps/openmw-mp/Factions.cpp new file mode 100644 index 000000000..a42754310 --- /dev/null +++ b/apps/openmw-mp/Factions.cpp @@ -0,0 +1,154 @@ +// +// Created by koncord on 17.08.17. +// + +#include +#include "Factions.hpp" + +#include "Player.hpp" +#include "Script/LuaState.hpp" +#include "Networking.hpp" + +void Factions::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Factions", + "addFaction", &Factions::addFaction, + "changesAction", sol::property(&Factions::getFactionChangesAction, &Factions::setFactionChangesAction), + "getFaction", &Factions::getFaction, + "setFaction", &Factions::setFaction, + "clear", &Factions::clear, + "size", &Factions::size + + ); +/*"InitializeFactionChanges", FactionFunctions::InitializeFactionChanges, + "GetFactionChangesSize", FactionFunctions::GetFactionChangesSize, + "GetFactionChangesAction", FactionFunctions::GetFactionChangesAction, + "GetFactionId", FactionFunctions::GetFactionId, + "GetFactionRank", FactionFunctions::GetFactionRank, + "GetFactionExpulsionState", FactionFunctions::GetFactionExpulsionState, + "GetFactionReputation", FactionFunctions::GetFactionReputation, + "SetFactionChangesAction", FactionFunctions::SetFactionChangesAction, + "SetFactionId", FactionFunctions::SetFactionId, + "SetFactionRank", FactionFunctions::SetFactionRank, + "SetFactionExpulsionState", FactionFunctions::SetFactionExpulsionState, + "SetFactionReputation", FactionFunctions::SetFactionReputation, + "AddFaction", FactionFunctions::AddFaction, + "SendFactionChanges", FactionFunctions::SendFactionChanges*/ +} + +Factions::Factions(Player *player): player(player), changed(false) +{ + +} + +Factions::~Factions() +{ + +} + +void Factions::update() +{ + if (!changed) + return; + changed = false; + + auto packet =mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_FACTION); + packet->setPlayer(player); + packet->Send(/*toOthers*/ false); + clear(); +} + +int Factions::getFactionChangesAction() const +{ + return player->factionChanges.action; +} + +void Factions::setFactionChangesAction(int action) +{ + player->factionChanges.action = action; + changed = true; +} + +void Factions::addFaction(Faction faction) +{ + player->factionChanges.factions.push_back(faction.faction); + changed = true; +} + + +Faction Factions::getFaction(int id) const +{ + return Faction(player->factionChanges.factions.at(id)); +} + +void Factions::setFaction(int id, Faction faction) +{ + player->factionChanges.factions.at(id) = faction.faction; + changed = true; +} + +void Factions::clear() +{ + player->factionChanges.factions.clear(); + changed = true; +} + +size_t Factions::size() const +{ + return player->factionChanges.factions.size(); +} + +void Faction::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Faction", + "factionId", sol::property(&Faction::getFactionId, &Faction::setFactionId), + "rank", sol::property(&Faction::getFactionRank, &Faction::setFactionRank), + "isExpelled", sol::property(&Faction::getFactionExpulsionState, &Faction::setFactionExpulsionState), + "reputation", sol::property(&Faction::getFactionReputation, &Faction::setFactionReputation) + ); +} + +Faction::Faction(mwmp::Faction &faction): faction(faction) +{ + +} + +std::string Faction::getFactionId() const +{ + return faction.factionId; +} + +void Faction::setFactionId(const std::string &factionId) +{ + faction.factionId = factionId; +} + +int Faction::getFactionRank() const +{ + return faction.rank; +} + +void Faction::setFactionRank(unsigned int rank) +{ + faction.rank = rank; +} + +bool Faction::getFactionExpulsionState() const +{ + return faction.isExpelled; +} + +void Faction::setFactionExpulsionState(bool expulsionState) +{ + faction.isExpelled = expulsionState; +} + +int Faction::getFactionReputation() const +{ + return faction.reputation; +} + +void Faction::setFactionReputation(int reputation) +{ + faction.reputation = reputation; +} \ No newline at end of file diff --git a/apps/openmw-mp/Factions.hpp b/apps/openmw-mp/Factions.hpp new file mode 100644 index 000000000..2a79b4185 --- /dev/null +++ b/apps/openmw-mp/Factions.hpp @@ -0,0 +1,59 @@ +// +// Created by koncord on 17.08.17. +// + +#pragma once + +#include +#include + +class LuaState; +class Player; + +class Faction +{ + friend class Factions; +public: + static void Init(LuaState &lua); +public: + explicit Faction(mwmp::Faction &faction); + + std::string getFactionId() const; + void setFactionId(const std::string &factionId); + + int getFactionRank() const; + void setFactionRank(unsigned int rank); + + bool getFactionExpulsionState() const; + void setFactionExpulsionState(bool expulsionState); + + int getFactionReputation() const; + void setFactionReputation(int reputation); + + mwmp::Faction faction; +}; + +class Factions +{ +public: + static void Init(LuaState &lua); +public: + explicit Factions(Player *player); + ~Factions(); + + void update(); + + int getFactionChangesAction() const; + void setFactionChangesAction(int action); + + void addFaction(Faction faction); + Faction getFaction(int id) const; + void setFaction(int id, Faction faction); + size_t size() const; + void clear(); + +private: + mwmp::Faction tempFaction; + Player *player; + bool changed; +}; diff --git a/apps/openmw-mp/GUI.cpp b/apps/openmw-mp/GUI.cpp new file mode 100644 index 000000000..6bbdf3492 --- /dev/null +++ b/apps/openmw-mp/GUI.cpp @@ -0,0 +1,100 @@ +// +// Created by koncord on 15.08.17. +// + +#include +#include "GUI.hpp" +#include "Player.hpp" +#include "Networking.hpp" + +void GUI::Init(LuaState &lua) +{ + lua.getState()->new_usertype("GUI", + "messageBox", &GUI::messageBox, + "customMessageBox", &GUI::customMessageBox, + "inputDialog", &GUI::inputDialog, + "passwordDialog", &GUI::passwordDialog, + "listBox", &GUI::listBox, + "setMapVisibility", &GUI::setMapVisibility, + "setMapVisibilityAll", &GUI::setMapVisibilityAll + ); +} + +GUI::GUI(Player *player): player(player), changed(false) +{ + +} + +GUI::~GUI() +{ + +} + +void GUI::update() +{ + if (!changed) + return; + changed = false; + + auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX); + packet->setPlayer(player); + packet->Send(false); +} + +void GUI::messageBox(int id, const char *label) +{ + player->guiMessageBox.id = id; + player->guiMessageBox.label = label; + player->guiMessageBox.type = Player::GUIMessageBox::MessageBox; + + changed = true; +} + +void GUI::customMessageBox(int id, const char *label, const char *buttons) +{ + player->guiMessageBox.id = id; + player->guiMessageBox.label = label; + player->guiMessageBox.buttons = buttons; + player->guiMessageBox.type = Player::GUIMessageBox::CustomMessageBox; + + changed = true; +} + +void GUI::inputDialog(int id, const char *label) +{ + player->guiMessageBox.id = id; + player->guiMessageBox.label = label; + player->guiMessageBox.type = Player::GUIMessageBox::InputDialog; + + changed = true; +} + +void GUI::passwordDialog(int id, const char *label, const char *note) +{ + player->guiMessageBox.id = id; + player->guiMessageBox.label = label; + player->guiMessageBox.note = note; + player->guiMessageBox.type = Player::GUIMessageBox::PasswordDialog; + + changed = true; +} + +void GUI::listBox(int id, const char *label, const char *items) +{ + player->guiMessageBox.id = id; + player->guiMessageBox.label = label; + player->guiMessageBox.data = items; + player->guiMessageBox.type = Player::GUIMessageBox::ListBox; + + changed = true; +} + +void GUI::setMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state) +{ + LOG_MESSAGE(Log::LOG_WARN, "stub"); +} + +void GUI::setMapVisibilityAll(unsigned short targetPID, unsigned short state) +{ + LOG_MESSAGE(Log::LOG_WARN, "stub"); +} diff --git a/apps/openmw-mp/GUI.hpp b/apps/openmw-mp/GUI.hpp new file mode 100644 index 000000000..4a8ec984c --- /dev/null +++ b/apps/openmw-mp/GUI.hpp @@ -0,0 +1,36 @@ +// +// Created by koncord on 15.08.17. +// + +#pragma once + +class LuaState; +class Player; + +class GUI +{ +public: + static void Init(LuaState &lua); +public: + explicit GUI(Player *player); + ~GUI(); + + void update(); + + void messageBox(int id, const char *label); + + void customMessageBox(int id, const char *label, const char *buttons); + void inputDialog(int id, const char *label); + void passwordDialog(int id, const char *label, const char *note); + + void listBox(int id, const char *label, const char *items); + + //state 0 - disallow, 1 - allow + void setMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state); + void setMapVisibilityAll(unsigned short targetPID, unsigned short state); +private: + Player *player; + bool changed; +}; + + diff --git a/apps/openmw-mp/Inventory.cpp b/apps/openmw-mp/Inventory.cpp new file mode 100644 index 000000000..b1f5adefe --- /dev/null +++ b/apps/openmw-mp/Inventory.cpp @@ -0,0 +1,164 @@ +// +// Created by koncord on 12.08.17. +// + +#include "Inventory.hpp" +#include +#include +#include +#include +#include "NetActor.hpp" +#include "Networking.hpp" + +using namespace std; + +void Inventory::Init(LuaState &lua) +{ + lua.getState()->new_usertype("Inventory", + "getInventoryChangesSize", &Inventory::getChangesSize, + "addItem", &Inventory::addItem, + "removeItem", &Inventory::removeItem, + "getInventoryItem", &Inventory::getInventoryItem, + + "equipItem", &Inventory::equipItem, + "unequipItem", &Inventory::unequipItem, + "hasItemEquipped", &Inventory::hasItemEquipped, + "getEquipmentItem", &Inventory::getEquipmentItem + + + ); +} + +Inventory::Inventory(NetActor *actor) : netActor(actor), equipmentChanged(false), inventoryChanged(0) +{ + printf("Inventory::Inventory()\n"); +} + +Inventory::~Inventory() +{ + printf("Inventory::~Inventory()\n"); +} + +void Inventory::update() +{ + printf("Inventory::update()"); + /*if (equipmentChanged) + { + auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT); + packet->setPlayer(netActor->getNetCreature()); + packet->Send(false); + packet->Send(true); + } + + if (inventoryChanged != 0) + { + auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT); + packet->setPlayer(netActor->getNetCreature()); + packet->Send(false); + } + + equipmentChanged = false; + inventoryChanged = 0;*/ +} + + +void Inventory::InitializeInventoryChanges() +{ + netActor->getNetCreature()->inventoryChanges.items.clear(); + netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::SET; +} + +int Inventory::getChangesSize() const +{ + return netActor->getNetCreature()->inventoryChanges.count; +} + +void Inventory::equipItem(unsigned short slot, const std::string& refId, unsigned int count, int charge) +{ + netActor->getNetCreature()->equipedItems[slot].refId = refId; + netActor->getNetCreature()->equipedItems[slot].count = count; + netActor->getNetCreature()->equipedItems[slot].charge = charge; + equipmentChanged = true; +} + +void Inventory::unequipItem( unsigned short slot) +{ + equipItem(slot, "", 0, -1); +} + + +void Inventory::addItem(const std::string &refId, unsigned int count, int charge) +{ + if (inventoryChanged == mwmp::InventoryChanges::REMOVE) + return; + if (inventoryChanged == 0) + InitializeInventoryChanges(); + + mwmp::Item item; + item.refId = refId; + item.count = count; + item.charge = charge; + + netActor->getNetCreature()->inventoryChanges.items.push_back(item); + netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::ADD; + inventoryChanged = netActor->getNetCreature()->inventoryChanges.action; +} + +void Inventory::removeItem(const std::string &refId, unsigned short count) +{ + if (inventoryChanged == mwmp::InventoryChanges::ADD) + return; + if (inventoryChanged == 0) + InitializeInventoryChanges(); + + mwmp::Item item; + item.refId = refId; + item.count = count; + + netActor->getNetCreature()->inventoryChanges.items.push_back(item); + netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::REMOVE; + inventoryChanged = netActor->getNetCreature()->inventoryChanges.action; +} + +bool Inventory::hasItemEquipped(const std::string &refId) const +{ + for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++) + if (Misc::StringUtils::ciEqual(netActor->getNetCreature()->equipedItems[slot].refId, refId)) + return true; + return false; +} + +std::tuple Inventory::getEquipmentItem(unsigned short slot) const +{ + const auto &item = netActor->getNetCreature()->equipedItems[slot]; + return make_tuple(item.refId, item.count, item.charge); +} + +std::tuple Inventory::getInventoryItem(unsigned int slot) const +{ + const auto &item = netActor->getNetCreature()->inventoryChanges.items.at(slot); + return make_tuple(item.refId, item.count, item.charge); +} + +void Inventory::resetEquipmentFlag() +{ + equipmentChanged = false; +} + +bool Inventory::isEquipmentChanged() +{ + return equipmentChanged; +} + +void Inventory::resetInventoryFlag() +{ + inventoryChanged = 0; +} + +int Inventory::inventoryChangeType() +{ + return inventoryChanged; +} + + + diff --git a/apps/openmw-mp/Inventory.hpp b/apps/openmw-mp/Inventory.hpp new file mode 100644 index 000000000..e0e1c7eea --- /dev/null +++ b/apps/openmw-mp/Inventory.hpp @@ -0,0 +1,63 @@ +// +// Created by koncord on 12.08.17. +// + +#pragma once + +#include +#include + +class LuaState; +class NetActor; + +class Inventory +{ +public: + static void Init(LuaState &lua); + bool isEquipmentChanged(); + void resetEquipmentFlag(); + int inventoryChangeType(); + void resetInventoryFlag(); +public: + explicit Inventory(NetActor *netActor); + ~Inventory(); + void update(); + + //inventory + int getChangesSize() const; + void addItem(const std::string& refId, unsigned int count, int charge); + void removeItem(const std::string& refId, unsigned short count); + + /** + * + * @param slot + * @return refid, count, charge + */ + std::tuple getInventoryItem(unsigned int slot) const; + + + // equipment + void equipItem(unsigned short slot, const std::string& refId, unsigned int count, int charge); + void unequipItem(unsigned short slot); + + bool hasItemEquipped(const std::string& refId) const; + + /** + * + * @param slot + * @return refid, count, charge + */ + std::tuple getEquipmentItem(unsigned short slot) const; + + +private: + void InitializeInventoryChanges(); + +private: + // not controlled pointer + NetActor *netActor; + bool equipmentChanged; + int inventoryChanged; +}; + + diff --git a/apps/openmw-mp/MasterClient.cpp b/apps/openmw-mp/MasterClient.cpp index 306feb9fd..52eb5a341 100644 --- a/apps/openmw-mp/MasterClient.cpp +++ b/apps/openmw-mp/MasterClient.cpp @@ -13,6 +13,7 @@ #include #include #include "Networking.hpp" +#include "Players.hpp" using namespace std; using namespace mwmp; @@ -32,7 +33,7 @@ MasterClient::MasterClient(RakNet::RakPeerInterface *peer, std::string queryAddr void MasterClient::SetPlayers(unsigned pl) { mutexData.lock(); - if (queryData.GetPlayers() != pl) + if ((unsigned) queryData.GetPlayers() != pl) { queryData.SetPlayers(pl); updated = true; @@ -43,7 +44,7 @@ void MasterClient::SetPlayers(unsigned pl) void MasterClient::SetMaxPlayers(unsigned pl) { mutexData.lock(); - if (queryData.GetMaxPlayers() != pl) + if ((unsigned) queryData.GetMaxPlayers() != pl) { queryData.SetMaxPlayers(pl); updated = true; @@ -194,22 +195,22 @@ void MasterClient::Thread() queryData.SetPassword((int) Networking::get().isPassworded()); queryData.SetVersion(TES3MP_VERSION); - auto *players = Players::getPlayers(); + //auto *players = Players::getPlayers(); while (sRun) { - SetPlayers((int) players->size()); + SetPlayers((unsigned) Players::size()); - auto pIt = players->begin(); - if (queryData.players.size() != players->size()) + auto pIt = Players::begin(); + if (queryData.players.size() != Players::size()) { queryData.players.clear(); updated = true; } else { - for (int i = 0; pIt != players->end(); i++, pIt++) + for (int i = 0; pIt != Players::end(); i++, pIt++) { - if (queryData.players[i] != pIt->second->npc.mName) + if (queryData.players[i] != (*pIt)->npc.mName) { queryData.players.clear(); updated = true; @@ -221,13 +222,12 @@ void MasterClient::Thread() if (updated) { updated = false; - if (pIt != players->end()) + if (pIt != Players::end()) { - for (auto player : *players) - { - if (!player.second->npc.mName.empty()) - queryData.players.push_back(player.second->npc.mName); - } + Players::for_each([this](auto player) { + if (!player->npc.mName.empty()) + queryData.players.push_back(player->npc.mName); + }); } Send(PacketMasterAnnounce::FUNCTION_ANNOUNCE); } diff --git a/apps/openmw-mp/MasterClient.hpp b/apps/openmw-mp/MasterClient.hpp index 858946297..2794afd69 100644 --- a/apps/openmw-mp/MasterClient.hpp +++ b/apps/openmw-mp/MasterClient.hpp @@ -46,7 +46,7 @@ private: std::thread thrQuery; mwmp::PacketMasterAnnounce pma; RakNet::BitStream writeStream; - bool updated; + std::atomic updated; }; diff --git a/apps/openmw-mp/NetActor.cpp b/apps/openmw-mp/NetActor.cpp new file mode 100644 index 000000000..13786ec32 --- /dev/null +++ b/apps/openmw-mp/NetActor.cpp @@ -0,0 +1,98 @@ +// +// Created by koncord on 25.08.17. +// + +#include "NetActor.hpp" + +#include +#include "Script/LuaState.hpp" +//#include "Player.hpp" +#include "Networking.hpp" +#include + +using namespace std; + +NetActor::NetActor() : inventory(this), cellAPI(this) +{ + +} + +void NetActor::resetUpdateFlags() +{ + statsChanged = false; + skillsChanged = false; + attributesChanged = false; + baseInfoChanged = false; + positionChanged = false; +} + +std::tuple NetActor::getPosition() const +{ + return make_tuple(netCreature->position.pos[0], netCreature->position.pos[1], netCreature->position.pos[2]); +} + +void NetActor::setPosition(float x, float y, float z) +{ + netCreature->position.pos[0] = x; + netCreature->position.pos[1] = y; + netCreature->position.pos[2] = z; + positionChanged = true; +} + +std::tuple NetActor::getRotation() const +{ + return make_tuple(netCreature->position.rot[0], netCreature->position.rot[2]); +} + +void NetActor::setRotation(float x, float z) +{ + netCreature->position.rot[0] = x; + netCreature->position.rot[2] = z; + positionChanged = true; +} + +std::tuple NetActor::getHealth() const +{ + return make_tuple(netCreature->creatureStats.mDynamic[0].mBase, netCreature->creatureStats.mDynamic[0].mCurrent); +} + +void NetActor::setHealth(float base, float current) +{ + netCreature->creatureStats.mDynamic[0].mBase = base; + netCreature->creatureStats.mDynamic[0].mCurrent = current; + statsChanged = true; +} + +std::tuple NetActor::getMagicka() const +{ + return make_tuple(netCreature->creatureStats.mDynamic[1].mBase, netCreature->creatureStats.mDynamic[1].mCurrent); +} + +void NetActor::setMagicka(float base, float current) +{ + netCreature->creatureStats.mDynamic[1].mBase = base; + netCreature->creatureStats.mDynamic[1].mCurrent = current; + statsChanged = true; +} + +std::tuple NetActor::getFatigue() const +{ + return make_tuple(netCreature->creatureStats.mDynamic[2].mBase, netCreature->creatureStats.mDynamic[2].mCurrent); +} + +void NetActor::setFatigue(float base, float current) +{ + netCreature->creatureStats.mDynamic[2].mBase = base; + netCreature->creatureStats.mDynamic[2].mCurrent = current; + statsChanged = true; +} + +Inventory &NetActor::getInventory() +{ + return inventory; +} + +Cells &NetActor::getCell() +{ + return cellAPI; +} \ No newline at end of file diff --git a/apps/openmw-mp/NetActor.hpp b/apps/openmw-mp/NetActor.hpp new file mode 100644 index 000000000..b9e637388 --- /dev/null +++ b/apps/openmw-mp/NetActor.hpp @@ -0,0 +1,75 @@ +// +// Created by koncord on 25.08.17. +// + +#pragma once + +#include +#include +#include "Inventory.hpp" +#include "Cells.hpp" + +namespace mwmp +{ + class BasePlayer; + class BaseNetCreature; + class BaseActor; +} + +class NetActor +{ +public: + NetActor(); + + void resetUpdateFlags(); + + /** + * + * @return x, y, z + */ + + std::tuple getPosition() const; + void setPosition(float x, float y, float z); + + /** + * + * @return x, y + */ + std::tuple getRotation() const; + void setRotation(float x, float z); + + /** + * + * @return base, current + */ + std::tuple getHealth() const; + void setHealth(float base, float current); + + /** + * + * @return base, current + */ + std::tuple getMagicka() const; + void setMagicka(float base, float current); + + /** + * + * @return base, current + */ + std::tuple getFatigue() const; + void setFatigue(float base, float current); + + Inventory &getInventory(); + Cells &getCell(); + + mwmp::BaseNetCreature *getNetCreature() { return netCreature; } +protected: + bool statsChanged, attributesChanged, skillsChanged, baseInfoChanged, positionChanged; + mwmp::BasePlayer *basePlayer; + mwmp::BaseNetCreature *netCreature; + + Inventory inventory; + Cells cellAPI; +}; + + diff --git a/apps/openmw-mp/Networking.cpp b/apps/openmw-mp/Networking.cpp index 3b3380702..b5eefae7d 100644 --- a/apps/openmw-mp/Networking.cpp +++ b/apps/openmw-mp/Networking.cpp @@ -2,7 +2,8 @@ // Created by koncord on 12.01.16. // -#include "Player.hpp" +#include "Players.hpp" +#include