From 4890ecd35704b8652c73ae11a1490d4251bed8a3 Mon Sep 17 00:00:00 2001 From: bret curtis Date: Tue, 27 Mar 2018 20:20:40 +0200 Subject: [PATCH 1/8] remove native GLESv* support, as it never worked; make things less complicated as result, fixed lighting.glsl to work with gl2es thanks to ptitSeb --- CI/before_script.msvc.sh | 3 +- CMakeLists.txt | 8 +- apps/openmw/mwrender/water.cpp | 2 - cmake/FindOpenGLES.cmake | 94 ------------------------ components/CMakeLists.txt | 15 +--- components/sdlutil/sdlgraphicswindow.cpp | 2 +- files/shaders/lighting.glsl | 6 +- 7 files changed, 8 insertions(+), 122 deletions(-) delete mode 100644 cmake/FindOpenGLES.cmake diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 2a052912a..a0cf06919 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -613,8 +613,7 @@ fi SUFFIX="" fi - add_runtime_dlls "$(pwd)/bin/lib"{EGL,GLESv2}${SUFFIX}.dll \ - "$(pwd)/bin/Qt5"{Core,Gui,Network,OpenGL,Widgets}${SUFFIX}.dll + add_runtime_dlls "$(pwd)/bin/Qt5"{Core,Gui,Network,OpenGL,Widgets}${SUFFIX}.dll add_qt_platform_dlls "$(pwd)/plugins/platforms/qwindows${SUFFIX}.dll" echo Done. diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c1f961f5..1f97323e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,6 +135,8 @@ if (WIN32) endif() # Dependencies +find_package(OpenGL REQUIRED) + if (USE_QT) message(STATUS "Using Qt${DESIRED_QT_VERSION}") @@ -182,12 +184,6 @@ if (NOT WIN32 AND BUILD_WIZARD) # windows users can just run the morrowind insta set(OPENMW_USE_UNSHIELD TRUE) endif() -option(OPENGL_ES "enable opengl es support" FALSE ) - -if (OPENGL_ES) - add_definitions(-DOPENGL_ES) -endif(OPENGL_ES) - # Fix for not visible pthreads functions for linker with glibc 2.15 if (UNIX AND NOT APPLE) find_package (Threads) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index dbfee05df..6e1fef716 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -503,13 +503,11 @@ void Water::createSimpleWaterStateSet(osg::Node* node, float alpha) // use a shader to render the simple water, ensuring that fog is applied per pixel as required. // this could be removed if a more detailed water mesh, using some sort of paging solution, is implemented. -#if !defined(OPENGL_ES) && !defined(ANDROID) Resource::SceneManager* sceneManager = mResourceSystem->getSceneManager(); bool oldValue = sceneManager->getForceShaders(); sceneManager->setForceShaders(true); sceneManager->recreateShaders(node); sceneManager->setForceShaders(oldValue); -#endif } void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, Refraction* refraction) diff --git a/cmake/FindOpenGLES.cmake b/cmake/FindOpenGLES.cmake deleted file mode 100644 index 6a0466409..000000000 --- a/cmake/FindOpenGLES.cmake +++ /dev/null @@ -1,94 +0,0 @@ -#------------------------------------------------------------------- -# This file is part of the CMake build system for OGRE -# (Object-oriented Graphics Rendering Engine) -# For the latest info, see https://www.ogre3d.org/ -# -# The contents of this file are placed in the public domain. Feel -# free to make use of it in any way you like. -#------------------------------------------------------------------- - -# - Try to find OpenGLES -# Once done this will define -# -# OPENGLES_FOUND - system has OpenGLES -# OPENGLES_INCLUDE_DIR - the GL include directory -# OPENGLES_LIBRARIES - Link these to use OpenGLES - -IF (WIN32) - IF (CYGWIN) - - FIND_PATH(OPENGLES_INCLUDE_DIR GLES/gl.h ) - - FIND_LIBRARY(OPENGLES_gl_LIBRARY libgles_cm ) - - ELSE (CYGWIN) - - IF(BORLAND) - SET (OPENGLES_gl_LIBRARY import32 CACHE STRING "OpenGL ES 1.x library for win32") - ELSE(BORLAND) - #MS compiler - todo - fix the following line: - SET (OPENGLES_gl_LIBRARY ${OGRE_SOURCE_DIR}/Dependencies/lib/release/libgles_cm.lib CACHE STRING "OpenGL ES 1.x library for win32") - ENDIF(BORLAND) - - ENDIF (CYGWIN) - -ELSE (WIN32) - - IF (APPLE) - - #create_search_paths(/Developer/Platforms) - #findpkg_framework(OpenGLES) - #set(OPENGLES_gl_LIBRARY "-framework OpenGLES") - - ELSE(APPLE) - - FIND_PATH(OPENGLES_INCLUDE_DIR GLES/gl.h - /opt/vc/include - /opt/graphics/OpenGL/include - /usr/openwin/share/include - /usr/X11R6/include - /usr/include - ) - - FIND_LIBRARY(OPENGLES_gl_LIBRARY - NAMES GLES_CM GLESv1_CM - PATHS /opt/vc/lib - /opt/graphics/OpenGL/lib - /usr/openwin/lib - /usr/shlib /usr/X11R6/lib - /usr/lib - ) - - # On Unix OpenGL most certainly always requires X11. - # Feel free to tighten up these conditions if you don't - # think this is always true. - - #IF (OPENGLES_gl_LIBRARY) - # IF(NOT X11_FOUND) - # INCLUDE(FindX11) - # ENDIF(NOT X11_FOUND) - # IF (X11_FOUND) - # SET (OPENGLES_LIBRARIES ${X11_LIBRARIES}) - # ENDIF (X11_FOUND) - #ENDIF (OPENGLES_gl_LIBRARY) - - ENDIF(APPLE) -ENDIF (WIN32) - -SET( OPENGLES_FOUND "NO" ) -IF(OPENGLES_gl_LIBRARY) - - SET( OPENGLES_LIBRARIES ${OPENGLES_gl_LIBRARY} ${OPENGLES_LIBRARIES}) - - SET( OPENGLES_FOUND "YES" ) - -ENDIF(OPENGLES_gl_LIBRARY) - -MARK_AS_ADVANCED( - OPENGLES_INCLUDE_DIR - OPENGLES_gl_LIBRARY -) - -INCLUDE(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENGLES REQUIRED_VARS OPENGLES_LIBRARIES OPENGLES_INCLUDE_DIR) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index a0b426a16..8256f1443 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -26,12 +26,6 @@ else (GIT_CHECKOUT) configure_resource_file(${VERSION_IN_FILE} ${VERSION_FILE_PATH_BASE} ${VERSION_FILE_PATH_RELATIVE}) endif (GIT_CHECKOUT) -if (OPENGL_ES) - find_package(OpenGLES REQUIRED) -else() - find_package(OpenGL REQUIRED) -endif() - # source files add_component_dir (settings @@ -191,12 +185,6 @@ include_directories(${Bullet_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) -if (OPENGL_ES) - set(GL_LIB ${OPENGLES_gl_LIBRARY}) -else() - set(GL_LIB ${OPENGL_gl_LIBRARY}) -endif() - target_link_libraries(components ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} @@ -213,8 +201,7 @@ target_link_libraries(components ${OSGANIMATION_LIBRARIES} ${Bullet_LIBRARIES} ${SDL2_LIBRARIES} - # For MyGUI platform - ${GL_LIB} + ${OPENGL_gl_LIBRARY} ${MyGUI_LIBRARIES} ) diff --git a/components/sdlutil/sdlgraphicswindow.cpp b/components/sdlutil/sdlgraphicswindow.cpp index de82ca850..f9767238f 100644 --- a/components/sdlutil/sdlgraphicswindow.cpp +++ b/components/sdlutil/sdlgraphicswindow.cpp @@ -91,7 +91,7 @@ void GraphicsWindowSDL2::init() SDL_Window *oldWin = SDL_GL_GetCurrentWindow(); SDL_GLContext oldCtx = SDL_GL_GetCurrentContext(); -#if defined(OPENGL_ES) || defined(ANDROID) +#if defined(ANDROID) int major = 1; int minor = 1; char *ver = getenv("OPENMW_GLES_VERSION"); diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index 7b8486fbe..06eebea68 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -47,8 +47,8 @@ vec3 getSpecular(vec3 viewNormal, vec3 viewDirection, float shininess, vec3 matS { vec3 lightDir = normalize(gl_LightSource[0].position.xyz); float NdotL = max(dot(viewNormal, lightDir), 0.0); - if (NdotL < 0) - return vec3(0,0,0); + if (NdotL < 0.0) + return vec3(0.,0.,0.); vec3 halfVec = normalize(lightDir - viewDirection); - return pow(max(dot(viewNormal, halfVec), 0.0), 128) * gl_LightSource[0].specular.xyz * matSpec; + return pow(max(dot(viewNormal, halfVec), 0.0), 128.) * gl_LightSource[0].specular.xyz * matSpec; } From fdcfbdbdd1ef376cba88bd2aeca0780c284087a8 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Sat, 24 Mar 2018 21:26:58 -0400 Subject: [PATCH 2/8] android: Update for sdl 2.0.8 --- apps/openmw/android_main.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/apps/openmw/android_main.c b/apps/openmw/android_main.c index 3f28afa1b..d234a369d 100644 --- a/apps/openmw/android_main.c +++ b/apps/openmw/android_main.c @@ -35,28 +35,11 @@ int Java_org_libsdl_app_SDLActivity_isMouseShown(JNIEnv *env, jclass cls, jobjec return SDL_ShowCursor(SDL_QUERY); } - -int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, - jobject obj) { - +int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) { setenv("OPENMW_DECOMPRESS_TEXTURES", "1", 1); - SDL_Android_Init(env, cls); - - SDL_SetMainReady(); - // On Android, we use a virtual controller with guid="Virtual" SDL_GameControllerAddMapping("5669727475616c000000000000000000,Virtual,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4"); - /* Run the application code! */ - - int status; - - status = main(argcData+1, argvData); - releaseArgv(); - /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ - /* exit(status); */ - - return status; + return 0; } - From d8b48f6cf49794060990419368675ff8fff98aee Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 1 Apr 2018 07:11:43 +0300 Subject: [PATCH 3/8] [Client] Remove redundant container methods from CellController --- apps/openmw/mwgui/container.cpp | 6 +++-- apps/openmw/mwmp/CellController.cpp | 42 ----------------------------- apps/openmw/mwmp/CellController.hpp | 3 --- 3 files changed, 4 insertions(+), 47 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 5fd46f9b3..c2d80b839 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -11,6 +11,7 @@ #include #include "../mwmp/Main.hpp" #include "../mwmp/Networking.hpp" +#include "../mwmp/LocalPlayer.hpp" #include "../mwmp/WorldEvent.hpp" #include "../mwmp/CellController.hpp" /* @@ -217,7 +218,7 @@ namespace MWGui Mark this container as open for multiplayer logic purposes */ - mwmp::Main::get().getCellController()->openContainer(container); + mwmp::Main::get().getLocalPlayer()->storeCurrentContainer(container); /* End of tes3mp addition */ @@ -269,7 +270,8 @@ namespace MWGui Mark this container as closed for multiplayer logic purposes */ - mwmp::Main::get().getCellController()->closeContainer(mPtr); + mwmp::Main::get().getLocalPlayer()->clearCurrentContainer(); + mwmp::Main::get().getLocalPlayer()->updateInventory(); /* End of tes3mp addition */ diff --git a/apps/openmw/mwmp/CellController.cpp b/apps/openmw/mwmp/CellController.cpp index eb89f7b45..cca055a7f 100644 --- a/apps/openmw/mwmp/CellController.cpp +++ b/apps/openmw/mwmp/CellController.cpp @@ -345,48 +345,6 @@ bool CellController::isSameCell(const ESM::Cell& cell, const ESM::Cell& otherCel return false; } -void CellController::openContainer(const MWWorld::Ptr &container) -{ - // Record this as the player's current open container - Main::get().getLocalPlayer()->storeCurrentContainer(container); - - const auto &cellRef = container.getCellRef(); - LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Container \"%s\" (%d) is opened", - cellRef.getRefId().c_str(), cellRef.getRefNum().mIndex); - - for (const auto &ptr : container.getClass().getContainerStore(container)) - { - int count = ptr.getRefData().getCount(); - const std::string &name = ptr.getCellRef().getRefId(); - - LOG_APPEND(Log::LOG_VERBOSE, " - Item. Refid: \"%s\" Count: %d", name.c_str(), count); - - /*if (::Misc::StringUtils::ciEqual(name, "gold_001")) - cont.remove("gold_001", count, container);*/ - } -} - -void CellController::closeContainer(const MWWorld::Ptr &container) -{ - Main::get().getLocalPlayer()->clearCurrentContainer(); - - // If the player died while in a container, the container's Ptr could be invalid now - if (!container.isEmpty()) - { - LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Container \"%s\" (%d) is closed.", container.getCellRef().getRefId().c_str(), - container.getCellRef().getRefNum().mIndex); - - MWWorld::ContainerStore &cont = container.getClass().getContainerStore(container); - for (const auto &ptr : cont) - { - LOG_APPEND(Log::LOG_VERBOSE, " - Item. Refid: \"%s\" Count: %d", ptr.getCellRef().getRefId().c_str(), - ptr.getRefData().getCount()); - } - } - - Main::get().getLocalPlayer()->updateInventory(); -} - int CellController::getCellSize() const { return 8192; diff --git a/apps/openmw/mwmp/CellController.hpp b/apps/openmw/mwmp/CellController.hpp index 78777913e..d93989e9d 100644 --- a/apps/openmw/mwmp/CellController.hpp +++ b/apps/openmw/mwmp/CellController.hpp @@ -60,9 +60,6 @@ namespace mwmp bool isSameCell(const ESM::Cell& cell, const ESM::Cell& otherCell); - void openContainer(const MWWorld::Ptr& container); - void closeContainer(const MWWorld::Ptr& container); - int getCellSize() const; private: From afe8c97cb94343fbf74fe404426d5fe455017cc9 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 1 Apr 2018 08:41:57 +0300 Subject: [PATCH 4/8] [Client] Require InventoryStore for unequipping actors in editContainers --- apps/openmw/mwmp/WorldEvent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmp/WorldEvent.cpp b/apps/openmw/mwmp/WorldEvent.cpp index 5a5352805..07bdcc577 100644 --- a/apps/openmw/mwmp/WorldEvent.cpp +++ b/apps/openmw/mwmp/WorldEvent.cpp @@ -151,7 +151,7 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore) takeAllSound = itemPtr.getClass().getUpSoundId(itemPtr); // Is this an actor's container? If so, unequip this item if it was equipped - if (ptrFound.getClass().isActor()) + if (ptrFound.getClass().isActor() && ptrFound.getClass().hasInventoryStore(ptrFound)) { MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound); From 258e319acb67d75e4ccfc97dbfaff3c991935e9f Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 1 Apr 2018 09:02:26 +0300 Subject: [PATCH 5/8] [Client] Require InventoryStore for autoequipping actors --- apps/openmw/mwmp/WorldEvent.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmp/WorldEvent.cpp b/apps/openmw/mwmp/WorldEvent.cpp index 07bdcc577..21450d177 100644 --- a/apps/openmw/mwmp/WorldEvent.cpp +++ b/apps/openmw/mwmp/WorldEvent.cpp @@ -84,6 +84,7 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore) // ptrFound.getCellRef().getRefNum(), ptrFound.getCellRef().getMpNum()); bool isCurrentContainer = false; + bool hasActorEquipment = ptrFound.getClass().isActor() && ptrFound.getClass().hasInventoryStore(ptrFound); // If we are in a container, and it happens to be this container, keep track of that if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Container)) @@ -133,8 +134,8 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore) newPtr.getCellRef().setEnchantmentCharge(containerItem.enchantmentCharge); containerStore.add(newPtr, containerItem.count, ownerPtr, true); - } - + } + else if (action == BaseEvent::REMOVE && containerItem.actionCount > 0) { // We have to find the right item ourselves because ContainerStore has no method @@ -151,7 +152,7 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore) takeAllSound = itemPtr.getClass().getUpSoundId(itemPtr); // Is this an actor's container? If so, unequip this item if it was equipped - if (ptrFound.getClass().isActor() && ptrFound.getClass().hasInventoryStore(ptrFound)) + if (hasActorEquipment) { MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound); @@ -170,7 +171,7 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore) isResolved = containerWindow->dragItemByPtr(itemPtr, containerItem.actionCount); } } - + if (!isResolved) { containerStore.remove(itemPtr, containerItem.actionCount, ownerPtr); @@ -190,7 +191,7 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore) // Was this a SET or ADD action on an actor's container, and are we the authority // over the actor? If so, autoequip the actor - if ((action == BaseEvent::ADD || action == BaseEvent::SET) && ptrFound.getClass().isActor() && + if ((action == BaseEvent::ADD || action == BaseEvent::SET) && hasActorEquipment && mwmp::Main::get().getCellController()->isLocalActor(ptrFound)) { MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound); From ec1311fcb79875c5d732c4025da795f7afd88acb Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 1 Apr 2018 09:33:07 +0300 Subject: [PATCH 6/8] [Client] Make it possible to check whether a class has a ContainerStore --- apps/openmw/mwclass/container.hpp | 10 ++++++++++ apps/openmw/mwclass/creature.hpp | 10 ++++++++++ apps/openmw/mwclass/npc.hpp | 10 ++++++++++ apps/openmw/mwworld/class.cpp | 13 +++++++++++++ apps/openmw/mwworld/class.hpp | 11 +++++++++++ 5 files changed, 54 insertions(+) diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index e38d98b5c..f3d6e6cd8 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -36,6 +36,16 @@ namespace MWClass virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; ///< Return container store + /* + Start of tes3mp addition + + Make it possible to check whether a class has a container store + */ + virtual bool hasContainerStore(const MWWorld::Ptr &ptr) const { return true; } + /* + End of tes3mp addition + */ + virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index e3689204a..824a462a9 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -73,6 +73,16 @@ namespace MWClass virtual bool hasInventoryStore (const MWWorld::Ptr &ptr) const; + /* + Start of tes3mp addition + + Make it possible to check whether a class has a container store + */ + virtual bool hasContainerStore(const MWWorld::Ptr &ptr) const { return true; } + /* + End of tes3mp addition + */ + virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index e91dc7113..dc856dd39 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -71,6 +71,16 @@ namespace MWClass virtual bool hasInventoryStore(const MWWorld::Ptr &ptr) const { return true; } + /* + Start of tes3mp addition + + Make it possible to check whether a class has a container store + */ + virtual bool hasContainerStore(const MWWorld::Ptr &ptr) const { return true; } + /* + End of tes3mp addition + */ + virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const; virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index e59dde7b1..a8d4ee014 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -128,6 +128,19 @@ namespace MWWorld throw std::runtime_error ("class does not have an inventory store"); } + /* + Start of tes3mp addition + + Make it possible to check whether a class has a container store + */ + bool Class::hasContainerStore(const Ptr &ptr) const + { + return false; + } + /* + End of tes3mp addition + */ + bool Class::hasInventoryStore(const Ptr &ptr) const { return false; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 097ec0faa..ebe160570 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -154,6 +154,17 @@ namespace MWWorld ///< Return inventory store or throw an exception, if class does not have a /// inventory store (default implementation: throw an exception) + /* + Start of tes3mp addition + + Make it possible to check whether a class has a container store + */ + virtual bool hasContainerStore(const Ptr& ptr) const; + ///< Does this object have a container store? (default implementation: false) + /* + End of tes3mp addition + */ + virtual bool hasInventoryStore (const Ptr& ptr) const; ///< Does this object have an inventory store, i.e. equipment slots? (default implementation: false) From f80f3bd484794fa7df7c17d901e05580add1b104 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 1 Apr 2018 10:00:39 +0300 Subject: [PATCH 7/8] [Client] Make it possible to reply to requests about specific containers Previously, a Container packet with a REQUEST action always made the client respond with the contents of all the containers in that cell. The previous behavior now only happens for requests that have no WorldObjects attached, while requests that have WorldObjects attached get a reply with the contents of those specific containers. --- apps/openmw/mwmp/WorldEvent.cpp | 126 ++++++++++-------- apps/openmw/mwmp/WorldEvent.hpp | 12 +- .../processors/world/ProcessorContainer.hpp | 28 +++- 3 files changed, 108 insertions(+), 58 deletions(-) diff --git a/apps/openmw/mwmp/WorldEvent.cpp b/apps/openmw/mwmp/WorldEvent.cpp index 21450d177..f0a86aab5 100644 --- a/apps/openmw/mwmp/WorldEvent.cpp +++ b/apps/openmw/mwmp/WorldEvent.cpp @@ -62,6 +62,43 @@ void WorldEvent::addObject(WorldObject worldObject) worldObjects.push_back(worldObject); } +WorldObject WorldEvent::getWorldObject(const MWWorld::Ptr& ptr) +{ + mwmp::WorldObject worldObject; + worldObject.refId = ptr.getCellRef().getRefId(); + worldObject.refNumIndex = ptr.getCellRef().getRefNum().mIndex; + worldObject.mpNum = ptr.getCellRef().getMpNum(); + return worldObject; +} + +void WorldEvent::addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount) +{ + mwmp::ContainerItem containerItem; + containerItem.refId = itemPtr.getCellRef().getRefId(); + containerItem.count = itemPtr.getRefData().getCount(); + containerItem.charge = itemPtr.getCellRef().getCharge(); + containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); + containerItem.actionCount = actionCount; + + LOG_APPEND(Log::LOG_INFO, "- Adding container item %s", containerItem.refId.c_str()); + + worldObject.containerItems.push_back(containerItem); +} + +void WorldEvent::addEntireContainer(const MWWorld::Ptr& ptr) +{ + MWWorld::ContainerStore& containerStore = ptr.getClass().getContainerStore(ptr); + + mwmp::WorldObject worldObject = getWorldObject(ptr); + + for (const auto itemPtr : containerStore) + { + addContainerItem(worldObject, itemPtr, itemPtr.getRefData().getCount()); + } + + addObject(worldObject); +} + void WorldEvent::editContainers(MWWorld::CellStore* cellStore) { bool isLocalEvent = guid == Main::get().getLocalPlayer()->guid; @@ -678,39 +715,45 @@ void WorldEvent::playVideo() } } -WorldObject WorldEvent::getWorldObject(const MWWorld::Ptr& ptr) +void WorldEvent::addAllContainers(MWWorld::CellStore* cellStore) { - mwmp::WorldObject worldObject; - worldObject.refId = ptr.getCellRef().getRefId(); - worldObject.refNumIndex = ptr.getCellRef().getRefNum().mIndex; - worldObject.mpNum = ptr.getCellRef().getMpNum(); - return worldObject; -} + MWWorld::CellRefList *containerList = cellStore->getContainers(); -void WorldEvent::addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount) -{ - mwmp::ContainerItem containerItem; - containerItem.refId = itemPtr.getCellRef().getRefId(); - containerItem.count = itemPtr.getRefData().getCount(); - containerItem.charge = itemPtr.getCellRef().getCharge(); - containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); - containerItem.actionCount = actionCount; - - worldObject.containerItems.push_back(containerItem); -} - -void WorldEvent::addEntireContainer(const MWWorld::Ptr& ptr) -{ - MWWorld::ContainerStore& containerStore = ptr.getClass().getContainerStore(ptr); - - mwmp::WorldObject worldObject = getWorldObject(ptr); - - for (const auto itemPtr : containerStore) + for (auto &container : containerList->mList) { - addContainerItem(worldObject, itemPtr, itemPtr.getRefData().getCount()); - } + mwmp::WorldObject worldObject; + worldObject.refId = container.mRef.getRefId(); + worldObject.refNumIndex = container.mRef.getRefNum().mIndex; + worldObject.mpNum = container.mRef.getMpNum(); - addObject(worldObject); + MWWorld::ContainerStore& containerStore = container.mClass->getContainerStore(MWWorld::Ptr(&container, 0)); + + for (const auto itemPtr : containerStore) + { + addContainerItem(worldObject, itemPtr, 0); + } + + addObject(worldObject); + } +} + +void WorldEvent::addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector& requestObjects) +{ + for (const auto &worldObject : requestObjects) + { + LOG_APPEND(Log::LOG_VERBOSE, "- cellRef: %s, %i, %i", worldObject.refId.c_str(), + worldObject.refNumIndex, worldObject.mpNum); + + MWWorld::Ptr ptrFound = cellStore->searchExact(worldObject.refNumIndex, worldObject.mpNum); + + if (ptrFound) + { + if (ptrFound.getClass().hasContainerStore(ptrFound)) + addEntireContainer(ptrFound); + else + LOG_APPEND(Log::LOG_VERBOSE, "-- Object lacks container store", ptrFound.getCellRef().getRefId().c_str()); + } + } } void WorldEvent::addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer) @@ -1083,30 +1126,9 @@ void WorldEvent::sendScriptGlobalShort() mwmp::Main::get().getNetworking()->getWorldPacket(ID_SCRIPT_GLOBAL_SHORT)->Send(); } -void WorldEvent::sendCellContainers(MWWorld::CellStore* cellStore) +void WorldEvent::sendContainer() { - reset(); - cell = *cellStore->getCell(); - action = BaseEvent::SET; - - MWWorld::CellRefList *containerList = cellStore->getContainers(); - - for (auto &container : containerList->mList) - { - mwmp::WorldObject worldObject; - worldObject.refId = container.mRef.getRefId(); - worldObject.refNumIndex = container.mRef.getRefNum().mIndex; - worldObject.mpNum = container.mRef.getMpNum(); - - MWWorld::ContainerStore& containerStore = container.mClass->getContainerStore(MWWorld::Ptr(&container, 0)); - - for (const auto itemPtr : containerStore) - { - addContainerItem(worldObject, itemPtr, 0); - } - - addObject(worldObject); - } + LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Sending ID_CONTAINER"); mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->setEvent(this); mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->Send(); diff --git a/apps/openmw/mwmp/WorldEvent.hpp b/apps/openmw/mwmp/WorldEvent.hpp index 416a0efb8..7ef4e7dbf 100644 --- a/apps/openmw/mwmp/WorldEvent.hpp +++ b/apps/openmw/mwmp/WorldEvent.hpp @@ -16,7 +16,11 @@ namespace mwmp virtual ~WorldEvent(); void reset(); + void addObject(WorldObject worldObject); + WorldObject getWorldObject(const MWWorld::Ptr& ptr); + void addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount); + void addEntireContainer(const MWWorld::Ptr& ptr); void editContainers(MWWorld::CellStore* cellStore); @@ -41,9 +45,8 @@ namespace mwmp void playMusic(); void playVideo(); - WorldObject getWorldObject(const MWWorld::Ptr& ptr); - void addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount); - void addEntireContainer(const MWWorld::Ptr& ptr); + void addAllContainers(MWWorld::CellStore* cellStore); + void addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector& requestObjects); void addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer = false); void addObjectSpawn(const MWWorld::Ptr& ptr); @@ -78,8 +81,7 @@ namespace mwmp void sendScriptLocalFloat(); void sendScriptMemberShort(); void sendScriptGlobalShort(); - - void sendCellContainers(MWWorld::CellStore* cellStore); + void sendContainer(); private: Networking *getNetworking(); diff --git a/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp b/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp index fa6c5668f..bce080716 100644 --- a/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp +++ b/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp @@ -21,10 +21,36 @@ namespace mwmp // If we've received a request for information, comply with it if (event.action == mwmp::BaseEvent::REQUEST) - event.sendCellContainers(ptrCellStore); + { + if (event.worldObjectCount == 0) + { + LOG_APPEND(Log::LOG_VERBOSE, "- Request had no objects attached, so we are sending all containers in the cell %s", + event.cell.getDescription().c_str()); + event.reset(); + event.cell = *ptrCellStore->getCell(); + event.action = event.action == mwmp::BaseEvent::SET; + event.addAllContainers(ptrCellStore); + event.sendContainer(); + } + else + { + LOG_APPEND(Log::LOG_VERBOSE, "- Request was for %i %s", event.worldObjectCount, event.worldObjectCount == 1 ? "object" : "objects"); + std::vector requestObjects = event.worldObjects; + event.reset(); + event.cell = *ptrCellStore->getCell(); + event.action = event.action == mwmp::BaseEvent::SET; + event.addRequestedContainers(ptrCellStore, requestObjects); + + if (event.worldObjects.size() > 0) + event.sendContainer(); + } + } // Otherwise, edit containers based on the information received else + { + LOG_APPEND(Log::LOG_VERBOSE, "- Editing container contents to match those of packet", event.worldObjectCount); event.editContainers(ptrCellStore); + } } }; From 1e3c4fd488c140745626cf1ba843f646c46de75e Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 1 Apr 2018 10:47:57 +0300 Subject: [PATCH 8/8] [Client] Fix ProcessorContainer typos caused by careless copy-pasting --- apps/openmw/mwmp/processors/world/ProcessorContainer.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp b/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp index bce080716..02a2fb8db 100644 --- a/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp +++ b/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp @@ -28,7 +28,7 @@ namespace mwmp event.cell.getDescription().c_str()); event.reset(); event.cell = *ptrCellStore->getCell(); - event.action = event.action == mwmp::BaseEvent::SET; + event.action = mwmp::BaseEvent::SET; event.addAllContainers(ptrCellStore); event.sendContainer(); } @@ -38,14 +38,14 @@ namespace mwmp std::vector requestObjects = event.worldObjects; event.reset(); event.cell = *ptrCellStore->getCell(); - event.action = event.action == mwmp::BaseEvent::SET; + event.action = mwmp::BaseEvent::SET; event.addRequestedContainers(ptrCellStore, requestObjects); if (event.worldObjects.size() > 0) event.sendContainer(); } } - // Otherwise, edit containers based on the information received + // Otherwise, edit containers based on the information received else { LOG_APPEND(Log::LOG_VERBOSE, "- Editing container contents to match those of packet", event.worldObjectCount);