From 1464762bcd4dcfe8437872d4d0381813700fe29f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 7 Nov 2022 00:12:35 -0800 Subject: [PATCH 001/166] Implement GTest and change windows output path Implement GTest as a testing infrastructure. Make windows output binaries to the build folder instead of the release type folder (potentially issue further down the line) Add a simple unit test for DestroyableComponent --- .gitignore | 2 +- CMakeLists.txt | 20 +- CMakePresets.json | 228 ++++++------- CMakeVariables.txt | 2 + README.md | 4 + dAuthServer/CMakeLists.txt | 4 +- dChatServer/CMakeLists.txt | 16 +- dGame/dComponents/DestroyableComponent.cpp | 15 +- dGame/dComponents/DestroyableComponent.h | 10 +- dMasterServer/CMakeLists.txt | 16 +- dNet/dServer.cpp | 11 +- dNet/dServer.h | 14 +- dWorldServer/CMakeLists.txt | 15 +- tests/CMakeLists.txt | 45 +-- tests/CommonCxxTests.cpp | 0 tests/CommonCxxTests.h | 4 - tests/TestEncoding.cpp | 52 --- .../AMFDeserializeTests.cpp | 129 ++++---- tests/dCommonTests/CMakeLists.txt | 19 ++ .../TestBitStreams/AMFBitStreamTest.bin | Bin .../AMFBitStreamUnimplementedTest.bin | 0 .../TestBitStreams/CMakeLists.txt | 11 + tests/dCommonTests/TestEncoding.cpp | 68 ++++ tests/{ => dCommonTests}/TestLDFFormat.cpp | 10 +- tests/{ => dCommonTests}/TestNiPoint3.cpp | 11 +- tests/dGameTests/CMakeLists.txt | 14 + tests/dGameTests/GameDependencies.cpp | 15 + tests/dGameTests/GameDependencies.h | 43 +++ .../dComponentsTests/CMakeLists.txt | 10 + .../DestroyableComponentTests.cpp | 300 ++++++++++++++++++ 30 files changed, 763 insertions(+), 325 deletions(-) delete mode 100644 tests/CommonCxxTests.cpp delete mode 100644 tests/CommonCxxTests.h delete mode 100644 tests/TestEncoding.cpp rename tests/{ => dCommonTests}/AMFDeserializeTests.cpp (83%) create mode 100644 tests/dCommonTests/CMakeLists.txt rename tests/{ => dCommonTests}/TestBitStreams/AMFBitStreamTest.bin (100%) rename tests/{ => dCommonTests}/TestBitStreams/AMFBitStreamUnimplementedTest.bin (100%) create mode 100644 tests/dCommonTests/TestBitStreams/CMakeLists.txt create mode 100644 tests/dCommonTests/TestEncoding.cpp rename tests/{ => dCommonTests}/TestLDFFormat.cpp (69%) rename tests/{ => dCommonTests}/TestNiPoint3.cpp (59%) create mode 100644 tests/dGameTests/CMakeLists.txt create mode 100644 tests/dGameTests/GameDependencies.cpp create mode 100644 tests/dGameTests/GameDependencies.h create mode 100644 tests/dGameTests/dComponentsTests/CMakeLists.txt create mode 100644 tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp diff --git a/.gitignore b/.gitignore index 3777608d..e093ba4b 100644 --- a/.gitignore +++ b/.gitignore @@ -121,4 +121,4 @@ docker/__pycache__ docker-compose.override.yml -!/tests/TestBitStreams/*.bin +!*Test.bin diff --git a/CMakeLists.txt b/CMakeLists.txt index 34a6cd27..7dfef867 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,15 @@ endif() # Our output dir set(CMAKE_BINARY_DIR ${PROJECT_BINARY_DIR}) + +# TODO make this not have to override the build type directories +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) @@ -239,6 +248,11 @@ set(INCLUDED_DIRECTORIES "thirdparty/recastnavigation" "thirdparty/SQLite" "thirdparty/cpplinq" + + "tests" + "tests/dCommonTests" + "tests/dGameTests" + "tests/dGameTests/dComponentsTests" ) # Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux) @@ -320,8 +334,6 @@ if (UNIX) endif() endif() -add_subdirectory(tests) - # Include all of our binary directories add_subdirectory(dWorldServer) add_subdirectory(dAuthServer) @@ -354,3 +366,7 @@ target_precompile_headers( tinyxml2 PRIVATE "$<$:${PROJECT_SOURCE_DIR}/thirdparty/tinyxml2/tinyxml2.h>" ) + +if (${__enable_testing__} MATCHES "1") + add_subdirectory(tests) +endif() diff --git a/CMakePresets.json b/CMakePresets.json index badb161d..15eb729e 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,131 +1,131 @@ { - "version": 3, - "cmakeMinimumRequired": { - "major": 3, - "minor": 14, - "patch": 0 - }, - "configurePresets": [ - { - "name": "default", - "displayName": "Default configure step", - "description": "Use 'build' dir and Unix makefiles", - "binaryDir": "${sourceDir}/build", - "generator": "Unix Makefiles" + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 14, + "patch": 0 }, - { - "name": "ci-ubuntu-20.04", - "displayName": "CI configure step for Ubuntu", - "description": "Same as default, Used in GitHub actions workflow", - "inherits": "default" - }, - { - "name": "ci-macos-11", - "displayName": "CI configure step for MacOS", - "description": "Same as default, Used in GitHub actions workflow", - "inherits": "default", - "cacheVariables": { - "OPENSSL_ROOT_DIR": "/usr/local/Cellar/openssl@3/3.0.5/" - } - }, - { - "name": "ci-windows-2022", - "displayName": "CI configure step for Windows", - "description": "Set architecture to 64-bit (b/c RakNet)", - "inherits": "default", - "generator": "Visual Studio 17 2022", - "architecture": { - "value": "x64" + "configurePresets": [ + { + "name": "default", + "displayName": "Default configure step", + "description": "Use 'build' dir and Unix makefiles", + "binaryDir": "${sourceDir}/build", + "generator": "Unix Makefiles" }, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo" + { + "name": "ci-ubuntu-20.04", + "displayName": "CI configure step for Ubuntu", + "description": "Same as default, Used in GitHub actions workflow", + "inherits": "default" + }, + { + "name": "ci-macos-11", + "displayName": "CI configure step for MacOS", + "description": "Same as default, Used in GitHub actions workflow", + "inherits": "default", + "cacheVariables": { + "OPENSSL_ROOT_DIR": "/usr/local/Cellar/openssl@3/3.0.5/" + } + }, + { + "name": "ci-windows-2022", + "displayName": "CI configure step for Windows", + "description": "Set architecture to 64-bit (b/c RakNet)", + "inherits": "default", + "generator": "Visual Studio 17 2022", + "architecture": { + "value": "x64" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "windows-default", + "inherits": "ci-windows-2022", + "displayName": "Windows only Configure Settings", + "description": "Sets build and install directories", + "generator": "Ninja", + "architecture": { + "value": "x64", + "strategy": "external" + } } - }, - { - "name": "windows-default", - "inherits": "ci-windows-2022", - "displayName": "Windows only Configure Settings", - "description": "Sets build and install directories", - "generator": "Ninja", - "architecture": { - "value": "x64", - "strategy": "external" - } - } - ], - "buildPresets": [ - { - "name": "default", - "configurePreset": "default", - "displayName": "Default Build", - "description": "Default Build", - "jobs": 2 - }, - { - "name": "ci-windows-2022", - "configurePreset": "ci-windows-2022", - "displayName": "Windows CI Build", - "description": "This preset is used by the CI build on windows", - "configuration": "RelWithDebInfo", - "jobs": 2 - }, - { - "name": "ci-ubuntu-20.04", - "configurePreset": "ci-ubuntu-20.04", - "displayName": "Linux CI Build", - "description": "This preset is used by the CI build on linux", - "jobs": 2 - }, - { - "name": "ci-macos-11", - "configurePreset": "ci-macos-11", - "displayName": "MacOS CI Build", - "description": "This preset is used by the CI build on MacOS", - "jobs": 2 - } - ], - "testPresets": [ - { - "name": "ci-ubuntu-20.04", - "configurePreset": "ci-ubuntu-20.04", - "displayName": "CI Tests on Linux", - "description": "Runs all tests on a linux configuration", - "execution": { + ], + "buildPresets": [ + { + "name": "default", + "configurePreset": "default", + "displayName": "Default Build", + "description": "Default Build", "jobs": 2 }, - "output": { - "outputOnFailure": true - } - }, - { - "name": "ci-macos-11", - "configurePreset": "ci-macos-11", - "displayName": "CI Tests on MacOS", - "description": "Runs all tests on a Mac configuration", - "execution": { + { + "name": "ci-windows-2022", + "configurePreset": "ci-windows-2022", + "displayName": "Windows CI Build", + "description": "This preset is used by the CI build on windows", + "configuration": "RelWithDebInfo", "jobs": 2 }, - "output": { - "outputOnFailure": true + { + "name": "ci-ubuntu-20.04", + "configurePreset": "ci-ubuntu-20.04", + "displayName": "Linux CI Build", + "description": "This preset is used by the CI build on linux", + "jobs": 2 + }, + { + "name": "ci-macos-11", + "configurePreset": "ci-macos-11", + "displayName": "MacOS CI Build", + "description": "This preset is used by the CI build on MacOS", + "jobs": 2 } - }, - { - "name": "ci-windows-2022", - "configurePreset": "ci-windows-2022", - "displayName": "CI Tests on windows", - "description": "Runs all tests on a windows configuration", - "configuration": "RelWithDebInfo", + ], + "testPresets": [ + { + "name": "ci-ubuntu-20.04", + "configurePreset": "ci-ubuntu-20.04", + "displayName": "CI Tests on Linux", + "description": "Runs all tests on a linux configuration", "execution": { "jobs": 2 }, + "output": { + "outputOnFailure": true + } + }, + { + "name": "ci-macos-11", + "configurePreset": "ci-macos-11", + "displayName": "CI Tests on MacOS", + "description": "Runs all tests on a Mac configuration", + "execution": { + "jobs": 2 + }, + "output": { + "outputOnFailure": true + } + }, + { + "name": "ci-windows-2022", + "configurePreset": "ci-windows-2022", + "displayName": "CI Tests on windows", + "description": "Runs all tests on a windows configuration", + "configuration": "RelWithDebInfo", + "execution": { + "jobs": 2 + }, + "output": { + "outputOnFailure": true + }, "filter": { "exclude": { "name": "((example)|(minigzip))+" } - }, - "output": { - "outputOnFailure": true + } } - } - ] -} + ] + } diff --git a/CMakeVariables.txt b/CMakeVariables.txt index e68e826e..94e9cd20 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -18,3 +18,5 @@ __dynamic=1 # Set __compile_backtrace__ to 1 to compile the backtrace library instead of using system libraries. __maria_db_connector_compile_jobs__=1 # Set to the number of jobs (make -j equivalent) to compile the mariadbconn files with. +__enable_testing__=1 +# When set to 1 and uncommented, compiling and linking testing folders and libraries will be done. diff --git a/README.md b/README.md index 8f9eaf8d..e588d341 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ This was done make sure that older and incomplete clients wouldn't produce false If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number. +### Enabling testing +While it is highly recommended to enable testing, if you would like to save compilation time, you'll want to comment out the enable_testing variable in CMakeVariables.txt. +It is recommended that after building and if testing is enabled, to run `ctest` and make sure all the tests pass. + ### Using Docker Refer to [Docker.md](/Docker.md). diff --git a/dAuthServer/CMakeLists.txt b/dAuthServer/CMakeLists.txt index 353f2a54..00fa6e7a 100644 --- a/dAuthServer/CMakeLists.txt +++ b/dAuthServer/CMakeLists.txt @@ -1,4 +1,2 @@ -set(DAUTHSERVER_SOURCES "AuthServer.cpp") - -add_executable(AuthServer ${DAUTHSERVER_SOURCES}) +add_executable(AuthServer "AuthServer.cpp") target_link_libraries(AuthServer ${COMMON_LIBRARIES}) diff --git a/dChatServer/CMakeLists.txt b/dChatServer/CMakeLists.txt index 948593fb..9a47803d 100644 --- a/dChatServer/CMakeLists.txt +++ b/dChatServer/CMakeLists.txt @@ -1,6 +1,10 @@ -set(DCHATSERVER_SOURCES "ChatPacketHandler.cpp" - "ChatServer.cpp" - "PlayerContainer.cpp") - -add_executable(ChatServer ${DCHATSERVER_SOURCES}) -target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter) +set(DCHATSERVER_SOURCES + "ChatPacketHandler.cpp" + "PlayerContainer.cpp" +) + +add_executable(ChatServer "ChatServer.cpp") +add_library(dChatServer ${DCHATSERVER_SOURCES}) + +target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter) +target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 8b9ae42d..3cf206da 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -138,25 +138,17 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn if (m_IsSmashable) { outBitStream->Write(m_HasBricks); - - if (m_ExplodeFactor != 1.0f) { - outBitStream->Write1(); - outBitStream->Write(m_ExplodeFactor); - } else { - outBitStream->Write0(); - } + outBitStream->Write(m_ExplodeFactor != 1.0f); + if (m_ExplodeFactor != 1.0f) outBitStream->Write(m_ExplodeFactor); } } - m_DirtyHealth = false; } + outBitStream->Write(m_DirtyThreatList || bIsInitialUpdate); if (m_DirtyThreatList || bIsInitialUpdate) { - outBitStream->Write1(); outBitStream->Write(m_HasThreats); m_DirtyThreatList = false; - } else { - outBitStream->Write0(); } } @@ -438,7 +430,6 @@ void DestroyableComponent::AddEnemyFaction(int32_t factionID) { void DestroyableComponent::SetIsSmashable(bool value) { m_DirtyHealth = true; m_IsSmashable = value; - //m_HasBricks = value; } void DestroyableComponent::SetAttacksToBlock(const uint32_t value) { diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index a403717b..b8e81b33 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -239,7 +239,7 @@ public: * Sets the multiplier for the explosion that's visible when the bricks fly out when this entity is smashed * @param value the multiplier for the explosion that's visible when the bricks fly out when this entity is smashed */ - void SetExplodeFactor(float value); + void SetExplodeFactor(float value) { m_ExplodeFactor = value; }; /** * Returns the current multiplier for explosions @@ -414,6 +414,14 @@ public: */ void AddOnHitCallback(const std::function& callback); + /** + * Pushes a faction back to the list of factions. + * @param value Faction to add to list. + * + * This method should only be used for testing. Use AddFaction(int32_t, bool) for adding a faction properly. + */ + void AddFactionNoLookup(int32_t faction) { m_FactionIDs.push_back(faction); }; + private: /** * Whether or not the health should be serialized diff --git a/dMasterServer/CMakeLists.txt b/dMasterServer/CMakeLists.txt index 08fc63db..2161681f 100644 --- a/dMasterServer/CMakeLists.txt +++ b/dMasterServer/CMakeLists.txt @@ -1,9 +1,13 @@ -set(DMASTERSERVER_SOURCES "InstanceManager.cpp" - "MasterServer.cpp" - "ObjectIDManager.cpp") - -add_executable(MasterServer ${DMASTERSERVER_SOURCES}) -target_link_libraries(MasterServer ${COMMON_LIBRARIES}) +set(DMASTERSERVER_SOURCES + "InstanceManager.cpp" + "ObjectIDManager.cpp" +) + +add_library(dMasterServer ${DMASTERSERVER_SOURCES}) +add_executable(MasterServer "MasterServer.cpp") + +target_link_libraries(dMasterServer ${COMMON_LIBRARIES}) +target_link_libraries(MasterServer ${COMMON_LIBRARIES} dMasterServer) if(WIN32) add_dependencies(MasterServer WorldServer AuthServer ChatServer) diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 4c032f33..c46b156c 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -50,7 +50,6 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect mNetIDManager = nullptr; mReplicaManager = nullptr; mServerType = serverType; - //Attempt to start our server here: mIsOkay = Startup(); @@ -193,7 +192,10 @@ bool dServer::Startup() { } void dServer::Shutdown() { - mPeer->Shutdown(1000); + if (mPeer) { + mPeer->Shutdown(1000); + RakNetworkFactory::DestroyRakPeerInterface(mPeer); + } if (mNetIDManager) { delete mNetIDManager; @@ -205,10 +207,9 @@ void dServer::Shutdown() { mReplicaManager = nullptr; } - //RakNetworkFactory::DestroyRakPeerInterface(mPeer); //Not needed, we already called Shutdown ourselves. - if (mServerType != ServerType::Master) { + if (mServerType != ServerType::Master && mMasterPeer) { mMasterPeer->Shutdown(1000); - //RakNetworkFactory::DestroyRakPeerInterface(mMasterPeer); + RakNetworkFactory::DestroyRakPeerInterface(mMasterPeer); } } diff --git a/dNet/dServer.h b/dNet/dServer.h index bd052f86..264932ee 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -15,6 +15,8 @@ enum class ServerType : uint32_t { class dServer { public: + // Default constructor should only used for testing! + dServer() {}; dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, unsigned int zoneID = 0); ~dServer(); @@ -22,7 +24,7 @@ public: Packet* Receive(); void DeallocatePacket(Packet* packet); void DeallocateMasterPacket(Packet* packet); - void Send(RakNet::BitStream* bitStream, const SystemAddress& sysAddr, bool broadcast); + virtual void Send(RakNet::BitStream* bitStream, const SystemAddress& sysAddr, bool broadcast); void SendToMaster(RakNet::BitStream* bitStream); void Disconnect(const SystemAddress& sysAddr, uint32_t disconNotifyID); @@ -55,10 +57,10 @@ private: bool ConnectToMaster(); private: - dLogger* mLogger; - RakPeerInterface* mPeer; - ReplicaManager* mReplicaManager; - NetworkIDManager* mNetIDManager; + dLogger* mLogger = nullptr; + RakPeerInterface* mPeer = nullptr; + ReplicaManager* mReplicaManager = nullptr; + NetworkIDManager* mNetIDManager = nullptr; SocketDescriptor mSocketDescriptor; std::string mIP; int mPort; @@ -71,7 +73,7 @@ private: bool mMasterConnectionActive; ServerType mServerType; - RakPeerInterface* mMasterPeer; + RakPeerInterface* mMasterPeer = nullptr; SocketDescriptor mMasterSocketDescriptor; SystemAddress mMasterSystemAddress; std::string mMasterIP; diff --git a/dWorldServer/CMakeLists.txt b/dWorldServer/CMakeLists.txt index fcf29838..c616da87 100644 --- a/dWorldServer/CMakeLists.txt +++ b/dWorldServer/CMakeLists.txt @@ -1,6 +1,11 @@ -set(DWORLDSERVER_SOURCES "ObjectIDManager.cpp" - "PerformanceManager.cpp" - "WorldServer.cpp") +set(DWORLDSERVER_SOURCES + "ObjectIDManager.cpp" + "PerformanceManager.cpp" +) + +add_library(dWorldServer ${DWORLDSERVER_SOURCES}) +add_executable(WorldServer "WorldServer.cpp") + +target_link_libraries(dWorldServer ${COMMON_LIBRARIES}) +target_link_libraries(WorldServer ${COMMON_LIBRARIES} dChatFilter dGame dZoneManager dPhysics Detour Recast tinyxml2 dWorldServer dNavigation) -add_executable(WorldServer ${DWORLDSERVER_SOURCES}) -target_link_libraries(WorldServer ${COMMON_LIBRARIES} dChatFilter dGame dZoneManager Detour Recast dPhysics tinyxml2 dNavigation) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fb1ed5ac..9ba75a2f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,34 +1,21 @@ -# create the testing file and list of tests -create_test_sourcelist (Tests - CommonCxxTests.cpp - AMFDeserializeTests.cpp - TestNiPoint3.cpp - TestLDFFormat.cpp - TestEncoding.cpp +message (STATUS "Testing is enabled. Fetching gtest...") +enable_testing() + +include(FetchContent) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG release-1.12.1 ) -# add the executable -add_executable (CommonCxxTests ${Tests}) -target_link_libraries(CommonCxxTests ${COMMON_LIBRARIES}) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -# remove the test driver source file -set (TestsToRun ${Tests}) -remove (TestsToRun CommonCxxTests.cpp) +FetchContent_MakeAvailable(GoogleTest) +include(GoogleTest) -# Copy test files to testing directory -configure_file( - ${CMAKE_SOURCE_DIR}/tests/TestBitStreams/AMFBitStreamTest.bin ${PROJECT_BINARY_DIR}/tests/AMFBitStreamTest.bin - COPYONLY -) +message(STATUS "gtest fetched and is now ready.") -configure_file( - ${CMAKE_SOURCE_DIR}/tests/TestBitStreams/AMFBitStreamUnimplementedTest.bin ${PROJECT_BINARY_DIR}/tests/AMFBitStreamUnimplementedTest.bin - COPYONLY -) - -# Add all the ADD_TEST for each test -foreach (test ${TestsToRun}) - get_filename_component (TName ${test} NAME_WE) - add_test (NAME ${TName} COMMAND CommonCxxTests ${TName}) - set_property(TEST ${TName} PROPERTY ENVIRONMENT CTEST_OUTPUT_ON_FAILURE=1) -endforeach () +# Add the subdirectories +add_subdirectory(dCommonTests) +add_subdirectory(dGameTests) diff --git a/tests/CommonCxxTests.cpp b/tests/CommonCxxTests.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/CommonCxxTests.h b/tests/CommonCxxTests.h deleted file mode 100644 index f1894927..00000000 --- a/tests/CommonCxxTests.h +++ /dev/null @@ -1,4 +0,0 @@ -#include - -#define ASSERT_EQ(a,b) { if (!(a == b)) { printf("Failed assertion: " #a " == " #b " \n in %s:%d\n", __FILE__, __LINE__); return 1; }} -#define ASSERT_NE(a,b) { if (!(a != b)) { printf("Failed assertion: " #a " != " #b " \n in %s:%d\n", __FILE__, __LINE__); return 1; }} diff --git a/tests/TestEncoding.cpp b/tests/TestEncoding.cpp deleted file mode 100644 index c23e2db6..00000000 --- a/tests/TestEncoding.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -#include "GeneralUtils.h" -#include "CommonCxxTests.h" - -int TestEncoding(int argc, char** const argv) { - std::string x = "Hello World!"; - std::string_view v(x); - - uint32_t out; - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 'H'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 'e'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 'l'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 'l'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 'o'); - ASSERT_EQ(GeneralUtils::_NextUTF8Char(v, out), true); - - x = u8"Frühling"; - v = x; - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'F'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'r'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'ü'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'h'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'l'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'i'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'n'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'g'); - ASSERT_EQ(GeneralUtils::_NextUTF8Char(v, out), false); - - x = "中文字"; - v = x; - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'中'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'文'); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, U'字'); - ASSERT_EQ(GeneralUtils::_NextUTF8Char(v, out), false); - - x = "👨‍⚖️"; - v = x; - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 0x1F468); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 0x200D); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 0x2696); - GeneralUtils::_NextUTF8Char(v, out); ASSERT_EQ(out, 0xFE0F); - ASSERT_EQ(GeneralUtils::_NextUTF8Char(v, out), false); - - ASSERT_EQ(GeneralUtils::UTF8ToUTF16("Hello World!"), u"Hello World!"); - ASSERT_EQ(GeneralUtils::UTF8ToUTF16("Frühling"), u"Frühling"); - ASSERT_EQ(GeneralUtils::UTF8ToUTF16("中文字"), u"中文字"); - ASSERT_EQ(GeneralUtils::UTF8ToUTF16("👨‍⚖️"), u"👨‍⚖️"); - - return 0; -} diff --git a/tests/AMFDeserializeTests.cpp b/tests/dCommonTests/AMFDeserializeTests.cpp similarity index 83% rename from tests/AMFDeserializeTests.cpp rename to tests/dCommonTests/AMFDeserializeTests.cpp index 8d4974a3..a823b0dc 100644 --- a/tests/AMFDeserializeTests.cpp +++ b/tests/dCommonTests/AMFDeserializeTests.cpp @@ -1,52 +1,65 @@ -#include #include -#include #include +#include #include "AMFDeserialize.h" #include "AMFFormat.h" -#include "CommonCxxTests.h" +/** + * Helper method that all tests use to get their respective AMF. + */ std::unique_ptr ReadFromBitStream(RakNet::BitStream* bitStream) { AMFDeserialize deserializer; std::unique_ptr returnValue(deserializer.Read(bitStream)); return returnValue; } -int ReadAMFUndefinedFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFUndefined value from a BitStream. + */ +TEST(dCommonTests, AMFDeserializeAMFUndefinedTest) { + CBITSTREAM bitStream.Write(0x00); std::unique_ptr res(ReadFromBitStream(&bitStream)); ASSERT_EQ(res->GetValueType(), AMFValueType::AMFUndefined); - return 0; } -int ReadAMFNullFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFNull value from a BitStream. + * + */ +TEST(dCommonTests, AMFDeserializeAMFNullTest) { + CBITSTREAM bitStream.Write(0x01); std::unique_ptr res(ReadFromBitStream(&bitStream)); ASSERT_EQ(res->GetValueType(), AMFValueType::AMFNull); - return 0; } -int ReadAMFFalseFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFFalse value from a BitStream. + */ +TEST(dCommonTests, AMFDeserializeAMFFalseTest) { + CBITSTREAM bitStream.Write(0x02); std::unique_ptr res(ReadFromBitStream(&bitStream)); ASSERT_EQ(res->GetValueType(), AMFValueType::AMFFalse); - return 0; } -int ReadAMFTrueFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFTrue value from a BitStream. + */ +TEST(dCommonTests, AMFDeserializeAMFTrueTest) { + CBITSTREAM bitStream.Write(0x03); std::unique_ptr res(ReadFromBitStream(&bitStream)); ASSERT_EQ(res->GetValueType(), AMFValueType::AMFTrue); - return 0; } -int ReadAMFIntegerFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFInteger value from a BitStream. + */ +TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { + CBITSTREAM { bitStream.Write(0x04); // 127 == 01111111 @@ -91,21 +104,25 @@ int ReadAMFIntegerFromBitStream() { // Check that 2 byte max can be read correctly ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), 16383); } - return 0; } -int ReadAMFDoubleFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFDouble value from a BitStream. + */ +TEST(dCommonTests, AMFDeserializeAMFDoubleTest) { + CBITSTREAM bitStream.Write(0x05); bitStream.Write(25346.4f); std::unique_ptr res(ReadFromBitStream(&bitStream)); ASSERT_EQ(res->GetValueType(), AMFValueType::AMFDouble); ASSERT_EQ(static_cast(res.get())->GetDoubleValue(), 25346.4f); - return 0; } -int ReadAMFStringFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFString value from a BitStream. + */ +TEST(dCommonTests, AMFDeserializeAMFStringTest) { + CBITSTREAM bitStream.Write(0x06); bitStream.Write(0x0F); std::string toWrite = "stateID"; @@ -113,11 +130,13 @@ int ReadAMFStringFromBitStream() { std::unique_ptr res(ReadFromBitStream(&bitStream)); ASSERT_EQ(res->GetValueType(), AMFValueType::AMFString); ASSERT_EQ(static_cast(res.get())->GetStringValue(), "stateID"); - return 0; } -int ReadAMFArrayFromBitStream() { - CBITSTREAM; +/** + * @brief Test reading an AMFArray value from a BitStream. + */ +TEST(dCommonTests, AMFDeserializeAMFArrayTest) { + CBITSTREAM // Test empty AMFArray bitStream.Write(0x09); bitStream.Write(0x01); @@ -149,15 +168,15 @@ int ReadAMFArrayFromBitStream() { ASSERT_EQ(static_cast(res.get())->FindValue("BehaviorID")->GetStringValue(), "10447"); ASSERT_EQ(static_cast(res.get())->GetValueAt(0)->GetStringValue(), "10447"); } - // Test a dense array - return 0; } /** - * This test checks that if we recieve an unimplemented AMFValueType + * @brief This test checks that if we recieve an unimplemented AMFValueType * we correctly throw an error and can actch it. + * */ -int TestUnimplementedAMFValues() { +#pragma message("-- The AMFDeserializeUnimplementedValuesTest causes a known memory leak of 880 bytes since it throws errors! --") +TEST(dCommonTests, AMFDeserializeUnimplementedValuesTest) { std::vector unimplementedValues = { AMFValueType::AMFXMLDoc, AMFValueType::AMFDate, @@ -196,13 +215,15 @@ int TestUnimplementedAMFValues() { } catch (AMFValueType unimplementedValueType) { caughtException = true; } - std::cout << "Testing unimplemented value " << amfValueType << " Did we catch an exception: " << (caughtException ? "YES" : "NO") << std::endl; + ASSERT_EQ(caughtException, true); } - return 0; } -int TestLiveCapture() { +/** + * @brief Test reading a packet capture from live from a BitStream + */ +TEST(dCommonTests, AMFDeserializeLivePacketTest) { std::ifstream testFileStream; testFileStream.open("AMFBitStreamTest.bin", std::ios::binary); @@ -267,9 +288,9 @@ int TestLiveCapture() { auto actionID = firstStrip->FindValue("id"); - ASSERT_EQ(actionID->GetDoubleValue(), 0.0f) + ASSERT_EQ(actionID->GetDoubleValue(), 0.0f); - auto uiArray = firstStrip->FindValue("ui"); + auto uiArray = firstStrip->FindValue("ui"); auto xPos = uiArray->FindValue("x"); auto yPos = uiArray->FindValue("y"); @@ -279,9 +300,9 @@ int TestLiveCapture() { auto stripID = firstStrip->FindValue("id"); - ASSERT_EQ(stripID->GetDoubleValue(), 0.0f) + ASSERT_EQ(stripID->GetDoubleValue(), 0.0f); - auto firstAction = dynamic_cast(actionsInFirstStrip[0]); + auto firstAction = dynamic_cast(actionsInFirstStrip[0]); auto firstType = firstAction->FindValue("Type"); @@ -318,17 +339,17 @@ int TestLiveCapture() { auto thirdDistance = thirdAction->FindValue("Distance"); ASSERT_EQ(thirdDistance->GetDoubleValue(), 25.0f); - - return 0; } -int TestNullStream() { +/** + * @brief Tests that having no BitStream returns a nullptr. + */ +TEST(dCommonTests, AMFDeserializeNullTest) { auto result = ReadFromBitStream(nullptr); ASSERT_EQ(result.get(), nullptr); - return 0; } -int TestBadConversion() { +TEST(dCommonTests, AMFBadConversionTest) { std::ifstream testFileStream; testFileStream.open("AMFBitStreamTest.bin", std::ios::binary); @@ -360,30 +381,6 @@ int TestBadConversion() { // Value is out of bounds ASSERT_EQ(result->GetValueAt(1), nullptr); - - return 0; -} - -int AMFDeserializeTests(int argc, char** const argv) { - std::cout << "Checking that using a null bitstream doesnt cause exception" << std::endl; - if (TestNullStream()) return 1; - std::cout << "passed nullptr test, checking basic tests" << std::endl; - if (ReadAMFUndefinedFromBitStream() != 0) return 1; - if (ReadAMFNullFromBitStream() != 0) return 1; - if (ReadAMFFalseFromBitStream() != 0) return 1; - if (ReadAMFTrueFromBitStream() != 0) return 1; - if (ReadAMFIntegerFromBitStream() != 0) return 1; - if (ReadAMFDoubleFromBitStream() != 0) return 1; - if (ReadAMFStringFromBitStream() != 0) return 1; - if (ReadAMFArrayFromBitStream() != 0) return 1; - std::cout << "Passed basic test, checking live capture" << std::endl; - if (TestLiveCapture() != 0) return 1; - std::cout << "Passed live capture, checking unimplemented amf values" << std::endl; - if (TestUnimplementedAMFValues() != 0) return 1; - std::cout << "Passed unimplemented values, checking poor casting" << std::endl; - if (TestBadConversion() != 0) return 1; - std::cout << "Passed all tests." << std::endl; - return 0; } /** diff --git a/tests/dCommonTests/CMakeLists.txt b/tests/dCommonTests/CMakeLists.txt new file mode 100644 index 00000000..86c00c58 --- /dev/null +++ b/tests/dCommonTests/CMakeLists.txt @@ -0,0 +1,19 @@ +set(DCOMMONTEST_SOURCES + "AMFDeserializeTests.cpp" + "TestLDFFormat.cpp" + "TestNiPoint3.cpp" + "TestEncoding.cpp" +) + +# Set our executable +add_executable(dCommonTests ${DCOMMONTEST_SOURCES}) + +# Link needed libraries +target_link_libraries(dCommonTests ${COMMON_LIBRARIES} GTest::gtest_main) + +# Copy test files to testing directory +add_subdirectory(TestBitStreams) +file(COPY ${TESTBITSTREAMS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + +# Discover the tests +gtest_discover_tests(dCommonTests) diff --git a/tests/TestBitStreams/AMFBitStreamTest.bin b/tests/dCommonTests/TestBitStreams/AMFBitStreamTest.bin similarity index 100% rename from tests/TestBitStreams/AMFBitStreamTest.bin rename to tests/dCommonTests/TestBitStreams/AMFBitStreamTest.bin diff --git a/tests/TestBitStreams/AMFBitStreamUnimplementedTest.bin b/tests/dCommonTests/TestBitStreams/AMFBitStreamUnimplementedTest.bin similarity index 100% rename from tests/TestBitStreams/AMFBitStreamUnimplementedTest.bin rename to tests/dCommonTests/TestBitStreams/AMFBitStreamUnimplementedTest.bin diff --git a/tests/dCommonTests/TestBitStreams/CMakeLists.txt b/tests/dCommonTests/TestBitStreams/CMakeLists.txt new file mode 100644 index 00000000..93606df6 --- /dev/null +++ b/tests/dCommonTests/TestBitStreams/CMakeLists.txt @@ -0,0 +1,11 @@ +set(TESTBITSTREAMS + "AMFBitStreamTest.bin" + "AMFBitStreamUnimplementedTest.bin" +) + +# Get the folder name and prepend it to the files above +get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME) +list(TRANSFORM TESTBITSTREAMS PREPEND "${thisFolderName}/") + +# Export our list of files +set(TESTBITSTREAMS ${TESTBITSTREAMS} PARENT_SCOPE) diff --git a/tests/dCommonTests/TestEncoding.cpp b/tests/dCommonTests/TestEncoding.cpp new file mode 100644 index 00000000..c103ccbf --- /dev/null +++ b/tests/dCommonTests/TestEncoding.cpp @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "GeneralUtils.h" + +class EncodingTest : public ::testing::Test { +protected: + std::string originalWord; + std::string_view originalWordSv; + uint32_t out; +}; + +TEST_F(EncodingTest, TestEncodingHello) { + originalWord = "Hello World!"; + originalWordSv = originalWord; + + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'H'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'e'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'l'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'l'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'o'); + EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), true); + + EXPECT_EQ(GeneralUtils::UTF8ToUTF16("Hello World!"), u"Hello World!"); +}; + +TEST_F(EncodingTest, TestEncodingUmlaut) { + originalWord = u8"Frühling"; + originalWordSv = originalWord; + + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'F'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'r'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'ü'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'h'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'l'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'i'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'n'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'g'); + EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), false); + + EXPECT_EQ(GeneralUtils::UTF8ToUTF16("Frühling"), u"Frühling"); +}; + +TEST_F(EncodingTest, TestEncodingChinese) { + originalWord = "中文字"; + originalWordSv = originalWord; + + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'中'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'文'); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'字'); + EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), false); + + EXPECT_EQ(GeneralUtils::UTF8ToUTF16("中文字"), u"中文字"); +}; + +TEST_F(EncodingTest, TestEncodingEmoji) { + originalWord = "👨‍⚖️"; + originalWordSv = originalWord; + + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x1F468); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x200D); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x2696); + GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0xFE0F); + EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), false); + + EXPECT_EQ(GeneralUtils::UTF8ToUTF16("👨‍⚖️"), u"👨‍⚖️"); +}; diff --git a/tests/TestLDFFormat.cpp b/tests/dCommonTests/TestLDFFormat.cpp similarity index 69% rename from tests/TestLDFFormat.cpp rename to tests/dCommonTests/TestLDFFormat.cpp index a7433e96..647c3cbf 100644 --- a/tests/TestLDFFormat.cpp +++ b/tests/dCommonTests/TestLDFFormat.cpp @@ -1,14 +1,10 @@ #include "LDFFormat.h" -#include "CommonCxxTests.h" +#include /** * @brief Test parsing an LDF value - * - * @param argc Number of command line arguments for this test - * @param argv Command line arguments - * @return 0 on success, non-zero on failure */ -int TestLDFFormat(int argc, char** const argv) { +TEST(dCommonTests, LDFTest) { // Create auto* data = LDFBaseData::DataFromString("KEY=0:VALUE"); @@ -26,6 +22,4 @@ int TestLDFFormat(int argc, char** const argv) { // Cleanup the object delete data; - - return 0; } diff --git a/tests/TestNiPoint3.cpp b/tests/dCommonTests/TestNiPoint3.cpp similarity index 59% rename from tests/TestNiPoint3.cpp rename to tests/dCommonTests/TestNiPoint3.cpp index d1588b8b..33cd51d2 100644 --- a/tests/TestNiPoint3.cpp +++ b/tests/dCommonTests/TestNiPoint3.cpp @@ -1,13 +1,14 @@ -#include +#include #include "NiPoint3.h" -#include "CommonCxxTests.h" -int TestNiPoint3(int argc, char** const argv) { +/** + * @brief Basic test for NiPoint3 functionality + * + */ +TEST(dCommonTests, NiPoint3Test) { // Check that Unitize works ASSERT_EQ(NiPoint3(3, 0, 0).Unitize(), NiPoint3::UNIT_X); // Check what unitize does to a vector of length 0 ASSERT_EQ(NiPoint3::ZERO.Unitize(), NiPoint3::ZERO); - // If we get here, all was successful - return 0; } diff --git a/tests/dGameTests/CMakeLists.txt b/tests/dGameTests/CMakeLists.txt new file mode 100644 index 00000000..68192b3f --- /dev/null +++ b/tests/dGameTests/CMakeLists.txt @@ -0,0 +1,14 @@ +set(DGAMETEST_SOURCES + "GameDependencies.cpp" +) + +add_subdirectory(dComponentsTests) +list(APPEND DGAMETEST_SOURCES ${DCOMPONENTS_TESTS}) + +# Add the executable. Remember to add all tests above this! +add_executable(dGameTests ${DGAMETEST_SOURCES}) + +target_link_libraries(dGameTests ${COMMON_LIBRARIES} GTest::gtest_main dGame dZoneManager dPhysics Detour Recast tinyxml2 dWorldServer dChatFilter dNavigation) + +# Discover the tests +gtest_discover_tests(dGameTests) diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp new file mode 100644 index 00000000..8a572668 --- /dev/null +++ b/tests/dGameTests/GameDependencies.cpp @@ -0,0 +1,15 @@ +#include "GameDependencies.h" + +namespace Game { + dLogger* logger; + dServer* server; + dZoneManager* zoneManager; + dpWorld* physicsWorld; + dChatFilter* chatFilter; + dConfig* config; + dLocale* locale; + std::mt19937 randomEngine; + RakPeerInterface* chatServer; + AssetManager* assetManager; + SystemAddress chatSysAddr; +} diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h new file mode 100644 index 00000000..593ec0fc --- /dev/null +++ b/tests/dGameTests/GameDependencies.h @@ -0,0 +1,43 @@ +#ifndef __GAMEDEPENDENCIES__H__ +#define __GAMEDEPENDENCIES__H__ + +#include "Game.h" +#include "dLogger.h" +#include "dServer.h" +#include "EntityManager.h" +class dZoneManager; +class AssetManager; +#include + +class dServerMock : public dServer { +public: + dServerMock() {}; + ~dServerMock() {}; + void Send(RakNet::BitStream* bitStream, const SystemAddress& sysAddr, bool broadcast) override {}; +}; + +class GameDependenciesTest : public ::testing::Test { +protected: + void SetUpDependencies() { + info.pos = NiPoint3::ZERO; + info.rot = NiQuaternion::IDENTITY; + info.scale = 1.0f; + info.spawner = nullptr; + info.lot = 999; + Game::logger = new dLogger("./testing.log", true, true); + Game::server = new dServerMock(); + } + + void TearDownDependencies() { + if (Game::server) delete Game::server; + delete EntityManager::Instance(); + if (Game::logger) { + Game::logger->Flush(); + delete Game::logger; + } + } + + EntityInfo info; +}; + +#endif //!__GAMEDEPENDENCIES__H__ diff --git a/tests/dGameTests/dComponentsTests/CMakeLists.txt b/tests/dGameTests/dComponentsTests/CMakeLists.txt new file mode 100644 index 00000000..17e69a2f --- /dev/null +++ b/tests/dGameTests/dComponentsTests/CMakeLists.txt @@ -0,0 +1,10 @@ +set(DCOMPONENTS_TESTS + "DestroyableComponentTests.cpp" +) + +# Get the folder name and prepend it to the files above +get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME) +list(TRANSFORM DCOMPONENTS_TESTS PREPEND "${thisFolderName}/") + +# Export to parent scope +set(DCOMPONENTS_TESTS ${DCOMPONENTS_TESTS} PARENT_SCOPE) diff --git a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp new file mode 100644 index 00000000..97288909 --- /dev/null +++ b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp @@ -0,0 +1,300 @@ +#include "GameDependencies.h" +#include + +#include "BitStream.h" +#include "DestroyableComponent.h" +#include "Entity.h" + +class DestroyableTest : public GameDependenciesTest { +protected: + Entity* baseEntity; + DestroyableComponent* destroyableComponent; + CBITSTREAM + uint32_t flags = 0; + void SetUp() override { + SetUpDependencies(); + baseEntity = new Entity(15, GameDependenciesTest::info); + destroyableComponent = new DestroyableComponent(baseEntity); + baseEntity->AddComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent); + // Initialize some values to be not default + destroyableComponent->SetMaxHealth(12345.0f); + destroyableComponent->SetHealth(23); + destroyableComponent->SetMaxArmor(14.0f); + destroyableComponent->SetArmor(7); + destroyableComponent->SetMaxImagination(14000.0f); + destroyableComponent->SetImagination(6000); + destroyableComponent->SetIsSmashable(true); + destroyableComponent->SetExplodeFactor(1.1f); + destroyableComponent->AddFactionNoLookup(-1); + destroyableComponent->AddFactionNoLookup(6); + } + + void TearDown() override { + delete baseEntity; + TearDownDependencies(); + } +}; + +/** + * Test Construction of a DestroyableComponent + */ +TEST_F(DestroyableTest, DestroyableComponentSerializeConstructionTest) { + destroyableComponent->Serialize(&bitStream, true, flags); + // Assert that the full number of bits are present + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 460); + { + // Now read in the full serialized construction BitStream + bool optionStatusImmunityInfo{}; // Values under this option are unused. + bool optionStatsInfo{}; + uint32_t currentHealth{}; + float maxHealth{}; + uint32_t currentArmor{}; + float maxArmor{}; + uint32_t currentImagination{}; + float maxImagination{}; + uint32_t damageAbsorptionPoints{}; + bool hasImmunity{}; + bool isGmImmune{}; + bool isShielded{}; + float actualMaxHealth{}; + float actualMaxArmor{}; + float actualMaxImagination{}; + uint32_t factionsSize{}; + std::vector factions{}; + bool isSmashable{}; + bool isDead{}; + bool isSmashed{}; + bool isModuleAssembly{}; + bool optionExplodeFactor{}; + float explodeFactor{}; + bool optionIsOnThreatList{}; + bool isThreatened{}; + bitStream.Read(optionStatusImmunityInfo); + + bitStream.Read(optionStatsInfo); + bitStream.Read(currentHealth); + bitStream.Read(maxHealth); + bitStream.Read(currentArmor); + bitStream.Read(maxArmor); + bitStream.Read(currentImagination); + bitStream.Read(maxImagination); + bitStream.Read(damageAbsorptionPoints); + bitStream.Read(hasImmunity); + bitStream.Read(isGmImmune); + bitStream.Read(isShielded); + bitStream.Read(actualMaxHealth); + bitStream.Read(actualMaxArmor); + bitStream.Read(actualMaxImagination); + bitStream.Read(factionsSize); + for (uint32_t i = 0; i < factionsSize; i++) { + int32_t factionID{}; + bitStream.Read(factionID); + factions.push_back(factionID); + } + bitStream.Read(isSmashable); // This is an option later and also a flag at this spot + bitStream.Read(isDead); + bitStream.Read(isSmashed); + // if IsSmashable is true, read the next bits. + bitStream.Read(isModuleAssembly); + bitStream.Read(optionExplodeFactor); + bitStream.Read(explodeFactor); + + bitStream.Read(optionIsOnThreatList); + bitStream.Read(isThreatened); + EXPECT_EQ(optionStatusImmunityInfo, false); + + EXPECT_EQ(optionStatsInfo, true); + EXPECT_EQ(currentHealth, 23); + EXPECT_EQ(maxHealth, 12345.0f); + EXPECT_EQ(currentArmor, 7); + EXPECT_EQ(maxArmor, 14.0f); + EXPECT_EQ(currentImagination, 6000); + EXPECT_EQ(maxImagination, 14000.0f); + EXPECT_EQ(damageAbsorptionPoints, 0.0f); + EXPECT_EQ(hasImmunity, false); + EXPECT_EQ(isGmImmune, false); + EXPECT_EQ(isShielded, false); + EXPECT_EQ(actualMaxHealth, 12345.0f); + EXPECT_EQ(actualMaxArmor, 14.0f); + EXPECT_EQ(actualMaxImagination, 14000.0f); + EXPECT_EQ(factionsSize, 2); + EXPECT_NE(std::find(factions.begin(), factions.end(), -1), factions.end()); + EXPECT_NE(std::find(factions.begin(), factions.end(), 6), factions.end()); + EXPECT_EQ(isSmashable, true); + EXPECT_EQ(isDead, false); + EXPECT_EQ(isSmashed, false); + EXPECT_EQ(isSmashable, true); // For the sake of readability with the struct viewers, we will test this twice since its used as an option here, but as a bool above. + EXPECT_EQ(isModuleAssembly, false); + EXPECT_EQ(optionExplodeFactor, true); + EXPECT_EQ(explodeFactor, 1.1f); + + EXPECT_EQ(optionIsOnThreatList, true); + EXPECT_EQ(isThreatened, false); + } + bitStream.Reset(); +} + +/** + * Test serialization of a DestroyableComponent + */ +TEST_F(DestroyableTest, DestroyableComponentSerializeTest) { + bitStream.Reset(); + // Initialize some values to be not default so we can test a full serialization + destroyableComponent->SetMaxHealth(1233.0f); + + // Now we test a serialization for correctness. + destroyableComponent->Serialize(&bitStream, false, flags); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 422); + { + // Now read in the full serialized BitStream + bool optionStatsInfo{}; + uint32_t currentHealth{}; + float maxHealth{}; + uint32_t currentArmor{}; + float maxArmor{}; + uint32_t currentImagination{}; + float maxImagination{}; + uint32_t damageAbsorptionPoints{}; + bool hasImmunity{}; + bool isGmImmune{}; + bool isShielded{}; + float actualMaxHealth{}; + float actualMaxArmor{}; + float actualMaxImagination{}; + uint32_t factionsSize{}; + std::vector factions{}; + bool isSmashable{}; + bool optionIsOnThreatList{}; + bitStream.Read(optionStatsInfo); + bitStream.Read(currentHealth); + bitStream.Read(maxHealth); + bitStream.Read(currentArmor); + bitStream.Read(maxArmor); + bitStream.Read(currentImagination); + bitStream.Read(maxImagination); + bitStream.Read(damageAbsorptionPoints); + bitStream.Read(hasImmunity); + bitStream.Read(isGmImmune); + bitStream.Read(isShielded); + bitStream.Read(actualMaxHealth); + bitStream.Read(actualMaxArmor); + bitStream.Read(actualMaxImagination); + bitStream.Read(factionsSize); + for (uint32_t i = 0; i < factionsSize; i++) { + int32_t factionID{}; + bitStream.Read(factionID); + factions.push_back(factionID); + } + bitStream.Read(isSmashable); + + bitStream.Read(optionIsOnThreatList); + + EXPECT_EQ(optionStatsInfo, true); + EXPECT_EQ(currentHealth, 23); + EXPECT_EQ(maxHealth, 1233.0f); + EXPECT_EQ(currentArmor, 7); + EXPECT_EQ(maxArmor, 14.0f); + EXPECT_EQ(currentImagination, 6000); + EXPECT_EQ(maxImagination, 14000.0f); + EXPECT_EQ(damageAbsorptionPoints, 0.0f); + EXPECT_EQ(hasImmunity, false); + EXPECT_EQ(isGmImmune, false); + EXPECT_EQ(isShielded, false); + EXPECT_EQ(actualMaxHealth, 1233.0f); + EXPECT_EQ(actualMaxArmor, 14.0f); + EXPECT_EQ(actualMaxImagination, 14000.0f); + EXPECT_EQ(factionsSize, 2); + EXPECT_NE(std::find(factions.begin(), factions.end(), -1), factions.end()); + EXPECT_NE(std::find(factions.begin(), factions.end(), 6), factions.end()); + EXPECT_EQ(isSmashable, true); + + EXPECT_EQ(optionIsOnThreatList, false); // Always zero for now on serialization + } +} + +/** + * Test the Damage method of DestroyableComponent + */ +TEST_F(DestroyableTest, DestroyableComponentDamageTest) { + // Do some actions + destroyableComponent->SetMaxHealth(100.0f); + destroyableComponent->SetHealth(100); + destroyableComponent->SetMaxArmor(0.0f); + destroyableComponent->Damage(10, LWOOBJID_EMPTY); + // Check that we take damage + ASSERT_EQ(destroyableComponent->GetHealth(), 90); + // Check that if we have armor, we take the correct amount of damage + destroyableComponent->SetMaxArmor(10.0f); + destroyableComponent->SetArmor(5); + destroyableComponent->Damage(10, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 85); + // Check that if we have damage absorption we take the correct damage + destroyableComponent->SetDamageToAbsorb(10); + destroyableComponent->Damage(9, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 85); + ASSERT_EQ(destroyableComponent->GetDamageToAbsorb(), 1); + destroyableComponent->Damage(6, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 80); + // Check that we take the correct reduced damage if we take reduced damage + destroyableComponent->SetDamageReduction(2); + destroyableComponent->Damage(7, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 75); + destroyableComponent->Damage(2, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 74); + ASSERT_EQ(destroyableComponent->GetDamageReduction(), 2); + destroyableComponent->SetDamageReduction(0); + // Check that blocking works + destroyableComponent->SetAttacksToBlock(1); + destroyableComponent->Damage(UINT32_MAX, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 74); + destroyableComponent->Damage(4, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 70); + // Check that immunity works + destroyableComponent->SetIsImmune(true); + destroyableComponent->Damage(UINT32_MAX, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 70); + ASSERT_TRUE(destroyableComponent->IsImmune()); + destroyableComponent->SetIsImmune(false); + destroyableComponent->SetIsGMImmune(true); + destroyableComponent->Damage(UINT32_MAX, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 70); + ASSERT_TRUE(destroyableComponent->IsImmune()); + destroyableComponent->SetIsGMImmune(false); + // Check knockback immunity + destroyableComponent->SetIsShielded(true); + ASSERT_TRUE(destroyableComponent->IsKnockbackImmune()); + // Finally deal enough damage to kill the Entity + destroyableComponent->Damage(71, LWOOBJID_EMPTY); + ASSERT_EQ(destroyableComponent->GetHealth(), 0); + // Now lets heal some stats + destroyableComponent->Heal(15); + ASSERT_EQ(destroyableComponent->GetHealth(), 15); + destroyableComponent->Heal(15000); + ASSERT_EQ(destroyableComponent->GetHealth(), 100); + destroyableComponent->Repair(10); + ASSERT_EQ(destroyableComponent->GetArmor(), 10); + destroyableComponent->Repair(15000); + ASSERT_EQ(destroyableComponent->GetArmor(), 10); + destroyableComponent->SetMaxImagination(100.0f); + destroyableComponent->SetImagination(0); + destroyableComponent->Imagine(99); + ASSERT_EQ(destroyableComponent->GetImagination(), 99); + destroyableComponent->Imagine(4); + ASSERT_EQ(destroyableComponent->GetImagination(), 100); +} + +TEST_F(DestroyableTest, DestroyableComponentFactionTest) { + ASSERT_TRUE(destroyableComponent->HasFaction(-1)); + ASSERT_TRUE(destroyableComponent->HasFaction(6)); +} + +TEST_F(DestroyableTest, DestroyableComponentValiditiyTest) { + auto* enemyEntity = new Entity(19, info); + auto* enemyDestroyableComponent = new DestroyableComponent(enemyEntity); + enemyEntity->AddComponent(COMPONENT_TYPE_DESTROYABLE, enemyDestroyableComponent); + enemyDestroyableComponent->AddFactionNoLookup(16); + destroyableComponent->AddEnemyFaction(16); + EXPECT_TRUE(destroyableComponent->IsEnemy(enemyEntity)); + EXPECT_FALSE(destroyableComponent->IsFriend(enemyEntity)); + delete enemyEntity; +} From 2f48981801e57eff625033929d560f1baf5069fa Mon Sep 17 00:00:00 2001 From: Jonathan Romano Date: Mon, 7 Nov 2022 04:26:15 -0500 Subject: [PATCH 002/166] Address socket issues with MariaDB Use a new method of determining how to send the connection information to the database --- dDatabase/Database.cpp | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/dDatabase/Database.cpp b/dDatabase/Database.cpp index 91589377..1ce6966f 100644 --- a/dDatabase/Database.cpp +++ b/dDatabase/Database.cpp @@ -14,8 +14,6 @@ std::string Database::database; void Database::Connect(const string& host, const string& database, const string& username, const string& password) { //To bypass debug issues: - std::string newHost = "tcp://" + host; - const char* szHost = newHost.c_str(); const char* szDatabase = database.c_str(); const char* szUsername = username.c_str(); const char* szPassword = password.c_str(); @@ -23,7 +21,24 @@ void Database::Connect(const string& host, const string& database, const string& driver = sql::mariadb::get_driver_instance(); sql::Properties properties; - properties["hostName"] = szHost; + // The mariadb connector is *supposed* to handle unix:// and pipe:// prefixes to hostName, but there are bugs where + // 1) it tries to parse a database from the connection string (like in tcp://localhost:3001/darkflame) based on the + // presence of a / + // 2) even avoiding that, the connector still assumes you're connecting with a tcp socket + // So, what we do in the presence of a unix socket or pipe is to set the hostname to the protocol and localhost, + // which avoids parsing errors while still ensuring the correct connection type is used, and then setting the appropriate + // property manually (which the URL parsing fails to do) + const std::string UNIX_PROTO = "unix://"; + const std::string PIPE_PROTO = "pipe://"; + if (host.find(UNIX_PROTO) == 0) { + properties["hostName"] = "unix://localhost"; + properties["localSocket"] = host.substr(UNIX_PROTO.length()).c_str(); + } else if (host.find(PIPE_PROTO) == 0) { + properties["hostName"] = "pipe://localhost"; + properties["pipe"] = host.substr(PIPE_PROTO.length()).c_str(); + } else { + properties["hostName"] = host.c_str(); + } properties["user"] = szUsername; properties["password"] = szPassword; properties["autoReconnect"] = "true"; @@ -35,7 +50,13 @@ void Database::Connect(const string& host, const string& database, const string& } void Database::Connect() { - con = driver->connect(Database::props["hostName"].c_str(), Database::props["user"].c_str(), Database::props["password"].c_str()); + // `connect(const Properties& props)` segfaults in windows debug, but + // `connect(const SQLString& host, const SQLString& user, const SQLString& pwd)` doesn't handle pipes/unix sockets correctly + if (Database::props.find("localSocket") != Database::props.end() || Database::props.find("pipe") != Database::props.end()) { + con = driver->connect(Database::props); + } else { + con = driver->connect(Database::props["hostName"].c_str(), Database::props["user"].c_str(), Database::props["password"].c_str()); + } con->setSchema(Database::database.c_str()); } From 2570c74b713200a632332b7d61a5740f58343b5d Mon Sep 17 00:00:00 2001 From: Jonathan Romano Date: Mon, 7 Nov 2022 04:27:48 -0500 Subject: [PATCH 003/166] Remove hardcoded port number in AuthPackets Removes the hard coded port numbers in AuthPackets --- dNet/AuthPackets.cpp | 6 +++--- dNet/AuthPackets.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 60fe13c5..636f3fcf 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -29,16 +29,16 @@ void AuthPackets::HandleHandshake(dServer* server, Packet* packet) { inStream.Read(clientVersion); server->GetLogger()->Log("AuthPackets", "Received client version: %i", clientVersion); - SendHandshake(server, packet->systemAddress, server->GetIP(), server->GetPort()); + SendHandshake(server, packet->systemAddress, server->GetIP(), server->GetPort(), server->GetServerType()); } -void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort) { +void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType) { RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, SERVER, MSG_SERVER_VERSION_CONFIRM); bitStream.Write(NET_VERSION); bitStream.Write(uint32_t(0x93)); - if (nextServerPort == 1001) bitStream.Write(uint32_t(1)); //Conn: auth + if (serverType == ServerType::Auth) bitStream.Write(uint32_t(1)); //Conn: auth else bitStream.Write(uint32_t(4)); //Conn: world bitStream.Write(uint32_t(0)); //Server process ID diff --git a/dNet/AuthPackets.h b/dNet/AuthPackets.h index e972d2f7..378a5862 100644 --- a/dNet/AuthPackets.h +++ b/dNet/AuthPackets.h @@ -5,11 +5,12 @@ #include "dCommonVars.h" #include "dNetCommon.h" +enum class ServerType : uint32_t; class dServer; namespace AuthPackets { void HandleHandshake(dServer* server, Packet* packet); - void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort); + void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType); void HandleLoginRequest(dServer* server, Packet* packet); void SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username); From 7c2437173bdb5d5a0c01efc4092e88310924ad61 Mon Sep 17 00:00:00 2001 From: Jack Kawell Date: Mon, 7 Nov 2022 16:04:20 -0700 Subject: [PATCH 004/166] Fixed docker installation (#823) --- docker/setup.sh | 6 ++---- docker/start_server.sh | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docker/setup.sh b/docker/setup.sh index 1a95f4de..0f5c0d2e 100755 --- a/docker/setup.sh +++ b/docker/setup.sh @@ -30,6 +30,7 @@ function update_ini_values() { cp resources/authconfig.ini /docker/configs/ cp resources/chatconfig.ini /docker/configs/ cp resources/worldconfig.ini /docker/configs/ + cp resources/sharedconfig.ini /docker/configs/ update_ini worldconfig.ini chat_server_port $CHAT_SERVER_PORT update_ini worldconfig.ini max_clients $MAX_CLIENTS @@ -37,10 +38,7 @@ function update_ini_values() { # always use the internal docker hostname update_ini masterconfig.ini master_ip "darkflame" - update_database_ini_values_for masterconfig.ini - update_database_ini_values_for authconfig.ini - update_database_ini_values_for chatconfig.ini - update_database_ini_values_for worldconfig.ini + update_database_ini_values_for sharedconfig.ini } function fdb_to_sqlite() { diff --git a/docker/start_server.sh b/docker/start_server.sh index feb61361..ca1a49a0 100755 --- a/docker/start_server.sh +++ b/docker/start_server.sh @@ -8,6 +8,8 @@ function symlink_client_files() { ln -s /client/client/res/names/ /app/res/names ln -s /client/client/res/CDServer.sqlite /app/res/CDServer.sqlite ln -s /client/client/locale/locale.xml /app/locale/locale.xml + # need to create this file so the server knows the client is unpacked (see `dCommon/dClient/AssetManager.cpp`) + touch /app/res/cdclient.fdb # need to iterate over entries in maps due to maps already being a directory with navmeshes/ in it ( cd /client/client/res/maps @@ -25,6 +27,7 @@ function symlink_config_files() { ln -s /shared_configs/configs/chatconfig.ini /app/chatconfig.ini ln -s /shared_configs/configs/masterconfig.ini /app/masterconfig.ini ln -s /shared_configs/configs/worldconfig.ini /app/worldconfig.ini + ln -s /shared_configs/configs/sharedconfig.ini /app/sharedconfig.ini } # check to make sure the setup has completed From 1eff3ae454cc42b9b07db1902c73d1e58b23dc1a Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 10 Nov 2022 12:59:31 -0600 Subject: [PATCH 005/166] Add checks to AssetBuffers before they are used (#820) * add checks to buffers before they are used to avoid crashing * address feedback --- dGame/dInventory/Item.cpp | 5 +++++ dGame/dUtilities/BrickDatabase.cpp | 5 +++++ dGame/dUtilities/SlashCommandHandler.cpp | 6 ++++++ dZoneManager/Zone.cpp | 11 ++++++++++- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 655af84e..c05c0672 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -344,6 +344,11 @@ void Item::DisassembleModel() { std::string lxfmlPath = "BrickModels/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.').at(0) + ".lxfml"; auto buffer = Game::assetManager->GetFileAsBuffer(lxfmlPath.c_str()); + if (!buffer.m_Success) { + Game::logger->Log("Item", "Failed to load %s to disassemble model into bricks, check that this file exists", lxfmlPath.c_str()); + return; + } + std::istream file(&buffer); result.finalize(); diff --git a/dGame/dUtilities/BrickDatabase.cpp b/dGame/dUtilities/BrickDatabase.cpp index c36a1097..6d1e380c 100644 --- a/dGame/dUtilities/BrickDatabase.cpp +++ b/dGame/dUtilities/BrickDatabase.cpp @@ -19,6 +19,11 @@ std::vector& BrickDatabase::GetBricks(const std::string& lxfmlPath) { } AssetMemoryBuffer buffer = Game::assetManager->GetFileAsBuffer((lxfmlPath).c_str()); + + if (!buffer.m_Success) { + return emptyCache; + } + std::istream file(&buffer); if (!file.good()) { return emptyCache; diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index e8f1659e..8f4ac1a8 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -584,6 +584,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (args[0].find("\\") != std::string::npos) return; auto buf = Game::assetManager->GetFileAsBuffer(("macros/" + args[0] + ".scm").c_str()); + + if (!buf.m_Success){ + ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?"); + return; + } + std::istream infile(&buf); if (infile.good()) { diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 1fe47454..e507f859 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -42,6 +42,12 @@ void Zone::LoadZoneIntoMemory() { if (m_ZoneFilePath == "ERR") return; AssetMemoryBuffer buffer = Game::assetManager->GetFileAsBuffer(m_ZoneFilePath.c_str()); + + if (!buffer.m_Success) { + Game::logger->Log("Zone", "Failed to load %s", m_ZoneFilePath.c_str()); + throw std::runtime_error("Aborting Zone loading due to no Zone File."); + } + std::istream file(&buffer); if (file) { BinaryIO::BinaryRead(file, m_ZoneFileFormatVersion); @@ -265,7 +271,10 @@ std::vector Zone::LoadLUTriggers(std::string triggerFile, auto buffer = Game::assetManager->GetFileAsBuffer((m_ZonePath + triggerFile).c_str()); - if (!buffer.m_Success) return lvlTriggers; + if (!buffer.m_Success) { + Game::logger->Log("Zone", "Failed to load %s from disk. Skipping loading triggers", (m_ZonePath + triggerFile).c_str()); + return lvlTriggers; + } std::istream file(&buffer); std::stringstream data; From cf7fa8e52d750e158c464fbed3ff8987cc483fa3 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 12 Nov 2022 08:44:03 -0600 Subject: [PATCH 006/166] cleanup and define all unknowns in zone reading (#826) * cleanup and define all unknowns in zone reading fix for movement path config reading * simplify reading and don't use intermediates * fix spelling * remove dup variable in struct read to the proper name that relates to the enum --- dZoneManager/Zone.cpp | 91 ++++++++++++++----------------------------- dZoneManager/Zone.h | 43 ++++++++++++++++++-- 2 files changed, 68 insertions(+), 66 deletions(-) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index e507f859..eb1d789a 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -98,15 +98,12 @@ void Zone::LoadZoneIntoMemory() { if (m_ZoneFileFormatVersion >= Zone::ZoneFileFormatVersion::EarlyAlpha) { BinaryIO::BinaryRead(file, m_PathDataLength); - uint32_t unknown; - uint32_t pathCount; + BinaryIO::BinaryRead(file, m_PathChunkVersion); // always should be 1 - BinaryIO::BinaryRead(file, unknown); + uint32_t pathCount; BinaryIO::BinaryRead(file, pathCount); - for (uint32_t i = 0; i < pathCount; ++i) { - LoadPath(file); - } + for (uint32_t i = 0; i < pathCount; ++i) LoadPath(file); for (Path path : m_Paths) { if (path.pathType == PathType::Spawner) { @@ -251,15 +248,6 @@ void Zone::LoadScene(std::istream& file) { scene.name = BinaryIO::ReadString(file, sceneNameLength); file.ignore(3); - /* - if (m_Scenes.find(scene.id) != m_Scenes.end()) { - //Extract the layer id from the filename (bad I know, but it's reliable at least): - std::string layer = scene.filename.substr(scene.filename.rfind('x') + 1); - layer = layer.substr(0, layer.find('_')); - lwoSceneID.SetLayerID(std::atoi(layer.c_str())); - } - */ - lwoSceneID.SetLayerID(scene.sceneType); m_Scenes.insert(std::make_pair(lwoSceneID, scene)); @@ -377,14 +365,10 @@ SceneTransitionInfo Zone::LoadSceneTransitionInfo(std::istream& file) { } void Zone::LoadPath(std::istream& file) { - // Currently only spawner (type 4) paths are supported Path path = Path(); - uint32_t unknown1; - uint32_t pathType; - uint32_t pathBehavior; - BinaryIO::BinaryRead(file, path.pathVersion); + uint8_t stringLength; BinaryIO::BinaryRead(file, stringLength); for (uint8_t i = 0; i < stringLength; ++i) { @@ -392,16 +376,14 @@ void Zone::LoadPath(std::istream& file) { BinaryIO::BinaryRead(file, character); path.pathName.push_back(character); } - BinaryIO::BinaryRead(file, pathType); - path.pathType = PathType(pathType); - BinaryIO::BinaryRead(file, unknown1); - BinaryIO::BinaryRead(file, pathBehavior); - path.pathType = PathType(pathType); + + BinaryIO::BinaryRead(file, path.pathType); + BinaryIO::BinaryRead(file, path.flags); + BinaryIO::BinaryRead(file, path.pathBehavior); if (path.pathType == PathType::MovingPlatform) { if (path.pathVersion >= 18) { - uint8_t unknown; - BinaryIO::BinaryRead(file, unknown); + BinaryIO::BinaryRead(file, path.movingPlatform.timeBasedMovement); } else if (path.pathVersion >= 13) { uint8_t count; BinaryIO::BinaryRead(file, count); @@ -412,10 +394,9 @@ void Zone::LoadPath(std::istream& file) { } } } else if (path.pathType == PathType::Property) { - int32_t unknown; - BinaryIO::BinaryRead(file, unknown); + BinaryIO::BinaryRead(file, path.property.pathType); BinaryIO::BinaryRead(file, path.property.price); - BinaryIO::BinaryRead(file, path.property.rentalTime); + BinaryIO::BinaryRead(file, path.property.rentalTimeUnit); BinaryIO::BinaryRead(file, path.property.associatedZone); if (path.pathVersion >= 5) { @@ -435,10 +416,7 @@ void Zone::LoadPath(std::istream& file) { } } - if (path.pathVersion >= 6) { - int32_t unknown1; - BinaryIO::BinaryRead(file, unknown1); - } + if (path.pathVersion >= 6) BinaryIO::BinaryRead(file, path.property.type); if (path.pathVersion >= 7) { BinaryIO::BinaryRead(file, path.property.cloneLimit); @@ -462,11 +440,10 @@ void Zone::LoadPath(std::istream& file) { path.camera.nextPath.push_back(character); } if (path.pathVersion >= 14) { - uint8_t unknown; - BinaryIO::BinaryRead(file, unknown); + BinaryIO::BinaryRead(file, path.camera.rotatePlayer); + } } else if (path.pathType == PathType::Spawner) { - //SpawnerPath* path = static_cast(path); // Convert to a spawner path BinaryIO::BinaryRead(file, path.spawner.spawnedLOT); BinaryIO::BinaryRead(file, path.spawner.respawnTime); BinaryIO::BinaryRead(file, path.spawner.maxToSpawn); @@ -487,7 +464,7 @@ void Zone::LoadPath(std::istream& file) { BinaryIO::BinaryRead(file, waypoint.position.z); - if (path.pathType == PathType::Spawner || path.pathType == PathType::MovingPlatform || path.pathType == PathType::Race) { + if (path.pathType == PathType::Spawner || path.pathType == PathType::MovingPlatform || path.pathType == PathType::Race || path.pathType == PathType::Camera || path.pathType == PathType::Rail) { BinaryIO::BinaryRead(file, waypoint.rotation.w); BinaryIO::BinaryRead(file, waypoint.rotation.x); BinaryIO::BinaryRead(file, waypoint.rotation.y); @@ -515,33 +492,17 @@ void Zone::LoadPath(std::istream& file) { } } } else if (path.pathType == PathType::Camera) { - float unknown; - BinaryIO::BinaryRead(file, unknown); - BinaryIO::BinaryRead(file, unknown); - BinaryIO::BinaryRead(file, unknown); - BinaryIO::BinaryRead(file, unknown); BinaryIO::BinaryRead(file, waypoint.camera.time); - BinaryIO::BinaryRead(file, unknown); + BinaryIO::BinaryRead(file, waypoint.camera.fov); BinaryIO::BinaryRead(file, waypoint.camera.tension); BinaryIO::BinaryRead(file, waypoint.camera.continuity); BinaryIO::BinaryRead(file, waypoint.camera.bias); } else if (path.pathType == PathType::Race) { - uint8_t unknown; - BinaryIO::BinaryRead(file, unknown); - BinaryIO::BinaryRead(file, unknown); - float unknown1; - BinaryIO::BinaryRead(file, unknown1); - BinaryIO::BinaryRead(file, unknown1); - BinaryIO::BinaryRead(file, unknown1); - } else if (path.pathType == PathType::Rail) { - float unknown; - BinaryIO::BinaryRead(file, unknown); - BinaryIO::BinaryRead(file, unknown); - BinaryIO::BinaryRead(file, unknown); - BinaryIO::BinaryRead(file, unknown); - if (path.pathVersion >= 17) { - BinaryIO::BinaryRead(file, unknown); - } + BinaryIO::BinaryRead(file, waypoint.racing.isResetNode); + BinaryIO::BinaryRead(file, waypoint.racing.isNonHorizontalCamera); + BinaryIO::BinaryRead(file, waypoint.racing.planeWidth); + BinaryIO::BinaryRead(file, waypoint.racing.planeHeight); + BinaryIO::BinaryRead(file, waypoint.racing.shortestDistanceToEnd); } // object LDF configs @@ -565,8 +526,14 @@ void Zone::LoadPath(std::istream& file) { BinaryIO::BinaryRead(file, character); value.push_back(character); } - LDFBaseData* ldfConfig = LDFBaseData::DataFromString(parameter + "=" + value); - waypoint.config.push_back(ldfConfig); + + LDFBaseData* ldfConfig = nullptr; + if (path.pathType == PathType::Movement) { + ldfConfig = LDFBaseData::DataFromString(parameter + "=0:" + value); + } else { + ldfConfig = LDFBaseData::DataFromString(parameter + "=" + value); + } + if (ldfConfig) waypoint.config.push_back(ldfConfig); } } diff --git a/dZoneManager/Zone.h b/dZoneManager/Zone.h index f041b616..0e7ae5eb 100644 --- a/dZoneManager/Zone.h +++ b/dZoneManager/Zone.h @@ -59,16 +59,32 @@ struct MovingPlatformPathWaypoint { struct CameraPathWaypoint { float time; + float fov; float tension; float continuity; float bias; }; +struct RacingPathWaypoint { + uint8_t isResetNode; + uint8_t isNonHorizontalCamera; + float planeWidth; + float planeHeight; + float shortestDistanceToEnd; +}; + +struct RailPathWaypoint { + float speed; + std::vector config; +}; + struct PathWaypoint { NiPoint3 position; NiQuaternion rotation; // not included in all, but it's more convenient here MovingPlatformPathWaypoint movingPlatform; CameraPathWaypoint camera; + RacingPathWaypoint racing; + RailPathWaypoint rail; std::vector config; }; @@ -89,6 +105,19 @@ enum class PathBehavior : uint32_t { Once = 2 }; +enum class PropertyPathType : int32_t { + Path = 0, + EntireZone = 1, + GenetatedRectangle = 2 +}; + +enum class PropertyType : int32_t{ + Premiere = 0, + Prize = 1, + LUP = 2, + Headspace = 3 +}; + enum class PropertyRentalTimeUnit : int32_t { Forever = 0, Seconds = 1, @@ -116,17 +145,19 @@ enum class PropertyAchievmentRequired : int32_t { struct MovingPlatformPath { std::string platformTravelSound; + uint8_t timeBasedMovement; }; struct PropertyPath { + PropertyPathType pathType; int32_t price; - int32_t rentalTime; + PropertyRentalTimeUnit rentalTimeUnit; uint64_t associatedZone; std::string displayName; std::string displayDesc; + PropertyType type; int32_t cloneLimit; float repMultiplier; - PropertyRentalTimeUnit rentalTimeUnit; PropertyAchievmentRequired achievementRequired; NiPoint3 playerZoneCoords; float maxBuildHeight; @@ -134,6 +165,7 @@ struct PropertyPath { struct CameraPath { std::string nextPath; + uint8_t rotatePlayer; }; struct SpawnerPath { @@ -150,6 +182,7 @@ struct Path { uint32_t pathVersion; PathType pathType; std::string pathName; + uint32_t flags; PathBehavior pathBehavior; uint32_t waypointCount; std::vector pathWaypoints; @@ -219,9 +252,11 @@ private: std::map m_Scenes; std::vector m_SceneTransitions; + uint32_t m_PathDataLength; - //std::vector m_PathData; //Binary path data - std::vector m_Paths; + uint32_t m_PathChunkVersion; + std::vector m_Paths; + std::map m_MapRevisions; //rhs is the revision! //private ("helper") functions: From 22e5d024009663723f98ca992af5b08f7acf4af1 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 12 Nov 2022 08:44:13 -0600 Subject: [PATCH 007/166] Use Property path name and desc when claiming (#827) --- .../dComponents/PropertyManagementComponent.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 1e90e8db..d196e935 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -200,6 +200,16 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { // If we are not on our clone do not allow us to claim the property if (propertyCloneId != playerCloneId) return false; + std::string name = zone->GetZoneName(); + std::string description = ""; + + auto prop_path = zone->GetPath(m_Parent->GetVarAsString(u"propertyName")); + + if (prop_path){ + if (!prop_path->property.displayName.empty()) name = prop_path->property.displayName; + description = prop_path->property.displayDesc; + } + SetOwnerId(playerId); propertyId = ObjectIDManager::GenerateRandomObjectID(); @@ -207,14 +217,15 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { auto* insertion = Database::CreatePreppedStmt( "INSERT INTO properties" "(id, owner_id, template_id, clone_id, name, description, rent_amount, rent_due, privacy_option, last_updated, time_claimed, rejection_reason, reputation, zone_id, performance_cost)" - "VALUES (?, ?, ?, ?, ?, '', 0, 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '', 0, ?, 0.0)" + "VALUES (?, ?, ?, ?, ?, ?, 0, 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '', 0, ?, 0.0)" ); insertion->setUInt64(1, propertyId); insertion->setUInt64(2, (uint32_t)playerId); insertion->setUInt(3, templateId); insertion->setUInt64(4, playerCloneId); - insertion->setString(5, zone->GetZoneName().c_str()); - insertion->setInt(6, propertyZoneId); + insertion->setString(5, name.c_str()); + insertion->setString(6, description.c_str()); + insertion->setInt(7, propertyZoneId); // Try and execute the query, print an error if it fails. try { From 7429902a646699013d94954556c00b015e71ccf8 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 12 Nov 2022 08:44:27 -0600 Subject: [PATCH 008/166] Prevent adding movingplatform components to all entites with an attached_path (#829) * Stop adding movingpla comps where they aren't needed * move stuff around to make it more congruent * invert if else block logic patter Since setting up the comp will be longer han just adding the path will make the readability flow better * address feedback --- dGame/Entity.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 52eddd06..62ac8bc2 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -317,15 +317,6 @@ void Entity::Initialize() { m_Components.insert(std::make_pair(COMPONENT_TYPE_SOUND_TRIGGER, comp)); } - //Check to see if we have a moving platform component: - //Which, for some reason didn't get added to the ComponentsRegistry so we have to check for a path manually here. - std::string attachedPath = GetVarAsString(u"attached_path"); - - if (!attachedPath.empty() || compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MOVING_PLATFORM, -1) != -1) { - MovingPlatformComponent* plat = new MovingPlatformComponent(this, attachedPath); - m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVING_PLATFORM, plat)); - } - //Also check for the collectible id: m_CollectibleID = GetVarAs(u"collectible_id"); @@ -696,6 +687,26 @@ void Entity::Initialize() { m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); } + std::string pathName = GetVarAsString(u"attached_path"); + const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName); + + //Check to see if we have an attached path and add the appropiate component to handle it: + if (path){ + // if we have a moving platform path, then we need a moving platform component + if (path->pathType == PathType::MovingPlatform) { + MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); + m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVING_PLATFORM, plat)); + // else if we are a movement path + } /*else if (path->pathType == PathType::Movement) { + auto movementAIcomp = GetComponent(); + if (movementAIcomp){ + // TODO: set path in existing movementAIComp + } else { + // TODO: create movementAIcomp and set path + } + }*/ + } + int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PROXIMITY_MONITOR); if (proximityMonitorID > 0) { CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance()->GetTable("ProximityMonitorComponent"); From 848c0669248c506e5b916f52b9fec436ac655548 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 12 Nov 2022 08:44:37 -0600 Subject: [PATCH 009/166] Not every scene has triggers, that is normal (#831) Quell the onslaught of meaningless logs --- dZoneManager/Zone.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index eb1d789a..3a1127a4 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -233,7 +233,8 @@ void Zone::LoadScene(std::istream& file) { scene.filename = BinaryIO::ReadString(file, sceneFilenameLength); std::string luTriggersPath = scene.filename.substr(0, scene.filename.size() - 4) + ".lutriggers"; - std::vector triggers = LoadLUTriggers(luTriggersPath, scene.id); + std::vector triggers; + if(Game::assetManager->HasFile(luTriggersPath.c_str())) triggers = LoadLUTriggers(luTriggersPath, scene.id); for (LUTriggers::Trigger* trigger : triggers) { scene.triggers.insert({ trigger->id, trigger }); From 53b559bef3407f6376bb61bfa4bf8c8cb70e5b73 Mon Sep 17 00:00:00 2001 From: Jonathan Romano Date: Mon, 14 Nov 2022 09:08:49 -0500 Subject: [PATCH 010/166] Make build script fail if any command fails (#832) --- build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.sh b/build.sh index 4a476cc1..a736a4ee 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,6 @@ +# Error if any command fails +set -e + # Create the build directory, preserving it if it already exists mkdir -p build cd build From 37524af549de353d89552ab7dd1f29576deb55de Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Mon, 14 Nov 2022 12:55:40 -0600 Subject: [PATCH 011/166] fix trigger loading (#838) Fixes #836 --- dZoneManager/Zone.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 3a1127a4..adf66dc9 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -234,7 +234,7 @@ void Zone::LoadScene(std::istream& file) { std::string luTriggersPath = scene.filename.substr(0, scene.filename.size() - 4) + ".lutriggers"; std::vector triggers; - if(Game::assetManager->HasFile(luTriggersPath.c_str())) triggers = LoadLUTriggers(luTriggersPath, scene.id); + if(Game::assetManager->HasFile((m_ZonePath + luTriggersPath).c_str())) triggers = LoadLUTriggers(luTriggersPath, scene.id); for (LUTriggers::Trigger* trigger : triggers) { scene.triggers.insert({ trigger->id, trigger }); From 3fa6ea4cea758e15f4590fbee38be0024b7fbe4a Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Mon, 14 Nov 2022 13:57:49 -0600 Subject: [PATCH 012/166] Fix ninjago crashes (#837) Fixed reading speed from rail paths Made the config of rail paths be read in sanely due to not having a type Fixes #835 --- dZoneManager/Zone.cpp | 4 +++- dZoneManager/Zone.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index adf66dc9..ec73237e 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -504,6 +504,8 @@ void Zone::LoadPath(std::istream& file) { BinaryIO::BinaryRead(file, waypoint.racing.planeWidth); BinaryIO::BinaryRead(file, waypoint.racing.planeHeight); BinaryIO::BinaryRead(file, waypoint.racing.shortestDistanceToEnd); + } else if (path.pathType == PathType::Rail) { + if (path.pathVersion > 16) BinaryIO::BinaryRead(file, waypoint.rail.speed); } // object LDF configs @@ -529,7 +531,7 @@ void Zone::LoadPath(std::istream& file) { } LDFBaseData* ldfConfig = nullptr; - if (path.pathType == PathType::Movement) { + if (path.pathType == PathType::Movement || path.pathType == PathType::Rail) { ldfConfig = LDFBaseData::DataFromString(parameter + "=0:" + value); } else { ldfConfig = LDFBaseData::DataFromString(parameter + "=" + value); diff --git a/dZoneManager/Zone.h b/dZoneManager/Zone.h index 0e7ae5eb..978438aa 100644 --- a/dZoneManager/Zone.h +++ b/dZoneManager/Zone.h @@ -75,7 +75,6 @@ struct RacingPathWaypoint { struct RailPathWaypoint { float speed; - std::vector config; }; struct PathWaypoint { From 416021c2081e924fed3faca7202882a7d5aa8cf7 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 21 Nov 2022 14:18:01 -0800 Subject: [PATCH 013/166] Remove need for Avant Gardens Survival Client Fix This addresses the Avant Gardens Survival bug Does not conflict with clients that have the fix. --- README.md | 16 +++------------- dGame/dGameMessages/GameMessageHandler.cpp | 2 +- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e588d341..87319c10 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Some tools utilized to streamline the setup process require Python 3, make sure ### Choosing the right version for your client DLU clients identify themselves using a higher version number than the regular live clients out there. -This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client. +This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client. If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number. @@ -173,7 +173,7 @@ Known good SHA256 checksums of the client: - `0d862f71eedcadc4494c4358261669721b40b2131101cbd6ef476c5a6ec6775b` (unpacked client, includes extra locales, rar compressed) Known good *SHA1* checksum of the DLU client: -- `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed) +- `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed) How to generate a SHA256 checksum: ```bash @@ -273,16 +273,6 @@ To connect to a server follow these steps: * Launch `legouniverse.exe`, through `wine` if on a Unix-like operating system * Note that if you are on WSL2, you will need to configure the public IP in the server and client to be the IP of the WSL2 instance and not localhost, which can be found by running `ifconfig` in the terminal. Windows defaults to WSL1, so this will not apply to most users. -### Survival - -The client script for the survival minigame has a bug in it which can cause the minigame to not load. To fix this, follow these instructions: -* Open `res/scripts/ai/minigame/survival/l_zone_survival_client.lua` -* Navigate to line `617` -* Change `PlayerReady(self)` to `onPlayerReady(self)` -* Save the file, overriding readonly mode if required - -If you still experience the bug, try deleting/renaming `res/pack/scripts.pk`. - ### Brick-By-Brick building Brick-By-Brick building requires `PATCHSERVERIP=0:` in the `boot.cfg` to point to a HTTP server which always returns `HTTP 404 - Not Found` for all requests. This can be achieved by pointing it to `localhost` while having `sudo python -m http.server 80` running in the background. @@ -340,7 +330,7 @@ Here is a summary of the commands available in-game. All commands are prefixed b /instanceinfo - Displays in the chat the current zone, clone, and instance id. + Displays in the chat the current zone, clone, and instance id. diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 9cf09bbc..2ce79966 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -157,8 +157,8 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System Game::logger->Log("GameMessageHandler", "Player %s (%llu) loaded.", entity->GetCharacter()->GetName().c_str(), entity->GetObjectID()); // After we've done our thing, tell the client they're ready - GameMessages::SendPlayerReady(dZoneManager::Instance()->GetZoneControlObject(), sysAddr); GameMessages::SendPlayerReady(entity, sysAddr); + GameMessages::SendPlayerReady(dZoneManager::Instance()->GetZoneControlObject(), sysAddr); break; } From 9d62a8cd0bec17febc132c3b84f78b9e122687fd Mon Sep 17 00:00:00 2001 From: Demetri Van Sickle Date: Mon, 21 Nov 2022 14:19:37 -0800 Subject: [PATCH 014/166] Add backwards compatibility with servers using previous setup method * MasterServer will nolonger require cdclient.fdb * Added support for packed/unpacked clients not requiring .fdb file if .sqlite exsits --- dCommon/dClient/AssetManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dCommon/dClient/AssetManager.cpp b/dCommon/dClient/AssetManager.cpp index 0cb2db31..349b5271 100644 --- a/dCommon/dClient/AssetManager.cpp +++ b/dCommon/dClient/AssetManager.cpp @@ -26,11 +26,11 @@ AssetManager::AssetManager(const std::string& path) { m_RootPath = (m_Path / ".." / ".."); m_ResPath = m_Path; - } else if (std::filesystem::exists(m_Path / "res" / "cdclient.fdb") && !std::filesystem::exists(m_Path / "res" / "pack")) { + } else if ((std::filesystem::exists(m_Path / "res" / "cdclient.fdb") || std::filesystem::exists(m_Path / "res" / "CDServer.sqlite")) && !std::filesystem::exists(m_Path / "res" / "pack")) { m_AssetBundleType = eAssetBundleType::Unpacked; m_ResPath = (m_Path / "res"); - } else if (std::filesystem::exists(m_Path / "cdclient.fdb") && !std::filesystem::exists(m_Path / "pack")) { + } else if ((std::filesystem::exists(m_Path / "cdclient.fdb") || std::filesystem::exists(m_Path / "CDServer.sqlite")) && !std::filesystem::exists(m_Path / "pack")) { m_AssetBundleType = eAssetBundleType::Unpacked; m_ResPath = m_Path; From b17ba56af17f42f47dafdfbe56913caabf49c450 Mon Sep 17 00:00:00 2001 From: Nico Mexis Date: Wed, 23 Nov 2022 19:50:45 +0100 Subject: [PATCH 015/166] Update workflow actions (#844) --- .github/workflows/build-and-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 8f65fd8e..ab3917c1 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -16,7 +16,7 @@ jobs: os: [ windows-2022, ubuntu-20.04, macos-11 ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true - name: Add msbuild to PATH (Windows only) @@ -35,7 +35,7 @@ jobs: buildPreset: "ci-${{matrix.os}}" testPreset: "ci-${{matrix.os}}" - name: artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: ${{ github.ref == 'ref/head/main' }} with: name: build-${{matrix.os}} From afb97a81b5001272a2b9510c993bf79a63e81a86 Mon Sep 17 00:00:00 2001 From: Jonathan Romano Date: Fri, 25 Nov 2022 20:28:20 -0500 Subject: [PATCH 016/166] Address Mac CI using specific versions of OpenSSL Corrected CI to use the version brew links in opt rather than the specific version in Cellar --- CMakePresets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakePresets.json b/CMakePresets.json index 15eb729e..3968b3ce 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -25,7 +25,7 @@ "description": "Same as default, Used in GitHub actions workflow", "inherits": "default", "cacheVariables": { - "OPENSSL_ROOT_DIR": "/usr/local/Cellar/openssl@3/3.0.5/" + "OPENSSL_ROOT_DIR": "/usr/local/opt/openssl@3/" } }, { From 4569f621007cdd70e1b45c6141e8fba173cd0fb4 Mon Sep 17 00:00:00 2001 From: Jonathan Romano Date: Sat, 26 Nov 2022 05:29:53 -0500 Subject: [PATCH 017/166] Fix three-part names coming across as INVALID with custom client path --- dGame/UserManager.cpp | 49 +++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 7da26b9a..f3fd78c4 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -20,6 +20,7 @@ #include "Entity.h" #include "EntityManager.h" #include "SkillComponent.h" +#include "AssetManager.h" UserManager* UserManager::m_Address = nullptr; @@ -32,43 +33,59 @@ inline void StripCR(std::string& str) { } void UserManager::Initialize() { - std::string firstNamePath = "./res/names/minifigname_first.txt"; - std::string middleNamePath = "./res/names/minifigname_middle.txt"; - std::string lastNamePath = "./res/names/minifigname_last.txt"; std::string line; - std::fstream fnFile(firstNamePath, std::ios::in); - std::fstream mnFile(middleNamePath, std::ios::in); - std::fstream lnFile(lastNamePath, std::ios::in); - - while (std::getline(fnFile, line, '\n')) { + AssetMemoryBuffer fnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_first.txt"); + if (!fnBuff.m_Success) { + Game::logger->Log("UserManager", "Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_first.txt").string().c_str()); + throw std::runtime_error("Aborting initialization due to missing minifigure name file."); + } + std::istream fnStream = std::istream(&fnBuff); + while (std::getline(fnStream, line, '\n')) { std::string name = line; StripCR(name); m_FirstNames.push_back(name); } + fnBuff.close(); - while (std::getline(mnFile, line, '\n')) { + AssetMemoryBuffer mnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_middle.txt"); + if (!mnBuff.m_Success) { + Game::logger->Log("UserManager", "Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_middle.txt").string().c_str()); + throw std::runtime_error("Aborting initialization due to missing minifigure name file."); + } + std::istream mnStream = std::istream(&mnBuff); + while (std::getline(mnStream, line, '\n')) { std::string name = line; StripCR(name); m_MiddleNames.push_back(name); } + mnBuff.close(); - while (std::getline(lnFile, line, '\n')) { + AssetMemoryBuffer lnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_last.txt"); + if (!lnBuff.m_Success) { + Game::logger->Log("UserManager", "Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_last.txt").string().c_str()); + throw std::runtime_error("Aborting initialization due to missing minifigure name file."); + } + std::istream lnStream = std::istream(&lnBuff); + while (std::getline(lnStream, line, '\n')) { std::string name = line; StripCR(name); m_LastNames.push_back(name); } - - fnFile.close(); - mnFile.close(); - lnFile.close(); + lnBuff.close(); //Load our pre-approved names: - std::fstream chatList("./res/chatplus_en_us.txt", std::ios::in); - while (std::getline(chatList, line, '\n')) { + AssetMemoryBuffer chatListBuff = Game::assetManager->GetFileAsBuffer("chatplus_en_us.txt"); + if (!chatListBuff.m_Success) { + Game::logger->Log("UserManager", "Failed to load %s", (Game::assetManager->GetResPath() / "names/chatplus_en_us.txt").string().c_str()); + throw std::runtime_error("Aborting initialization due to missing chat whitelist file."); + } + std::istream chatListStream = std::istream(&chatListBuff); + while (std::getline(chatListStream, line, '\n')) { StripCR(line); m_PreapprovedNames.push_back(line); } + chatListBuff.close(); } UserManager::~UserManager() { From 36eecd693dde89979d4ab2ddb785ba82b4d87b4e Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 26 Nov 2022 03:30:53 -0700 Subject: [PATCH 018/166] Brick stack sizes are now unlimited Make brick stacks unlimited as they were in live. If you have more than uint32_max bricks, the extra bricks are trashed. --- dGame/dComponents/InventoryComponent.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 930ace8d..12b6792e 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -211,7 +211,7 @@ void InventoryComponent::AddItem( // info.itemType of 1 is item type brick if (inventoryType == eInventoryType::BRICKS || (stack == 0 && info.itemType == 1)) { - stack = 999; + stack = UINT32_MAX; } else if (stack == 0) { stack = 1; } @@ -232,7 +232,8 @@ void InventoryComponent::AddItem( } } - while (left > 0) { + // If we have some leftover and we aren't bricks, make a new stack + while (left > 0 && !(inventoryType == eInventoryType::BRICKS || (stack == 0 && info.itemType == 1))) { const auto size = std::min(left, stack); left -= size; From e2616c5f11ca6057ded4e5740b036e0c32a76e2e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 26 Nov 2022 14:22:00 -0800 Subject: [PATCH 019/166] Move enums to a single directory A technical change to move all emum files to a single directory --- CMakeLists.txt | 3 ++- dCommon/{ => dEnums}/AddFriendResponseCode.h | 0 dCommon/{ => dEnums}/AddFriendResponseType.h | 0 .../dInventory => dCommon/dEnums}/ItemSetPassiveAbilityID.h | 0 {dGame/dMission => dCommon/dEnums}/MissionLockState.h | 0 {dGame/dMission => dCommon/dEnums}/MissionState.h | 0 {dGame/dMission => dCommon/dEnums}/MissionTaskType.h | 0 {dGame/dMission => dCommon/dEnums}/RacingTaskParam.h | 0 dCommon/{ => dEnums}/dCommonVars.h | 5 +++++ {dNet => dCommon/dEnums}/dMessageIdentifiers.h | 0 dCommon/{ => dEnums}/dPlatforms.h | 0 {dPhysics => dCommon/dEnums}/dpCollisionGroups.h | 0 {dPhysics => dCommon/dEnums}/dpCommon.h | 0 dCommon/{ => dEnums}/eAninmationFlags.h | 0 dCommon/{ => dEnums}/eItemType.h | 0 dCommon/{ => dEnums}/eUnequippableActiveType.h | 0 16 files changed, 7 insertions(+), 1 deletion(-) rename dCommon/{ => dEnums}/AddFriendResponseCode.h (100%) rename dCommon/{ => dEnums}/AddFriendResponseType.h (100%) rename {dGame/dInventory => dCommon/dEnums}/ItemSetPassiveAbilityID.h (100%) rename {dGame/dMission => dCommon/dEnums}/MissionLockState.h (100%) rename {dGame/dMission => dCommon/dEnums}/MissionState.h (100%) rename {dGame/dMission => dCommon/dEnums}/MissionTaskType.h (100%) rename {dGame/dMission => dCommon/dEnums}/RacingTaskParam.h (100%) rename dCommon/{ => dEnums}/dCommonVars.h (99%) rename {dNet => dCommon/dEnums}/dMessageIdentifiers.h (100%) rename dCommon/{ => dEnums}/dPlatforms.h (100%) rename {dPhysics => dCommon/dEnums}/dpCollisionGroups.h (100%) rename {dPhysics => dCommon/dEnums}/dpCommon.h (100%) rename dCommon/{ => dEnums}/eAninmationFlags.h (100%) rename dCommon/{ => dEnums}/eItemType.h (100%) rename dCommon/{ => dEnums}/eUnequippableActiveType.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dfef867..644fc383 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,8 @@ endforeach() # Create our list of include directories set(INCLUDED_DIRECTORIES "dCommon" + "dCommon/dClient" + "dCommon/dEnums" "dChatFilter" "dGame" "dGame/dBehaviors" @@ -165,7 +167,6 @@ set(INCLUDED_DIRECTORIES "dGame/dEntity" "dGame/dPropertyBehaviors" "dGame/dUtilities" - "dCommon/dClient" "dPhysics" "dNavigation" "dNavigation/dTerrain" diff --git a/dCommon/AddFriendResponseCode.h b/dCommon/dEnums/AddFriendResponseCode.h similarity index 100% rename from dCommon/AddFriendResponseCode.h rename to dCommon/dEnums/AddFriendResponseCode.h diff --git a/dCommon/AddFriendResponseType.h b/dCommon/dEnums/AddFriendResponseType.h similarity index 100% rename from dCommon/AddFriendResponseType.h rename to dCommon/dEnums/AddFriendResponseType.h diff --git a/dGame/dInventory/ItemSetPassiveAbilityID.h b/dCommon/dEnums/ItemSetPassiveAbilityID.h similarity index 100% rename from dGame/dInventory/ItemSetPassiveAbilityID.h rename to dCommon/dEnums/ItemSetPassiveAbilityID.h diff --git a/dGame/dMission/MissionLockState.h b/dCommon/dEnums/MissionLockState.h similarity index 100% rename from dGame/dMission/MissionLockState.h rename to dCommon/dEnums/MissionLockState.h diff --git a/dGame/dMission/MissionState.h b/dCommon/dEnums/MissionState.h similarity index 100% rename from dGame/dMission/MissionState.h rename to dCommon/dEnums/MissionState.h diff --git a/dGame/dMission/MissionTaskType.h b/dCommon/dEnums/MissionTaskType.h similarity index 100% rename from dGame/dMission/MissionTaskType.h rename to dCommon/dEnums/MissionTaskType.h diff --git a/dGame/dMission/RacingTaskParam.h b/dCommon/dEnums/RacingTaskParam.h similarity index 100% rename from dGame/dMission/RacingTaskParam.h rename to dCommon/dEnums/RacingTaskParam.h diff --git a/dCommon/dCommonVars.h b/dCommon/dEnums/dCommonVars.h similarity index 99% rename from dCommon/dCommonVars.h rename to dCommon/dEnums/dCommonVars.h index 4c0e15fa..41d6cb67 100644 --- a/dCommon/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -1,5 +1,8 @@ #pragma once +#ifndef __DCOMMONVARS__H__ +#define __DCOMMONVARS__H__ + #include #include #include @@ -648,3 +651,5 @@ inline T const& clamp(const T& val, const T& low, const T& high) { return val; } + +#endif //!__DCOMMONVARS__H__ diff --git a/dNet/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h similarity index 100% rename from dNet/dMessageIdentifiers.h rename to dCommon/dEnums/dMessageIdentifiers.h diff --git a/dCommon/dPlatforms.h b/dCommon/dEnums/dPlatforms.h similarity index 100% rename from dCommon/dPlatforms.h rename to dCommon/dEnums/dPlatforms.h diff --git a/dPhysics/dpCollisionGroups.h b/dCommon/dEnums/dpCollisionGroups.h similarity index 100% rename from dPhysics/dpCollisionGroups.h rename to dCommon/dEnums/dpCollisionGroups.h diff --git a/dPhysics/dpCommon.h b/dCommon/dEnums/dpCommon.h similarity index 100% rename from dPhysics/dpCommon.h rename to dCommon/dEnums/dpCommon.h diff --git a/dCommon/eAninmationFlags.h b/dCommon/dEnums/eAninmationFlags.h similarity index 100% rename from dCommon/eAninmationFlags.h rename to dCommon/dEnums/eAninmationFlags.h diff --git a/dCommon/eItemType.h b/dCommon/dEnums/eItemType.h similarity index 100% rename from dCommon/eItemType.h rename to dCommon/dEnums/eItemType.h diff --git a/dCommon/eUnequippableActiveType.h b/dCommon/dEnums/eUnequippableActiveType.h similarity index 100% rename from dCommon/eUnequippableActiveType.h rename to dCommon/dEnums/eUnequippableActiveType.h From af28d170fbd394f560c077365d161566402e797c Mon Sep 17 00:00:00 2001 From: Jonathan Romano Date: Sun, 27 Nov 2022 04:06:17 -0500 Subject: [PATCH 020/166] Fix chat whitelist path in UserManager error log (#853) --- dGame/UserManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index f3fd78c4..ddbad03a 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -77,7 +77,7 @@ void UserManager::Initialize() { //Load our pre-approved names: AssetMemoryBuffer chatListBuff = Game::assetManager->GetFileAsBuffer("chatplus_en_us.txt"); if (!chatListBuff.m_Success) { - Game::logger->Log("UserManager", "Failed to load %s", (Game::assetManager->GetResPath() / "names/chatplus_en_us.txt").string().c_str()); + Game::logger->Log("UserManager", "Failed to load %s", (Game::assetManager->GetResPath() / "chatplus_en_us.txt").string().c_str()); throw std::runtime_error("Aborting initialization due to missing chat whitelist file."); } std::istream chatListStream = std::istream(&chatListBuff); From e40a597f1854bd315953a90c572d74c6d42fc880 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 27 Nov 2022 01:24:35 -0800 Subject: [PATCH 021/166] Property Behavior deserialize definitions (#812) * Implement basic functionality Implements the basic functionality and parsing of property behaviors. Unhandled messages and logged and discarded for the time being. The only implemented message is a basic one that sends the needed info the the client side User Interface to pop up. --- dCommon/dEnums/dCommonVars.h | 2 + dGame/dPropertyBehaviors/BehaviorStates.h | 20 + dGame/dPropertyBehaviors/ControlBehaviors.cpp | 600 ++++++++++++++++-- dGame/dPropertyBehaviors/ControlBehaviors.h | 10 +- 4 files changed, 583 insertions(+), 49 deletions(-) create mode 100644 dGame/dPropertyBehaviors/BehaviorStates.h diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 41d6cb67..005d7205 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -33,6 +33,8 @@ typedef uint32_t LWOCLONEID; //!< Used for Clone IDs typedef uint16_t LWOMAPID; //!< Used for Map IDs typedef uint16_t LWOINSTANCEID; //!< Used for Instance IDs typedef uint32_t PROPERTYCLONELIST; //!< Used for Property Clone IDs +typedef uint32_t STRIPID; +typedef uint32_t BEHAVIORSTATE; typedef int32_t PetTamingPiece; //!< Pet Taming Pieces diff --git a/dGame/dPropertyBehaviors/BehaviorStates.h b/dGame/dPropertyBehaviors/BehaviorStates.h new file mode 100644 index 00000000..e09e45ba --- /dev/null +++ b/dGame/dPropertyBehaviors/BehaviorStates.h @@ -0,0 +1,20 @@ +#pragma once + +#ifndef __BEHAVIORSTATES__H__ +#define __BEHAVIORSTATES__H__ + +#include +#include + +#include "dCommonVars.h" + +enum States : BEHAVIORSTATE { + HOME_STATE = 0, //!< The HOME behavior state + CIRCLE_STATE, //!< The CIRCLE behavior state + SQUARE_STATE, //!< The SQUARE behavior state + DIAMOND_STATE, //!< The DIAMOND behavior state + TRIANGLE_STATE, //!< The TRIANGLE behavior state + STAR_STATE //!< The STAR behavior state +}; + +#endif //!__BEHAVIORSTATES__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 4e922ee0..d5b71a3a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -5,50 +5,67 @@ #include "Game.h" #include "GameMessages.h" #include "ModelComponent.h" +#include "../../dWorldServer/ObjectIDManager.h" #include "dLogger.h" -void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) { - if (!modelEntity || !modelOwner || !arguments) return; +uint32_t GetBehaviorIDFromArgument(AMFArrayValue* arguments, const std::string& key = "BehaviorID") { + auto* behaviorIDValue = arguments->FindValue(key); + uint32_t behaviorID = -1; - if (command == "sendBehaviorListToClient") - SendBehaviorListToClient(modelEntity, sysAddr, modelOwner); - else if (command == "modelTypeChanged") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "toggleExecutionUpdates") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "addStrip") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "removeStrip") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "mergeStrips") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "splitStrip") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "updateStripUI") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "addAction") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "migrateActions") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "rearrangeStrip") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "add") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "removeActions") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "rename") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "sendBehaviorBlocksToClient") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "moveToInventory") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else if (command == "updateAction") - Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str()); - else - Game::logger->Log("ControlBehaviors", "Unknown behavior command (%s)\n", command.c_str()); + if (behaviorIDValue) { + behaviorID = std::stoul(behaviorIDValue->GetStringValue()); + } else if (arguments->FindValue(key) == nullptr){ + throw std::invalid_argument("Unable to find behavior ID from argument \"" + key + "\""); + } + + return behaviorID; } -void ControlBehaviors::SendBehaviorListToClient( +BEHAVIORSTATE GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key = "stateID") { + auto* stateIDValue = arguments->FindValue(key); + if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); + + BEHAVIORSTATE stateID = static_cast(stateIDValue->GetDoubleValue()); + + return stateID; +} + +STRIPID GetStripIDFromArgument(AMFArrayValue* arguments, const std::string& key = "stripID") { + auto* stripIDValue = arguments->FindValue(key); + if (!stripIDValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); + + STRIPID stripID = static_cast(stripIDValue->GetDoubleValue()); + + return stripID; +} + +void RequestUpdatedID(int32_t behaviorID, ModelComponent* modelComponent, Entity* modelOwner, const SystemAddress& sysAddr) { + // auto behavior = modelComponent->FindBehavior(behaviorID); + // if (behavior->GetBehaviorID() == -1 || behavior->GetShouldSetNewID()) { + // ObjectIDManager::Instance()->RequestPersistentID( + // [behaviorID, behavior, modelComponent, modelOwner, sysAddr](uint32_t persistentId) { + // behavior->SetShouldGetNewID(false); + // behavior->SetIsTemplated(false); + // behavior->SetBehaviorID(persistentId); + + // // This updates the behavior ID of the behavior should this be a new behavior + // AMFArrayValue args; + + // AMFStringValue* behaviorIDString = new AMFStringValue(); + // behaviorIDString->SetStringValue(std::to_string(persistentId)); + // args.InsertValue("behaviorID", behaviorIDString); + + // AMFStringValue* objectIDAsString = new AMFStringValue(); + // objectIDAsString->SetStringValue(std::to_string(modelComponent->GetParent()->GetObjectID())); + // args.InsertValue("objectID", objectIDAsString); + + // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorID", &args); + // ControlBehaviors::SendBehaviorListToClient(modelComponent->GetParent(), sysAddr, modelOwner); + // }); + // } +} + +void SendBehaviorListToClient( Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner @@ -57,7 +74,7 @@ void ControlBehaviors::SendBehaviorListToClient( if (!modelComponent) return; - AMFArrayValue behaviorsToSerialize; + AMFArrayValue behaviorsToSerialize; AMFArrayValue* behaviors = new AMFArrayValue(); // Empty for now @@ -79,3 +96,506 @@ void ControlBehaviors::SendBehaviorListToClient( behaviorsToSerialize.InsertValue("objectID", amfStringValueForObjectID); GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", &behaviorsToSerialize); } + +void ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) { + auto* modelTypeAmf = arguments->FindValue("ModelType"); + if (!modelTypeAmf) return; + + uint32_t modelType = static_cast(modelTypeAmf->GetDoubleValue()); + + //TODO Update the model type here +} + +void ToggleExecutionUpdates() { + //TODO do something with this info +} + +void AddStrip(AMFArrayValue* arguments) { + auto* strip = arguments->FindValue("strip"); + if (!strip) return; + + auto* actions = strip->FindValue("actions"); + if (!actions) return; + + auto* uiArray = arguments->FindValue("ui"); + if (!uiArray) return; + + auto* xPositionValue = uiArray->FindValue("x"); + if (!xPositionValue) return; + + double xPosition = xPositionValue->GetDoubleValue(); + + auto* yPositionValue = uiArray->FindValue("y"); + if (!yPositionValue) return; + + double yPosition = yPositionValue->GetDoubleValue(); + + STRIPID stripID = GetStripIDFromArgument(arguments); + + BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + std::string type = ""; + std::string valueParameterName = ""; + std::string valueParameterString = ""; + double valueParameterDouble = 0.0; + for (uint32_t position = 0; position < actions->GetDenseValueSize(); position++) { + auto* actionAsArray = actions->GetValueAt(position); + if (!actionAsArray) continue; + + for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { + if (typeValueMap.first == "Type") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + + type = static_cast(typeValueMap.second)->GetStringValue(); + } else { + valueParameterName = typeValueMap.first; + // Message is the only known string parameter + if (valueParameterName == "Message") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + valueParameterString = static_cast(typeValueMap.second)->GetStringValue(); + } else { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; + valueParameterDouble = static_cast(typeValueMap.second)->GetDoubleValue(); + } + } + } + // modelComponent->AddStrip(stateID, stripID, type, behaviorID, valueParameterName, valueParameterString, valueParameterDouble, "", xPosition, yPosition); + type.clear(); + valueParameterName.clear(); + valueParameterString.clear(); + valueParameterDouble = 0.0; + } + // RequestUpdatedID(behaviorID); +} + +void RemoveStrip(AMFArrayValue* arguments) { + STRIPID stripID = GetStripIDFromArgument(arguments); + + BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + // modelComponent->RemoveStrip(stateID, stripID, behaviorID); + + // RequestUpdatedID(behaviorID); +} + +void MergeStrips(AMFArrayValue* arguments) { + STRIPID srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); + + BEHAVIORSTATE dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); + + BEHAVIORSTATE srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); + + auto* dstActionIndexValue = arguments->FindValue("dstActionIndex"); + if (!dstActionIndexValue) return; + + uint32_t dstActionIndex = static_cast(dstActionIndexValue->GetDoubleValue()); + + STRIPID dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + // modelComponent->MergeStrips(srcStripID, dstStripID, srcStateID, dstStateID, behaviorID, dstActionIndex); + + // RequestUpdatedID(behaviorID); +} + +void SplitStrip(AMFArrayValue* arguments) { + auto* srcActionIndexValue = arguments->FindValue("srcActionIndex"); + if (!srcActionIndexValue) return; + + uint32_t srcActionIndex = static_cast(srcActionIndexValue->GetDoubleValue()); + + STRIPID srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); + + BEHAVIORSTATE srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); + + STRIPID dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); + + BEHAVIORSTATE dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); + + auto* dstStripUIArray = arguments->FindValue("dstStripUI"); + if (!dstStripUIArray) return; + + auto* xPositionValue = dstStripUIArray->FindValue("x"); + auto* yPositionValue = dstStripUIArray->FindValue("y"); + if (!xPositionValue || !yPositionValue) return; + + // x and y position 15 are just where the game puts the strip by default if none is given. + double yPosition = yPositionValue->GetDoubleValue(); + double xPosition = xPositionValue->GetDoubleValue(); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + // modelComponent->SplitStrip(srcActionIndex, srcStripID, srcStateID, dstStripID, dstStateID, behaviorID, yPosition, xPosition); + + // RequestUpdatedID(behaviorID); +} + +void UpdateStripUI(AMFArrayValue* arguments) { + auto* uiArray = arguments->FindValue("ui"); + if (!uiArray) return; + + auto* xPositionValue = uiArray->FindValue("x"); + auto* yPositionValue = uiArray->FindValue("y"); + if (!xPositionValue || !yPositionValue) return; + + double yPosition = yPositionValue->GetDoubleValue(); + double xPosition = xPositionValue->GetDoubleValue(); + + STRIPID stripID = GetStripIDFromArgument(arguments); + + BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + // modelComponent->UpdateUIOfStrip(stateID, stripID, xPosition, yPosition, behaviorID); + + // RequestUpdatedID(behaviorID); +} + +void AddAction(AMFArrayValue* arguments) { + auto* actionIndexAmf = arguments->FindValue("actionIndex"); + if (!actionIndexAmf) return; + + uint32_t actionIndex = static_cast(actionIndexAmf->GetDoubleValue()); + + STRIPID stripID = GetStripIDFromArgument(arguments); + + BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); + + std::string type = ""; + std::string valueParameterName = ""; + std::string valueParameterString = ""; + double valueParameterDouble = 0.0; + auto* action = arguments->FindValue("action"); + if (!action) return; + + for (auto& typeValueMap : action->GetAssociativeMap()) { + if (typeValueMap.first == "Type") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + type = static_cast(typeValueMap.second)->GetStringValue(); + } else { + valueParameterName = typeValueMap.first; + // Message is the only known string parameter + if (valueParameterName == "Message") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + valueParameterString = static_cast(typeValueMap.second)->GetStringValue(); + } else { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; + valueParameterDouble = static_cast(typeValueMap.second)->GetDoubleValue(); + } + } + } + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + // modelComponent->AddAction(stateID, stripID, type, valueParameterName, valueParameterString, valueParameterDouble, "", actionIndex, behaviorID); + + // RequestUpdatedID(behaviorID); +} + +void MigrateActions(AMFArrayValue* arguments) { + auto* srcActionIndexAmf = arguments->FindValue("srcActionIndex"); + if (!srcActionIndexAmf) return; + + uint32_t srcActionIndex = static_cast(srcActionIndexAmf->GetDoubleValue()); + + STRIPID srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); + + BEHAVIORSTATE srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); + + auto* dstActionIndexAmf = arguments->FindValue("dstActionIndex"); + if (!dstActionIndexAmf) return; + + uint32_t dstActionIndex = static_cast(dstActionIndexAmf->GetDoubleValue()); + + STRIPID dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); + + BEHAVIORSTATE dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + // modelComponent->MigrateActions(srcActionIndex, srcStripID, srcStateID, dstActionIndex, dstStripID, dstStateID, behaviorID); + + // RequestUpdatedID(behaviorID); +} + +void RearrangeStrip(AMFArrayValue* arguments) { + auto* srcActionIndexValue = arguments->FindValue("srcActionIndex"); + uint32_t srcActionIndex = static_cast(srcActionIndexValue->GetDoubleValue()); + + uint32_t stripID = GetStripIDFromArgument(arguments); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* dstActionIndexValue = arguments->FindValue("dstActionIndex"); + uint32_t dstActionIndex = static_cast(dstActionIndexValue->GetDoubleValue()); + + BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); + + // modelComponent->RearrangeStrip(stateID, stripID, srcActionIndex, dstActionIndex, behaviorID); + + // RequestUpdatedID(behaviorID); +} + +void Add(AMFArrayValue* arguments) { + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + uint32_t behaviorIndex = 0; + auto* behaviorIndexAmf = arguments->FindValue("BehaviorIndex"); + + if (!behaviorIndexAmf) return; + + behaviorIndex = static_cast(behaviorIndexAmf->GetDoubleValue()); + + // modelComponent->AddBehavior(behaviorID, behaviorIndex, modelOwner); + + // SendBehaviorListToClient(); +} + +void RemoveActions(AMFArrayValue* arguments) { + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* actionIndexAmf = arguments->FindValue("actionIndex"); + if (!actionIndexAmf) return; + + uint32_t actionIndex = static_cast(actionIndexAmf->GetDoubleValue()); + + STRIPID stripID = GetStripIDFromArgument(arguments); + + BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); + + // modelComponent->RemoveAction(stateID, stripID, actionIndex, behaviorID); + + // RequestUpdatedID(behaviorID); +} + +void Rename(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* nameAmf = arguments->FindValue("Name"); + if (!nameAmf) return; + + auto name = nameAmf->GetStringValue(); + + // modelComponent->Rename(behaviorID, name); + + SendBehaviorListToClient(modelEntity, sysAddr, modelOwner); + + // RequestUpdatedID(behaviorID); +} + +// TODO This is also supposed to serialize the state of the behaviors in progress but those aren't implemented yet +void SendBehaviorBlocksToClient(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + // auto modelBehavior = modelComponent->FindBehavior(behaviorID); + + // if (!modelBehavior) return; + + // modelBehavior->VerifyStates(); + + // auto states = modelBehavior->GetBehaviorStates(); + + // // Begin serialization. + + // /** + // * for each state + // * strip id + // * ui info + // * x + // * y + // * actions + // * action1 + // * action2 + // * ... + // * behaviorID of strip + // * objectID of strip + // */ + // LWOOBJID targetObjectID = LWOOBJID_EMPTY; + // behaviorID = 0; + // AMFArrayValue behaviorInfo; + + // AMFArrayValue* stateSerialize = new AMFArrayValue(); + + // for (auto it = states.begin(); it != states.end(); it++) { + // Game::logger->Log("PropertyBehaviors", "Begin serialization of state %i!\n", it->first); + // AMFArrayValue* state = new AMFArrayValue(); + + // AMFDoubleValue* stateAsDouble = new AMFDoubleValue(); + // stateAsDouble->SetDoubleValue(it->first); + // state->InsertValue("id", stateAsDouble); + + // AMFArrayValue* strips = new AMFArrayValue(); + // auto stripsInState = it->second->GetStrips(); + // for (auto strip = stripsInState.begin(); strip != stripsInState.end(); strip++) { + // Game::logger->Log("PropertyBehaviors", "Begin serialization of strip %i!\n", strip->first); + // AMFArrayValue* thisStrip = new AMFArrayValue(); + + // AMFDoubleValue* stripID = new AMFDoubleValue(); + // stripID->SetDoubleValue(strip->first); + // thisStrip->InsertValue("id", stripID); + + // AMFArrayValue* uiArray = new AMFArrayValue(); + // AMFDoubleValue* yPosition = new AMFDoubleValue(); + // yPosition->SetDoubleValue(strip->second->GetYPosition()); + // uiArray->InsertValue("y", yPosition); + + // AMFDoubleValue* xPosition = new AMFDoubleValue(); + // xPosition->SetDoubleValue(strip->second->GetXPosition()); + // uiArray->InsertValue("x", xPosition); + + // thisStrip->InsertValue("ui", uiArray); + // targetObjectID = modelComponent->GetParent()->GetObjectID(); + // behaviorID = modelBehavior->GetBehaviorID(); + + // AMFArrayValue* stripSerialize = new AMFArrayValue(); + // for (auto behaviorAction : strip->second->GetActions()) { + // Game::logger->Log("PropertyBehaviors", "Begin serialization of action %s!\n", behaviorAction->actionName.c_str()); + // AMFArrayValue* thisAction = new AMFArrayValue(); + + // AMFStringValue* actionName = new AMFStringValue(); + // actionName->SetStringValue(behaviorAction->actionName); + // thisAction->InsertValue("Type", actionName); + + // if (behaviorAction->parameterValueString != "") + // { + // AMFStringValue* valueAsString = new AMFStringValue(); + // valueAsString->SetStringValue(behaviorAction->parameterValueString); + // thisAction->InsertValue(behaviorAction->parameterName, valueAsString); + // } + // else if (behaviorAction->parameterValueDouble != 0.0) + // { + // AMFDoubleValue* valueAsDouble = new AMFDoubleValue(); + // valueAsDouble->SetDoubleValue(behaviorAction->parameterValueDouble); + // thisAction->InsertValue(behaviorAction->parameterName, valueAsDouble); + // } + // stripSerialize->PushBackValue(thisAction); + // } + // thisStrip->InsertValue("actions", stripSerialize); + // strips->PushBackValue(thisStrip); + // } + // state->InsertValue("strips", strips); + // stateSerialize->PushBackValue(state); + // } + // behaviorInfo.InsertValue("states", stateSerialize); + + // AMFStringValue* objectidAsString = new AMFStringValue(); + // objectidAsString->SetStringValue(std::to_string(targetObjectID)); + // behaviorInfo.InsertValue("objectID", objectidAsString); + + // AMFStringValue* behaviorIDAsString = new AMFStringValue(); + // behaviorIDAsString->SetStringValue(std::to_string(behaviorID)); + // behaviorInfo.InsertValue("BehaviorID", behaviorIDAsString); + + // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorBlocks", &behaviorInfo); +} + +void UpdateAction(AMFArrayValue* arguments) { + std::string type = ""; + std::string valueParameterName = ""; + std::string valueParameterString = ""; + double valueParameterDouble = 0.0; + auto* actionAsArray = arguments->FindValue("action"); + if (!actionAsArray) return; + for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { + if (typeValueMap.first == "Type") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + type = static_cast(typeValueMap.second)->GetStringValue(); + } else { + valueParameterName = typeValueMap.first; + // Message is the only known string parameter + if (valueParameterName == "Message") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + valueParameterString = static_cast(typeValueMap.second)->GetStringValue(); + } else { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; + valueParameterDouble = static_cast(typeValueMap.second)->GetDoubleValue(); + } + } + } + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* actionIndexValue = arguments->FindValue("actionIndex"); + if (!actionIndexValue) return; + + uint32_t actionIndex = static_cast(actionIndexValue->GetDoubleValue()); + + STRIPID stripID = GetStripIDFromArgument(arguments); + + BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); + + // modelComponent->UpdateAction(stateID, stripID, type, valueParameterName, valueParameterString, valueParameterDouble, "", actionIndex, behaviorID); + + // RequestUpdatedID(behaviorID); +} + +void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { + // This closes the UI menu should it be open while the player is removing behaviors + AMFArrayValue args; + + AMFFalseValue* stateToPop = new AMFFalseValue(); + args.InsertValue("visible", stateToPop); + + GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "ToggleBehaviorEditor", &args); + + uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* behaviorIndexValue = arguments->FindValue("BehaviorIndex"); + if (!behaviorIndexValue) return; + + uint32_t behaviorIndex = static_cast(behaviorIndexValue->GetDoubleValue()); + + // modelComponent->MoveBehaviorToInventory(behaviorID, behaviorIndex, modelOwner); + + SendBehaviorListToClient(modelComponent->GetParent(), sysAddr, modelOwner); +} + +void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) { + if (!modelEntity || !modelOwner || !arguments) return; + auto* modelComponent = modelEntity->GetComponent(); + + if (!modelComponent) return; + + if (command == "sendBehaviorListToClient") + SendBehaviorListToClient(modelEntity, sysAddr, modelOwner); + else if (command == "modelTypeChanged") + ModelTypeChanged(arguments, modelComponent); + else if (command == "toggleExecutionUpdates") + ToggleExecutionUpdates(); + else if (command == "addStrip") + AddStrip(arguments); + else if (command == "removeStrip") + RemoveStrip(arguments); + else if (command == "mergeStrips") + MergeStrips(arguments); + else if (command == "splitStrip") + SplitStrip(arguments); + else if (command == "updateStripUI") + UpdateStripUI(arguments); + else if (command == "addAction") + AddAction(arguments); + else if (command == "migrateActions") + MigrateActions(arguments); + else if (command == "rearrangeStrip") + RearrangeStrip(arguments); + else if (command == "add") + Add(arguments); + else if (command == "removeActions") + RemoveActions(arguments); + else if (command == "rename") + Rename(modelEntity, sysAddr, modelOwner, arguments); + else if (command == "sendBehaviorBlocksToClient") + SendBehaviorBlocksToClient(modelComponent, sysAddr, modelOwner, arguments); + else if (command == "moveToInventory") + MoveToInventory(modelComponent, sysAddr, modelOwner, arguments); + else if (command == "updateAction") + UpdateAction(arguments); + else + Game::logger->Log("ControlBehaviors", "Unknown behavior command (%s)\n", command.c_str()); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index 7c24da68..d487f929 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -9,6 +9,7 @@ class Entity; class AMFArrayValue; +class ModelComponent; namespace ControlBehaviors { /** @@ -21,15 +22,6 @@ namespace ControlBehaviors { * @param modelOwner The owner of the model which sent this command */ void ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner); - - /** - * @brief Helper function to send the behavior list to the client - * - * @param modelEntity The model that sent this command - * @param sysAddr The SystemAddress to respond to - * @param modelOwner The owner of the model which sent this command - */ - void SendBehaviorListToClient(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner); }; #endif //!__CONTROLBEHAVIORS__H__ From f8f5b731f189a1a31ceecbb5256bfc4a3da08ed7 Mon Sep 17 00:00:00 2001 From: Jonathan Romano Date: Sun, 27 Nov 2022 06:59:59 -0500 Subject: [PATCH 022/166] Allow servers to be run from directories other than `build`. Read/write files relative to binary instead of cwd (#834) Allows the server to be run from a non-build directory. Also only read or write files relative to the build directory, regardless of where the server is run from --- dAuthServer/AuthServer.cpp | 3 +- dChatServer/ChatServer.cpp | 14 +++-- dCommon/BinaryPathFinder.cpp | 71 ++++++++++++++++++++++++ dCommon/BinaryPathFinder.h | 15 +++++ dCommon/CMakeLists.txt | 1 + dCommon/dClient/AssetManager.cpp | 8 ++- dCommon/dClient/AssetManager.h | 2 +- dCommon/dConfig.cpp | 5 +- dDatabase/MigrationRunner.cpp | 7 ++- dGame/dUtilities/SlashCommandHandler.cpp | 3 +- dGame/dUtilities/VanityUtilities.cpp | 5 +- dGame/dUtilities/dLocale.cpp | 3 +- dMasterServer/InstanceManager.cpp | 11 ++-- dMasterServer/MasterServer.cpp | 40 +++++++------ dNavigation/dNavMesh.cpp | 3 +- dWorldServer/WorldServer.cpp | 13 +++-- 16 files changed, 158 insertions(+), 46 deletions(-) create mode 100644 dCommon/BinaryPathFinder.cpp create mode 100644 dCommon/BinaryPathFinder.h diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 73cb4212..9621f683 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -11,6 +11,7 @@ #include "Database.h" #include "dConfig.h" #include "Diagnostics.h" +#include "BinaryPathFinder.h" //RakNet includes: #include "RakNetDefines.h" @@ -150,7 +151,7 @@ int main(int argc, char** argv) { } dLogger* SetupLogger() { - std::string logPath = "./logs/AuthServer_" + std::to_string(time(nullptr)) + ".log"; + std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/AuthServer_" + std::to_string(time(nullptr)) + ".log")).string(); bool logToConsole = false; bool logDebugStatements = false; #ifdef _DEBUG diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index fc8bdd5b..e0073747 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -13,6 +13,7 @@ #include "dChatFilter.h" #include "Diagnostics.h" #include "AssetManager.h" +#include "BinaryPathFinder.h" #include "PlayerContainer.h" #include "ChatPacketHandler.h" @@ -53,9 +54,14 @@ int main(int argc, char** argv) { Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); try { - std::string client_path = config.GetValue("client_location"); - if (client_path.empty()) client_path = "./res"; - Game::assetManager = new AssetManager(client_path); + std::string clientPathStr = config.GetValue("client_location"); + if (clientPathStr.empty()) clientPathStr = "./res"; + std::filesystem::path clientPath = std::filesystem::path(clientPathStr); + if (clientPath.is_relative()) { + clientPath = BinaryPathFinder::GetBinaryDir() / clientPath; + } + + Game::assetManager = new AssetManager(clientPath); } catch (std::runtime_error& ex) { Game::logger->Log("ChatServer", "Got an error while setting up assets: %s", ex.what()); @@ -167,7 +173,7 @@ int main(int argc, char** argv) { } dLogger* SetupLogger() { - std::string logPath = "./logs/ChatServer_" + std::to_string(time(nullptr)) + ".log"; + std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/ChatServer_" + std::to_string(time(nullptr)) + ".log")).string(); bool logToConsole = false; bool logDebugStatements = false; #ifdef _DEBUG diff --git a/dCommon/BinaryPathFinder.cpp b/dCommon/BinaryPathFinder.cpp new file mode 100644 index 00000000..b1c2afef --- /dev/null +++ b/dCommon/BinaryPathFinder.cpp @@ -0,0 +1,71 @@ +#include +#include +#include "BinaryPathFinder.h" +#include "dPlatforms.h" + +#if defined(DARKFLAME_PLATFORM_WIN32) +#include +#elif defined(DARKFLAME_PLATFORM_MACOS) || defined(DARKFLAME_PLATFORM_IOS) +#include +#elif defined(DARKFLAME_PLATFORM_FREEBSD) +#include +#include +#include +#endif + +std::filesystem::path BinaryPathFinder::binaryDir; + +std::filesystem::path BinaryPathFinder::GetBinaryDir() { + if (!binaryDir.empty()) { + return binaryDir; + } + + std::string pathStr; + + // Derived from boost::dll::program_location, licensed under the Boost Software License: http://www.boost.org/LICENSE_1_0.txt +#if defined(DARKFLAME_PLATFORM_WIN32) + char path[MAX_PATH]; + GetModuleFileName(NULL, path, MAX_PATH); + pathStr = std::string(path); +#elif defined(DARKFLAME_PLATFORM_MACOS) || defined(DARKFLAME_PLATFORM_IOS) + char path[1024]; + uint32_t size = sizeof(path); + if (_NSGetExecutablePath(path, &size) == 0) { + pathStr = std::string(path); + } else { + // The filepath size is greater than our initial buffer size, so try again with the size + // that _NSGetExecutablePath told us it actually is + char *p = new char[size]; + if (_NSGetExecutablePath(p, &size) != 0) { + throw std::runtime_error("Failed to get binary path from _NSGetExecutablePath"); + } + + pathStr = std::string(p); + delete[] p; + } +#elif defined(DARKFLAME_PLATFORM_FREEBSD) + int mib[4]; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + char buf[10240]; + size_t cb = sizeof(buf); + sysctl(mib, 4, buf, &cb, NULL, 0); + pathStr = std::string(buf); +#else // DARKFLAME_PLATFORM_LINUX || DARKFLAME_PLATFORM_UNIX || DARKFLAME_PLATFORM_ANDROID + pathStr = std::filesystem::read_symlink("/proc/self/exe"); +#endif + + // Some methods like _NSGetExecutablePath could return a symlink + // Either way, we need to get the parent path because we want the directory, not the binary itself + // We also ensure that it is an absolute path so that it is valid if we need to construct a path + // to exucute on unix systems (eg sudo BinaryPathFinder::GetBinaryDir() / WorldServer) + if (std::filesystem::is_symlink(pathStr)) { + binaryDir = std::filesystem::absolute(std::filesystem::read_symlink(pathStr).parent_path()); + } else { + binaryDir = std::filesystem::absolute(std::filesystem::path(pathStr).parent_path()); + } + + return binaryDir; +} diff --git a/dCommon/BinaryPathFinder.h b/dCommon/BinaryPathFinder.h new file mode 100644 index 00000000..c4ca6da2 --- /dev/null +++ b/dCommon/BinaryPathFinder.h @@ -0,0 +1,15 @@ +#pragma once + +#ifndef __BINARYPATHFINDER__H__ +#define __BINARYPATHFINDER__H__ + +#include + +class BinaryPathFinder { +private: + static std::filesystem::path binaryDir; +public: + static std::filesystem::path GetBinaryDir(); +}; + +#endif //!__BINARYPATHFINDER__H__ diff --git a/dCommon/CMakeLists.txt b/dCommon/CMakeLists.txt index 46102b74..8d02186b 100644 --- a/dCommon/CMakeLists.txt +++ b/dCommon/CMakeLists.txt @@ -15,6 +15,7 @@ set(DCOMMON_SOURCES "AMFFormat.cpp" "Type.cpp" "ZCompression.cpp" "BrickByBrickFix.cpp" + "BinaryPathFinder.cpp" ) add_subdirectory(dClient) diff --git a/dCommon/dClient/AssetManager.cpp b/dCommon/dClient/AssetManager.cpp index 349b5271..dc3db0a1 100644 --- a/dCommon/dClient/AssetManager.cpp +++ b/dCommon/dClient/AssetManager.cpp @@ -1,15 +1,17 @@ +#include + #include "AssetManager.h" #include "Game.h" #include "dLogger.h" #include -AssetManager::AssetManager(const std::string& path) { +AssetManager::AssetManager(const std::filesystem::path& path) { if (!std::filesystem::is_directory(path)) { - throw std::runtime_error("Attempted to load asset bundle (" + path + ") however it is not a valid directory."); + throw std::runtime_error("Attempted to load asset bundle (" + path.string() + ") however it is not a valid directory."); } - m_Path = std::filesystem::path(path); + m_Path = path; if (std::filesystem::exists(m_Path / "client") && std::filesystem::exists(m_Path / "versions")) { m_AssetBundleType = eAssetBundleType::Packed; diff --git a/dCommon/dClient/AssetManager.h b/dCommon/dClient/AssetManager.h index 87653845..73b24f18 100644 --- a/dCommon/dClient/AssetManager.h +++ b/dCommon/dClient/AssetManager.h @@ -48,7 +48,7 @@ struct AssetMemoryBuffer : std::streambuf { class AssetManager { public: - AssetManager(const std::string& path); + AssetManager(const std::filesystem::path& path); ~AssetManager(); std::filesystem::path GetResPath(); diff --git a/dCommon/dConfig.cpp b/dCommon/dConfig.cpp index c22c91cc..1bc940e8 100644 --- a/dCommon/dConfig.cpp +++ b/dCommon/dConfig.cpp @@ -1,9 +1,10 @@ #include "dConfig.h" #include +#include "BinaryPathFinder.h" dConfig::dConfig(const std::string& filepath) { m_EmptyString = ""; - std::ifstream in(filepath); + std::ifstream in(BinaryPathFinder::GetBinaryDir() / filepath); if (!in.good()) return; std::string line; @@ -13,7 +14,7 @@ dConfig::dConfig(const std::string& filepath) { } } - std::ifstream sharedConfig("sharedconfig.ini", std::ios::in); + std::ifstream sharedConfig(BinaryPathFinder::GetBinaryDir() / "sharedconfig.ini", std::ios::in); if (!sharedConfig.good()) return; while (std::getline(sharedConfig, line)) { diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index 25312608..fe0f933a 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -6,12 +6,13 @@ #include "Game.h" #include "GeneralUtils.h" #include "dLogger.h" +#include "BinaryPathFinder.h" #include Migration LoadMigration(std::string path) { Migration migration{}; - std::ifstream file("./migrations/" + path); + std::ifstream file(BinaryPathFinder::GetBinaryDir() / "migrations/" / path); if (file.is_open()) { std::string line; @@ -37,7 +38,7 @@ void MigrationRunner::RunMigrations() { sql::SQLString finalSQL = ""; bool runSd0Migrations = false; - for (const auto& entry : GeneralUtils::GetFileNamesFromFolder("./migrations/dlu/")) { + for (const auto& entry : GeneralUtils::GetFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "./migrations/dlu/").string())) { auto migration = LoadMigration("dlu/" + entry); if (migration.data.empty()) { @@ -97,7 +98,7 @@ void MigrationRunner::RunSQLiteMigrations() { stmt->execute(); delete stmt; - for (const auto& entry : GeneralUtils::GetFileNamesFromFolder("./migrations/cdserver/")) { + for (const auto& entry : GeneralUtils::GetFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "migrations/cdserver/").string())) { auto migration = LoadMigration("cdserver/" + entry); if (migration.data.empty()) continue; diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 8f4ac1a8..2f4d9211 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -64,6 +64,7 @@ #include "ScriptedActivityComponent.h" #include "LevelProgressionComponent.h" #include "AssetManager.h" +#include "BinaryPathFinder.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; @@ -248,7 +249,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "credits" || chatCommand == "info") { - const auto& customText = chatCommand == "credits" ? VanityUtilities::ParseMarkdown("./vanity/CREDITS.md") : VanityUtilities::ParseMarkdown("./vanity/INFO.md"); + const auto& customText = chatCommand == "credits" ? VanityUtilities::ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/CREDITS.md").string()) : VanityUtilities::ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/INFO.md").string()); { AMFArrayValue args; diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 733d94c4..3a1259a2 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -13,6 +13,7 @@ #include "tinyxml2.h" #include "Game.h" #include "dLogger.h" +#include "BinaryPathFinder.h" #include @@ -27,7 +28,7 @@ void VanityUtilities::SpawnVanity() { const uint32_t zoneID = Game::server->GetZoneID(); - ParseXML("./vanity/NPC.xml"); + ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/NPC.xml").string()); // Loop through all parties for (const auto& party : m_Parties) { @@ -131,7 +132,7 @@ void VanityUtilities::SpawnVanity() { info.spawnerID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); info.settings = { new LDFData(u"hasCustomText", true), - new LDFData(u"customText", ParseMarkdown("./vanity/TESTAMENT.md")) }; + new LDFData(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string())) }; auto* entity = EntityManager::Instance()->CreateEntity(info); diff --git a/dGame/dUtilities/dLocale.cpp b/dGame/dUtilities/dLocale.cpp index 65ef3a58..de65511b 100644 --- a/dGame/dUtilities/dLocale.cpp +++ b/dGame/dUtilities/dLocale.cpp @@ -9,13 +9,14 @@ #include "tinyxml2.h" #include "Game.h" #include "dConfig.h" +#include "BinaryPathFinder.h" dLocale::dLocale() { if (Game::config->GetValue("locale_enabled") != "1") { return; } - std::ifstream file(m_LocalePath); + std::ifstream file(BinaryPathFinder::GetBinaryDir() / m_LocalePath); if (!file.good()) { return; diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index 0c605ed6..83378dbb 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -10,6 +10,7 @@ #include "dMessageIdentifiers.h" #include "MasterPackets.h" #include "PacketUtils.h" +#include "BinaryPathFinder.h" InstanceManager::InstanceManager(dLogger* logger, const std::string& externalIP) { mLogger = logger; @@ -48,13 +49,13 @@ Instance* InstanceManager::GetInstance(LWOMAPID mapID, bool isFriendTransfer, LW //Start the actual process: #ifdef _WIN32 - std::string cmd = "start ./WorldServer.exe -zone "; + std::string cmd = "start " + (BinaryPathFinder::GetBinaryDir() / "WorldServer.exe").string() + " -zone "; #else std::string cmd; if (std::atoi(Game::config->GetValue("use_sudo_world").c_str())) { - cmd = "sudo ./WorldServer -zone "; + cmd = "sudo " + (BinaryPathFinder::GetBinaryDir() / "WorldServer").string() + " -zone "; } else { - cmd = "./WorldServer -zone "; + cmd = (BinaryPathFinder::GetBinaryDir() / "WorldServer").string() + " -zone "; } #endif @@ -300,10 +301,10 @@ Instance* InstanceManager::CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID clon instance = new Instance(mExternalIP, port, mapID, ++m_LastInstanceID, cloneID, maxPlayers, maxPlayers, true, password); //Start the actual process: - std::string cmd = "start ./WorldServer.exe -zone "; + std::string cmd = "start " + (BinaryPathFinder::GetBinaryDir() / "WorldServer").string() + " -zone "; #ifndef _WIN32 - cmd = "./WorldServer -zone "; + cmd = (BinaryPathFinder::GetBinaryDir() / "WorldServer").string() + " -zone "; #endif cmd.append(std::to_string(mapID)); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 061a91c7..34e2f71a 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -26,6 +26,7 @@ #include "dLogger.h" #include "dServer.h" #include "AssetManager.h" +#include "BinaryPathFinder.h" //RakNet includes: #include "RakNetDefines.h" @@ -102,9 +103,14 @@ int main(int argc, char** argv) { } try { - std::string client_path = config.GetValue("client_location"); - if (client_path.empty()) client_path = "./res"; - Game::assetManager = new AssetManager(client_path); + std::string clientPathStr = config.GetValue("client_location"); + if (clientPathStr.empty()) clientPathStr = "./res"; + std::filesystem::path clientPath = std::filesystem::path(clientPathStr); + if (clientPath.is_relative()) { + clientPath = BinaryPathFinder::GetBinaryDir() / clientPath; + } + + Game::assetManager = new AssetManager(clientPath); } catch (std::runtime_error& ex) { Game::logger->Log("MasterServer", "Got an error while setting up assets: %s", ex.what()); @@ -127,18 +133,16 @@ int main(int argc, char** argv) { stmt->executeUpdate(); delete stmt; - std::string res = "python3 ../thirdparty/docker-utils/utils/fdb_to_sqlite.py " + (Game::assetManager->GetResPath() / "cdclient.fdb").string(); + std::string res = "python3 " + + (BinaryPathFinder::GetBinaryDir() / "../thirdparty/docker-utils/utils/fdb_to_sqlite.py").string() + + " --sqlite_path " + (Game::assetManager->GetResPath() / "CDServer.sqlite").string() + + " " + (Game::assetManager->GetResPath() / "cdclient.fdb").string(); int result = system(res.c_str()); if (result != 0) { Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite"); return EXIT_FAILURE; } - - if (std::rename("./cdclient.sqlite", (Game::assetManager->GetResPath() / "CDServer.sqlite").string().c_str()) != 0) { - Game::logger->Log("MasterServer", "Failed to move cdclient file."); - return EXIT_FAILURE; - } } //Connect to CDClient @@ -363,7 +367,7 @@ int main(int argc, char** argv) { dLogger* SetupLogger() { std::string logPath = - "./logs/MasterServer_" + std::to_string(time(nullptr)) + ".log"; + (BinaryPathFinder::GetBinaryDir() / ("logs/MasterServer_" + std::to_string(time(nullptr)) + ".log")).string(); bool logToConsole = false; bool logDebugStatements = false; #ifdef _DEBUG @@ -738,28 +742,28 @@ void HandlePacket(Packet* packet) { void StartChatServer() { #ifdef __APPLE__ //macOS doesn't need sudo to run on ports < 1024 - system("./ChatServer&"); + system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); #elif _WIN32 - system("start ./ChatServer.exe"); + system(("start " + (BinaryPathFinder::GetBinaryDir() / "ChatServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_chat").c_str())) { - system("sudo ./ChatServer&"); + system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } else { - system("./ChatServer&"); + system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } #endif } void StartAuthServer() { #ifdef __APPLE__ - system("./AuthServer&"); + system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); #elif _WIN32 - system("start ./AuthServer.exe"); + system(("start " + (BinaryPathFinder::GetBinaryDir() / "AuthServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_auth").c_str())) { - system("sudo ./AuthServer&"); + system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } else { - system("./AuthServer&"); + system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } #endif } diff --git a/dNavigation/dNavMesh.cpp b/dNavigation/dNavMesh.cpp index e5ba0129..fdba4a2d 100644 --- a/dNavigation/dNavMesh.cpp +++ b/dNavigation/dNavMesh.cpp @@ -7,6 +7,7 @@ #include "dPlatforms.h" #include "NiPoint3.h" #include "BinaryIO.h" +#include "BinaryPathFinder.h" #include "dZoneManager.h" @@ -43,7 +44,7 @@ dNavMesh::~dNavMesh() { void dNavMesh::LoadNavmesh() { - std::string path = "./navmeshes/" + std::to_string(m_ZoneId) + ".bin"; + std::string path = (BinaryPathFinder::GetBinaryDir() / "navmeshes/" / (std::to_string(m_ZoneId) + ".bin")).string(); if (!BinaryIO::DoesFileExist(path)) { return; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index d4e55cb5..b7d7cc14 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -17,6 +17,7 @@ #include "Metrics.hpp" #include "PerformanceManager.h" #include "Diagnostics.h" +#include "BinaryPathFinder.h" //RakNet includes: #include "RakNetDefines.h" @@ -146,9 +147,13 @@ int main(int argc, char** argv) { if (config.GetValue("disable_chat") == "1") chatDisabled = true; try { - std::string client_path = config.GetValue("client_location"); - if (client_path.empty()) client_path = "./res"; - Game::assetManager = new AssetManager(client_path); + std::string clientPathStr = config.GetValue("client_location"); + if (clientPathStr.empty()) clientPathStr = "./res"; + std::filesystem::path clientPath = std::filesystem::path(clientPathStr); + if (clientPath.is_relative()) { + clientPath = BinaryPathFinder::GetBinaryDir() / clientPath; + } + Game::assetManager = new AssetManager(clientPath); } catch (std::runtime_error& ex) { Game::logger->Log("WorldServer", "Got an error while setting up assets: %s", ex.what()); @@ -489,7 +494,7 @@ int main(int argc, char** argv) { } dLogger* SetupLogger(int zoneID, int instanceID) { - std::string logPath = "./logs/WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(instanceID) + "_" + std::to_string(time(nullptr)) + ".log"; + std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(instanceID) + "_" + std::to_string(time(nullptr)) + ".log")).string(); bool logToConsole = false; bool logDebugStatements = false; #ifdef _DEBUG From d382eb3bc2d97e73d56995c532fb6795b31922a7 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 27 Nov 2022 04:03:30 -0800 Subject: [PATCH 023/166] Fix Boogie Down (#854) - Give entities that have a script component ID of zero a script component still - Progress scripted entity missions within the for loop as we do for script calls Tested that Boogie Down is (finally) completable. Tested that Mission 737 is still completable Checked that missions progressed inside OnEmoteReceived scripts to not double trigger progression --- dGame/Entity.cpp | 4 ++-- dGame/dGameMessages/GameMessages.cpp | 13 +++++++------ dScripts/ai/FV/FvNinjaGuard.cpp | 7 ------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 62ac8bc2..1f094291 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -454,7 +454,7 @@ void Entity::Initialize() { */ CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable("ScriptComponent"); - int scriptComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SCRIPT); + int32_t scriptComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SCRIPT, -1); std::string scriptName = ""; bool client = false; @@ -496,7 +496,7 @@ void Entity::Initialize() { scriptName = customScriptServer; } - if (!scriptName.empty() || client || m_Character) { + if (!scriptName.empty() || client || m_Character || scriptComponentID >= 0) { m_Components.insert(std::make_pair(COMPONENT_TYPE_SCRIPT, new ScriptComponent(this, scriptName, true, client && scriptName.empty()))); } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 18d7e0f6..025c26b3 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4894,27 +4894,27 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) inStream->Read(emoteID); inStream->Read(targetID); - Game::logger->Log("GameMessages", "Emote (%i) (%llu)", emoteID, targetID); + Game::logger->LogDebug("GameMessages", "Emote (%i) (%llu)", emoteID, targetID); //TODO: If targetID != 0, and we have one of the "perform emote" missions, complete them. if (emoteID == 0) return; std::string sAnimationName = "deaded"; //Default name in case we fail to get the emote - MissionComponent* mission = static_cast(entity->GetComponent(COMPONENT_TYPE_MISSION)); - if (mission) { - mission->Progress(MissionTaskType::MISSION_TASK_TYPE_EMOTE, emoteID, targetID); - } + MissionComponent* missionComponent = entity->GetComponent(); + if (!missionComponent) return; if (targetID != LWOOBJID_EMPTY) { auto* targetEntity = EntityManager::Instance()->GetEntity(targetID); - Game::logger->Log("GameMessages", "Emote target found (%d)", targetEntity != nullptr); + Game::logger->LogDebug("GameMessages", "Emote target found (%d)", targetEntity != nullptr); if (targetEntity != nullptr) { targetEntity->OnEmoteReceived(emoteID, entity); + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_EMOTE, emoteID, targetID); } } else { + Game::logger->LogDebug("GameMessages", "Target ID is empty, using backup"); const auto scriptedEntities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPT); const auto& referencePoint = entity->GetPosition(); @@ -4923,6 +4923,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (Vector3::DistanceSquared(scripted->GetPosition(), referencePoint) > 5.0f * 5.0f) continue; scripted->OnEmoteReceived(emoteID, entity); + missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_EMOTE, emoteID, scripted->GetObjectID()); } } diff --git a/dScripts/ai/FV/FvNinjaGuard.cpp b/dScripts/ai/FV/FvNinjaGuard.cpp index 6a841ccf..58267999 100644 --- a/dScripts/ai/FV/FvNinjaGuard.cpp +++ b/dScripts/ai/FV/FvNinjaGuard.cpp @@ -19,12 +19,6 @@ void FvNinjaGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* ta GameMessages::SendPlayAnimation(self, u"scared"); - auto* missionComponent = target->GetComponent(); - - if (missionComponent != nullptr && missionComponent->HasMission(737)) { - missionComponent->ForceProgressTaskType(737, 5, 1, false); - } - if (self->GetLOT() == 7412) { auto* rightGuard = EntityManager::Instance()->GetEntity(m_RightGuard); @@ -39,4 +33,3 @@ void FvNinjaGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* ta } } } - From 1556f580d6ce37f2845a39481066d6bea73b01f5 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 27 Nov 2022 13:47:14 -0800 Subject: [PATCH 024/166] Improve Diagnostics logging (#841) Improve diagnostics to write the file name and signal to the log file should there be a crash. --- dCommon/Diagnostics.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dCommon/Diagnostics.cpp b/dCommon/Diagnostics.cpp index 4c2c8beb..3025f083 100644 --- a/dCommon/Diagnostics.cpp +++ b/dCommon/Diagnostics.cpp @@ -1,4 +1,6 @@ #include "Diagnostics.h" +#include "Game.h" +#include "dLogger.h" // If we're on Win32, we'll include our minidump writer #ifdef _WIN32 @@ -26,7 +28,7 @@ void make_minidump(EXCEPTION_POINTERS* e) { "_%4d%02d%02d_%02d%02d%02d.dmp", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); } - + Game::logger->Log("Diagnostics", "Creating crash dump %s", name); auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) return; @@ -81,6 +83,7 @@ struct bt_ctx { static inline void Bt(struct backtrace_state* state) { std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log"; + Game::logger->Log("Diagnostics", "backtrace is enabled, crash dump located at %s", fileName.c_str()); FILE* file = fopen(fileName.c_str(), "w+"); if (file != nullptr) { backtrace_print(state, 2, file); @@ -114,6 +117,8 @@ void GenerateDump() { void CatchUnhandled(int sig) { #ifndef __include_backtrace__ + std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log"; + Game::logger->Log("Diagnostics", "Encountered signal %i, creating crash dump %s", sig, fileName.c_str()); if (Diagnostics::GetProduceMemoryDump()) { GenerateDump(); } @@ -124,7 +129,6 @@ void CatchUnhandled(int sig) { // get void*'s for all entries on the stack size = backtrace(array, 10); - printf("Fatal error %i\nStacktrace:\n", sig); #if defined(__GNUG__) and defined(__dynamic) // Loop through the returned addresses, and get the symbols to be demangled @@ -142,19 +146,18 @@ void CatchUnhandled(int sig) { demangled = demangle(functionName.c_str()); if (demangled.empty()) { - printf("[%02zu] %s\n", i, demangled.c_str()); + Game::logger->Log("Diagnostics", "[%02zu] %s", i, demangled.c_str()); } else { - printf("[%02zu] %s\n", i, functionName.c_str()); + Game::logger->Log("Diagnostics", "[%02zu] %s", i, functionName.c_str()); } } else { - printf("[%02zu] %s\n", i, functionName.c_str()); + Game::logger->Log("Diagnostics", "[%02zu] %s", i, functionName.c_str()); } } #else backtrace_symbols_fd(array, size, STDOUT_FILENO); #endif - std::string fileName = Diagnostics::GetOutDirectory() + "crash_" + Diagnostics::GetProcessName() + "_" + std::to_string(getpid()) + ".log"; FILE* file = fopen(fileName.c_str(), "w+"); if (file != NULL) { // print out all the frames to stderr From 3939f19b08f8c1dc642933e016a56ac373d68244 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 27 Nov 2022 16:40:14 -0800 Subject: [PATCH 025/166] Add Remove Buff Behavior and patch infinite use Imagination Backpack(#845) Testing does not reveal any issues with existing buff removals sending this GM as well and may fix more bugs that were unknown, or cause more. --- dCommon/dEnums/dMessageIdentifiers.h | 1 + dGame/dBehaviors/Behavior.cpp | 5 ++++- dGame/dBehaviors/CMakeLists.txt | 1 + dGame/dBehaviors/RemoveBuffBehavior.cpp | 21 +++++++++++++++++++++ dGame/dBehaviors/RemoveBuffBehavior.h | 22 ++++++++++++++++++++++ dGame/dComponents/BuffComponent.cpp | 4 +++- dGame/dComponents/BuffComponent.h | 3 ++- dGame/dComponents/InventoryComponent.cpp | 1 + dGame/dGameMessages/GameMessages.cpp | 14 ++++++++++++++ dGame/dGameMessages/GameMessages.h | 2 ++ 10 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 dGame/dBehaviors/RemoveBuffBehavior.cpp create mode 100644 dGame/dBehaviors/RemoveBuffBehavior.h diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index 7dc08711..5f7e9128 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -537,6 +537,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_REMOVE_RUN_SPEED_MODIFIER = 1506, GAME_MSG_UPDATE_PROPERTY_PERFORMANCE_COST = 1547, GAME_MSG_PROPERTY_ENTRANCE_BEGIN = 1553, + GAME_MSG_REMOVE_BUFF = 1648, GAME_MSG_REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1666, GAME_MSG_RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1667, GAME_MSG_PLAYER_SET_CAMERA_CYCLING_MODE = 1676, diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 046df117..d0d6192b 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -42,6 +42,7 @@ #include "SkillCastFailedBehavior.h" #include "SpawnBehavior.h" #include "ForceMovementBehavior.h" +#include "RemoveBuffBehavior.h" #include "ImmunityBehavior.h" #include "InterruptBehavior.h" #include "PlayEffectBehavior.h" @@ -226,7 +227,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { break; case BehaviorTemplates::BEHAVIOR_ALTER_CHAIN_DELAY: break; case BehaviorTemplates::BEHAVIOR_CAMERA: break; - case BehaviorTemplates::BEHAVIOR_REMOVE_BUFF: break; + case BehaviorTemplates::BEHAVIOR_REMOVE_BUFF: + behavior = new RemoveBuffBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_GRAB: break; case BehaviorTemplates::BEHAVIOR_MODULAR_BUILD: break; case BehaviorTemplates::BEHAVIOR_NPC_COMBAT_SKILL: diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index fe8e89b8..297c389b 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -34,6 +34,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "PlayEffectBehavior.cpp" "ProjectileAttackBehavior.cpp" "PullToPointBehavior.cpp" + "RemoveBuffBehavior.cpp" "RepairBehavior.cpp" "SkillCastFailedBehavior.cpp" "SkillEventBehavior.cpp" diff --git a/dGame/dBehaviors/RemoveBuffBehavior.cpp b/dGame/dBehaviors/RemoveBuffBehavior.cpp new file mode 100644 index 00000000..be3066ac --- /dev/null +++ b/dGame/dBehaviors/RemoveBuffBehavior.cpp @@ -0,0 +1,21 @@ +#include "RemoveBuffBehavior.h" + +#include "BehaviorBranchContext.h" +#include "BehaviorContext.h" +#include "EntityManager.h" +#include "BuffComponent.h" + +void RemoveBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + auto* entity = EntityManager::Instance()->GetEntity(context->caster); + if (!entity) return; + + auto* buffComponent = entity->GetComponent(); + if (!buffComponent) return; + + buffComponent->RemoveBuff(m_BuffId, false, m_RemoveImmunity); +} + +void RemoveBuffBehavior::Load() { + this->m_RemoveImmunity = GetBoolean("remove_immunity"); + this->m_BuffId = GetInt("buff_id"); +} diff --git a/dGame/dBehaviors/RemoveBuffBehavior.h b/dGame/dBehaviors/RemoveBuffBehavior.h new file mode 100644 index 00000000..f2d8547b --- /dev/null +++ b/dGame/dBehaviors/RemoveBuffBehavior.h @@ -0,0 +1,22 @@ +#pragma once +#include "Behavior.h" + +class RemoveBuffBehavior final : public Behavior +{ +public: + + /* + * Inherited + */ + + explicit RemoveBuffBehavior(const uint32_t behaviorId) : Behavior(behaviorId) { + } + + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + + void Load() override; + +private: + bool m_RemoveImmunity; + uint32_t m_BuffId; +}; diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index ecb10017..af20fc00 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -123,13 +123,15 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO m_Buffs.emplace(id, buff); } -void BuffComponent::RemoveBuff(int32_t id) { +void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity) { const auto& iter = m_Buffs.find(id); if (iter == m_Buffs.end()) { return; } + GameMessages::SendRemoveBuff(m_Parent, fromUnEquip, removeImmunity, id); + m_Buffs.erase(iter); RemoveBuffEffect(id); diff --git a/dGame/dComponents/BuffComponent.h b/dGame/dComponents/BuffComponent.h index aa669b13..7f7c6b0f 100644 --- a/dGame/dComponents/BuffComponent.h +++ b/dGame/dComponents/BuffComponent.h @@ -78,8 +78,9 @@ public: /** * Removes a buff from the parent entity, reversing its effects * @param id the id of the buff to remove + * @param removeImmunity whether or not to remove immunity on removing the buff */ - void RemoveBuff(int32_t id); + void RemoveBuff(int32_t id, bool fromUnEquip = false, bool removeImmunity = false); /** * Returns whether or not the entity has a buff identified by `id` diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 12b6792e..9f53cfa3 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -986,6 +986,7 @@ void InventoryComponent::ApplyBuff(Item* item) const { } } +// TODO Something needs to send the remove buff GameMessage as well when it is unequipping items that would remove buffs. void InventoryComponent::RemoveBuff(Item* item) const { const auto buffs = FindBuffs(item, false); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 025c26b3..896dfa0c 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3476,6 +3476,20 @@ void GameMessages::SendPlayEmote(LWOOBJID objectId, int32_t emoteID, LWOOBJID ta SEND_PACKET; } +void GameMessages::SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(entity->GetObjectID()); + bitStream.Write(GAME_MSG::GAME_MSG_REMOVE_BUFF); + + bitStream.Write(false); // bFromRemoveBehavior but setting this to true makes the GM not do anything on the client? + bitStream.Write(fromUnEquip); + bitStream.Write(removeImmunity); + bitStream.Write(buffId); + + SEND_PACKET_BROADCAST; +} void GameMessages::SendBouncerActiveStatus(LWOOBJID objectId, bool bActive, const SystemAddress& sysAddr) { CBITSTREAM; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 31bdebb3..3594a86a 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -566,6 +566,8 @@ namespace GameMessages { void HandleReportBug(RakNet::BitStream* inStream, Entity* entity); + void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId); + /* Message to synchronize a skill cast */ class EchoSyncSkill { static const GAME_MSG MsgID = GAME_MSG_ECHO_SYNC_SKILL; From 3222e788155e17931e3b0af82f35239722f6c847 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 27 Nov 2022 16:48:46 -0800 Subject: [PATCH 026/166] Implement undo action for pre-built models (#830) Brick building as of right now does not implement the undo action properly. This commit addresses the issue with undoing button being non-functional server side and implements the GM needed for addressing further issues. Implement GameMessage UnUseModel which is called when a model in BrickBuilding is UnUsed. Important for UGC content down the line. Final code has been tested as follows: 1. Placed a model in brick build 2. saved placed a brick 3. repeat 2 and 3 twice more for 6 total models 4. Place a new model in brick mode and then edit all 7 models into one brick model instance 5. Pressing undo returns the converted model to the inventory and properly discards the other 6 without crashing. Intended live behavior is to store this in the inventory instead however behind the scenes work is needed to implement UGC models properly. Implement enum Implement the BlueprintSaveResponseType enum so there are less magic numbers sent via packets. Correct int sizes from unsigned int to uint32_t Add deserialize test Add a test for de-serializing a GM that is sent to the client. Assertions verify the data is in the correct order and has no extra information. --- dCommon/dEnums/dCommonVars.h | 1 + dCommon/dEnums/dMessageIdentifiers.h | 1 + dCommon/eBlueprintSaveResponseType.h | 26 +++++++ dGame/dComponents/InventoryComponent.cpp | 13 ++-- .../PropertyManagementComponent.cpp | 2 +- dGame/dGameMessages/GameMessageHandler.cpp | 4 ++ dGame/dGameMessages/GameMessages.cpp | 70 ++++++++++++++++--- dGame/dGameMessages/GameMessages.h | 11 +++ dGame/dInventory/Inventory.h | 2 +- dMasterServer/ObjectIDManager.cpp | 4 +- dWorldServer/WorldServer.cpp | 7 +- tests/dGameTests/CMakeLists.txt | 3 + tests/dGameTests/GameDependencies.h | 9 ++- .../dGameMessagesTests/CMakeLists.txt | 9 +++ .../dGameMessagesTests/GameMessageTests.cpp | 52 ++++++++++++++ 15 files changed, 188 insertions(+), 26 deletions(-) create mode 100644 dCommon/eBlueprintSaveResponseType.h create mode 100644 tests/dGameTests/dGameMessagesTests/CMakeLists.txt create mode 100644 tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 005d7205..74d83b11 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -434,6 +434,7 @@ enum eInventoryType : uint32_t { ITEMS = 0, VAULT_ITEMS, BRICKS, + MODELS_IN_BBB, TEMP_ITEMS = 4, MODELS, TEMP_MODELS, diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index 5f7e9128..5a5c9088 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -433,6 +433,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_ORIENT_TO_POSITION = 906, GAME_MSG_ORIENT_TO_ANGLE = 907, GAME_MSG_BOUNCER_ACTIVE_STATUS = 942, + GAME_MSG_UN_USE_BBB_MODEL = 999, GAME_MSG_BBB_LOAD_ITEM_REQUEST = 1000, GAME_MSG_BBB_SAVE_REQUEST = 1001, GAME_MSG_BBB_SAVE_RESPONSE = 1006, diff --git a/dCommon/eBlueprintSaveResponseType.h b/dCommon/eBlueprintSaveResponseType.h new file mode 100644 index 00000000..29d15695 --- /dev/null +++ b/dCommon/eBlueprintSaveResponseType.h @@ -0,0 +1,26 @@ +#pragma once + +#ifndef __EBLUEPRINTSAVERESPONSETYPE__H__ +#define __EBLUEPRINTSAVERESPONSETYPE__H__ + +#include + +enum class eBlueprintSaveResponseType : uint32_t { + EverythingWorked = 0, + SaveCancelled, + CantBeginTransaction, + SaveBlueprintFailed, + SaveUgobjectFailed, + CantEndTransaction, + SaveFilesFailed, + BadInput, + NotEnoughBricks, + InventoryFull, + ModelGenerationFailed, + PlacementFailed, + GmLevelInsufficient, + WaitForPreviousSave, + FindMatchesFailed +}; + +#endif //!__EBLUEPRINTSAVERESPONSETYPE__H__ diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 9f53cfa3..77f3f035 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -606,16 +606,17 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) { return; } - std::vector inventories; + std::vector inventoriesToSave; + // Need to prevent some transfer inventories from being saved for (const auto& pair : this->m_Inventories) { auto* inventory = pair.second; - if (inventory->GetType() == VENDOR_BUYBACK) { + if (inventory->GetType() == VENDOR_BUYBACK || inventory->GetType() == eInventoryType::MODELS_IN_BBB) { continue; } - inventories.push_back(inventory); + inventoriesToSave.push_back(inventory); } inventoryElement->SetAttribute("csl", m_Consumable); @@ -630,7 +631,7 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) { bags->DeleteChildren(); - for (const auto* inventory : inventories) { + for (const auto* inventory : inventoriesToSave) { auto* bag = document->NewElement("b"); bag->SetAttribute("t", inventory->GetType()); @@ -649,7 +650,7 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) { items->DeleteChildren(); - for (auto* inventory : inventories) { + for (auto* inventory : inventoriesToSave) { if (inventory->GetSize() == 0) { continue; } @@ -1260,7 +1261,7 @@ BehaviorSlot InventoryComponent::FindBehaviorSlot(const eItemType type) { } bool InventoryComponent::IsTransferInventory(eInventoryType type) { - return type == VENDOR_BUYBACK || type == VAULT_ITEMS || type == VAULT_MODELS || type == TEMP_ITEMS || type == TEMP_MODELS; + return type == VENDOR_BUYBACK || type == VAULT_ITEMS || type == VAULT_MODELS || type == TEMP_ITEMS || type == TEMP_MODELS || type == MODELS_IN_BBB; } uint32_t InventoryComponent::FindSkill(const LOT lot) { diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index d196e935..eaade8be 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -474,7 +474,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet settings.push_back(propertyObjectID); settings.push_back(modelType); - inventoryComponent->AddItem(6662, 1, eLootSourceType::LOOT_SOURCE_DELETION, eInventoryType::HIDDEN, settings, LWOOBJID_EMPTY, false, false, spawnerId); + inventoryComponent->AddItem(6662, 1, eLootSourceType::LOOT_SOURCE_DELETION, eInventoryType::MODELS_IN_BBB, settings, LWOOBJID_EMPTY, false, false, spawnerId); auto* item = inventoryComponent->FindItemBySubKey(spawnerId); if (item == nullptr) { diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 2ce79966..b7687c19 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -46,6 +46,10 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System switch (messageID) { + case GAME_MSG_UN_USE_BBB_MODEL: { + GameMessages::HandleUnUseModel(inStream, entity, sysAddr); + break; + } case GAME_MSG_PLAY_EMOTE: { GameMessages::HandlePlayEmote(inStream, entity); break; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 896dfa0c..6639197c 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -70,6 +70,7 @@ #include "TradingManager.h" #include "ControlBehaviors.h" #include "AMFDeserialize.h" +#include "eBlueprintSaveResponseType.h" void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) { CBITSTREAM; @@ -2139,6 +2140,32 @@ void GameMessages::HandleSetPropertyAccess(RakNet::BitStream* inStream, Entity* PropertyManagementComponent::Instance()->SetPrivacyOption(static_cast(accessType)); } +void GameMessages::HandleUnUseModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { + bool unknown{}; + LWOOBJID objIdToAddToInventory{}; + inStream->Read(unknown); + inStream->Read(objIdToAddToInventory); + auto* inventoryComponent = entity->GetComponent(); + if (inventoryComponent) { + auto* inventory = inventoryComponent->GetInventory(eInventoryType::MODELS_IN_BBB); + auto* item = inventory->FindItemById(objIdToAddToInventory); + if (item) { + inventoryComponent->MoveItemToInventory(item, eInventoryType::MODELS, 1); + } else { + Game::logger->Log("GameMessages", "item id %llu not found in MODELS_IN_BBB inventory, likely because it does not exist", objIdToAddToInventory); + } + } + + if (unknown) { + CBITSTREAM; + PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_BLUEPRINT_SAVE_RESPONSE); + bitStream.Write(LWOOBJID_EMPTY); //always zero so that a check on the client passes + bitStream.Write(eBlueprintSaveResponseType::PlacementFailed); // Sending a non-zero error code here prevents the client from deleting its in progress build for some reason? + bitStream.Write(0); + SEND_PACKET; + } +} + void GameMessages::HandleUpdatePropertyOrModelForFilterCheck(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { bool isProperty{}; LWOOBJID objectId{}; @@ -2353,16 +2380,40 @@ void GameMessages::HandleDeletePropertyModel(RakNet::BitStream* inStream, Entity } void GameMessages::HandleBBBLoadItemRequest(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - LWOOBJID itemID = LWOOBJID_EMPTY; - inStream->Read(itemID); + LWOOBJID previousItemID = LWOOBJID_EMPTY; + inStream->Read(previousItemID); - Game::logger->Log("BBB", "Load item request for: %lld", itemID); + Game::logger->Log("BBB", "Load item request for: %lld", previousItemID); + LWOOBJID newId = previousItemID; + auto* inventoryComponent = entity->GetComponent(); + if (inventoryComponent) { + auto* inventory = inventoryComponent->GetInventory(eInventoryType::MODELS); + auto* itemToMove = inventory->FindItemById(previousItemID); + if (itemToMove) { + LOT previousLot = itemToMove->GetLot(); + inventoryComponent->MoveItemToInventory(itemToMove, eInventoryType::MODELS_IN_BBB, 1, false); + + auto* destinationInventory = inventoryComponent->GetInventory(eInventoryType::MODELS_IN_BBB); + if (destinationInventory) { + auto* movedItem = destinationInventory->FindItemByLot(previousLot); + if (movedItem) newId = movedItem->GetId(); + } + } else { + Game::logger->Log("GameMessages", "item id %llu not found in MODELS inventory, likely because it does not exist", previousItemID); + } + } + + // Second argument always true (successful) for now + SendBlueprintLoadItemResponse(sysAddr, true, previousItemID, newId); +} + +void GameMessages::SendBlueprintLoadItemResponse(const SystemAddress& sysAddr, bool success, LWOOBJID oldItemId, LWOOBJID newItemId) { CBITSTREAM; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_BLUEPRINT_LOAD_RESPONSE_ITEMID); - bitStream.Write(static_cast(1)); - bitStream.Write(itemID); - bitStream.Write(itemID); + bitStream.Write(static_cast(success)); + bitStream.Write(oldItemId); + bitStream.Write(newItemId); SEND_PACKET; } @@ -2413,7 +2464,7 @@ void GameMessages::HandleControlBehaviors(RakNet::BitStream* inStream, Entity* e } auto owner = PropertyManagementComponent::Instance()->GetOwner(); - if (!owner) return; + if (!owner) return; ControlBehaviors::ProcessCommand(entity, sysAddr, static_cast(amfArguments.get()), command, owner); } @@ -2609,8 +2660,8 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent CBITSTREAM; PacketUtils::WriteHeader(bitStream, CLIENT, CLIENT::MSG_CLIENT_BLUEPRINT_SAVE_RESPONSE); bitStream.Write(localId); - bitStream.Write(0); - bitStream.Write(1); + bitStream.Write(eBlueprintSaveResponseType::EverythingWorked); + bitStream.Write(1); bitStream.Write(blueprintID); bitStream.Write(sd0Size); @@ -2620,7 +2671,6 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent } SEND_PACKET; - // PacketUtils::SavePacket("MSG_CLIENT_BLUEPRINT_SAVE_RESPONSE.bin", (char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed()); //Now we have to construct this object: diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 3594a86a..f9968d14 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -121,6 +121,7 @@ namespace GameMessages { void SendMatchResponse(Entity* entity, const SystemAddress& sysAddr, int response); void SendMatchUpdate(Entity* entity, const SystemAddress& sysAddr, std::string data, int type); + void HandleUnUseModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void SendStartCelebrationEffect(Entity* entity, const SystemAddress& sysAddr, int celebrationID); /** @@ -197,6 +198,16 @@ namespace GameMessages { void SendDownloadPropertyData(LWOOBJID objectId, const PropertyDataMessage& data, const SystemAddress& sysAddr); + /** + * @brief Send an updated item id to the client when they load a blueprint in brick build mode + * + * @param sysAddr SystemAddress to respond to + * @param oldItemId The item ID that was requested to be loaded + * @param newItemId The new item ID of the loaded item + * + */ + void SendBlueprintLoadItemResponse(const SystemAddress& sysAddr, bool success, LWOOBJID oldItemId, LWOOBJID newItemId); + void SendPropertyRentalResponse(LWOOBJID objectId, LWOCLONEID cloneId, uint32_t code, LWOOBJID propertyId, int64_t rentDue, const SystemAddress& sysAddr); void SendLockNodeRotation(Entity* entity, std::string nodeName); diff --git a/dGame/dInventory/Inventory.h b/dGame/dInventory/Inventory.h index 30f753da..6c6a4306 100644 --- a/dGame/dInventory/Inventory.h +++ b/dGame/dInventory/Inventory.h @@ -95,7 +95,7 @@ public: * @param lot the lot to find items for * @param ignoreEquipped ignores equipped items * @param ignoreBound ignores bound items - * @return item in the inventory for the provided LOT + * @return item with the lowest stack count in the inventory for the provided LOT */ Item* FindItemByLot(LOT lot, bool ignoreEquipped = false, bool ignoreBound = false) const; diff --git a/dMasterServer/ObjectIDManager.cpp b/dMasterServer/ObjectIDManager.cpp index 0f3b98c9..83dde8dd 100644 --- a/dMasterServer/ObjectIDManager.cpp +++ b/dMasterServer/ObjectIDManager.cpp @@ -51,13 +51,13 @@ uint32_t ObjectIDManager::GeneratePersistentID(void) { uint32_t toReturn = ++this->currentPersistentID; // So we peroidically save our ObjID to the database: - if (toReturn % 25 == 0) { // TEMP: DISABLED FOR DEBUG / DEVELOPMENT! + // if (toReturn % 25 == 0) { // TEMP: DISABLED FOR DEBUG / DEVELOPMENT! sql::PreparedStatement* stmt = Database::CreatePreppedStmt( "UPDATE object_id_tracker SET last_object_id=?"); stmt->setUInt(1, toReturn); stmt->execute(); delete stmt; - } + // } return toReturn; } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index b7d7cc14..16e0b1c1 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -57,6 +57,7 @@ #include "Player.h" #include "PropertyManagementComponent.h" #include "AssetManager.h" +#include "eBlueprintSaveResponseType.h" #include "ZCompression.h" @@ -1082,9 +1083,9 @@ void HandlePacket(Packet* packet) { CBITSTREAM; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_BLUEPRINT_SAVE_RESPONSE); - bitStream.Write(0); //always zero so that a check on the client passes - bitStream.Write(0); - bitStream.Write(1); + bitStream.Write(LWOOBJID_EMPTY); //always zero so that a check on the client passes + bitStream.Write(eBlueprintSaveResponseType::EverythingWorked); + bitStream.Write(1); bitStream.Write(blueprintID); bitStream.Write(lxfmlSize); diff --git a/tests/dGameTests/CMakeLists.txt b/tests/dGameTests/CMakeLists.txt index 68192b3f..ba7d4d1c 100644 --- a/tests/dGameTests/CMakeLists.txt +++ b/tests/dGameTests/CMakeLists.txt @@ -5,6 +5,9 @@ set(DGAMETEST_SOURCES add_subdirectory(dComponentsTests) list(APPEND DGAMETEST_SOURCES ${DCOMPONENTS_TESTS}) +add_subdirectory(dGameMessagesTests) +list(APPEND DGAMETEST_SOURCES ${DGAMEMESSAGES_TESTS}) + # Add the executable. Remember to add all tests above this! add_executable(dGameTests ${DGAMETEST_SOURCES}) diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 593ec0fc..ee52dec6 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -5,15 +5,18 @@ #include "dLogger.h" #include "dServer.h" #include "EntityManager.h" -class dZoneManager; -class AssetManager; #include +class dZoneManager; +class AssetManager; + class dServerMock : public dServer { + RakNet::BitStream* sentBitStream = nullptr; public: dServerMock() {}; ~dServerMock() {}; - void Send(RakNet::BitStream* bitStream, const SystemAddress& sysAddr, bool broadcast) override {}; + RakNet::BitStream* GetMostRecentBitStream() { return sentBitStream; }; + void Send(RakNet::BitStream* bitStream, const SystemAddress& sysAddr, bool broadcast) override { sentBitStream = bitStream; }; }; class GameDependenciesTest : public ::testing::Test { diff --git a/tests/dGameTests/dGameMessagesTests/CMakeLists.txt b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt new file mode 100644 index 00000000..2417d29c --- /dev/null +++ b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt @@ -0,0 +1,9 @@ +SET(DGAMEMESSAGES_TESTS + "GameMessageTests.cpp") + +# Get the folder name and prepend it to the files above +get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME) +list(TRANSFORM DGAMEMESSAGES_TESTS PREPEND "${thisFolderName}/") + +# Export to parent scope +set(DGAMEMESSAGES_TESTS ${DGAMEMESSAGES_TESTS} PARENT_SCOPE) diff --git a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp new file mode 100644 index 00000000..3d8b2d04 --- /dev/null +++ b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp @@ -0,0 +1,52 @@ +#include "GameMessages.h" +#include "GameDependencies.h" +#include + +class GameMessageTests : public GameDependenciesTest { + protected: + void SetUp() override { + SetUpDependencies(); + } + void TearDown() override { + TearDownDependencies(); + } +}; + +/** + * @brief Tests that the serialization struct BlueprintLoadItemResponse is serialized correctly + * + */ +TEST_F(GameMessageTests, SendBlueprintLoadItemResponse) { + GameMessages::SendBlueprintLoadItemResponse(UNASSIGNED_SYSTEM_ADDRESS, true, 515, 990); + auto* bitStream = static_cast(Game::server)->GetMostRecentBitStream(); + ASSERT_NE(bitStream, nullptr); + ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 200); + // First read in the packets' header + uint8_t rakNetPacketId{}; + uint16_t remoteConnectionType{}; + uint32_t packetId{}; + uint8_t always0{}; + + bitStream->Read(rakNetPacketId); + bitStream->Read(remoteConnectionType); + bitStream->Read(packetId); + bitStream->Read(always0); + ASSERT_EQ(rakNetPacketId, 0x53); + ASSERT_EQ(remoteConnectionType, 0x05); + ASSERT_EQ(packetId, 0x17); + ASSERT_EQ(always0, 0x00); + + // Next read in packet data + + uint8_t bSuccess{}; // unsigned bool + LWOOBJID previousId{}; + LWOOBJID newId{}; + bitStream->Read(bSuccess); + bitStream->Read(previousId); + bitStream->Read(newId); + ASSERT_EQ(bSuccess, static_cast(true)); + ASSERT_EQ(previousId, 515); + ASSERT_EQ(newId, 990); + + ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0); +} From 56da3f8543bdb1b9eb754332dca32b570b07d6c0 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 27 Nov 2022 16:56:55 -0800 Subject: [PATCH 027/166] Remove Locale (#808) * Remove Locale (finally) --- CMakeLists.txt | 3 - dCommon/Game.h | 2 - dGame/dMission/Mission.cpp | 12 ++-- dGame/dUtilities/CMakeLists.txt | 1 - dGame/dUtilities/dLocale.cpp | 82 --------------------------- dGame/dUtilities/dLocale.h | 19 ------- dWorldServer/WorldServer.cpp | 3 - docker/start_server.sh | 2 +- tests/dGameTests/GameDependencies.cpp | 1 - 9 files changed, 5 insertions(+), 120 deletions(-) delete mode 100644 dGame/dUtilities/dLocale.cpp delete mode 100644 dGame/dUtilities/dLocale.h mode change 100755 => 100644 docker/start_server.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 644fc383..163196fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,9 +92,6 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) # Create a /res directory make_directory(${CMAKE_BINARY_DIR}/res) -# Create a /locale directory -make_directory(${CMAKE_BINARY_DIR}/locale) - # Create a /logs directory make_directory(${CMAKE_BINARY_DIR}/logs) diff --git a/dCommon/Game.h b/dCommon/Game.h index 616c7fbf..1c4bbc85 100644 --- a/dCommon/Game.h +++ b/dCommon/Game.h @@ -8,7 +8,6 @@ class InstanceManager; class dpWorld; class dChatFilter; class dConfig; -class dLocale; class RakPeerInterface; class AssetManager; struct SystemAddress; @@ -20,7 +19,6 @@ namespace Game { extern dpWorld* physicsWorld; extern dChatFilter* chatFilter; extern dConfig* config; - extern dLocale* locale; extern std::mt19937 randomEngine; extern RakPeerInterface* chatServer; extern AssetManager* assetManager; diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 6020e51c..0a8a57fe 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -13,7 +13,6 @@ #include "Mail.h" #include "MissionComponent.h" #include "RacingTaskParam.h" -#include "dLocale.h" #include "dLogger.h" #include "dServer.h" #include "dZoneManager.h" @@ -335,13 +334,10 @@ void Mission::Complete(const bool yieldRewards) { for (const auto& email : missionEmails) { const auto missionEmailBase = "MissionEmail_" + std::to_string(email.ID) + "_"; - const auto senderLocale = missionEmailBase + "senderName"; - const auto announceLocale = missionEmailBase + "announceText"; - - if (email.messageType == 1 && Game::locale->HasPhrase(senderLocale)) { - const auto subject = dLocale::GetTemplate(missionEmailBase + "subjectText"); - const auto body = dLocale::GetTemplate(missionEmailBase + "bodyText"); - const auto sender = dLocale::GetTemplate(senderLocale); + if (email.messageType == 1) { + const auto subject = "%[" + missionEmailBase + "subjectText]"; + const auto body = "%[" + missionEmailBase + "bodyText]"; + const auto sender = "%[" + missionEmailBase + "senderName]"; Mail::SendMail(LWOOBJID_EMPTY, sender, GetAssociate(), subject, body, email.attachmentLOT, 1); } diff --git a/dGame/dUtilities/CMakeLists.txt b/dGame/dUtilities/CMakeLists.txt index 0c848bf4..2c453a2e 100644 --- a/dGame/dUtilities/CMakeLists.txt +++ b/dGame/dUtilities/CMakeLists.txt @@ -1,5 +1,4 @@ set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp" - "dLocale.cpp" "GameConfig.cpp" "GUID.cpp" "Loot.cpp" diff --git a/dGame/dUtilities/dLocale.cpp b/dGame/dUtilities/dLocale.cpp deleted file mode 100644 index de65511b..00000000 --- a/dGame/dUtilities/dLocale.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "dLocale.h" - -#include -#include -#include -#include -#include - -#include "tinyxml2.h" -#include "Game.h" -#include "dConfig.h" -#include "BinaryPathFinder.h" - -dLocale::dLocale() { - if (Game::config->GetValue("locale_enabled") != "1") { - return; - } - - std::ifstream file(BinaryPathFinder::GetBinaryDir() / m_LocalePath); - - if (!file.good()) { - return; - } - - std::stringstream data; - data << file.rdbuf(); - - if (data.str().empty()) { - return; - } - - auto* doc = new tinyxml2::XMLDocument(); - - if (doc == nullptr) { - return; - } - - if (doc->Parse(data.str().c_str(), data.str().size()) != 0) { - return; - } - - std::hash hash; - - auto* localization = doc->FirstChildElement("localization"); - auto* phrases = localization->FirstChildElement("phrases"); - - auto* phrase = phrases->FirstChildElement("phrase"); - - while (phrase != nullptr) { - // Add the phrase hash to the vector - m_Phrases.push_back(hash(phrase->Attribute("id"))); - phrase = phrase->NextSiblingElement("phrase"); - } - - file.close(); - - delete doc; -} - -dLocale::~dLocale() = default; - -std::string dLocale::GetTemplate(const std::string& phraseID) { - return "%[" + phraseID + "]"; -} - -bool dLocale::HasPhrase(const std::string& phraseID) { - if (Game::config->GetValue("locale_enabled") != "1") { - return true; - } - - // Compute the hash and see if it's in the vector - std::hash hash; - std::size_t hashValue = hash(phraseID); - return std::find(m_Phrases.begin(), m_Phrases.end(), hashValue) != m_Phrases.end(); -} - -/*std::string dLocale::GetPhrase(const std::string& phraseID) { - if (m_Phrases.find(phraseID) == m_Phrases.end()) { - return ""; - } - return m_Phrases[phraseID]; -}*/ diff --git a/dGame/dUtilities/dLocale.h b/dGame/dUtilities/dLocale.h deleted file mode 100644 index db5d2a4f..00000000 --- a/dGame/dUtilities/dLocale.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include -#include -#include -#include - -class dLocale { -public: - dLocale(); - ~dLocale(); - static std::string GetTemplate(const std::string& phraseID); - bool HasPhrase(const std::string& phraseID); - //std::string GetPhrase(const std::string& phraseID); - -private: - std::string m_LocalePath = "./locale/locale.xml"; - std::string m_Locale = "en_US"; // TODO: add to config - std::vector m_Phrases; -}; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 16e0b1c1..bbba1166 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -48,7 +48,6 @@ #include "GameMessageHandler.h" #include "GameMessages.h" #include "Mail.h" -#include "dLocale.h" #include "TeamManager.h" #include "SkillComponent.h" #include "DestroyableComponent.h" @@ -68,7 +67,6 @@ namespace Game { dpWorld* physicsWorld; dChatFilter* chatFilter; dConfig* config; - dLocale* locale; std::mt19937 randomEngine; AssetManager* assetManager; @@ -223,7 +221,6 @@ int main(int argc, char** argv) { //Set up other things: Game::randomEngine = std::mt19937(time(0)); - Game::locale = new dLocale(); //Run it until server gets a kill message from Master: auto lastTime = std::chrono::high_resolution_clock::now(); diff --git a/docker/start_server.sh b/docker/start_server.sh old mode 100755 new mode 100644 index ca1a49a0..4fd6e2be --- a/docker/start_server.sh +++ b/docker/start_server.sh @@ -7,7 +7,7 @@ function symlink_client_files() { ln -s /client/client/res/chatplus_en_us.txt /app/res/chatplus_en_us.txt ln -s /client/client/res/names/ /app/res/names ln -s /client/client/res/CDServer.sqlite /app/res/CDServer.sqlite - ln -s /client/client/locale/locale.xml /app/locale/locale.xml + # need to create this file so the server knows the client is unpacked (see `dCommon/dClient/AssetManager.cpp`) touch /app/res/cdclient.fdb # need to iterate over entries in maps due to maps already being a directory with navmeshes/ in it diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index 8a572668..5ac3339a 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -7,7 +7,6 @@ namespace Game { dpWorld* physicsWorld; dChatFilter* chatFilter; dConfig* config; - dLocale* locale; std::mt19937 randomEngine; RakPeerInterface* chatServer; AssetManager* assetManager; From 09dfb6df3a53ce3fd3870351e8b3e6633e5a349b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 27 Nov 2022 22:19:15 -0800 Subject: [PATCH 028/166] Address news feed showing up on every world transfer (#855) Addresses the news feed showing up on every world transfer --- dCommon/dEnums/dCommonVars.h | 1 + dGame/Character.cpp | 51 ++++++++++++++++++++++++++++-------- dGame/Character.h | 15 ++++++++++- dGame/UserManager.cpp | 1 + 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 74d83b11..f64d496f 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -560,6 +560,7 @@ enum ePlayerFlags { ENTER_BBB_FROM_PROPERTY_EDIT_CONFIRMATION_DIALOG = 64, AG_FIRST_COMBAT_COMPLETE = 65, AG_COMPLETE_BOB_MISSION = 66, + IS_NEWS_SCREEN_VISIBLE = 114, NJ_GARMADON_CINEMATIC_SEEN = 125, ELEPHANT_PET_3050 = 801, CAT_PET_3054 = 802, diff --git a/dGame/Character.cpp b/dGame/Character.cpp index 440c30c1..a9cffc65 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -264,14 +264,17 @@ void Character::DoQuickXMLDataParse() { if (flags) { auto* currentChild = flags->FirstChildElement(); while (currentChild) { - uint32_t index = 0; - uint64_t value = 0; const auto* temp = currentChild->Attribute("v"); + const auto* id = currentChild->Attribute("id"); + if (temp && id) { + uint32_t index = 0; + uint64_t value = 0; - index = std::stoul(currentChild->Attribute("id")); - value = std::stoull(temp); + index = std::stoul(id); + value = std::stoull(temp); - m_PlayerFlags.insert(std::make_pair(index, value)); + m_PlayerFlags.insert(std::make_pair(index, value)); + } currentChild = currentChild->NextSiblingElement(); } } @@ -351,6 +354,13 @@ void Character::SaveXMLToDatabase() { flags->LinkEndChild(f); } + // Prevents the news feed from showing up on world transfers + if (GetPlayerFlag(ePlayerFlags::IS_NEWS_SCREEN_VISIBLE)) { + auto* s = m_Doc->NewElement("s"); + s->SetAttribute("si", ePlayerFlags::IS_NEWS_SCREEN_VISIBLE); + flags->LinkEndChild(s); + } + SaveXmlRespawnCheckpoints(); //Call upon the entity to update our xmlDoc: @@ -361,6 +371,31 @@ void Character::SaveXMLToDatabase() { m_OurEntity->UpdateXMLDoc(m_Doc); + WriteToDatabase(); + + //For metrics, log the time it took to save: + auto end = std::chrono::system_clock::now(); + std::chrono::duration elapsed = end - start; + Game::logger->Log("Character", "Saved character to Database in: %fs", elapsed.count()); +} + +void Character::SetIsNewLogin() { + // If we dont have a flag element, then we cannot have a s element as a child of flag. + auto* flags = m_Doc->FirstChildElement("obj")->FirstChildElement("flag"); + if (!flags) return; + + auto* currentChild = flags->FirstChildElement(); + while (currentChild) { + if (currentChild->Attribute("si")) { + flags->DeleteChild(currentChild); + Game::logger->Log("Character", "Removed isLoggedIn flag from character %i, saving character to database", GetID()); + WriteToDatabase(); + } + currentChild = currentChild->NextSiblingElement(); + } +} + +void Character::WriteToDatabase() { //Dump our xml into m_XMLData: auto* printer = new tinyxml2::XMLPrinter(0, true, 0); m_Doc->Print(printer); @@ -372,12 +407,6 @@ void Character::SaveXMLToDatabase() { stmt->setUInt(2, m_ID); stmt->execute(); delete stmt; - - //For metrics, log the time it took to save: - auto end = std::chrono::system_clock::now(); - std::chrono::duration elapsed = end - start; - Game::logger->Log("Character", "Saved character to Database in: %fs", elapsed.count()); - delete printer; } diff --git a/dGame/Character.h b/dGame/Character.h index 52bff83d..07bde36c 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -23,6 +23,10 @@ public: Character(uint32_t id, User* parentUser); ~Character(); + /** + * Write the current m_Doc to the database for saving. + */ + void WriteToDatabase(); void SaveXMLToDatabase(); void UpdateFromDatabase(); @@ -32,6 +36,15 @@ public: const std::string& GetXMLData() const { return m_XMLData; } tinyxml2::XMLDocument* GetXMLDoc() const { return m_Doc; } + /** + * Out of abundance of safety and clarity of what this saves, this is its own function. + * + * Clears the s element from the flag element and saves the xml to the database. Used to prevent the news + * feed from showing up on world transfers. + * + */ + void SetIsNewLogin(); + /** * Gets the database ID of the character * @return the database ID of the character @@ -427,7 +440,7 @@ public: /** * @brief Get the flying state - * @return value of the flying state + * @return value of the flying state */ bool GetIsFlying() { return m_IsFlying; } diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index ddbad03a..6779a42c 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -227,6 +227,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) { while (res->next()) { LWOOBJID objID = res->getUInt64(1); Character* character = new Character(uint32_t(objID), u); + character->SetIsNewLogin(); chars.push_back(character); } } From 63460ea00d944ccb0c1ab7735010c90c028d1e84 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 30 Nov 2022 01:04:46 -0800 Subject: [PATCH 029/166] Fix bricks not creating new stacks (#860) Unintentionally, bricks were not creating new stacks if you tried to get another stack. This prevents some missions from being completed. This issue is now fixed --- dGame/dComponents/InventoryComponent.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 77f3f035..acf1ae6a 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -209,8 +209,10 @@ void InventoryComponent::AddItem( auto stack = static_cast(info.stackSize); + bool isBrick = inventoryType == eInventoryType::BRICKS || (stack == 0 && info.itemType == 1); + // info.itemType of 1 is item type brick - if (inventoryType == eInventoryType::BRICKS || (stack == 0 && info.itemType == 1)) { + if (isBrick) { stack = UINT32_MAX; } else if (stack == 0) { stack = 1; @@ -233,7 +235,7 @@ void InventoryComponent::AddItem( } // If we have some leftover and we aren't bricks, make a new stack - while (left > 0 && !(inventoryType == eInventoryType::BRICKS || (stack == 0 && info.itemType == 1))) { + while (left > 0 && (!isBrick || (isBrick && !existing))) { const auto size = std::min(left, stack); left -= size; From 2b9c014b86e8c5f8cd8a50577b8a2877563d4b42 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 2 Dec 2022 01:44:20 -0700 Subject: [PATCH 030/166] Quiet activity manager timer logs (#861) --- dScripts/ActivityManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 18d72311..36e85b11 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -124,7 +124,7 @@ void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerN auto* timer = new ActivityTimer{ timerName, updateInterval, stopTime }; activeTimers.push_back(timer); - Game::logger->Log("ActivityManager", "Starting timer '%s', %f, %f", timerName.c_str(), updateInterval, stopTime); + Game::logger->LogDebug("ActivityManager", "Starting timer '%s', %f, %f", timerName.c_str(), updateInterval, stopTime); self->AddTimer(GetPrefixedName(timer->name), timer->updateInterval); } @@ -205,10 +205,10 @@ void ActivityManager::OnTimerDone(Entity* self, std::string timerName) { activeTimers.erase(std::remove(activeTimers.begin(), activeTimers.end(), timer), activeTimers.end()); delete timer; - Game::logger->Log("ActivityManager", "Executing timer '%s'", activityTimerName.c_str()); + Game::logger->LogDebug("ActivityManager", "Executing timer '%s'", activityTimerName.c_str()); OnActivityTimerDone(self, activityTimerName); } else { - Game::logger->Log("ActivityManager", "Updating timer '%s'", activityTimerName.c_str()); + Game::logger->LogDebug("ActivityManager", "Updating timer '%s'", activityTimerName.c_str()); OnActivityTimerUpdate(self, timer->name, timer->stopTime - timer->runTime, timer->runTime); self->AddTimer(GetPrefixedName(timer->name), timer->updateInterval); } From d8945e9067fe56175259f943fa432d57c4da471c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 2 Dec 2022 04:46:54 -0700 Subject: [PATCH 031/166] Add migration to make play_key_id nullable (#857) since there is an option not to use play_keys --- migrations/dlu/7_make_play_key_id_nullable.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 migrations/dlu/7_make_play_key_id_nullable.sql diff --git a/migrations/dlu/7_make_play_key_id_nullable.sql b/migrations/dlu/7_make_play_key_id_nullable.sql new file mode 100644 index 00000000..7491874f --- /dev/null +++ b/migrations/dlu/7_make_play_key_id_nullable.sql @@ -0,0 +1 @@ +ALTER TABLE account MODIFY play_key_id INT DEFAULT 0; From e1af528d9b7fa849d99264dcae2971bac305419a Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 2 Dec 2022 03:47:27 -0800 Subject: [PATCH 032/166] Add SlashCommand for spawngroup (#858) --- dGame/dUtilities/SlashCommandHandler.cpp | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 2f4d9211..79e61bae 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1264,6 +1264,57 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->ConstructEntity(newEntity); } + if (chatCommand == "spawngroup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { + auto controllablePhysicsComponent = entity->GetComponent(); + if (!controllablePhysicsComponent) return; + + LOT lot{}; + uint32_t numberToSpawn{}; + float radiusToSpawnWithin{}; + + if (!GeneralUtils::TryParse(args[0], lot)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid lot."); + return; + } + + if (!GeneralUtils::TryParse(args[1], numberToSpawn) && numberToSpawn > 0) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid number of enemies to spawn."); + return; + } + + // Must spawn within a radius of at least 0.0f + if (!GeneralUtils::TryParse(args[2], radiusToSpawnWithin) && radiusToSpawnWithin < 0.0f) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid radius to spawn within."); + return; + } + + EntityInfo info; + info.lot = lot; + info.spawner = nullptr; + info.spawnerID = entity->GetObjectID(); + info.spawnerNodeID = 0; + + auto playerPosition = controllablePhysicsComponent->GetPosition(); + while (numberToSpawn > 0) { + auto randomAngle = GeneralUtils::GenerateRandomNumber(0.0f, 2 * PI); + auto randomRadius = GeneralUtils::GenerateRandomNumber(0.0f, radiusToSpawnWithin); + + // Set the position to the generated random position plus the player position. This will + // spawn the entity in a circle around the player. As you get further from the player, the angle chosen will get less accurate. + info.pos = playerPosition + NiPoint3(cos(randomAngle) * randomRadius, 0.0f, sin(randomAngle) * randomRadius); + info.rot = NiQuaternion(); + + auto newEntity = EntityManager::Instance()->CreateEntity(info); + if (newEntity == nullptr) { + ChatPackets::SendSystemMessage(sysAddr, u"Failed to spawn entity."); + return; + } + + EntityManager::Instance()->ConstructEntity(newEntity); + numberToSpawn--; + } + } + if ((chatCommand == "giveuscore") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { int32_t uscore; From ab5adea24c7b603b58b2c57d39fc53a17dde9113 Mon Sep 17 00:00:00 2001 From: Wincent Holm Date: Sat, 3 Dec 2022 13:17:13 +0100 Subject: [PATCH 033/166] Move CDServer migration history table (#867) --- dDatabase/MigrationRunner.cpp | 37 +++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index fe0f933a..31fb9148 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -94,6 +94,10 @@ void MigrationRunner::RunMigrations() { } void MigrationRunner::RunSQLiteMigrations() { + auto cdstmt = CDClientDatabase::CreatePreppedStmt("CREATE TABLE IF NOT EXISTS migration_history (name TEXT NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);"); + cdstmt.execQuery().finalize(); + cdstmt.finalize(); + auto* stmt = Database::CreatePreppedStmt("CREATE TABLE IF NOT EXISTS migration_history (name TEXT NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP());"); stmt->execute(); delete stmt; @@ -103,13 +107,31 @@ void MigrationRunner::RunSQLiteMigrations() { if (migration.data.empty()) continue; + // Check if there is an entry in the migration history table on the cdclient database. + cdstmt = CDClientDatabase::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;"); + cdstmt.bind((int32_t) 1, migration.name.c_str()); + auto cdres = cdstmt.execQuery(); + bool doExit = !cdres.eof(); + cdres.finalize(); + cdstmt.finalize(); + + if (doExit) continue; + + // Check first if there is entry in the migration history table on the main database. stmt = Database::CreatePreppedStmt("SELECT name FROM migration_history WHERE name = ?;"); stmt->setString(1, migration.name.c_str()); auto* res = stmt->executeQuery(); - bool doExit = res->next(); + doExit = res->next(); delete res; delete stmt; - if (doExit) continue; + if (doExit) { + // Insert into cdclient database if there is an entry in the main database but not the cdclient database. + cdstmt = CDClientDatabase::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); + cdstmt.bind((int32_t) 1, migration.name.c_str()); + cdstmt.execQuery().finalize(); + cdstmt.finalize(); + continue; + } // Doing these 1 migration at a time since one takes a long time and some may think it is crashing. // This will at the least guarentee that the full migration needs to be run in order to be counted as "migrated". @@ -122,10 +144,13 @@ void MigrationRunner::RunSQLiteMigrations() { Game::logger->Log("MigrationRunner", "Encountered error running DML command: (%i) : %s", e.errorCode(), e.errorMessage()); } } - stmt = Database::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); - stmt->setString(1, migration.name); - stmt->execute(); - delete stmt; + + // Insert into cdclient database. + cdstmt = CDClientDatabase::CreatePreppedStmt("INSERT INTO migration_history (name) VALUES (?);"); + cdstmt.bind((int32_t) 1, migration.name.c_str()); + cdstmt.execQuery().finalize(); + cdstmt.finalize(); } + Game::logger->Log("MigrationRunner", "CDServer database is up to date."); } From de3e53de6cbcbf599d2c6f9fedbd14883ee6b0a1 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 4 Dec 2022 14:25:25 -0800 Subject: [PATCH 034/166] Fix Model Vault (#870) Allow pets, rockets and racecars to be stored in vault --- dGame/dComponents/InventoryComponent.cpp | 6 ++++-- dGame/dGameMessages/GameMessages.cpp | 14 +++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index acf1ae6a..8215664c 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -330,7 +330,9 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in const auto lot = item->GetLot(); - if (item->GetConfig().empty() && !item->GetBound() || (item->GetBound() && item->GetInfo().isBOP)) { + const auto subkey = item->GetSubKey(); + + if (subkey == LWOOBJID_EMPTY && item->GetConfig().empty() && (!item->GetBound() || (item->GetBound() && item->GetInfo().isBOP))) { auto left = std::min(count, origin->GetLotCount(lot)); while (left > 0) { @@ -361,7 +363,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in const auto delta = std::min(item->GetCount(), count); - AddItem(lot, delta, eLootSourceType::LOOT_SOURCE_NONE, inventory, config, LWOOBJID_EMPTY, showFlyingLot, isModMoveAndEquip, LWOOBJID_EMPTY, origin->GetType(), 0, item->GetBound(), preferredSlot); + AddItem(lot, delta, eLootSourceType::LOOT_SOURCE_NONE, inventory, config, LWOOBJID_EMPTY, showFlyingLot, isModMoveAndEquip, subkey, origin->GetType(), 0, item->GetBound(), preferredSlot); item->SetCount(item->GetCount() - delta, false, false); } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 6639197c..fcc25fdc 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4462,13 +4462,13 @@ void GameMessages::SendAddBuff(LWOOBJID& objectID, const LWOOBJID& casterID, uin // NT void GameMessages::HandleRequestMoveItemBetweenInventoryTypes(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - bool bAllowPartial; + bool bAllowPartial{}; int32_t destSlot = -1; int32_t iStackCount = 1; eInventoryType invTypeDst = ITEMS; eInventoryType invTypeSrc = ITEMS; LWOOBJID itemID = LWOOBJID_EMPTY; - bool showFlyingLoot; + bool showFlyingLoot{}; LWOOBJID subkey = LWOOBJID_EMPTY; LOT itemLOT = 0; @@ -4492,12 +4492,12 @@ void GameMessages::HandleRequestMoveItemBetweenInventoryTypes(RakNet::BitStream* if (itemID != LWOOBJID_EMPTY) { auto* item = inventoryComponent->FindItemById(itemID); - if (item == nullptr) { - return; - } + if (!item) return; - if (inventoryComponent->IsPet(item->GetSubKey()) || !item->GetConfig().empty()) { - return; + // Despawn the pet if we are moving that pet to the vault. + auto* petComponent = PetComponent::GetActivePet(entity->GetObjectID()); + if (petComponent && petComponent->GetDatabaseId() == item->GetSubKey()) { + inventoryComponent->DespawnPet(); } inventoryComponent->MoveItemToInventory(item, invTypeDst, iStackCount, showFlyingLoot, false, false, destSlot); From e8ba3357e8c28f22136babdcd6a6a9e489fc520c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 4 Dec 2022 14:25:58 -0800 Subject: [PATCH 035/166] Add support to reload the config (#868) --- dCommon/dConfig.cpp | 56 ++++++++----------- dCommon/dConfig.h | 24 ++++++-- .../dComponents/ScriptedActivityComponent.cpp | 18 +++++- dGame/dComponents/ScriptedActivityComponent.h | 12 ++++ dGame/dUtilities/SlashCommandHandler.cpp | 15 +++++ dMasterServer/MasterServer.cpp | 29 +++++----- dPhysics/dpGrid.cpp | 2 + dPhysics/dpGrid.h | 10 ++++ dPhysics/dpWorld.cpp | 44 +++++++++++---- dPhysics/dpWorld.h | 4 +- dWorldServer/WorldServer.cpp | 2 - 11 files changed, 150 insertions(+), 66 deletions(-) diff --git a/dCommon/dConfig.cpp b/dCommon/dConfig.cpp index 1bc940e8..f09a44c1 100644 --- a/dCommon/dConfig.cpp +++ b/dCommon/dConfig.cpp @@ -1,61 +1,53 @@ #include "dConfig.h" + #include + #include "BinaryPathFinder.h" +#include "GeneralUtils.h" dConfig::dConfig(const std::string& filepath) { - m_EmptyString = ""; - std::ifstream in(BinaryPathFinder::GetBinaryDir() / filepath); + m_ConfigFilePath = filepath; + LoadConfig(); +} + +void dConfig::LoadConfig() { + std::ifstream in(BinaryPathFinder::GetBinaryDir() / m_ConfigFilePath); if (!in.good()) return; - std::string line; + std::string line{}; while (std::getline(in, line)) { - if (line.length() > 0) { - if (line[0] != '#') ProcessLine(line); - } + if (!line.empty() && line.front() != '#') ProcessLine(line); } std::ifstream sharedConfig(BinaryPathFinder::GetBinaryDir() / "sharedconfig.ini", std::ios::in); if (!sharedConfig.good()) return; + line.clear(); while (std::getline(sharedConfig, line)) { - if (line.length() > 0) { - if (line[0] != '#') ProcessLine(line); - } + if (!line.empty() && line.front() != '#') ProcessLine(line); } } -dConfig::~dConfig(void) { +void dConfig::ReloadConfig() { + this->m_ConfigValues.clear(); + LoadConfig(); } const std::string& dConfig::GetValue(std::string key) { - for (size_t i = 0; i < m_Keys.size(); ++i) { - if (m_Keys[i] == key) return m_Values[i]; - } - - return m_EmptyString; + return this->m_ConfigValues[key]; } void dConfig::ProcessLine(const std::string& line) { - std::stringstream ss(line); - std::string segment; - std::vector seglist; + auto splitLine = GeneralUtils::SplitString(line, '='); - while (std::getline(ss, segment, '=')) { - seglist.push_back(segment); - } - - if (seglist.size() != 2) return; + if (splitLine.size() != 2) return; //Make sure that on Linux, we remove special characters: - if (!seglist[1].empty() && seglist[1][seglist[1].size() - 1] == '\r') - seglist[1].erase(seglist[1].size() - 1); + auto& key = splitLine.at(0); + auto& value = splitLine.at(1); + if (!value.empty() && value.at(value.size() - 1) == '\r') value.erase(value.size() - 1); - for (const auto& key : m_Keys) { - if (seglist[0] == key) { - return; // first loaded key is preferred due to loading shared config secondarily - } - } + if (this->m_ConfigValues.find(key) != this->m_ConfigValues.end()) return; - m_Keys.push_back(seglist[0]); - m_Values.push_back(seglist[1]); + this->m_ConfigValues.insert(std::make_pair(key, value)); } diff --git a/dCommon/dConfig.h b/dCommon/dConfig.h index 7764fa54..a6dd5df7 100644 --- a/dCommon/dConfig.h +++ b/dCommon/dConfig.h @@ -1,20 +1,34 @@ #pragma once #include +#include #include -#include class dConfig { public: dConfig(const std::string& filepath); - ~dConfig(void); + /** + * Gets the specified key from the config. Returns an empty string if the value is not found. + * + * @param key Key to find + * @return The keys value in the config + */ const std::string& GetValue(std::string key); + /** + * Loads the config from a file + */ + void LoadConfig(); + + /** + * Reloads the config file to reset values + */ + void ReloadConfig(); + private: void ProcessLine(const std::string& line); private: - std::vector m_Keys; - std::vector m_Values; - std::string m_EmptyString; + std::map m_ConfigValues; + std::string m_ConfigFilePath; }; diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 4b5ec41d..f6d50d66 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -19,8 +19,9 @@ #include "DestroyableComponent.h" ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { + m_ActivityID = activityID; CDActivitiesTable* activitiesTable = CDClientManager::Instance()->GetTable("Activities"); - std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == activityID); }); + std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); for (CDActivities activity : activities) { m_ActivityInfo = activity; @@ -88,6 +89,21 @@ void ScriptedActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool } } +void ScriptedActivityComponent::ReloadConfig() { + CDActivitiesTable* activitiesTable = CDClientManager::Instance()->GetTable("Activities"); + std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); + for (auto activity : activities) { + auto mapID = m_ActivityInfo.instanceMapID; + if ((mapID == 1203 || mapID == 1261 || mapID == 1303 || mapID == 1403) && Game::config->GetValue("solo_racing") == "1") { + m_ActivityInfo.minTeamSize = 1; + m_ActivityInfo.minTeams = 1; + } else { + m_ActivityInfo.minTeamSize = activity.minTeamSize; + m_ActivityInfo.minTeams = activity.minTeams; + } + } +} + void ScriptedActivityComponent::HandleMessageBoxResponse(Entity* player, const std::string& id) { if (m_ActivityInfo.ActivityID == 103) { return; diff --git a/dGame/dComponents/ScriptedActivityComponent.h b/dGame/dComponents/ScriptedActivityComponent.h index 66ca799f..8bb17093 100644 --- a/dGame/dComponents/ScriptedActivityComponent.h +++ b/dGame/dComponents/ScriptedActivityComponent.h @@ -276,6 +276,12 @@ public: */ ActivityInstance* GetInstance(const LWOOBJID playerID); + /** + * @brief Reloads the config settings for this component + * + */ + void ReloadConfig(); + /** * Removes all the instances */ @@ -361,6 +367,12 @@ private: * LMIs for team sizes */ std::unordered_map m_ActivityLootMatrices; + + /** + * The activity id + * + */ + int32_t m_ActivityID; }; #endif // SCRIPTEDACTIVITYCOMPONENT_H diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 79e61bae..60862c1a 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -65,6 +65,7 @@ #include "LevelProgressionComponent.h" #include "AssetManager.h" #include "BinaryPathFinder.h" +#include "dConfig.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; @@ -1766,6 +1767,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } + if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + Game::config->ReloadConfig(); + VanityUtilities::SpawnVanity(); + dpWorld::Instance().Reload(); + auto entities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY); + for (auto entity : entities) { + auto* scriptedActivityComponent = entity->GetComponent(); + if (!scriptedActivityComponent) continue; + + scriptedActivityComponent->ReloadConfig(); + } + ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!"); + } + if (chatCommand == "rollloot" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR && args.size() >= 3) { uint32_t lootMatrixIndex = 0; uint32_t targetLot = 0; diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 34e2f71a..0a387d8e 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -82,17 +82,15 @@ int main(int argc, char** argv) { Game::logger->Log("MasterServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("MasterServer", "Compiled on: %s", __TIMESTAMP__); - //Read our config: - dConfig config("masterconfig.ini"); - Game::config = &config; - Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); + Game::config = new dConfig("masterconfig.ini"); + Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); //Connect to the MySQL Database - std::string mysql_host = config.GetValue("mysql_host"); - std::string mysql_database = config.GetValue("mysql_database"); - std::string mysql_username = config.GetValue("mysql_username"); - std::string mysql_password = config.GetValue("mysql_password"); + std::string mysql_host = Game::config->GetValue("mysql_host"); + std::string mysql_database = Game::config->GetValue("mysql_database"); + std::string mysql_username = Game::config->GetValue("mysql_username"); + std::string mysql_password = Game::config->GetValue("mysql_password"); try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); @@ -103,7 +101,7 @@ int main(int argc, char** argv) { } try { - std::string clientPathStr = config.GetValue("client_location"); + std::string clientPathStr = Game::config->GetValue("client_location"); if (clientPathStr.empty()) clientPathStr = "./res"; std::filesystem::path clientPath = std::filesystem::path(clientPathStr); if (clientPath.is_relative()) { @@ -223,16 +221,16 @@ int main(int argc, char** argv) { int maxClients = 999; int ourPort = 1000; - if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); - if (config.GetValue("port") != "") ourPort = std::stoi(config.GetValue("port")); + if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); + if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port")); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master); //Query for the database for a server labeled "master" auto* masterLookupStatement = Database::CreatePreppedStmt("SELECT id FROM `servers` WHERE `name` = 'master'"); auto* result = masterLookupStatement->executeQuery(); - auto master_server_ip = config.GetValue("master_ip"); + auto master_server_ip = Game::config->GetValue("master_ip"); if (master_server_ip == "") { master_server_ip = Game::server->GetIP(); @@ -260,7 +258,7 @@ int main(int argc, char** argv) { Game::im = new InstanceManager(Game::logger, Game::server->GetIP()); //Depending on the config, start up servers: - if (config.GetValue("prestart_servers") != "" && config.GetValue("prestart_servers") == "1") { + if (Game::config->GetValue("prestart_servers") != "" && Game::config->GetValue("prestart_servers") == "1") { StartChatServer(); Game::im->GetInstance(0, false, 0)->SetIsReady(true); @@ -843,6 +841,7 @@ void ShutdownSequence() { int FinalizeShutdown() { //Delete our objects here: Database::Destroy("MasterServer"); + if (Game::config) delete Game::config; if (Game::im) delete Game::im; if (Game::server) delete Game::server; if (Game::logger) delete Game::logger; diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index 6e44ade9..b4fe385e 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -6,6 +6,7 @@ dpGrid::dpGrid(int numCells, int cellSize) { NUM_CELLS = numCells; CELL_SIZE = cellSize; + m_DeleteGrid = true; //dumb method but i can't be bothered @@ -23,6 +24,7 @@ dpGrid::dpGrid(int numCells, int cellSize) { } dpGrid::~dpGrid() { + if (!this->m_DeleteGrid) return; for (auto& x : m_Cells) { //x for (auto& y : x) { //y for (auto en : y) { diff --git a/dPhysics/dpGrid.h b/dPhysics/dpGrid.h index a10f165e..229e7449 100644 --- a/dPhysics/dpGrid.h +++ b/dPhysics/dpGrid.h @@ -23,6 +23,15 @@ public: void Update(float deltaTime); + /** + * Sets the delete grid parameter to value. When false, the grid will not clean up memory. + * + * @param value Whether or not to delete entities on deletion of the grid. + */ + void SetDeleteGrid(bool value) { this->m_DeleteGrid = value; }; + + std::vector>> GetCells() { return this->m_Cells; }; + private: void HandleEntity(dpEntity* entity, dpEntity* other); void HandleCell(int x, int z, float deltaTime); @@ -31,4 +40,5 @@ private: //cells on X, cells on Y for that X, then another vector that contains the entities within that cell. std::vector>> m_Cells; std::map m_GargantuanObjects; + bool m_DeleteGrid = true; }; diff --git a/dPhysics/dpWorld.cpp b/dPhysics/dpWorld.cpp index 510da518..70fbfa3a 100644 --- a/dPhysics/dpWorld.cpp +++ b/dPhysics/dpWorld.cpp @@ -9,7 +9,7 @@ #include "dLogger.h" #include "dConfig.h" -void dpWorld::Initialize(unsigned int zoneID) { +void dpWorld::Initialize(unsigned int zoneID, bool generateNewNavMesh) { phys_sp_tilecount = std::atoi(Game::config->GetValue("phys_sp_tilecount").c_str()); phys_sp_tilesize = std::atoi(Game::config->GetValue("phys_sp_tilesize").c_str()); @@ -21,13 +21,37 @@ void dpWorld::Initialize(unsigned int zoneID) { m_Grid = new dpGrid(phys_sp_tilecount, phys_sp_tilesize); } - m_NavMesh = new dNavMesh(zoneID); + if (generateNewNavMesh) m_NavMesh = new dNavMesh(zoneID); Game::logger->Log("dpWorld", "Physics world initialized!"); + m_ZoneID = zoneID; +} + +void dpWorld::Reload() { + if (m_Grid) { + m_Grid->SetDeleteGrid(false); + auto oldGridCells = m_Grid->GetCells(); + delete m_Grid; + m_Grid = nullptr; + + Initialize(m_ZoneID, false); + for (auto column : oldGridCells) { + for (auto row : column) { + for (auto entity : row) { + AddEntity(entity); + } + } + } + Game::logger->Log("dpWorld", "Successfully reloaded physics world!"); + } else { + Game::logger->Log("dpWorld", "No physics world to reload!"); + } } dpWorld::~dpWorld() { if (m_Grid) { + // Triple check this is true + m_Grid->SetDeleteGrid(true); delete m_Grid; m_Grid = nullptr; } @@ -103,14 +127,14 @@ bool dpWorld::ShouldUseSP(unsigned int zoneID) { // Only large maps should be added as tiling likely makes little difference on small maps. switch (zoneID) { - case 1100: // Avant Gardens - case 1200: // Nimbus Station - case 1300: // Gnarled Forest - case 1400: // Forbidden Valley - case 1800: // Crux Prime - case 1900: // Nexus Tower - case 2000: // Ninjago - return true; + case 1100: // Avant Gardens + case 1200: // Nimbus Station + case 1300: // Gnarled Forest + case 1400: // Forbidden Valley + case 1800: // Crux Prime + case 1900: // Nexus Tower + case 2000: // Ninjago + return true; } return false; diff --git a/dPhysics/dpWorld.h b/dPhysics/dpWorld.h index 45e550cb..d48435d0 100644 --- a/dPhysics/dpWorld.h +++ b/dPhysics/dpWorld.h @@ -19,7 +19,8 @@ class dpGrid; class dpWorld : public Singleton { public: - void Initialize(unsigned int zoneID); + void Initialize(unsigned int zoneID, bool generateNewNavMesh = true); + void Reload(); ~dpWorld(); @@ -43,4 +44,5 @@ private: std::vector m_DynamicEntites; dNavMesh* m_NavMesh = nullptr; + uint32_t m_ZoneID = 0; }; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index bbba1166..b4be7511 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -250,7 +250,6 @@ int main(int argc, char** argv) { //Load our level: if (zoneID != 0) { dpWorld::Instance().Initialize(zoneID); - Game::physicsWorld = &dpWorld::Instance(); //just in case some old code references it dZoneManager::Instance()->Initialize(LWOZONEID(zoneID, instanceID, cloneID)); g_CloneID = cloneID; @@ -1281,7 +1280,6 @@ void WorldShutdownSequence() { void FinalizeShutdown() { //Delete our objects here: - if (Game::physicsWorld) Game::physicsWorld = nullptr; if (Game::zoneManager) delete Game::zoneManager; Game::logger->Log("WorldServer", "Shutdown complete, zone (%i), instance (%i)", Game::server->GetZoneID(), instanceID); From 2ba3103a0c69252976f5114c67197be38753fabb Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 5 Dec 2022 00:57:58 -0800 Subject: [PATCH 036/166] Implement FDB to SQLite (#872) --- dCommon/CMakeLists.txt | 1 + dCommon/FdbToSqlite.cpp | 248 +++++++++++++++++++++++++++++++ dCommon/FdbToSqlite.h | 49 ++++++ dCommon/dEnums/eSqliteDataType.h | 16 ++ dDatabase/MigrationRunner.cpp | 2 + dMasterServer/MasterServer.cpp | 14 +- 6 files changed, 319 insertions(+), 11 deletions(-) create mode 100644 dCommon/FdbToSqlite.cpp create mode 100644 dCommon/FdbToSqlite.h create mode 100644 dCommon/dEnums/eSqliteDataType.h diff --git a/dCommon/CMakeLists.txt b/dCommon/CMakeLists.txt index 8d02186b..549acfb2 100644 --- a/dCommon/CMakeLists.txt +++ b/dCommon/CMakeLists.txt @@ -16,6 +16,7 @@ set(DCOMMON_SOURCES "AMFFormat.cpp" "ZCompression.cpp" "BrickByBrickFix.cpp" "BinaryPathFinder.cpp" + "FdbToSqlite.cpp" ) add_subdirectory(dClient) diff --git a/dCommon/FdbToSqlite.cpp b/dCommon/FdbToSqlite.cpp new file mode 100644 index 00000000..d98d4962 --- /dev/null +++ b/dCommon/FdbToSqlite.cpp @@ -0,0 +1,248 @@ +#include "FdbToSqlite.h" + +#include +#include +#include +#include + +#include "BinaryIO.h" +#include "CDClientDatabase.h" +#include "GeneralUtils.h" +#include "Game.h" +#include "dLogger.h" + +#include "eSqliteDataType.h" + +std::map FdbToSqlite::Convert::sqliteType = { + { eSqliteDataType::NONE, "none"}, + { eSqliteDataType::INT32, "int32"}, + { eSqliteDataType::REAL, "real"}, + { eSqliteDataType::TEXT_4, "text_4"}, + { eSqliteDataType::INT_BOOL, "int_bool"}, + { eSqliteDataType::INT64, "int64"}, + { eSqliteDataType::TEXT_8, "text_8"} +}; + +FdbToSqlite::Convert::Convert(std::string basePath) { + this->basePath = basePath; +} + +bool FdbToSqlite::Convert::ConvertDatabase() { + fdb.open(basePath + "/cdclient.fdb", std::ios::binary); + + try { + CDClientDatabase::Connect(basePath + "/CDServer.sqlite"); + + CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;"); + + int32_t numberOfTables = ReadInt32(); + ReadTables(numberOfTables); + + CDClientDatabase::ExecuteQuery("COMMIT;"); + } catch (CppSQLite3Exception& e) { + Game::logger->Log("FdbToSqlite", "Encountered error %s converting FDB to SQLite", e.errorMessage()); + return false; + } + + fdb.close(); + return true; +} + +int32_t FdbToSqlite::Convert::ReadInt32() { + uint32_t numberOfTables{}; + BinaryIO::BinaryRead(fdb, numberOfTables); + return numberOfTables; +} + +int64_t FdbToSqlite::Convert::ReadInt64() { + int32_t prevPosition = SeekPointer(); + + int64_t value{}; + BinaryIO::BinaryRead(fdb, value); + + fdb.seekg(prevPosition); + return value; +} + +std::string FdbToSqlite::Convert::ReadString() { + int32_t prevPosition = SeekPointer(); + + auto readString = BinaryIO::ReadString(fdb); + + fdb.seekg(prevPosition); + return readString; +} + +int32_t FdbToSqlite::Convert::SeekPointer() { + int32_t position{}; + BinaryIO::BinaryRead(fdb, position); + int32_t prevPosition = fdb.tellg(); + fdb.seekg(position); + return prevPosition; +} + +std::string FdbToSqlite::Convert::ReadColumnHeader() { + int32_t prevPosition = SeekPointer(); + + int32_t numberOfColumns = ReadInt32(); + std::string tableName = ReadString(); + + auto columns = ReadColumns(numberOfColumns); + std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");"; + CDClientDatabase::ExecuteDML(newTable); + + fdb.seekg(prevPosition); + + return tableName; +} + +void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables) { + int32_t prevPosition = SeekPointer(); + + for (int32_t i = 0; i < numberOfTables; i++) { + auto columnHeader = ReadColumnHeader(); + ReadRowHeader(columnHeader); + } + + fdb.seekg(prevPosition); +} + +std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns) { + std::stringstream columnsToCreate; + int32_t prevPosition = SeekPointer(); + + std::string name{}; + eSqliteDataType dataType{}; + for (int32_t i = 0; i < numberOfColumns; i++) { + if (i != 0) columnsToCreate << ", "; + dataType = static_cast(ReadInt32()); + name = ReadString(); + columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::sqliteType[dataType]; + } + + fdb.seekg(prevPosition); + return columnsToCreate.str(); +} + +void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName) { + int32_t prevPosition = SeekPointer(); + + int32_t numberOfAllocatedRows = ReadInt32(); + if (numberOfAllocatedRows != 0) assert((numberOfAllocatedRows & (numberOfAllocatedRows - 1)) == 0); // assert power of 2 allocation size + ReadRows(numberOfAllocatedRows, tableName); + + fdb.seekg(prevPosition); +} + +void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName) { + int32_t prevPosition = SeekPointer(); + + int32_t rowid = 0; + for (int32_t row = 0; row < numberOfAllocatedRows; row++) { + int32_t rowPointer = ReadInt32(); + if (rowPointer == -1) rowid++; + else ReadRow(rowid, rowPointer, tableName); + } + + fdb.seekg(prevPosition); +} + +void FdbToSqlite::Convert::ReadRow(int32_t& rowid, int32_t& position, std::string& tableName) { + int32_t prevPosition = fdb.tellg(); + fdb.seekg(position); + + while (true) { + ReadRowInfo(tableName); + int32_t linked = ReadInt32(); + + rowid += 1; + + if (linked == -1) break; + + fdb.seekg(linked); + } + + fdb.seekg(prevPosition); +} + +void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName) { + int32_t prevPosition = SeekPointer(); + + int32_t numberOfColumns = ReadInt32(); + ReadRowValues(numberOfColumns, tableName); + + fdb.seekg(prevPosition); +} + +void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName) { + int32_t prevPosition = SeekPointer(); + + int32_t emptyValue{}; + int32_t intValue{}; + float_t floatValue{}; + std::string stringValue{}; + int32_t boolValue{}; + int64_t int64Value{}; + bool insertedFirstEntry = false; + std::stringstream insertedRow; + insertedRow << "INSERT INTO " << tableName << " values ("; + + for (int32_t i = 0; i < numberOfColumns; i++) { + if (i != 0) insertedRow << ", "; // Only append comma and space after first entry in row. + switch (static_cast(ReadInt32())) { + case eSqliteDataType::NONE: + BinaryIO::BinaryRead(fdb, emptyValue); + assert(emptyValue == 0); + insertedRow << "\"\""; + break; + + case eSqliteDataType::INT32: + intValue = ReadInt32(); + insertedRow << intValue; + break; + + case eSqliteDataType::REAL: + BinaryIO::BinaryRead(fdb, floatValue); + insertedRow << std::fixed << std::setprecision(34) << floatValue; // maximum precision of floating point number + break; + + case eSqliteDataType::TEXT_4: + case eSqliteDataType::TEXT_8: { + stringValue = ReadString(); + size_t position = 0; + + // Need to escape quote with a double of ". + while (position < stringValue.size()) { + if (stringValue.at(position) == '\"') { + stringValue.insert(position, "\""); + position++; + } + position++; + } + insertedRow << "\"" << stringValue << "\""; + break; + } + + case eSqliteDataType::INT_BOOL: + BinaryIO::BinaryRead(fdb, boolValue); + insertedRow << static_cast(boolValue); + break; + + case eSqliteDataType::INT64: + int64Value = ReadInt64(); + insertedRow << std::to_string(int64Value); + break; + + default: + throw std::invalid_argument("Unsupported SQLite type encountered."); + break; + + } + } + + insertedRow << ");"; + + auto copiedString = insertedRow.str(); + CDClientDatabase::ExecuteDML(copiedString); + fdb.seekg(prevPosition); +} diff --git a/dCommon/FdbToSqlite.h b/dCommon/FdbToSqlite.h new file mode 100644 index 00000000..a9611220 --- /dev/null +++ b/dCommon/FdbToSqlite.h @@ -0,0 +1,49 @@ +#ifndef __FDBTOSQLITE__H__ +#define __FDBTOSQLITE__H__ + +#pragma once + +#include +#include +#include + +enum class eSqliteDataType : int32_t; + +namespace FdbToSqlite { + class Convert { + public: + Convert(std::string inputFile); + + bool ConvertDatabase(); + + int32_t ReadInt32(); + + int64_t ReadInt64(); + + std::string ReadString(); + + int32_t SeekPointer(); + + std::string ReadColumnHeader(); + + void ReadTables(int32_t& numberOfTables); + + std::string ReadColumns(int32_t& numberOfColumns); + + void ReadRowHeader(std::string& tableName); + + void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName); + + void ReadRow(int32_t& rowid, int32_t& position, std::string& tableName); + + void ReadRowInfo(std::string& tableName); + + void ReadRowValues(int32_t& numberOfColumns, std::string& tableName); + private: + static std::map sqliteType; + std::string basePath{}; + std::ifstream fdb{}; + }; // class FdbToSqlite +}; //! namespace FdbToSqlite + +#endif //!__FDBTOSQLITE__H__ diff --git a/dCommon/dEnums/eSqliteDataType.h b/dCommon/dEnums/eSqliteDataType.h new file mode 100644 index 00000000..26e1233b --- /dev/null +++ b/dCommon/dEnums/eSqliteDataType.h @@ -0,0 +1,16 @@ +#ifndef __ESQLITEDATATYPE__H__ +#define __ESQLITEDATATYPE__H__ + +#include + +enum class eSqliteDataType : int32_t { + NONE = 0, + INT32, + REAL = 3, + TEXT_4, + INT_BOOL, + INT64, + TEXT_8 = 8 +}; + +#endif //!__ESQLITEDATATYPE__H__ diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index 31fb9148..d39201b2 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -136,6 +136,7 @@ void MigrationRunner::RunSQLiteMigrations() { // Doing these 1 migration at a time since one takes a long time and some may think it is crashing. // This will at the least guarentee that the full migration needs to be run in order to be counted as "migrated". Game::logger->Log("MigrationRunner", "Executing migration: %s. This may take a while. Do not shut down server.", migration.name.c_str()); + CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;"); for (const auto& dml : GeneralUtils::SplitString(migration.data, ';')) { if (dml.empty()) continue; try { @@ -150,6 +151,7 @@ void MigrationRunner::RunSQLiteMigrations() { cdstmt.bind((int32_t) 1, migration.name.c_str()); cdstmt.execQuery().finalize(); cdstmt.finalize(); + CDClientDatabase::ExecuteQuery("COMMIT;"); } Game::logger->Log("MigrationRunner", "CDServer database is up to date."); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 0a387d8e..0329d9a0 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -40,6 +40,7 @@ #include "ObjectIDManager.h" #include "PacketUtils.h" #include "dMessageIdentifiers.h" +#include "FdbToSqlite.h" namespace Game { dLogger* logger; @@ -126,18 +127,9 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - Game::logger->Log("WorldServer", "Found cdclient.fdb. Clearing cdserver migration_history then copying and converting to sqlite."); - auto stmt = Database::CreatePreppedStmt(R"#(DELETE FROM migration_history WHERE name LIKE "%cdserver%";)#"); - stmt->executeUpdate(); - delete stmt; + Game::logger->Log("WorldServer", "Found cdclient.fdb. Converting to SQLite"); - std::string res = "python3 " - + (BinaryPathFinder::GetBinaryDir() / "../thirdparty/docker-utils/utils/fdb_to_sqlite.py").string() - + " --sqlite_path " + (Game::assetManager->GetResPath() / "CDServer.sqlite").string() - + " " + (Game::assetManager->GetResPath() / "cdclient.fdb").string(); - - int result = system(res.c_str()); - if (result != 0) { + if (FdbToSqlite::Convert(Game::assetManager->GetResPath().string()).ConvertDatabase() == false) { Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite"); return EXIT_FAILURE; } From 0a616f891fd4e09bd52c5d68f56099cf62ea7954 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 5 Dec 2022 07:04:59 -0800 Subject: [PATCH 037/166] Change File Finder (#873) --- dCommon/GeneralUtils.cpp | 65 +++++++++++++---------------------- dCommon/GeneralUtils.h | 3 +- dDatabase/MigrationRunner.cpp | 4 +-- 3 files changed, 27 insertions(+), 45 deletions(-) diff --git a/dCommon/GeneralUtils.cpp b/dCommon/GeneralUtils.cpp index 24ea72a0..54ef5661 100644 --- a/dCommon/GeneralUtils.cpp +++ b/dCommon/GeneralUtils.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include template inline size_t MinSize(size_t size, const std::basic_string_view& string) { @@ -290,51 +292,30 @@ std::u16string GeneralUtils::ReadWString(RakNet::BitStream* inStream) { return string; } -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include - -std::vector GeneralUtils::GetFileNamesFromFolder(const std::string& folder) { - std::vector names; - std::string search_path = folder + "/*.*"; - WIN32_FIND_DATA fd; - HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); - if (hFind != INVALID_HANDLE_VALUE) { - do { - if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - names.push_back(fd.cFileName); - } - } while (::FindNextFile(hFind, &fd)); - ::FindClose(hFind); - } - return names; -} -#else -#include -#include -#include -#include -#include -#include - -std::vector GeneralUtils::GetFileNamesFromFolder(const std::string& folder) { - std::vector names; - struct dirent* entry; - DIR* dir = opendir(folder.c_str()); - if (dir == NULL) { - return names; +std::vector GeneralUtils::GetSqlFileNamesFromFolder(const std::string& folder) { + // Because we dont know how large the initial number before the first _ is we need to make it a map like so. + std::map filenames{}; + for (auto& t : std::filesystem::directory_iterator(folder)) { + auto filename = t.path().filename().string(); + auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0)); + filenames.insert(std::make_pair(index, filename)); } - while ((entry = readdir(dir)) != NULL) { - std::string value(entry->d_name, strlen(entry->d_name)); - if (value == "." || value == "..") { - continue; + // Now sort the map by the oldest migration. + std::vector sortedFiles{}; + auto fileIterator = filenames.begin(); + std::map::iterator oldest = filenames.begin(); + while (!filenames.empty()) { + if (fileIterator == filenames.end()) { + sortedFiles.push_back(oldest->second); + filenames.erase(oldest); + fileIterator = filenames.begin(); + oldest = filenames.begin(); + continue; } - names.push_back(value); + if (oldest->first > fileIterator->first) oldest = fileIterator; + fileIterator++; } - closedir(dir); - - return names; + return sortedFiles; } -#endif diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 898616d2..af7c7012 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -12,6 +12,7 @@ #include #include "Game.h" +#include "dLogger.h" /*! \file GeneralUtils.hpp @@ -138,7 +139,7 @@ namespace GeneralUtils { std::vector SplitString(const std::string& str, char delimiter); - std::vector GetFileNamesFromFolder(const std::string& folder); + std::vector GetSqlFileNamesFromFolder(const std::string& folder); template T Parse(const char* value); diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index d39201b2..54def9e2 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -38,7 +38,7 @@ void MigrationRunner::RunMigrations() { sql::SQLString finalSQL = ""; bool runSd0Migrations = false; - for (const auto& entry : GeneralUtils::GetFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "./migrations/dlu/").string())) { + for (const auto& entry : GeneralUtils::GetSqlFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "./migrations/dlu/").string())) { auto migration = LoadMigration("dlu/" + entry); if (migration.data.empty()) { @@ -102,7 +102,7 @@ void MigrationRunner::RunSQLiteMigrations() { stmt->execute(); delete stmt; - for (const auto& entry : GeneralUtils::GetFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "migrations/cdserver/").string())) { + for (const auto& entry : GeneralUtils::GetSqlFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "migrations/cdserver/").string())) { auto migration = LoadMigration("cdserver/" + entry); if (migration.data.empty()) continue; From 18a0ae599bcf3976b01e5550607a9d3abf04b9df Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 5 Dec 2022 16:08:47 -0800 Subject: [PATCH 038/166] Add bandwidth limit of 10kb/s(#863) --- dAuthServer/AuthServer.cpp | 2 +- dChatServer/ChatServer.cpp | 2 +- dGame/dUtilities/SlashCommandHandler.cpp | 1 + dMasterServer/MasterServer.cpp | 2 +- dNet/dServer.cpp | 11 +++++++++-- dNet/dServer.h | 5 ++++- dWorldServer/WorldServer.cpp | 2 +- resources/sharedconfig.ini | 3 +++ 8 files changed, 21 insertions(+), 7 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 9621f683..a9f02f53 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -83,7 +83,7 @@ int main(int argc, char** argv) { if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth); + Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index e0073747..e3c6d6e9 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -103,7 +103,7 @@ int main(int argc, char** argv) { if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat); + Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 60862c1a..9b37d4b8 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1778,6 +1778,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit scriptedActivityComponent->ReloadConfig(); } + Game::server->UpdateBandwidthLimit(); ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!"); } diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 0329d9a0..4acb9b26 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -216,7 +216,7 @@ int main(int argc, char** argv) { if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port")); - Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config); //Query for the database for a server labeled "master" auto* masterLookupStatement = Database::CreatePreppedStmt("SELECT id FROM `servers` WHERE `name` = 'master'"); diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index c46b156c..481667b8 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -2,6 +2,7 @@ #include "dServer.h" #include "dNetCommon.h" #include "dLogger.h" +#include "dConfig.h" #include "RakNetworkFactory.h" #include "MessageIdentifiers.h" @@ -35,7 +36,7 @@ public: } } ReceiveDownloadCompleteCB; -dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, unsigned int zoneID) { +dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, unsigned int zoneID) { mIP = ip; mPort = port; mZoneID = zoneID; @@ -50,6 +51,7 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect mNetIDManager = nullptr; mReplicaManager = nullptr; mServerType = serverType; + mConfig = config; //Attempt to start our server here: mIsOkay = Startup(); @@ -181,7 +183,7 @@ bool dServer::Startup() { if (mIsInternal) { mPeer->SetIncomingPassword("3.25 DARKFLAME1", 15); } else { - //mPeer->SetPerConnectionOutgoingBandwidthLimit(800000); //100Kb/s + UpdateBandwidthLimit(); mPeer->SetIncomingPassword("3.25 ND1", 8); } @@ -191,6 +193,11 @@ bool dServer::Startup() { return true; } +void dServer::UpdateBandwidthLimit() { + auto newBandwidth = mConfig->GetValue("maximum_outgoing_bandwidth"); + mPeer->SetPerConnectionOutgoingBandwidthLimit(!newBandwidth.empty() ? std::stoi(newBandwidth) : 0); +} + void dServer::Shutdown() { if (mPeer) { mPeer->Shutdown(1000); diff --git a/dNet/dServer.h b/dNet/dServer.h index 264932ee..0fbdecce 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -5,6 +5,7 @@ #include "NetworkIDManager.h" class dLogger; +class dConfig; enum class ServerType : uint32_t { Master, @@ -17,7 +18,7 @@ class dServer { public: // Default constructor should only used for testing! dServer() {}; - dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, unsigned int zoneID = 0); + dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, unsigned int zoneID = 0); ~dServer(); Packet* ReceiveFromMaster(); @@ -42,6 +43,7 @@ public: const int GetInstanceID() const { return mInstanceID; } ReplicaManager* GetReplicaManager() { return mReplicaManager; } void UpdateReplica(); + void UpdateBandwidthLimit(); int GetPing(const SystemAddress& sysAddr) const; int GetLatestPing(const SystemAddress& sysAddr) const; @@ -58,6 +60,7 @@ private: private: dLogger* mLogger = nullptr; + dConfig* mConfig = nullptr; RakPeerInterface* mPeer = nullptr; ReplicaManager* mReplicaManager = nullptr; NetworkIDManager* mNetIDManager = nullptr; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index b4be7511..acd38ad3 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -208,7 +208,7 @@ int main(int argc, char** argv) { LootGenerator::Instance(); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); - Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, zoneID); + Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, zoneID); //Connect to the chat server: int chatPort = 1501; diff --git a/resources/sharedconfig.ini b/resources/sharedconfig.ini index 847a6b7c..439ffe2f 100644 --- a/resources/sharedconfig.ini +++ b/resources/sharedconfig.ini @@ -25,3 +25,6 @@ dump_folder= # The location of the client # Either the folder with /res or with /client and /versions client_location= + +# The maximum outgoing bandwidth in bits +maximum_outgoing_bandwidth=80000 From 46f085eb4ba5a3c956eb9b0eaecb6fced5e39e3c Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 6 Dec 2022 04:39:09 -0800 Subject: [PATCH 039/166] Resolve warnings and change init order Initialize dConfig first, before logger so we know whether or not to log to console Initialize namespace Game variables to nullptr so they are a known value if accessed before initialization. Removed unused Game variables Replaced config with a pointer instead of referencing something on the stack. Assign return values to system calls to silence warnings. Tested that the server still compiles, runs and allows me to load into the game. --- dAuthServer/AuthServer.cpp | 38 +++++++------- dChatServer/ChatServer.cpp | 46 ++++++++--------- dCommon/Game.h | 2 - dMasterServer/InstanceManager.cpp | 4 +- dMasterServer/MasterServer.cpp | 34 ++++++------- dWorldServer/WorldServer.cpp | 71 ++++++++++++--------------- tests/dGameTests/GameDependencies.cpp | 1 - 7 files changed, 92 insertions(+), 104 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index a9f02f53..4999b62e 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -22,9 +22,9 @@ #include "Game.h" namespace Game { - dLogger* logger; - dServer* server; - dConfig* config; + dLogger* logger = nullptr; + dServer* server = nullptr; + dConfig* config = nullptr; } dLogger* SetupLogger(); @@ -37,22 +37,22 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(); - if (!Game::logger) return 0; + if (!Game::logger) return EXIT_FAILURE; + + //Read our config: + Game::config = new dConfig("authconfig.ini"); + Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + Game::logger->Log("AuthServer", "Starting Auth server..."); Game::logger->Log("AuthServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("AuthServer", "Compiled on: %s", __TIMESTAMP__); - //Read our config: - dConfig config("authconfig.ini"); - Game::config = &config; - Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); - //Connect to the MySQL Database - std::string mysql_host = config.GetValue("mysql_host"); - std::string mysql_database = config.GetValue("mysql_database"); - std::string mysql_username = config.GetValue("mysql_username"); - std::string mysql_password = config.GetValue("mysql_password"); + std::string mysql_host = Game::config->GetValue("mysql_host"); + std::string mysql_database = Game::config->GetValue("mysql_database"); + std::string mysql_username = Game::config->GetValue("mysql_username"); + std::string mysql_password = Game::config->GetValue("mysql_password"); try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); @@ -61,7 +61,7 @@ int main(int argc, char** argv) { Database::Destroy("AuthServer"); delete Game::server; delete Game::logger; - return 0; + return EXIT_FAILURE; } //Find out the master's IP: @@ -80,10 +80,10 @@ int main(int argc, char** argv) { //It's safe to pass 'localhost' here, as the IP is only used as the external IP. int maxClients = 50; int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. - if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); - if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); + if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); + if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); @@ -145,8 +145,8 @@ int main(int argc, char** argv) { Database::Destroy("AuthServer"); delete Game::server; delete Game::logger; + delete Game::config; - exit(EXIT_SUCCESS); return EXIT_SUCCESS; } diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index e3c6d6e9..2c36b222 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -20,11 +20,11 @@ #include "Game.h" namespace Game { - dLogger* logger; - dServer* server; - dConfig* config; - dChatFilter* chatFilter; - AssetManager* assetManager; + dLogger* logger = nullptr; + dServer* server = nullptr; + dConfig* config = nullptr; + dChatFilter* chatFilter = nullptr; + AssetManager* assetManager = nullptr; } //RakNet includes: @@ -42,19 +42,19 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(); - if (!Game::logger) return 0; + if (!Game::logger) return EXIT_FAILURE; + + //Read our config: + Game::config = new dConfig("chatconfig.ini"); + Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + Game::logger->Log("ChatServer", "Starting Chat server..."); Game::logger->Log("ChatServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("ChatServer", "Compiled on: %s", __TIMESTAMP__); - //Read our config: - dConfig config("chatconfig.ini"); - Game::config = &config; - Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); - try { - std::string clientPathStr = config.GetValue("client_location"); + std::string clientPathStr = Game::config->GetValue("client_location"); if (clientPathStr.empty()) clientPathStr = "./res"; std::filesystem::path clientPath = std::filesystem::path(clientPathStr); if (clientPath.is_relative()) { @@ -69,10 +69,10 @@ int main(int argc, char** argv) { } //Connect to the MySQL Database - std::string mysql_host = config.GetValue("mysql_host"); - std::string mysql_database = config.GetValue("mysql_database"); - std::string mysql_username = config.GetValue("mysql_username"); - std::string mysql_password = config.GetValue("mysql_password"); + std::string mysql_host = Game::config->GetValue("mysql_host"); + std::string mysql_database = Game::config->GetValue("mysql_database"); + std::string mysql_username = Game::config->GetValue("mysql_username"); + std::string mysql_password = Game::config->GetValue("mysql_password"); try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); @@ -81,7 +81,7 @@ int main(int argc, char** argv) { Database::Destroy("ChatServer"); delete Game::server; delete Game::logger; - return 0; + return EXIT_FAILURE; } //Find out the master's IP: @@ -100,12 +100,12 @@ int main(int argc, char** argv) { //It's safe to pass 'localhost' here, as the IP is only used as the external IP. int maxClients = 50; int ourPort = 1501; - if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); - if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); + if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); + if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config); - Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); + Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); @@ -167,8 +167,8 @@ int main(int argc, char** argv) { Database::Destroy("ChatServer"); delete Game::server; delete Game::logger; + delete Game::config; - exit(EXIT_SUCCESS); return EXIT_SUCCESS; } diff --git a/dCommon/Game.h b/dCommon/Game.h index 1c4bbc85..38cadb70 100644 --- a/dCommon/Game.h +++ b/dCommon/Game.h @@ -5,7 +5,6 @@ class dServer; class dLogger; class InstanceManager; -class dpWorld; class dChatFilter; class dConfig; class RakPeerInterface; @@ -16,7 +15,6 @@ namespace Game { extern dLogger* logger; extern dServer* server; extern InstanceManager* im; - extern dpWorld* physicsWorld; extern dChatFilter* chatFilter; extern dConfig* config; extern std::mt19937 randomEngine; diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index 83378dbb..a1983dd4 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -74,7 +74,7 @@ Instance* InstanceManager::GetInstance(LWOMAPID mapID, bool isFriendTransfer, LW cmd.append("&"); //Sends our next process to the background on Linux #endif - system(cmd.c_str()); + auto ret = system(cmd.c_str()); m_Instances.push_back(instance); @@ -322,7 +322,7 @@ Instance* InstanceManager::CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID clon cmd.append("&"); //Sends our next process to the background on Linux #endif - system(cmd.c_str()); + auto ret = system(cmd.c_str()); m_Instances.push_back(instance); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 4acb9b26..a4aa270a 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -43,11 +43,11 @@ #include "FdbToSqlite.h" namespace Game { - dLogger* logger; - dServer* server; - InstanceManager* im; - dConfig* config; - AssetManager* assetManager; + dLogger* logger = nullptr; + dServer* server = nullptr; + InstanceManager* im = nullptr; + dConfig* config = nullptr; + AssetManager* assetManager = nullptr; } //namespace Game bool shutdownSequenceStarted = false; @@ -79,14 +79,14 @@ int main(int argc, char** argv) { Game::logger = SetupLogger(); if (!Game::logger) return EXIT_FAILURE; - Game::logger->Log("MasterServer", "Starting Master server..."); - Game::logger->Log("MasterServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); - Game::logger->Log("MasterServer", "Compiled on: %s", __TIMESTAMP__); - Game::config = new dConfig("masterconfig.ini"); Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + Game::logger->Log("MasterServer", "Starting Master server..."); + Game::logger->Log("MasterServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); + Game::logger->Log("MasterServer", "Compiled on: %s", __TIMESTAMP__); + //Connect to the MySQL Database std::string mysql_host = Game::config->GetValue("mysql_host"); std::string mysql_database = Game::config->GetValue("mysql_database"); @@ -732,28 +732,28 @@ void HandlePacket(Packet* packet) { void StartChatServer() { #ifdef __APPLE__ //macOS doesn't need sudo to run on ports < 1024 - system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); #elif _WIN32 - system(("start " + (BinaryPathFinder::GetBinaryDir() / "ChatServer.exe").string()).c_str()); + auto result = system(("start " + (BinaryPathFinder::GetBinaryDir() / "ChatServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_chat").c_str())) { - system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } else { - system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } #endif } void StartAuthServer() { #ifdef __APPLE__ - system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); #elif _WIN32 - system(("start " + (BinaryPathFinder::GetBinaryDir() / "AuthServer.exe").string()).c_str()); + auto result = system(("start " + (BinaryPathFinder::GetBinaryDir() / "AuthServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_auth").c_str())) { - system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } else { - system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } #endif } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index acd38ad3..5887597d 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -61,17 +61,14 @@ #include "ZCompression.h" namespace Game { - dLogger* logger; - dServer* server; - dZoneManager* zoneManager; - dpWorld* physicsWorld; - dChatFilter* chatFilter; - dConfig* config; + dLogger* logger = nullptr; + dServer* server = nullptr; + dpWorld* physicsWorld = nullptr; + dChatFilter* chatFilter = nullptr; + dConfig* config = nullptr; + AssetManager* assetManager = nullptr; + RakPeerInterface* chatServer = nullptr; std::mt19937 randomEngine; - - AssetManager* assetManager; - - RakPeerInterface* chatServer; SystemAddress chatSysAddr; } @@ -127,26 +124,21 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(zoneID, instanceID); - if (!Game::logger) return 0; + if (!Game::logger) return EXIT_FAILURE; + + //Read our config: + Game::config = new dConfig("worldconfig.ini"); + Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); - Game::logger->SetLogToConsole(true); //We want this info to always be logged. Game::logger->Log("WorldServer", "Starting World server..."); Game::logger->Log("WorldServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("WorldServer", "Compiled on: %s", __TIMESTAMP__); -#ifndef _DEBUG - Game::logger->SetLogToConsole(false); //By default, turn it back off if not in debug. -#endif - - //Read our config: - dConfig config("worldconfig.ini"); - Game::config = &config; - Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); - if (config.GetValue("disable_chat") == "1") chatDisabled = true; + if (Game::config->GetValue("disable_chat") == "1") chatDisabled = true; try { - std::string clientPathStr = config.GetValue("client_location"); + std::string clientPathStr = Game::config->GetValue("client_location"); if (clientPathStr.empty()) clientPathStr = "./res"; std::filesystem::path clientPath = std::filesystem::path(clientPathStr); if (clientPath.is_relative()) { @@ -166,28 +158,28 @@ int main(int argc, char** argv) { Game::logger->Log("WorldServer", "Unable to connect to CDServer SQLite Database"); Game::logger->Log("WorldServer", "Error: %s", e.errorMessage()); Game::logger->Log("WorldServer", "Error Code: %i", e.errorCode()); - return -1; + return EXIT_FAILURE; } CDClientManager::Instance()->Initialize(); //Connect to the MySQL Database - std::string mysql_host = config.GetValue("mysql_host"); - std::string mysql_database = config.GetValue("mysql_database"); - std::string mysql_username = config.GetValue("mysql_username"); - std::string mysql_password = config.GetValue("mysql_password"); + std::string mysql_host = Game::config->GetValue("mysql_host"); + std::string mysql_database = Game::config->GetValue("mysql_database"); + std::string mysql_username = Game::config->GetValue("mysql_username"); + std::string mysql_password = Game::config->GetValue("mysql_password"); - Diagnostics::SetProduceMemoryDump(config.GetValue("generate_dump") == "1"); + Diagnostics::SetProduceMemoryDump(Game::config->GetValue("generate_dump") == "1"); - if (!config.GetValue("dump_folder").empty()) { - Diagnostics::SetOutDirectory(config.GetValue("dump_folder")); + if (!Game::config->GetValue("dump_folder").empty()) { + Diagnostics::SetOutDirectory(Game::config->GetValue("dump_folder")); } try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); } catch (sql::SQLException& ex) { Game::logger->Log("WorldServer", "Got an error while connecting to the database: %s", ex.what()); - return 0; + return EXIT_FAILURE; } //Find out the master's IP: @@ -206,13 +198,13 @@ int main(int argc, char** argv) { ObjectIDManager::Instance()->Initialize(); UserManager::Instance()->Initialize(); LootGenerator::Instance(); - Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); + Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, zoneID); //Connect to the chat server: int chatPort = 1501; - if (config.GetValue("chat_server_port") != "") chatPort = std::atoi(config.GetValue("chat_server_port").c_str()); + if (Game::config->GetValue("chat_server_port") != "") chatPort = std::atoi(Game::config->GetValue("chat_server_port").c_str()); auto chatSock = SocketDescriptor(uint16_t(ourPort + 2), 0); Game::chatServer = RakNetworkFactory::GetRakPeerInterface(); @@ -1279,16 +1271,15 @@ void WorldShutdownSequence() { } void FinalizeShutdown() { - //Delete our objects here: - if (Game::zoneManager) delete Game::zoneManager; - Game::logger->Log("WorldServer", "Shutdown complete, zone (%i), instance (%i)", Game::server->GetZoneID(), instanceID); + //Delete our objects here: Metrics::Clear(); Database::Destroy("WorldServer"); - delete Game::chatFilter; - delete Game::server; - delete Game::logger; + if (Game::chatFilter) delete Game::chatFilter; + if (Game::server) delete Game::server; + if (Game::logger) delete Game::logger; + if (Game::config) delete Game::config; worldShutdownSequenceComplete = true; diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index 5ac3339a..7b0a8412 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -4,7 +4,6 @@ namespace Game { dLogger* logger; dServer* server; dZoneManager* zoneManager; - dpWorld* physicsWorld; dChatFilter* chatFilter; dConfig* config; std::mt19937 randomEngine; From fde62a47773f02abdb3beed76d959cd86751f050 Mon Sep 17 00:00:00 2001 From: Demetri Van Sickle Date: Tue, 6 Dec 2022 06:36:42 -0800 Subject: [PATCH 040/166] Fixed typo (#875) --- migrations/dlu/7_make_play_key_id_nullable.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/dlu/7_make_play_key_id_nullable.sql b/migrations/dlu/7_make_play_key_id_nullable.sql index 7491874f..11239967 100644 --- a/migrations/dlu/7_make_play_key_id_nullable.sql +++ b/migrations/dlu/7_make_play_key_id_nullable.sql @@ -1 +1 @@ -ALTER TABLE account MODIFY play_key_id INT DEFAULT 0; +ALTER TABLE accounts MODIFY play_key_id INT DEFAULT 0; From a14e16237b8d20a1b43fc5770169c5d3ca4b5ad1 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:30:43 -0800 Subject: [PATCH 041/166] Only start Master of config files exist Also default the logging to console to on on the off chance the files exist but are wrong / corrupted. --- dAuthServer/AuthServer.cpp | 4 ++-- dChatServer/ChatServer.cpp | 4 ++-- dMasterServer/MasterServer.cpp | 29 +++++++++++++++++++++++++++-- dWorldServer/WorldServer.cpp | 4 ++-- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 4999b62e..aefc822b 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -40,8 +40,8 @@ int main(int argc, char** argv) { if (!Game::logger) return EXIT_FAILURE; //Read our config: - Game::config = new dConfig("authconfig.ini"); - Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "authconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); Game::logger->Log("AuthServer", "Starting Auth server..."); diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index 2c36b222..043e7869 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -45,8 +45,8 @@ int main(int argc, char** argv) { if (!Game::logger) return EXIT_FAILURE; //Read our config: - Game::config = new dConfig("chatconfig.ini"); - Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "chatconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); Game::logger->Log("ChatServer", "Starting Chat server..."); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index a4aa270a..4c18566e 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -79,8 +79,33 @@ int main(int argc, char** argv) { Game::logger = SetupLogger(); if (!Game::logger) return EXIT_FAILURE; - Game::config = new dConfig("masterconfig.ini"); - Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "authconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find authconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "chatconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find chatconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "masterconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find masterconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "sharedconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find sharedconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "worldconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find worldconfig.ini"); + return EXIT_FAILURE; + } + + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "masterconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); Game::logger->Log("MasterServer", "Starting Master server..."); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 5887597d..68ec0e57 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -127,8 +127,8 @@ int main(int argc, char** argv) { if (!Game::logger) return EXIT_FAILURE; //Read our config: - Game::config = new dConfig("worldconfig.ini"); - Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "worldconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); Game::logger->Log("WorldServer", "Starting World server..."); From 8886bf65475ff3cea82d5229d900e68828975f4f Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 8 Dec 2022 00:13:25 -0700 Subject: [PATCH 042/166] Address Force movement behaviors triggering twice (#878) --- dGame/dBehaviors/ForceMovementBehavior.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dBehaviors/ForceMovementBehavior.cpp b/dGame/dBehaviors/ForceMovementBehavior.cpp index 55cda622..e1ac6133 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.cpp +++ b/dGame/dBehaviors/ForceMovementBehavior.cpp @@ -75,5 +75,5 @@ void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::Bi this->m_hitAction->Calculate(context, bitStream, branch); this->m_hitEnemyAction->Calculate(context, bitStream, branch); - this->m_hitEnemyAction->Calculate(context, bitStream, branch); + this->m_hitFactionAction->Calculate(context, bitStream, branch); } From d5613b8034ea8594db6818606fe085a47c455611 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 8 Dec 2022 04:44:56 -0800 Subject: [PATCH 043/166] hot fix --- dCommon/FdbToSqlite.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dCommon/FdbToSqlite.cpp b/dCommon/FdbToSqlite.cpp index d98d4962..6015fd3a 100644 --- a/dCommon/FdbToSqlite.cpp +++ b/dCommon/FdbToSqlite.cpp @@ -49,9 +49,9 @@ bool FdbToSqlite::Convert::ConvertDatabase() { } int32_t FdbToSqlite::Convert::ReadInt32() { - uint32_t numberOfTables{}; - BinaryIO::BinaryRead(fdb, numberOfTables); - return numberOfTables; + int32_t nextInt{}; + BinaryIO::BinaryRead(fdb, nextInt); + return nextInt; } int64_t FdbToSqlite::Convert::ReadInt64() { @@ -193,7 +193,7 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& case eSqliteDataType::NONE: BinaryIO::BinaryRead(fdb, emptyValue); assert(emptyValue == 0); - insertedRow << "\"\""; + insertedRow << "NULL"; break; case eSqliteDataType::INT32: From da910309a043f50821a388531ace407507cf1e95 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 8 Dec 2022 13:32:47 -0800 Subject: [PATCH 044/166] Remove unneeded commands (#880) * Remove unneeded commands * Thank you aron --- dGame/dUtilities/SlashCommandHandler.cpp | 16 ---------------- docs/Commands.md | 2 -- 2 files changed, 18 deletions(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 9b37d4b8..89f11346 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -212,22 +212,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "skip-ags") { - auto* missionComponent = entity->GetComponent(); - - if (missionComponent != nullptr && missionComponent->HasMission(479)) { - missionComponent->CompleteMission(479); - } - } - - if (chatCommand == "skip-sg") { - auto* missionComponent = entity->GetComponent(); - - if (missionComponent != nullptr && missionComponent->HasMission(229)) { - missionComponent->CompleteMission(229); - } - } - if (chatCommand == "fix-stats") { // Reset skill component and buff component auto* skillComponent = entity->GetComponent(); diff --git a/docs/Commands.md b/docs/Commands.md index 95ec28f9..7a15bf37 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -14,8 +14,6 @@ Here is a summary of the commands available in-game. All commands are prefixed b |pvp|`/pvp`|Toggle your PVP flag.|| |resurrect|`/resurrect`|Resurrects the player.|| |requestmailcount|`/requestmailcount`|Sends notification with number of unread messages in the player's mailbox.|| -|skip-ags|`/skip-ags`|Skips the Avant Gardens Survival minigame mission, "Impress the Sentinel Faction".|| -|skip-sg|`/skip-sg`|Skips the Shooting Gallery minigame mission, "Monarch of the Sea".|| |who|`/who`|Displays in chat all players on the instance.|| ## Moderation Commands From 5292f36417e94085aa21400f31bf6ed595b12330 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 11 Dec 2022 00:27:01 -0800 Subject: [PATCH 045/166] Packages updates (#864) Update packages to not open if you dont have enough room. Update packages to no longer allow them selves to be open unless you meet the pre-reqs. --- dGame/dInventory/Item.cpp | 67 ++++++++++++++++++++++++------ dGame/dUtilities/Preconditions.cpp | 7 +--- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index c05c0672..02739ec2 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -253,7 +253,7 @@ bool Item::Consume() { } } - Game::logger->Log("Item", "Consumed (%i) / (%llu) with (%d)", lot, id, success); + Game::logger->LogDebug("Item", "Consumed LOT (%i) itemID (%llu). Success=(%d)", lot, id, success); GameMessages::SendUseItemResult(inventory->GetComponent()->GetParent(), lot, success); @@ -265,14 +265,34 @@ bool Item::Consume() { } void Item::UseNonEquip() { + LOT thisLot = this->GetLot(); + if (!GetInventory()) { + Game::logger->LogDebug("Item", "item %i has no inventory??", this->GetLot()); + return; + } + + auto* playerInventoryComponent = GetInventory()->GetComponent(); + if (!playerInventoryComponent) { + Game::logger->LogDebug("Item", "no inventory component attached to item id %llu lot %i", this->GetId(), this->GetLot()); + return; + } + + auto* playerEntity = playerInventoryComponent->GetParent(); + if (!playerEntity) { + Game::logger->LogDebug("Item", "no player entity attached to inventory? item id is %llu", this->GetId()); + return; + } + const auto type = static_cast(info->itemType); if (type == eItemType::ITEM_TYPE_MOUNT) { - GetInventory()->GetComponent()->HandlePossession(this); + playerInventoryComponent->HandlePossession(this); + // TODO Check if mounts are allowed to be spawned } else if (type == eItemType::ITEM_TYPE_PET_INVENTORY_ITEM && subKey != LWOOBJID_EMPTY) { - const auto& databasePet = GetInventory()->GetComponent()->GetDatabasePet(subKey); + const auto& databasePet = playerInventoryComponent->GetDatabasePet(subKey); if (databasePet.lot != LOT_NULL) { - GetInventory()->GetComponent()->SpawnPet(this); + playerInventoryComponent->SpawnPet(this); } + // This precondition response is taken care of in SpawnPet(). } else { auto* compRegistryTable = CDClientManager::Instance()->GetTable("ComponentsRegistry"); const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_PACKAGE); @@ -282,18 +302,41 @@ void Item::UseNonEquip() { auto* packCompTable = CDClientManager::Instance()->GetTable("PackageComponent"); auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast(packageComponentId); }); - const auto success = !packages.empty(); + auto success = !packages.empty(); if (success) { - auto* entityParent = inventory->GetComponent()->GetParent(); - for (auto& pack : packages) { - std::unordered_map result{}; - result = LootGenerator::Instance().RollLootMatrix(entityParent, pack.LootMatrixIndex); - if (!inventory->GetComponent()->HasSpaceForLoot(result)) { + if (this->GetPreconditionExpression()->Check(playerInventoryComponent->GetParent())) { + auto* entityParent = playerInventoryComponent->GetParent(); + // Roll the loot for all the packages then see if it all fits. If it fits, give it to the player, otherwise don't. + std::unordered_map rolledLoot{}; + for (auto& pack : packages) { + auto thisPackage = LootGenerator::Instance().RollLootMatrix(entityParent, pack.LootMatrixIndex); + for (auto& loot : thisPackage) { + // If we already rolled this lot, add it to the existing one, otherwise create a new entry. + auto existingLoot = rolledLoot.find(loot.first); + if (existingLoot == rolledLoot.end()) { + rolledLoot.insert(loot); + } else { + existingLoot->second += loot.second; + } + } } - LootGenerator::Instance().GiveLoot(inventory->GetComponent()->GetParent(), result, eLootSourceType::LOOT_SOURCE_CONSUMPTION); + if (playerInventoryComponent->HasSpaceForLoot(rolledLoot)) { + LootGenerator::Instance().GiveLoot(playerInventoryComponent->GetParent(), rolledLoot, eLootSourceType::LOOT_SOURCE_CONSUMPTION); + playerInventoryComponent->RemoveItem(lot, 1); + } else { + success = false; + } + } else { + GameMessages::SendUseItemRequirementsResponse( + playerInventoryComponent->GetParent()->GetObjectID(), + playerInventoryComponent->GetParent()->GetSystemAddress(), + UseItemResponse::FailedPrecondition + ); + success = false; } - inventory->GetComponent()->RemoveItem(lot, 1); } + Game::logger->LogDebug("Item", "Player %llu %s used item %i", playerEntity->GetObjectID(), success ? "successfully" : "unsuccessfully", thisLot); + GameMessages::SendUseItemResult(playerInventoryComponent->GetParent(), thisLot, success); } } diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index 1f719433..c23ac53b 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -154,7 +154,7 @@ bool Precondition::CheckValue(Entity* player, const uint32_t value, bool evaluat case PreconditionType::MissionComplete: mission = missionComponent->GetMission(value); - return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_COMPLETE; + return mission == nullptr ? false : mission->GetMissionState() >= MissionState::MISSION_STATE_COMPLETE; case PreconditionType::PetDeployed: return false; // TODO case PreconditionType::HasFlag: @@ -277,11 +277,6 @@ bool PreconditionExpression::Check(Entity* player, bool evaluateCosts) const { return true; } - if (player->GetGMLevel() >= 9) // Developers can skip this for testing - { - return true; - } - const auto a = Preconditions::Check(player, condition, evaluateCosts); if (!a) { From 435761f64bdf75edf717ed6a12b966624c16447c Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 15 Dec 2022 04:02:38 -0800 Subject: [PATCH 046/166] Improve shutdown --- dAuthServer/AuthServer.cpp | 41 ++++++------ dChatServer/ChatServer.cpp | 49 ++++++++------- dCommon/Game.h | 3 + dMasterServer/InstanceManager.cpp | 6 +- dMasterServer/MasterServer.cpp | 88 ++++++++++---------------- dNet/dServer.cpp | 8 ++- dNet/dServer.h | 20 +++++- dWorldServer/WorldServer.cpp | 91 +++++++++++++++------------ tests/dGameTests/GameDependencies.cpp | 1 + 9 files changed, 160 insertions(+), 147 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index aefc822b..4fffc5d0 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -22,9 +22,10 @@ #include "Game.h" namespace Game { - dLogger* logger = nullptr; - dServer* server = nullptr; - dConfig* config = nullptr; + dLogger* logger; + dServer* server; + dConfig* config; + bool shouldShutdown = false; } dLogger* SetupLogger(); @@ -37,22 +38,22 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(); - if (!Game::logger) return EXIT_FAILURE; - - //Read our config: - Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "authconfig.ini").string()); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); - + if (!Game::logger) return 0; Game::logger->Log("AuthServer", "Starting Auth server..."); Game::logger->Log("AuthServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("AuthServer", "Compiled on: %s", __TIMESTAMP__); + //Read our config: + dConfig config("authconfig.ini"); + Game::config = &config; + Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); + //Connect to the MySQL Database - std::string mysql_host = Game::config->GetValue("mysql_host"); - std::string mysql_database = Game::config->GetValue("mysql_database"); - std::string mysql_username = Game::config->GetValue("mysql_username"); - std::string mysql_password = Game::config->GetValue("mysql_password"); + std::string mysql_host = config.GetValue("mysql_host"); + std::string mysql_database = config.GetValue("mysql_database"); + std::string mysql_username = config.GetValue("mysql_username"); + std::string mysql_password = config.GetValue("mysql_password"); try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); @@ -61,7 +62,7 @@ int main(int argc, char** argv) { Database::Destroy("AuthServer"); delete Game::server; delete Game::logger; - return EXIT_FAILURE; + return 0; } //Find out the master's IP: @@ -80,10 +81,10 @@ int main(int argc, char** argv) { //It's safe to pass 'localhost' here, as the IP is only used as the external IP. int maxClients = 50; int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. - if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); - if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); + if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); + if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); - Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, Game::shouldShutdown); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); @@ -92,7 +93,7 @@ int main(int argc, char** argv) { int framesSinceMasterDisconnect = 0; int framesSinceLastSQLPing = 0; - while (true) { + while (!Game::shouldShutdown) { //Check if we're still connected to master: if (!Game::server->GetIsConnectedToMaster()) { framesSinceMasterDisconnect++; @@ -145,8 +146,8 @@ int main(int argc, char** argv) { Database::Destroy("AuthServer"); delete Game::server; delete Game::logger; - delete Game::config; + exit(EXIT_SUCCESS); return EXIT_SUCCESS; } diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index 043e7869..d2eb7fc7 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -20,11 +20,12 @@ #include "Game.h" namespace Game { - dLogger* logger = nullptr; - dServer* server = nullptr; - dConfig* config = nullptr; - dChatFilter* chatFilter = nullptr; - AssetManager* assetManager = nullptr; + dLogger* logger; + dServer* server; + dConfig* config; + dChatFilter* chatFilter; + AssetManager* assetManager; + bool shouldShutdown = false; } //RakNet includes: @@ -42,19 +43,19 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(); - if (!Game::logger) return EXIT_FAILURE; - - //Read our config: - Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "chatconfig.ini").string()); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); - + if (!Game::logger) return 0; Game::logger->Log("ChatServer", "Starting Chat server..."); Game::logger->Log("ChatServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("ChatServer", "Compiled on: %s", __TIMESTAMP__); + //Read our config: + dConfig config("chatconfig.ini"); + Game::config = &config; + Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); + try { - std::string clientPathStr = Game::config->GetValue("client_location"); + std::string clientPathStr = config.GetValue("client_location"); if (clientPathStr.empty()) clientPathStr = "./res"; std::filesystem::path clientPath = std::filesystem::path(clientPathStr); if (clientPath.is_relative()) { @@ -69,10 +70,10 @@ int main(int argc, char** argv) { } //Connect to the MySQL Database - std::string mysql_host = Game::config->GetValue("mysql_host"); - std::string mysql_database = Game::config->GetValue("mysql_database"); - std::string mysql_username = Game::config->GetValue("mysql_username"); - std::string mysql_password = Game::config->GetValue("mysql_password"); + std::string mysql_host = config.GetValue("mysql_host"); + std::string mysql_database = config.GetValue("mysql_database"); + std::string mysql_username = config.GetValue("mysql_username"); + std::string mysql_password = config.GetValue("mysql_password"); try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); @@ -81,7 +82,7 @@ int main(int argc, char** argv) { Database::Destroy("ChatServer"); delete Game::server; delete Game::logger; - return EXIT_FAILURE; + return 0; } //Find out the master's IP: @@ -100,12 +101,12 @@ int main(int argc, char** argv) { //It's safe to pass 'localhost' here, as the IP is only used as the external IP. int maxClients = 50; int ourPort = 1501; - if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); - if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); + if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); + if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); - Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config); + Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, Game::shouldShutdown); - Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); + Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); @@ -114,7 +115,7 @@ int main(int argc, char** argv) { int framesSinceMasterDisconnect = 0; int framesSinceLastSQLPing = 0; - while (true) { + while (!Game::shouldShutdown) { //Check if we're still connected to master: if (!Game::server->GetIsConnectedToMaster()) { framesSinceMasterDisconnect++; @@ -167,8 +168,8 @@ int main(int argc, char** argv) { Database::Destroy("ChatServer"); delete Game::server; delete Game::logger; - delete Game::config; + exit(EXIT_SUCCESS); return EXIT_SUCCESS; } diff --git a/dCommon/Game.h b/dCommon/Game.h index 38cadb70..cbddafec 100644 --- a/dCommon/Game.h +++ b/dCommon/Game.h @@ -5,6 +5,7 @@ class dServer; class dLogger; class InstanceManager; +class dpWorld; class dChatFilter; class dConfig; class RakPeerInterface; @@ -15,10 +16,12 @@ namespace Game { extern dLogger* logger; extern dServer* server; extern InstanceManager* im; + extern dpWorld* physicsWorld; extern dChatFilter* chatFilter; extern dConfig* config; extern std::mt19937 randomEngine; extern RakPeerInterface* chatServer; extern AssetManager* assetManager; extern SystemAddress chatSysAddr; + extern bool shouldShutdown; } diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index a1983dd4..327a18b9 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -74,7 +74,7 @@ Instance* InstanceManager::GetInstance(LWOMAPID mapID, bool isFriendTransfer, LW cmd.append("&"); //Sends our next process to the background on Linux #endif - auto ret = system(cmd.c_str()); + system(cmd.c_str()); m_Instances.push_back(instance); @@ -322,7 +322,7 @@ Instance* InstanceManager::CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID clon cmd.append("&"); //Sends our next process to the background on Linux #endif - auto ret = system(cmd.c_str()); + system(cmd.c_str()); m_Instances.push_back(instance); @@ -391,5 +391,5 @@ void Instance::Shutdown() { Game::server->Send(&bitStream, this->m_SysAddr, false); - Game::logger->Log("Instance", "Triggered world shutdown"); + Game::logger->Log("Instance", "Triggered world shutdown for zone/clone/instance %i/%i/%i", GetMapID(), GetCloneID(), GetInstanceID()); } diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 4c18566e..2f54243a 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -43,11 +43,12 @@ #include "FdbToSqlite.h" namespace Game { - dLogger* logger = nullptr; - dServer* server = nullptr; - InstanceManager* im = nullptr; - dConfig* config = nullptr; - AssetManager* assetManager = nullptr; + dLogger* logger; + dServer* server; + InstanceManager* im; + dConfig* config; + AssetManager* assetManager; + bool shouldShutdown = false; } //namespace Game bool shutdownSequenceStarted = false; @@ -58,7 +59,6 @@ void StartAuthServer(); void StartChatServer(); void HandlePacket(Packet* packet); std::map activeSessions; -bool shouldShutdown = false; SystemAddress chatServerMasterPeerSysAddr; int main(int argc, char** argv) { @@ -79,39 +79,14 @@ int main(int argc, char** argv) { Game::logger = SetupLogger(); if (!Game::logger) return EXIT_FAILURE; - if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "authconfig.ini")) { - Game::logger->Log("MasterServer", "Couldnt find authconfig.ini"); - return EXIT_FAILURE; - } - - if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "chatconfig.ini")) { - Game::logger->Log("MasterServer", "Couldnt find chatconfig.ini"); - return EXIT_FAILURE; - } - - if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "masterconfig.ini")) { - Game::logger->Log("MasterServer", "Couldnt find masterconfig.ini"); - return EXIT_FAILURE; - } - - if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "sharedconfig.ini")) { - Game::logger->Log("MasterServer", "Couldnt find sharedconfig.ini"); - return EXIT_FAILURE; - } - - if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "worldconfig.ini")) { - Game::logger->Log("MasterServer", "Couldnt find worldconfig.ini"); - return EXIT_FAILURE; - } - - Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "masterconfig.ini").string()); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); - Game::logger->Log("MasterServer", "Starting Master server..."); Game::logger->Log("MasterServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("MasterServer", "Compiled on: %s", __TIMESTAMP__); + Game::config = new dConfig("masterconfig.ini"); + Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + //Connect to the MySQL Database std::string mysql_host = Game::config->GetValue("mysql_host"); std::string mysql_database = Game::config->GetValue("mysql_database"); @@ -241,7 +216,7 @@ int main(int argc, char** argv) { if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port")); - Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config); + Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config, Game::shouldShutdown); //Query for the database for a server labeled "master" auto* masterLookupStatement = Database::CreatePreppedStmt("SELECT id FROM `servers` WHERE `name` = 'master'"); @@ -328,7 +303,7 @@ int main(int argc, char** argv) { framesSinceLastSQLPing++; //10m shutdown for universe kill command - if (shouldShutdown) { + if (Game::shouldShutdown) { if (framesSinceKillUniverseCommand >= 40000) { //Break main loop and exit break; @@ -406,7 +381,7 @@ void HandlePacket(Packet* packet) { Game::im->RemoveInstance(instance); //Delete the old } - if (packet->systemAddress == chatServerMasterPeerSysAddr && !shouldShutdown) { + if (packet->systemAddress == chatServerMasterPeerSysAddr && !Game::shouldShutdown) { StartChatServer(); } } @@ -422,7 +397,7 @@ void HandlePacket(Packet* packet) { //Game::im->GetInstance(zoneID.GetMapID(), false, 0); //Create the new } - if (packet->systemAddress == chatServerMasterPeerSysAddr && !shouldShutdown) { + if (packet->systemAddress == chatServerMasterPeerSysAddr && !Game::shouldShutdown) { StartChatServer(); } } @@ -744,7 +719,7 @@ void HandlePacket(Packet* packet) { case MSG_MASTER_SHUTDOWN_UNIVERSE: { Game::logger->Log("MasterServer", "Received shutdown universe command, shutting down in 10 minutes."); - shouldShutdown = true; + Game::shouldShutdown = true; break; } @@ -757,28 +732,28 @@ void HandlePacket(Packet* packet) { void StartChatServer() { #ifdef __APPLE__ //macOS doesn't need sudo to run on ports < 1024 - auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); #elif _WIN32 - auto result = system(("start " + (BinaryPathFinder::GetBinaryDir() / "ChatServer.exe").string()).c_str()); + system(("start " + (BinaryPathFinder::GetBinaryDir() / "ChatServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_chat").c_str())) { - auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } else { - auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } #endif } void StartAuthServer() { #ifdef __APPLE__ - auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); #elif _WIN32 - auto result = system(("start " + (BinaryPathFinder::GetBinaryDir() / "AuthServer.exe").string()).c_str()); + system(("start " + (BinaryPathFinder::GetBinaryDir() / "AuthServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_auth").c_str())) { - auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } else { - auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } #endif } @@ -790,14 +765,11 @@ void ShutdownSequence() { shutdownSequenceStarted = true; - if (Game::im) { - for (auto* instance : Game::im->GetInstances()) { - if (instance == nullptr) { - continue; - } - - instance->Shutdown(); - } + { + CBITSTREAM; + PacketUtils::WriteHeader(bitStream, MASTER, MSG_MASTER_SHUTDOWN); + Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true); + Game::logger->Log("MasterServer", "Triggered master shutdown"); } auto* objIdManager = ObjectIDManager::TryInstance(); @@ -813,6 +785,10 @@ void ShutdownSequence() { exit(EXIT_SUCCESS); } + for (auto instance : Game::im->GetInstances()) { + instance->SetIsShuttingDown(true); + } + Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds..."); while (true) { diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 481667b8..3a5ef822 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -36,7 +36,7 @@ public: } } ReceiveDownloadCompleteCB; -dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, unsigned int zoneID) { +dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, bool& shouldShutdown, unsigned int zoneID) { mIP = ip; mPort = port; mZoneID = zoneID; @@ -52,6 +52,7 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect mReplicaManager = nullptr; mServerType = serverType; mConfig = config; + mShouldShutdown = &shouldShutdown; //Attempt to start our server here: mIsOkay = Startup(); @@ -124,8 +125,11 @@ Packet* dServer::ReceiveFromMaster() { ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet); break; } + case MSG_MASTER_SHUTDOWN: + *mShouldShutdown = true; + break; - //When we handle these packets in World instead dServer, we just return the packet's pointer. + //When we handle these packets in World instead dServer, we just return the packet's pointer. default: return packet; diff --git a/dNet/dServer.h b/dNet/dServer.h index 0fbdecce..608b3b83 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -18,7 +18,20 @@ class dServer { public: // Default constructor should only used for testing! dServer() {}; - dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, unsigned int zoneID = 0); + dServer( + const std::string& ip, + int port, + int instanceID, + int maxConnections, + bool isInternal, + bool useEncryption, + dLogger* logger, + const std::string masterIP, + int masterPort, + ServerType serverType, + dConfig* config, + bool& shouldShutdown, + unsigned int zoneID = 0); ~dServer(); Packet* ReceiveFromMaster(); @@ -64,6 +77,11 @@ private: RakPeerInterface* mPeer = nullptr; ReplicaManager* mReplicaManager = nullptr; NetworkIDManager* mNetIDManager = nullptr; + + /** + * Whether or not to shut down the server. Pointer to Game::shouldShutdown. + */ + bool* mShouldShutdown = nullptr; SocketDescriptor mSocketDescriptor; std::string mIP; int mPort; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 68ec0e57..2fdb373b 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -61,20 +61,23 @@ #include "ZCompression.h" namespace Game { - dLogger* logger = nullptr; - dServer* server = nullptr; - dpWorld* physicsWorld = nullptr; - dChatFilter* chatFilter = nullptr; - dConfig* config = nullptr; - AssetManager* assetManager = nullptr; - RakPeerInterface* chatServer = nullptr; + dLogger* logger; + dServer* server; + dZoneManager* zoneManager; + dpWorld* physicsWorld; + dChatFilter* chatFilter; + dConfig* config; std::mt19937 randomEngine; + + AssetManager* assetManager; + + RakPeerInterface* chatServer; SystemAddress chatSysAddr; -} + bool shouldShutdown = false; +} // namespace Game bool chatDisabled = false; bool chatConnected = false; -bool worldShutdownSequenceStarted = false; bool worldShutdownSequenceComplete = false; void WorldShutdownSequence(); void WorldShutdownProcess(uint32_t zoneId); @@ -124,21 +127,26 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(zoneID, instanceID); - if (!Game::logger) return EXIT_FAILURE; - - //Read our config: - Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "worldconfig.ini").string()); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + if (!Game::logger) return 0; + Game::logger->SetLogToConsole(true); //We want this info to always be logged. Game::logger->Log("WorldServer", "Starting World server..."); Game::logger->Log("WorldServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("WorldServer", "Compiled on: %s", __TIMESTAMP__); - if (Game::config->GetValue("disable_chat") == "1") chatDisabled = true; +#ifndef _DEBUG + Game::logger->SetLogToConsole(false); //By default, turn it back off if not in debug. +#endif + + //Read our config: + dConfig config("worldconfig.ini"); + Game::config = &config; + Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); + Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); + if (config.GetValue("disable_chat") == "1") chatDisabled = true; try { - std::string clientPathStr = Game::config->GetValue("client_location"); + std::string clientPathStr = config.GetValue("client_location"); if (clientPathStr.empty()) clientPathStr = "./res"; std::filesystem::path clientPath = std::filesystem::path(clientPathStr); if (clientPath.is_relative()) { @@ -158,28 +166,28 @@ int main(int argc, char** argv) { Game::logger->Log("WorldServer", "Unable to connect to CDServer SQLite Database"); Game::logger->Log("WorldServer", "Error: %s", e.errorMessage()); Game::logger->Log("WorldServer", "Error Code: %i", e.errorCode()); - return EXIT_FAILURE; + return -1; } CDClientManager::Instance()->Initialize(); //Connect to the MySQL Database - std::string mysql_host = Game::config->GetValue("mysql_host"); - std::string mysql_database = Game::config->GetValue("mysql_database"); - std::string mysql_username = Game::config->GetValue("mysql_username"); - std::string mysql_password = Game::config->GetValue("mysql_password"); + std::string mysql_host = config.GetValue("mysql_host"); + std::string mysql_database = config.GetValue("mysql_database"); + std::string mysql_username = config.GetValue("mysql_username"); + std::string mysql_password = config.GetValue("mysql_password"); - Diagnostics::SetProduceMemoryDump(Game::config->GetValue("generate_dump") == "1"); + Diagnostics::SetProduceMemoryDump(config.GetValue("generate_dump") == "1"); - if (!Game::config->GetValue("dump_folder").empty()) { - Diagnostics::SetOutDirectory(Game::config->GetValue("dump_folder")); + if (!config.GetValue("dump_folder").empty()) { + Diagnostics::SetOutDirectory(config.GetValue("dump_folder")); } try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); } catch (sql::SQLException& ex) { Game::logger->Log("WorldServer", "Got an error while connecting to the database: %s", ex.what()); - return EXIT_FAILURE; + return 0; } //Find out the master's IP: @@ -198,13 +206,13 @@ int main(int argc, char** argv) { ObjectIDManager::Instance()->Initialize(); UserManager::Instance()->Initialize(); LootGenerator::Instance(); - Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); + Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); - Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, zoneID); + Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, Game::shouldShutdown, zoneID); //Connect to the chat server: int chatPort = 1501; - if (Game::config->GetValue("chat_server_port") != "") chatPort = std::atoi(Game::config->GetValue("chat_server_port").c_str()); + if (config.GetValue("chat_server_port") != "") chatPort = std::atoi(config.GetValue("chat_server_port").c_str()); auto chatSock = SocketDescriptor(uint16_t(ourPort + 2), 0); Game::chatServer = RakNetworkFactory::GetRakPeerInterface(); @@ -315,9 +323,9 @@ int main(int argc, char** argv) { framesSinceMasterDisconnect++; int framesToWaitForMaster = ready ? 10 : 200; - if (framesSinceMasterDisconnect >= framesToWaitForMaster && !worldShutdownSequenceStarted) { + if (framesSinceMasterDisconnect >= framesToWaitForMaster && !Game::shouldShutdown) { Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", framesToWaitForMaster); - worldShutdownSequenceStarted = true; + Game::shouldShutdown = true; } } else framesSinceMasterDisconnect = 0; @@ -413,7 +421,7 @@ int main(int argc, char** argv) { //If we haven't had any players for a while, time out and shut down: if (framesSinceLastUser == (cloneID != 0 ? 4000 : 40000)) { - worldShutdownSequenceStarted = true; + Game::shouldShutdown = true; } } else { framesSinceLastUser = 0; @@ -470,7 +478,7 @@ int main(int argc, char** argv) { } } - if (worldShutdownSequenceStarted && !worldShutdownSequenceComplete) { + if (Game::shouldShutdown && !worldShutdownSequenceComplete) { WorldShutdownProcess(zoneID); break; } @@ -789,7 +797,7 @@ void HandlePacket(Packet* packet) { } case MSG_MASTER_SHUTDOWN: { - worldShutdownSequenceStarted = true; + Game::shouldShutdown = true; Game::logger->Log("WorldServer", "Got shutdown request from master, zone (%i), instance (%i)", Game::server->GetZoneID(), Game::server->GetInstanceID()); break; } @@ -1259,11 +1267,11 @@ void WorldShutdownProcess(uint32_t zoneId) { } void WorldShutdownSequence() { - if (worldShutdownSequenceStarted || worldShutdownSequenceComplete) { + if (Game::shouldShutdown || worldShutdownSequenceComplete) { return; } - worldShutdownSequenceStarted = true; + Game::shouldShutdown = true; Game::logger->Log("WorldServer", "Zone (%i) instance (%i) shutting down outside of main loop!", Game::server->GetZoneID(), instanceID); WorldShutdownProcess(Game::server->GetZoneID()); @@ -1271,15 +1279,16 @@ void WorldShutdownSequence() { } void FinalizeShutdown() { + //Delete our objects here: + if (Game::zoneManager) delete Game::zoneManager; + Game::logger->Log("WorldServer", "Shutdown complete, zone (%i), instance (%i)", Game::server->GetZoneID(), instanceID); - //Delete our objects here: Metrics::Clear(); Database::Destroy("WorldServer"); - if (Game::chatFilter) delete Game::chatFilter; - if (Game::server) delete Game::server; - if (Game::logger) delete Game::logger; - if (Game::config) delete Game::config; + delete Game::chatFilter; + delete Game::server; + delete Game::logger; worldShutdownSequenceComplete = true; diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index 7b0a8412..5ac3339a 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -4,6 +4,7 @@ namespace Game { dLogger* logger; dServer* server; dZoneManager* zoneManager; + dpWorld* physicsWorld; dChatFilter* chatFilter; dConfig* config; std::mt19937 randomEngine; From 1afe71756332574988eea8fcc4f5979450c0faa4 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 15 Dec 2022 05:46:03 -0800 Subject: [PATCH 047/166] Properly exit Properly exit based on the path taken to shutdown master. Tested that shutting down through sigint or sigterm returns -1 Tested that a segfault exits the program properly Need to test that players who are trying to connect while master is shutting down are not able to spawn more child worlds. --- dAuthServer/AuthServer.cpp | 2 +- dChatServer/ChatServer.cpp | 2 +- dMasterServer/InstanceManager.cpp | 2 +- dMasterServer/MasterServer.cpp | 82 ++++++++++++++++++++++--------- dNet/dServer.cpp | 4 +- dNet/dServer.h | 2 +- dWorldServer/WorldServer.cpp | 2 +- 7 files changed, 65 insertions(+), 31 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 4fffc5d0..092b7fa4 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -84,7 +84,7 @@ int main(int argc, char** argv) { if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); - Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, Game::shouldShutdown); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::shouldShutdown); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index d2eb7fc7..ace5e287 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -104,7 +104,7 @@ int main(int argc, char** argv) { if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, Game::shouldShutdown); + Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::shouldShutdown); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index 327a18b9..de64c4ba 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -150,7 +150,7 @@ void InstanceManager::RemoveInstance(Instance* instance) { if (m_Instances[i] == instance) { instance->SetShutdownComplete(true); - RedirectPendingRequests(instance); + if (!Game::shouldShutdown) RedirectPendingRequests(instance); delete m_Instances[i]; diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 2f54243a..388654f5 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -52,13 +52,14 @@ namespace Game { } //namespace Game bool shutdownSequenceStarted = false; -void ShutdownSequence(); -int FinalizeShutdown(); +void ShutdownSequence(int signal = -1); +int FinalizeShutdown(int signal = -1); dLogger* SetupLogger(); void StartAuthServer(); void StartChatServer(); void HandlePacket(Packet* packet); std::map activeSessions; +SystemAddress authServerMasterPeerSysAddr; SystemAddress chatServerMasterPeerSysAddr; int main(int argc, char** argv) { @@ -71,9 +72,9 @@ int main(int argc, char** argv) { #endif //Triggers the shutdown sequence at application exit - std::atexit(ShutdownSequence); - signal(SIGINT, [](int) { ShutdownSequence(); }); - signal(SIGTERM, [](int) { ShutdownSequence(); }); + std::atexit([]() { ShutdownSequence(); }); + signal(SIGINT, [](int signal) { ShutdownSequence(EXIT_FAILURE); }); + signal(SIGTERM, [](int signal) { ShutdownSequence(EXIT_FAILURE); }); //Create all the objects we need to run our service: Game::logger = SetupLogger(); @@ -216,7 +217,7 @@ int main(int argc, char** argv) { if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port")); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config, Game::shouldShutdown); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config, &Game::shouldShutdown); //Query for the database for a server labeled "master" auto* masterLookupStatement = Database::CreatePreppedStmt("SELECT id FROM `servers` WHERE `name` = 'master'"); @@ -253,8 +254,8 @@ int main(int argc, char** argv) { if (Game::config->GetValue("prestart_servers") != "" && Game::config->GetValue("prestart_servers") == "1") { StartChatServer(); - Game::im->GetInstance(0, false, 0)->SetIsReady(true); - Game::im->GetInstance(1000, false, 0)->SetIsReady(true); + Game::im->GetInstance(0, false, 0); + Game::im->GetInstance(1000, false, 0); StartAuthServer(); } @@ -350,9 +351,7 @@ int main(int argc, char** argv) { t += std::chrono::milliseconds(highFrameRate); std::this_thread::sleep_until(t); } - FinalizeShutdown(); - exit(EXIT_SUCCESS); - return EXIT_SUCCESS; + return FinalizeShutdown(EXIT_SUCCESS); } dLogger* SetupLogger() { @@ -381,9 +380,15 @@ void HandlePacket(Packet* packet) { Game::im->RemoveInstance(instance); //Delete the old } - if (packet->systemAddress == chatServerMasterPeerSysAddr && !Game::shouldShutdown) { + if (packet->systemAddress == chatServerMasterPeerSysAddr) { + chatServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS; StartChatServer(); } + + if (packet->systemAddress == authServerMasterPeerSysAddr) { + authServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS; + StartAuthServer(); + } } if (packet->data[0] == ID_CONNECTION_LOST) { @@ -397,9 +402,15 @@ void HandlePacket(Packet* packet) { //Game::im->GetInstance(zoneID.GetMapID(), false, 0); //Create the new } - if (packet->systemAddress == chatServerMasterPeerSysAddr && !Game::shouldShutdown) { + if (packet->systemAddress == chatServerMasterPeerSysAddr) { + chatServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS; StartChatServer(); } + + if (packet->systemAddress == authServerMasterPeerSysAddr) { + authServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS; + StartAuthServer(); + } } if (packet->data[1] == MASTER) { @@ -495,6 +506,14 @@ void HandlePacket(Packet* packet) { chatServerMasterPeerSysAddr = copy; } + if (theirServerType == ServerType::Auth) { + SystemAddress copy; + copy.binaryAddress = packet->systemAddress.binaryAddress; + copy.port = packet->systemAddress.port; + + authServerMasterPeerSysAddr = copy; + } + Game::logger->Log("MasterServer", "Received server info, instance: %i port: %i", theirInstanceID, theirPort); break; @@ -726,10 +745,14 @@ void HandlePacket(Packet* packet) { default: Game::logger->Log("MasterServer", "Unknown master packet ID from server: %i", packet->data[3]); } + } } -} void StartChatServer() { + if (Game::shouldShutdown) { + Game::logger->Log("MasterServer", "Currently shutting down. Chat will not be restarted."); + return; + } #ifdef __APPLE__ //macOS doesn't need sudo to run on ports < 1024 system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); @@ -742,9 +765,13 @@ void StartChatServer() { system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } #endif -} + } void StartAuthServer() { + if (Game::shouldShutdown) { + Game::logger->Log("MasterServer", "Currently shutting down. Auth will not be restarted."); + return; + } #ifdef __APPLE__ system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); #elif _WIN32 @@ -758,12 +785,13 @@ void StartAuthServer() { #endif } -void ShutdownSequence() { +void ShutdownSequence(int signal) { if (shutdownSequenceStarted) { return; } shutdownSequenceStarted = true; + Game::shouldShutdown = true; { CBITSTREAM; @@ -782,7 +810,14 @@ void ShutdownSequence() { auto ticks = 0; if (!Game::im) { - exit(EXIT_SUCCESS); + FinalizeShutdown(EXIT_FAILURE); + } + + // A server might not be finished spinning up yet, remove all of those here. + for (auto instance : Game::im->GetInstances()) { + if (!instance->GetIsReady()) { + Game::im->RemoveInstance(instance); + } } for (auto instance : Game::im->GetInstances()) { @@ -792,7 +827,6 @@ void ShutdownSequence() { Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds..."); while (true) { - auto packet = Game::server->Receive(); if (packet) { HandlePacket(packet); @@ -811,8 +845,8 @@ void ShutdownSequence() { done = false; } } - - if (done) { + + if (done && authServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS && chatServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS) { Game::logger->Log("MasterServer", "Finished shutting down MasterServer!"); break; } @@ -828,10 +862,10 @@ void ShutdownSequence() { } } - FinalizeShutdown(); + FinalizeShutdown(signal); } -int FinalizeShutdown() { +int FinalizeShutdown(int signal) { //Delete our objects here: Database::Destroy("MasterServer"); if (Game::config) delete Game::config; @@ -839,6 +873,6 @@ int FinalizeShutdown() { if (Game::server) delete Game::server; if (Game::logger) delete Game::logger; - exit(EXIT_SUCCESS); - return EXIT_SUCCESS; + if (signal != EXIT_SUCCESS) exit(signal); + return signal; } diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 3a5ef822..f41b9699 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -36,7 +36,7 @@ public: } } ReceiveDownloadCompleteCB; -dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, bool& shouldShutdown, unsigned int zoneID) { +dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, bool* shouldShutdown, unsigned int zoneID) { mIP = ip; mPort = port; mZoneID = zoneID; @@ -52,7 +52,7 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect mReplicaManager = nullptr; mServerType = serverType; mConfig = config; - mShouldShutdown = &shouldShutdown; + mShouldShutdown = shouldShutdown; //Attempt to start our server here: mIsOkay = Startup(); diff --git a/dNet/dServer.h b/dNet/dServer.h index 608b3b83..af4c8322 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -30,7 +30,7 @@ public: int masterPort, ServerType serverType, dConfig* config, - bool& shouldShutdown, + bool* shouldShutdown, unsigned int zoneID = 0); ~dServer(); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 2fdb373b..abb2c19f 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -208,7 +208,7 @@ int main(int argc, char** argv) { LootGenerator::Instance(); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); - Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, Game::shouldShutdown, zoneID); + Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, &Game::shouldShutdown, zoneID); //Connect to the chat server: int chatPort = 1501; From b7341c8106bf030813a408ebeae74e92ef212d1e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 15 Dec 2022 06:13:49 -0800 Subject: [PATCH 048/166] Resolve warnings, change config init order and remove unused Game variables for all servers (#877) * Resolve warnings and change init order Initialize dConfig first, before logger so we know whether or not to log to console Initialize namespace Game variables to nullptr so they are a known value if accessed before initialization. Removed unused Game variables Replaced config with a pointer instead of referencing something on the stack. Assign return values to system calls to silence warnings. Tested that the server still compiles, runs and allows me to load into the game. * Only start Master of config files exist Also default the logging to console to on on the off chance the files exist but are wrong / corrupted. --- dAuthServer/AuthServer.cpp | 38 +++++++------- dChatServer/ChatServer.cpp | 46 ++++++++--------- dCommon/Game.h | 2 - dMasterServer/InstanceManager.cpp | 4 +- dMasterServer/MasterServer.cpp | 59 +++++++++++++++------- dWorldServer/WorldServer.cpp | 71 ++++++++++++--------------- tests/dGameTests/GameDependencies.cpp | 1 - 7 files changed, 117 insertions(+), 104 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index a9f02f53..aefc822b 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -22,9 +22,9 @@ #include "Game.h" namespace Game { - dLogger* logger; - dServer* server; - dConfig* config; + dLogger* logger = nullptr; + dServer* server = nullptr; + dConfig* config = nullptr; } dLogger* SetupLogger(); @@ -37,22 +37,22 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(); - if (!Game::logger) return 0; + if (!Game::logger) return EXIT_FAILURE; + + //Read our config: + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "authconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + Game::logger->Log("AuthServer", "Starting Auth server..."); Game::logger->Log("AuthServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("AuthServer", "Compiled on: %s", __TIMESTAMP__); - //Read our config: - dConfig config("authconfig.ini"); - Game::config = &config; - Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); - //Connect to the MySQL Database - std::string mysql_host = config.GetValue("mysql_host"); - std::string mysql_database = config.GetValue("mysql_database"); - std::string mysql_username = config.GetValue("mysql_username"); - std::string mysql_password = config.GetValue("mysql_password"); + std::string mysql_host = Game::config->GetValue("mysql_host"); + std::string mysql_database = Game::config->GetValue("mysql_database"); + std::string mysql_username = Game::config->GetValue("mysql_username"); + std::string mysql_password = Game::config->GetValue("mysql_password"); try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); @@ -61,7 +61,7 @@ int main(int argc, char** argv) { Database::Destroy("AuthServer"); delete Game::server; delete Game::logger; - return 0; + return EXIT_FAILURE; } //Find out the master's IP: @@ -80,10 +80,10 @@ int main(int argc, char** argv) { //It's safe to pass 'localhost' here, as the IP is only used as the external IP. int maxClients = 50; int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. - if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); - if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); + if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); + if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); @@ -145,8 +145,8 @@ int main(int argc, char** argv) { Database::Destroy("AuthServer"); delete Game::server; delete Game::logger; + delete Game::config; - exit(EXIT_SUCCESS); return EXIT_SUCCESS; } diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index e3c6d6e9..043e7869 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -20,11 +20,11 @@ #include "Game.h" namespace Game { - dLogger* logger; - dServer* server; - dConfig* config; - dChatFilter* chatFilter; - AssetManager* assetManager; + dLogger* logger = nullptr; + dServer* server = nullptr; + dConfig* config = nullptr; + dChatFilter* chatFilter = nullptr; + AssetManager* assetManager = nullptr; } //RakNet includes: @@ -42,19 +42,19 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(); - if (!Game::logger) return 0; + if (!Game::logger) return EXIT_FAILURE; + + //Read our config: + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "chatconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + Game::logger->Log("ChatServer", "Starting Chat server..."); Game::logger->Log("ChatServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("ChatServer", "Compiled on: %s", __TIMESTAMP__); - //Read our config: - dConfig config("chatconfig.ini"); - Game::config = &config; - Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); - try { - std::string clientPathStr = config.GetValue("client_location"); + std::string clientPathStr = Game::config->GetValue("client_location"); if (clientPathStr.empty()) clientPathStr = "./res"; std::filesystem::path clientPath = std::filesystem::path(clientPathStr); if (clientPath.is_relative()) { @@ -69,10 +69,10 @@ int main(int argc, char** argv) { } //Connect to the MySQL Database - std::string mysql_host = config.GetValue("mysql_host"); - std::string mysql_database = config.GetValue("mysql_database"); - std::string mysql_username = config.GetValue("mysql_username"); - std::string mysql_password = config.GetValue("mysql_password"); + std::string mysql_host = Game::config->GetValue("mysql_host"); + std::string mysql_database = Game::config->GetValue("mysql_database"); + std::string mysql_username = Game::config->GetValue("mysql_username"); + std::string mysql_password = Game::config->GetValue("mysql_password"); try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); @@ -81,7 +81,7 @@ int main(int argc, char** argv) { Database::Destroy("ChatServer"); delete Game::server; delete Game::logger; - return 0; + return EXIT_FAILURE; } //Find out the master's IP: @@ -100,12 +100,12 @@ int main(int argc, char** argv) { //It's safe to pass 'localhost' here, as the IP is only used as the external IP. int maxClients = 50; int ourPort = 1501; - if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients")); - if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str()); + if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); + if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); - Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config); + Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config); - Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); + Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); @@ -167,8 +167,8 @@ int main(int argc, char** argv) { Database::Destroy("ChatServer"); delete Game::server; delete Game::logger; + delete Game::config; - exit(EXIT_SUCCESS); return EXIT_SUCCESS; } diff --git a/dCommon/Game.h b/dCommon/Game.h index 1c4bbc85..38cadb70 100644 --- a/dCommon/Game.h +++ b/dCommon/Game.h @@ -5,7 +5,6 @@ class dServer; class dLogger; class InstanceManager; -class dpWorld; class dChatFilter; class dConfig; class RakPeerInterface; @@ -16,7 +15,6 @@ namespace Game { extern dLogger* logger; extern dServer* server; extern InstanceManager* im; - extern dpWorld* physicsWorld; extern dChatFilter* chatFilter; extern dConfig* config; extern std::mt19937 randomEngine; diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index 83378dbb..a1983dd4 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -74,7 +74,7 @@ Instance* InstanceManager::GetInstance(LWOMAPID mapID, bool isFriendTransfer, LW cmd.append("&"); //Sends our next process to the background on Linux #endif - system(cmd.c_str()); + auto ret = system(cmd.c_str()); m_Instances.push_back(instance); @@ -322,7 +322,7 @@ Instance* InstanceManager::CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID clon cmd.append("&"); //Sends our next process to the background on Linux #endif - system(cmd.c_str()); + auto ret = system(cmd.c_str()); m_Instances.push_back(instance); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 4acb9b26..4c18566e 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -43,11 +43,11 @@ #include "FdbToSqlite.h" namespace Game { - dLogger* logger; - dServer* server; - InstanceManager* im; - dConfig* config; - AssetManager* assetManager; + dLogger* logger = nullptr; + dServer* server = nullptr; + InstanceManager* im = nullptr; + dConfig* config = nullptr; + AssetManager* assetManager = nullptr; } //namespace Game bool shutdownSequenceStarted = false; @@ -79,14 +79,39 @@ int main(int argc, char** argv) { Game::logger = SetupLogger(); if (!Game::logger) return EXIT_FAILURE; + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "authconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find authconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "chatconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find chatconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "masterconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find masterconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "sharedconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find sharedconfig.ini"); + return EXIT_FAILURE; + } + + if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "worldconfig.ini")) { + Game::logger->Log("MasterServer", "Couldnt find worldconfig.ini"); + return EXIT_FAILURE; + } + + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "masterconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + Game::logger->Log("MasterServer", "Starting Master server..."); Game::logger->Log("MasterServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("MasterServer", "Compiled on: %s", __TIMESTAMP__); - Game::config = new dConfig("masterconfig.ini"); - Game::logger->SetLogToConsole(bool(std::stoi(Game::config->GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); - //Connect to the MySQL Database std::string mysql_host = Game::config->GetValue("mysql_host"); std::string mysql_database = Game::config->GetValue("mysql_database"); @@ -732,28 +757,28 @@ void HandlePacket(Packet* packet) { void StartChatServer() { #ifdef __APPLE__ //macOS doesn't need sudo to run on ports < 1024 - system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); #elif _WIN32 - system(("start " + (BinaryPathFinder::GetBinaryDir() / "ChatServer.exe").string()).c_str()); + auto result = system(("start " + (BinaryPathFinder::GetBinaryDir() / "ChatServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_chat").c_str())) { - system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } else { - system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } #endif } void StartAuthServer() { #ifdef __APPLE__ - system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); #elif _WIN32 - system(("start " + (BinaryPathFinder::GetBinaryDir() / "AuthServer.exe").string()).c_str()); + auto result = system(("start " + (BinaryPathFinder::GetBinaryDir() / "AuthServer.exe").string()).c_str()); #else if (std::atoi(Game::config->GetValue("use_sudo_auth").c_str())) { - system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } else { - system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); + auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } #endif } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index acd38ad3..68ec0e57 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -61,17 +61,14 @@ #include "ZCompression.h" namespace Game { - dLogger* logger; - dServer* server; - dZoneManager* zoneManager; - dpWorld* physicsWorld; - dChatFilter* chatFilter; - dConfig* config; + dLogger* logger = nullptr; + dServer* server = nullptr; + dpWorld* physicsWorld = nullptr; + dChatFilter* chatFilter = nullptr; + dConfig* config = nullptr; + AssetManager* assetManager = nullptr; + RakPeerInterface* chatServer = nullptr; std::mt19937 randomEngine; - - AssetManager* assetManager; - - RakPeerInterface* chatServer; SystemAddress chatSysAddr; } @@ -127,26 +124,21 @@ int main(int argc, char** argv) { //Create all the objects we need to run our service: Game::logger = SetupLogger(zoneID, instanceID); - if (!Game::logger) return 0; + if (!Game::logger) return EXIT_FAILURE; + + //Read our config: + Game::config = new dConfig((BinaryPathFinder::GetBinaryDir() / "worldconfig.ini").string()); + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); - Game::logger->SetLogToConsole(true); //We want this info to always be logged. Game::logger->Log("WorldServer", "Starting World server..."); Game::logger->Log("WorldServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR); Game::logger->Log("WorldServer", "Compiled on: %s", __TIMESTAMP__); -#ifndef _DEBUG - Game::logger->SetLogToConsole(false); //By default, turn it back off if not in debug. -#endif - - //Read our config: - dConfig config("worldconfig.ini"); - Game::config = &config; - Game::logger->SetLogToConsole(bool(std::stoi(config.GetValue("log_to_console")))); - Game::logger->SetLogDebugStatements(config.GetValue("log_debug_statements") == "1"); - if (config.GetValue("disable_chat") == "1") chatDisabled = true; + if (Game::config->GetValue("disable_chat") == "1") chatDisabled = true; try { - std::string clientPathStr = config.GetValue("client_location"); + std::string clientPathStr = Game::config->GetValue("client_location"); if (clientPathStr.empty()) clientPathStr = "./res"; std::filesystem::path clientPath = std::filesystem::path(clientPathStr); if (clientPath.is_relative()) { @@ -166,28 +158,28 @@ int main(int argc, char** argv) { Game::logger->Log("WorldServer", "Unable to connect to CDServer SQLite Database"); Game::logger->Log("WorldServer", "Error: %s", e.errorMessage()); Game::logger->Log("WorldServer", "Error Code: %i", e.errorCode()); - return -1; + return EXIT_FAILURE; } CDClientManager::Instance()->Initialize(); //Connect to the MySQL Database - std::string mysql_host = config.GetValue("mysql_host"); - std::string mysql_database = config.GetValue("mysql_database"); - std::string mysql_username = config.GetValue("mysql_username"); - std::string mysql_password = config.GetValue("mysql_password"); + std::string mysql_host = Game::config->GetValue("mysql_host"); + std::string mysql_database = Game::config->GetValue("mysql_database"); + std::string mysql_username = Game::config->GetValue("mysql_username"); + std::string mysql_password = Game::config->GetValue("mysql_password"); - Diagnostics::SetProduceMemoryDump(config.GetValue("generate_dump") == "1"); + Diagnostics::SetProduceMemoryDump(Game::config->GetValue("generate_dump") == "1"); - if (!config.GetValue("dump_folder").empty()) { - Diagnostics::SetOutDirectory(config.GetValue("dump_folder")); + if (!Game::config->GetValue("dump_folder").empty()) { + Diagnostics::SetOutDirectory(Game::config->GetValue("dump_folder")); } try { Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password); } catch (sql::SQLException& ex) { Game::logger->Log("WorldServer", "Got an error while connecting to the database: %s", ex.what()); - return 0; + return EXIT_FAILURE; } //Find out the master's IP: @@ -206,13 +198,13 @@ int main(int argc, char** argv) { ObjectIDManager::Instance()->Initialize(); UserManager::Instance()->Initialize(); LootGenerator::Instance(); - Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf")))); + Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, zoneID); //Connect to the chat server: int chatPort = 1501; - if (config.GetValue("chat_server_port") != "") chatPort = std::atoi(config.GetValue("chat_server_port").c_str()); + if (Game::config->GetValue("chat_server_port") != "") chatPort = std::atoi(Game::config->GetValue("chat_server_port").c_str()); auto chatSock = SocketDescriptor(uint16_t(ourPort + 2), 0); Game::chatServer = RakNetworkFactory::GetRakPeerInterface(); @@ -1279,16 +1271,15 @@ void WorldShutdownSequence() { } void FinalizeShutdown() { - //Delete our objects here: - if (Game::zoneManager) delete Game::zoneManager; - Game::logger->Log("WorldServer", "Shutdown complete, zone (%i), instance (%i)", Game::server->GetZoneID(), instanceID); + //Delete our objects here: Metrics::Clear(); Database::Destroy("WorldServer"); - delete Game::chatFilter; - delete Game::server; - delete Game::logger; + if (Game::chatFilter) delete Game::chatFilter; + if (Game::server) delete Game::server; + if (Game::logger) delete Game::logger; + if (Game::config) delete Game::config; worldShutdownSequenceComplete = true; diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index 5ac3339a..7b0a8412 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -4,7 +4,6 @@ namespace Game { dLogger* logger; dServer* server; dZoneManager* zoneManager; - dpWorld* physicsWorld; dChatFilter* chatFilter; dConfig* config; std::mt19937 randomEngine; From 4775dbf27f6d82b31dbe33fa83b82ecaf8d4fce4 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 15 Dec 2022 19:55:07 -0800 Subject: [PATCH 049/166] Condense frame rates --- dAuthServer/AuthServer.cpp | 2 +- dChatServer/ChatServer.cpp | 2 +- dCommon/dEnums/dCommonVars.h | 15 +++++++++++---- dMasterServer/MasterServer.cpp | 4 ++-- dWorldServer/PerformanceManager.cpp | 26 +++++++------------------- dWorldServer/PerformanceManager.h | 5 ----- dWorldServer/WorldServer.cpp | 4 ++-- 7 files changed, 24 insertions(+), 34 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 3fd4b0bf..e4d8a052 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -138,7 +138,7 @@ int main(int argc, char** argv) { } else framesSinceLastSQLPing++; //Sleep our thread since auth can afford to. - t += std::chrono::milliseconds(mediumFramerate); //Auth can run at a lower "fps" + t += std::chrono::milliseconds(mediumFrameDelta); //Auth can run at a lower "fps" std::this_thread::sleep_until(t); } diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index f3b2c123..8ae1a9bd 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -160,7 +160,7 @@ int main(int argc, char** argv) { } else framesSinceLastSQLPing++; //Sleep our thread since auth can afford to. - t += std::chrono::milliseconds(mediumFramerate); //Chat can run at a lower "fps" + t += std::chrono::milliseconds(mediumFrameDelta); //Chat can run at a lower "fps" std::this_thread::sleep_until(t); } diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index f64d496f..f3d02bf7 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -6,15 +6,22 @@ #include #include #include -#include "../thirdparty/raknet/Source/BitStream.h" +#include "BitStream.h" #pragma warning (disable:4251) //Disables SQL warnings typedef int RESTICKET; -const int highFrameRate = 16; //60fps -const int mediumFramerate = 33; //30fps -const int lowFramerate = 66; //15fps +#define FRAMES_TO_MS(x) 1000 / x + +//=========== FRAME TIMINGS =========== +constexpr uint32_t highFramerate = 60; +constexpr uint32_t mediumFramerate = 30; +constexpr uint32_t lowFramerate = 15; + +constexpr uint32_t highFrameDelta = FRAMES_TO_MS(highFramerate); +constexpr uint32_t mediumFrameDelta = FRAMES_TO_MS(mediumFramerate); +constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate); //========== MACROS =========== diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index bfe9f323..49919568 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -373,7 +373,7 @@ int main(int argc, char** argv) { } } - t += std::chrono::milliseconds(highFrameRate); + t += std::chrono::milliseconds(highFrameDelta); std::this_thread::sleep_until(t); } return FinalizeShutdown(EXIT_SUCCESS); @@ -876,7 +876,7 @@ void ShutdownSequence(int signal) { break; } - t += std::chrono::milliseconds(highFrameRate); + t += std::chrono::milliseconds(highFrameDelta); std::this_thread::sleep_until(t); ticks++; diff --git a/dWorldServer/PerformanceManager.cpp b/dWorldServer/PerformanceManager.cpp index 85546f28..66dcb615 100644 --- a/dWorldServer/PerformanceManager.cpp +++ b/dWorldServer/PerformanceManager.cpp @@ -2,23 +2,18 @@ #include "UserManager.h" -//Times are 1 / fps, in ms -#define HIGH 16 //60 fps -#define MEDIUM 33 //30 fps -#define LOW 66 //15 fps - -#define SOCIAL { LOW } -#define SOCIAL_HUB { MEDIUM } //Added to compensate for the large playercounts in NS and NT -#define BATTLE { HIGH } -#define BATTLE_INSTANCE { MEDIUM } -#define RACE { HIGH } -#define PROPERTY { LOW } +#define SOCIAL { lowFrameDelta } +#define SOCIAL_HUB { mediumFrameDelta } //Added to compensate for the large playercounts in NS and NT +#define BATTLE { highFrameDelta } +#define BATTLE_INSTANCE { mediumFrameDelta } +#define RACE { highFrameDelta } +#define PROPERTY { lowFrameDelta } PerformanceProfile PerformanceManager::m_CurrentProfile = SOCIAL; PerformanceProfile PerformanceManager::m_DefaultProfile = SOCIAL; -PerformanceProfile PerformanceManager::m_InactiveProfile = { LOW }; +PerformanceProfile PerformanceManager::m_InactiveProfile = { lowFrameDelta }; std::map PerformanceManager::m_Profiles = { // VE @@ -72,13 +67,6 @@ std::map PerformanceManager::m_Profiles = { { 2001, BATTLE_INSTANCE }, }; - -PerformanceManager::PerformanceManager() { -} - -PerformanceManager::~PerformanceManager() { -} - void PerformanceManager::SelectProfile(LWOMAPID mapID) { const auto pair = m_Profiles.find(mapID); diff --git a/dWorldServer/PerformanceManager.h b/dWorldServer/PerformanceManager.h index b8a090e0..3d8517eb 100644 --- a/dWorldServer/PerformanceManager.h +++ b/dWorldServer/PerformanceManager.h @@ -8,18 +8,13 @@ struct PerformanceProfile { uint32_t serverFramerate; }; - class PerformanceManager { public: - ~PerformanceManager(); - static void SelectProfile(LWOMAPID mapID); static uint32_t GetServerFramerate(); private: - PerformanceManager(); - static PerformanceProfile m_CurrentProfile; static PerformanceProfile m_DefaultProfile; static PerformanceProfile m_InactiveProfile; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 594d3dc7..c531595f 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -232,7 +232,7 @@ int main(int argc, char** argv) { bool ready = false; int framesSinceMasterStatus = 0; int framesSinceShutdownSequence = 0; - int currentFramerate = highFrameRate; + int currentFramerate = highFrameDelta; int ghostingStepCount = 0; auto ghostingLastTime = std::chrono::high_resolution_clock::now(); @@ -300,7 +300,7 @@ int main(int argc, char** argv) { const auto occupied = UserManager::Instance()->GetUserCount() != 0; if (!ready) { - currentFramerate = highFrameRate; + currentFramerate = highFrameDelta; } else { currentFramerate = PerformanceManager::GetServerFramerate(); } From 3c581fffbbb67c414add2be5afccb76c24ff42b6 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 15 Dec 2022 20:39:29 -0800 Subject: [PATCH 050/166] Remove magic numbers Replace magic numbers with constexpr calculated times. Tested that trying to create a new instance while shutting down doesn't allow a new instance to be created. --- dMasterServer/InstanceManager.cpp | 20 +++++++- dMasterServer/InstanceManager.h | 6 +++ dMasterServer/MasterServer.cpp | 81 ++++++++++++++++++------------- 3 files changed, 73 insertions(+), 34 deletions(-) diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index 868bf6ee..b277adbf 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -31,6 +31,15 @@ Instance* InstanceManager::GetInstance(LWOMAPID mapID, bool isFriendTransfer, LW Instance* instance = FindInstance(mapID, isFriendTransfer, cloneID); if (instance) return instance; + // If we are shutting down, return a nullptr so a new instance is not created. + if (m_IsShuttingDown) { + Game::logger->Log("InstanceManager", + "Tried to create a new instance map/instance/clone %i/%i/%i, but Master is shutting down.", + mapID, + m_LastInstanceID + 1, + cloneID); + return nullptr; + } //TODO: Update this so that the IP is read from a configuration file instead int softCap = 8; @@ -238,7 +247,7 @@ void InstanceManager::RedirectPendingRequests(Instance* instance) { for (const auto& request : instance->GetPendingAffirmations()) { auto* in = Game::im->GetInstance(zoneId.GetMapID(), false, zoneId.GetCloneID()); - if (!in->GetIsReady()) // Instance not ready, make a pending request + if (in && !in->GetIsReady()) // Instance not ready, make a pending request { in->GetPendingRequests().push_back(request); @@ -295,6 +304,15 @@ Instance* InstanceManager::CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID clon return instance; } + if (m_IsShuttingDown) { + Game::logger->Log("InstanceManager", + "Tried to create a new private instance map/instance/clone %i/%i/%i, but Master is shutting down.", + mapID, + m_LastInstanceID + 1, + cloneID); + return nullptr; + } + int maxPlayers = 999; uint32_t port = GetFreePort(); diff --git a/dMasterServer/InstanceManager.h b/dMasterServer/InstanceManager.h index 2c5083d4..5f48f93b 100644 --- a/dMasterServer/InstanceManager.h +++ b/dMasterServer/InstanceManager.h @@ -128,6 +128,7 @@ public: Instance* CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID cloneID, const std::string& password); Instance* FindPrivateInstance(const std::string& password); + void SetIsShuttingDown(bool value) { this->m_IsShuttingDown = value; }; private: dLogger* mLogger; @@ -136,6 +137,11 @@ private: unsigned short m_LastPort; LWOINSTANCEID m_LastInstanceID; + /** + * Whether or not the master server is currently shutting down. + */ + bool m_IsShuttingDown = false; + //Private functions: bool IsInstanceFull(Instance* instance, bool isFriendTransfer); int GetSoftCap(LWOMAPID mapID); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 49919568..ed94ff83 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -63,6 +63,8 @@ SystemAddress authServerMasterPeerSysAddr; SystemAddress chatServerMasterPeerSysAddr; int main(int argc, char** argv) { + constexpr uint32_t masterFramerate = mediumFramerate; + constexpr uint32_t masterFrameDelta = mediumFrameDelta; Diagnostics::SetProcessName("Master"); Diagnostics::SetProcessFileName(argv[0]); Diagnostics::Initialize(); @@ -287,6 +289,10 @@ int main(int argc, char** argv) { auto t = std::chrono::high_resolution_clock::now(); Packet* packet = nullptr; + constexpr uint32_t logFlushTime = 15 * masterFramerate; + constexpr uint32_t sqlPingTime = 10 * 60 * masterFramerate; + constexpr uint32_t shutdownUniverseTime = 10 * 60 * masterFramerate; + constexpr uint32_t instanceReadyTimeout = 30 * masterFramerate; int framesSinceLastFlush = 0; int framesSinceLastSQLPing = 0; int framesSinceKillUniverseCommand = 0; @@ -303,14 +309,14 @@ int main(int argc, char** argv) { } //Push our log every 15s: - if (framesSinceLastFlush >= 900) { + if (framesSinceLastFlush >= logFlushTime) { Game::logger->Flush(); framesSinceLastFlush = 0; } else framesSinceLastFlush++; //Every 10 min we ping our sql server to keep it alive hopefully: - if (framesSinceLastSQLPing >= 40000) { + if (framesSinceLastSQLPing >= sqlPingTime) { //Find out the master's IP for absolutely no reason: std::string masterIP; int masterPort; @@ -330,7 +336,7 @@ int main(int argc, char** argv) { //10m shutdown for universe kill command if (Game::shouldShutdown) { - if (framesSinceKillUniverseCommand >= 40000) { + if (framesSinceKillUniverseCommand >= shutdownUniverseTime) { //Break main loop and exit break; } else @@ -354,7 +360,7 @@ int main(int argc, char** argv) { instance->SetAffirmationTimeout(affirmTimeout); - if (affirmTimeout == 1000) { + if (affirmTimeout == instanceReadyTimeout) { instance->Shutdown(); instance->SetIsShuttingDown(true); @@ -373,7 +379,7 @@ int main(int argc, char** argv) { } } - t += std::chrono::milliseconds(highFrameDelta); + t += std::chrono::milliseconds(masterFrameDelta); std::this_thread::sleep_until(t); } return FinalizeShutdown(EXIT_SUCCESS); @@ -424,7 +430,6 @@ void HandlePacket(Packet* packet) { if (instance) { LWOZONEID zoneID = instance->GetZoneID(); //Get the zoneID so we can recreate a server Game::im->RemoveInstance(instance); //Delete the old - //Game::im->GetInstance(zoneID.GetMapID(), false, 0); //Create the new } if (packet->systemAddress == chatServerMasterPeerSysAddr) { @@ -465,14 +470,17 @@ void HandlePacket(Packet* packet) { inStream.Read(mythranShift); inStream.Read(zoneID); inStream.Read(zoneClone); - + if (shutdownSequenceStarted) { + Game::logger->Log("MasterServer", "Shutdown sequence has been started. Not creating a new zone."); + break; + } Instance* in = Game::im->GetInstance(zoneID, false, zoneClone); for (auto* instance : Game::im->GetInstances()) { Game::logger->Log("MasterServer", "Instance: %i/%i/%i -> %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance == in); } - if (!in->GetIsReady()) //Instance not ready, make a pending request + if (in && !in->GetIsReady()) //Instance not ready, make a pending request { in->GetPendingRequests().push_back({ requestID, static_cast(mythranShift), packet->systemAddress }); Game::logger->Log("MasterServer", "Server not ready, adding pending request %llu %i %i", requestID, zoneID, zoneClone); @@ -720,9 +728,13 @@ void HandlePacket(Packet* packet) { int zoneID; inStream.Read(zoneID); - - Game::logger->Log("MasterServer", "Prepping zone %i", zoneID); - Game::im->GetInstance(zoneID, false, 0); + if (shutdownSequenceStarted) { + Game::logger->Log("MasterServer", "Shutdown sequence has been started. Not prepping a new zone."); + break; + } else { + Game::logger->Log("MasterServer", "Prepping zone %i", zoneID); + Game::im->GetInstance(zoneID, false, 0); + } break; } @@ -770,8 +782,8 @@ void HandlePacket(Packet* packet) { default: Game::logger->Log("MasterServer", "Unknown master packet ID from server: %i", packet->data[3]); } - } } +} void StartChatServer() { if (Game::shouldShutdown) { @@ -788,9 +800,9 @@ void StartChatServer() { auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); } else { auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); - } +} #endif - } +} void StartAuthServer() { if (Game::shouldShutdown) { @@ -806,7 +818,7 @@ void StartAuthServer() { auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); } else { auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); - } +} #endif } @@ -815,6 +827,11 @@ void ShutdownSequence(int signal) { return; } + if (!Game::im) { + FinalizeShutdown(EXIT_FAILURE); + } + + Game::im->SetIsShuttingDown(true); shutdownSequenceStarted = true; Game::shouldShutdown = true; @@ -826,40 +843,38 @@ void ShutdownSequence(int signal) { } auto* objIdManager = ObjectIDManager::TryInstance(); - if (objIdManager != nullptr) { + if (objIdManager) { objIdManager->SaveToDatabase(); Game::logger->Log("MasterServer", "Saved ObjectIDTracker to DB"); } - auto t = std::chrono::high_resolution_clock::now(); - auto ticks = 0; - - if (!Game::im) { - FinalizeShutdown(EXIT_FAILURE); - } - // A server might not be finished spinning up yet, remove all of those here. - for (auto instance : Game::im->GetInstances()) { + for (auto* instance : Game::im->GetInstances()) { if (!instance->GetIsReady()) { Game::im->RemoveInstance(instance); } } - for (auto instance : Game::im->GetInstances()) { + for (auto* instance : Game::im->GetInstances()) { instance->SetIsShuttingDown(true); } Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds..."); + auto t = std::chrono::high_resolution_clock::now(); + uint32_t framesSinceShutdownStart = 0; + constexpr uint32_t maxShutdownTime = 60 * mediumFramerate; + bool allInstancesShutdown = false; + Packet* packet = nullptr; while (true) { - auto packet = Game::server->Receive(); + packet = Game::server->Receive(); if (packet) { HandlePacket(packet); Game::server->DeallocatePacket(packet); packet = nullptr; } - auto done = true; + allInstancesShutdown = true; for (auto* instance : Game::im->GetInstances()) { if (instance == nullptr) { @@ -867,21 +882,21 @@ void ShutdownSequence(int signal) { } if (!instance->GetShutdownComplete()) { - done = false; + allInstancesShutdown = false; } } - - if (done && authServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS && chatServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS) { + + if (allInstancesShutdown && authServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS && chatServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS) { Game::logger->Log("MasterServer", "Finished shutting down MasterServer!"); break; } - t += std::chrono::milliseconds(highFrameDelta); + t += std::chrono::milliseconds(mediumFrameDelta); std::this_thread::sleep_until(t); - ticks++; + framesSinceShutdownStart++; - if (ticks == 600 * 6) { + if (framesSinceShutdownStart == maxShutdownTime) { Game::logger->Log("MasterServer", "Finished shutting down by timeout!"); break; } From 213c3c37b0ac03d9ee6ffeb76e69e4f8dc5617e9 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 15 Dec 2022 22:10:58 -0800 Subject: [PATCH 051/166] Fix crash in BasicAttackBehavior (#862) * Add failArmor server side Address out of bounds reading in behavior Address the basicAttackBehavior reading out of bounds memory and reading bits that didnt exist, which occasionally caused crashes and also caused the behavior to do undefined behavior due to the bad reads. Tested that attacking a wall anywhere with a projectile now does not crash the game. Tested with logs that the behavior correctly returned when there were no allocated bits or returned when other states were met. Add back logs and add fail handle Remove comment block Revert "Add back logs and add fail handle" This reverts commit db19be0906fc8bf35bf89037e2bfba39f5ef9c0c. Split out checks * Remove case 2 * Update SkillComponent.cpp --- dGame/dBehaviors/BasicAttackBehavior.cpp | 85 ++++++++++++++++-------- dGame/dBehaviors/BasicAttackBehavior.h | 14 ++-- dGame/dComponents/SkillComponent.cpp | 29 +------- 3 files changed, 65 insertions(+), 63 deletions(-) diff --git a/dGame/dBehaviors/BasicAttackBehavior.cpp b/dGame/dBehaviors/BasicAttackBehavior.cpp index fe773f36..f166f00c 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.cpp +++ b/dGame/dBehaviors/BasicAttackBehavior.cpp @@ -14,43 +14,65 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi auto* destroyableComponent = entity->GetComponent(); if (destroyableComponent != nullptr) { PlayFx(u"onhit", entity->GetObjectID()); - destroyableComponent->Damage(this->m_maxDamage, context->originator, context->skillID); + destroyableComponent->Damage(this->m_MaxDamage, context->originator, context->skillID); } - this->m_onSuccess->Handle(context, bitStream, branch); + this->m_OnSuccess->Handle(context, bitStream, branch); return; } bitStream->AlignReadToByteBoundary(); - uint16_t allocatedBits; - bitStream->Read(allocatedBits); - + uint16_t allocatedBits{}; + if (!bitStream->Read(allocatedBits) || allocatedBits == 0) { + Game::logger->LogDebug("BasicAttackBehavior", "No allocated bits"); + return; + } + Game::logger->LogDebug("BasicAttackBehavior", "Number of allocated bits %i", allocatedBits); const auto baseAddress = bitStream->GetReadOffset(); - if (bitStream->ReadBit()) { // Blocked + bool isBlocked{}; + bool isImmune{}; + bool isSuccess{}; + + if (!bitStream->Read(isBlocked)) { + Game::logger->LogDebug("BasicAttackBehavior", "Unable to read isBlocked"); return; } - if (bitStream->ReadBit()) { // Immune + if (isBlocked) return; + + if (!bitStream->Read(isImmune)) { + Game::logger->LogDebug("BasicAttackBehavior", "Unable to read isImmune"); return; } - if (bitStream->ReadBit()) { // Success - uint32_t unknown; - bitStream->Read(unknown); + if (isImmune) return; - uint32_t damageDealt; - bitStream->Read(damageDealt); + if (bitStream->Read(isSuccess) && isSuccess) { // Success + uint32_t unknown{}; + if (!bitStream->Read(unknown)) { + Game::logger->LogDebug("BasicAttackBehavior", "Unable to read unknown"); + return; + } + + uint32_t damageDealt{}; + if (!bitStream->Read(damageDealt)) { + Game::logger->LogDebug("BasicAttackBehavior", "Unable to read damageDealt"); + return; + } // A value that's too large may be a cheating attempt, so we set it to MIN too - if (damageDealt > this->m_maxDamage || damageDealt < this->m_minDamage) { - damageDealt = this->m_minDamage; + if (damageDealt > this->m_MaxDamage || damageDealt < this->m_MinDamage) { + damageDealt = this->m_MinDamage; } auto* entity = EntityManager::Instance()->GetEntity(branch.target); - bool died; - bitStream->Read(died); + bool died{}; + if (!bitStream->Read(died)) { + Game::logger->LogDebug("BasicAttackBehavior", "Unable to read died"); + return; + } if (entity != nullptr) { auto* destroyableComponent = entity->GetComponent(); @@ -61,15 +83,18 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi } } - uint8_t successState; - bitStream->Read(successState); + uint8_t successState{}; + if (!bitStream->Read(successState)) { + Game::logger->LogDebug("BasicAttackBehavior", "Unable to read success state"); + return; + } switch (successState) { case 1: - this->m_onSuccess->Handle(context, bitStream, branch); + this->m_OnSuccess->Handle(context, bitStream, branch); break; default: - Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState); + Game::logger->LogDebug("BasicAttackBehavior", "Unknown success state (%i)!", successState); break; } @@ -79,7 +104,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { auto* self = EntityManager::Instance()->GetEntity(context->originator); if (self == nullptr) { - Game::logger->Log("BasicAttackBehavior", "Invalid self entity (%llu)!", context->originator); + Game::logger->LogDebug("BasicAttackBehavior", "Invalid self entity (%llu)!", context->originator); return; } @@ -99,7 +124,7 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* uint32_t unknown3 = 0; bitStream->Write(unknown3); - auto damage = this->m_minDamage; + auto damage = this->m_MinDamage; auto* entity = EntityManager::Instance()->GetEntity(branch.target); if (entity == nullptr) { @@ -124,10 +149,10 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* switch (successState) { case 1: - this->m_onSuccess->Calculate(context, bitStream, branch); + this->m_OnSuccess->Calculate(context, bitStream, branch); break; default: - Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState); + Game::logger->LogDebug("BasicAttackBehavior", "Unknown success state (%i)!", successState); break; } @@ -140,11 +165,13 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* } void BasicAttackBehavior::Load() { - this->m_minDamage = GetInt("min damage"); - if (this->m_minDamage == 0) this->m_minDamage = 1; + this->m_MinDamage = GetInt("min damage"); + if (this->m_MinDamage == 0) this->m_MinDamage = 1; - this->m_maxDamage = GetInt("max damage"); - if (this->m_maxDamage == 0) this->m_maxDamage = 1; + this->m_MaxDamage = GetInt("max damage"); + if (this->m_MaxDamage == 0) this->m_MaxDamage = 1; - this->m_onSuccess = GetAction("on_success"); + this->m_OnSuccess = GetAction("on_success"); + + this->m_OnFailArmor = GetAction("on_fail_armor"); } diff --git a/dGame/dBehaviors/BasicAttackBehavior.h b/dGame/dBehaviors/BasicAttackBehavior.h index 8e23d443..9c08141c 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.h +++ b/dGame/dBehaviors/BasicAttackBehavior.h @@ -4,12 +4,6 @@ class BasicAttackBehavior final : public Behavior { public: - uint32_t m_minDamage; - - uint32_t m_maxDamage; - - Behavior* m_onSuccess; - explicit BasicAttackBehavior(const uint32_t behaviorId) : Behavior(behaviorId) { } @@ -18,4 +12,12 @@ public: void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; void Load() override; +private: + uint32_t m_MinDamage; + + uint32_t m_MaxDamage; + + Behavior* m_OnSuccess; + + Behavior* m_OnFailArmor; }; diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index f7e8e7d9..c749dbaf 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -319,34 +319,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) { const auto distance = Vector3::DistanceSquared(targetPosition, closestPoint); if (distance > 3 * 3) { - /* - if (entry.TrackTarget && distance <= entry.TrackRadius) - { - const auto rotation = NiQuaternion::LookAtUnlocked(position, targetPosition); - - const auto speed = entry.Velocity.Length(); - - const auto homingTarget = rotation.GetForwardVector() * speed; - - Vector3 homing; - - // Move towards - - const auto difference = homingTarget - entry.Velocity; - const auto mag = difference.Length(); - if (mag <= speed || mag == 0) - { - homing = homingTarget; - } - else - { - entry.Velocity + homingTarget / mag * speed; - } - - entry.Velocity = homing; - } - */ - + // TODO There is supposed to be an implementation for homing projectiles here continue; } From 1ed3af63b9f2be42ecd1c7966c65a6ee604f90a7 Mon Sep 17 00:00:00 2001 From: Daniel Seiler Date: Fri, 16 Dec 2022 07:32:36 +0100 Subject: [PATCH 052/166] Log some recvfrom errors on linux (#885) --- thirdparty/raknet/Source/SocketLayer.cpp | 51 +++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/thirdparty/raknet/Source/SocketLayer.cpp b/thirdparty/raknet/Source/SocketLayer.cpp index b6af8751..6cb4f7c6 100644 --- a/thirdparty/raknet/Source/SocketLayer.cpp +++ b/thirdparty/raknet/Source/SocketLayer.cpp @@ -417,8 +417,14 @@ int SocketLayer::RecvFrom( const SOCKET s, RakPeer *rakPeer, int *errorCode, uns assert( 0 ); #endif - *errorCode = -1; - return -1; + //*errorCode = -1; +#ifdef __linux__ + char str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN); + printf("[RakNet] SocketLayer::RecvFrom: empty datagram from %s", str); +#endif + //return -1; + return 0; } if ( len > 0 ) @@ -479,6 +485,47 @@ int SocketLayer::RecvFrom( const SOCKET s, RakPeer *rakPeer, int *errorCode, uns } #endif } +#elif defined(__linux__) + if (len < -1) + { + printf("[RakNet] SocketLayer::RecvFrom: Unexpected return value."); + return -1; + } + + int local_errno = errno; + if (local_errno == EAGAIN || local_errno == EWOULDBLOCK) + { + return 0; // no data + } + + if (local_errno == EINTR) + { + printf("[RakNet] SocketLayer::RecvFrom: The receive was interrupted by delivery of a signal before any data were available."); + return 0; // log, but ignore + } + + char str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN); + printf("[RakNet] SocketLayer::RecvFrom: Error receiving data from %s", str); + + switch (local_errno) { + case EINVAL: + printf("[RakNet] SocketLayer::RecvFrom: Invalid argument passed."); break; + case ENOMEM: + case ENOBUFS: + printf("[RakNet] SocketLayer::RecvFrom: Could not allocate memory for recvmsg()."); break; + case EFAULT: + printf("[RakNet] SocketLayer::RecvFrom: The receive buffer pointer(s) point outside the process's address space."); break; + case EBADF: + printf("[RakNet] SocketLayer::RecvFrom: The argument sockfd is an invalid descriptor."); break; + case ENOTSOCK: + printf("[RakNet] SocketLayer::RecvFrom: The argument sockfd does not refer to a socket."); break; + case EPIPE: + printf("[RakNet] SocketLayer::RecvFrom: The connection was unexpectedly closed or shut down by the other end. "); break; + default: + printf("[RakNet] SocketLayer::RecvFrom: Unknown Error %d", local_errno); break; + } + return -1; #endif } From 3f1b4339f5df28a9b4510349f32819f184239c88 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 16 Dec 2022 02:24:02 -0800 Subject: [PATCH 053/166] Improve chat and Auth Also change most uses of int to specified lengths. --- dAuthServer/AuthServer.cpp | 26 ++++++++------ dChatServer/ChatServer.cpp | 33 ++++++++++-------- dMasterServer/MasterServer.cpp | 30 ++++++++-------- dWorldServer/WorldServer.cpp | 62 +++++++++++++++++----------------- 4 files changed, 80 insertions(+), 71 deletions(-) diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index e4d8a052..f5090495 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -32,6 +32,8 @@ dLogger* SetupLogger(); void HandlePacket(Packet* packet); int main(int argc, char** argv) { + constexpr uint32_t authFramerate = mediumFramerate; + constexpr uint32_t authFrameDelta = mediumFrameDelta; Diagnostics::SetProcessName("Auth"); Diagnostics::SetProcessFileName(argv[0]); Diagnostics::Initialize(); @@ -67,7 +69,7 @@ int main(int argc, char** argv) { //Find out the master's IP: std::string masterIP; - int masterPort = 1500; + uint32_t masterPort = 1500; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); auto res = stmt->executeQuery(); while (res->next()) { @@ -79,8 +81,8 @@ int main(int argc, char** argv) { delete stmt; //It's safe to pass 'localhost' here, as the IP is only used as the external IP. - int maxClients = 50; - int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. + uint32_t maxClients = 50; + uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); @@ -89,16 +91,18 @@ int main(int argc, char** argv) { //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); Packet* packet = nullptr; - int framesSinceLastFlush = 0; - int framesSinceMasterDisconnect = 0; - int framesSinceLastSQLPing = 0; + constexpr uint32_t logFlushTime = 30 * authFramerate; // 30 seconds in frames + constexpr uint32_t sqlPingTime = 10 * 60 * authFramerate; // 10 minutes in frames + uint32_t framesSinceLastFlush = 0; + uint32_t framesSinceMasterDisconnect = 0; + uint32_t framesSinceLastSQLPing = 0; while (!Game::shouldShutdown) { //Check if we're still connected to master: if (!Game::server->GetIsConnectedToMaster()) { framesSinceMasterDisconnect++; - if (framesSinceMasterDisconnect >= 30) + if (framesSinceMasterDisconnect >= authFramerate) break; //Exit our loop, shut down. } else framesSinceMasterDisconnect = 0; @@ -114,16 +118,16 @@ int main(int argc, char** argv) { } //Push our log every 30s: - if (framesSinceLastFlush >= 900) { + if (framesSinceLastFlush >= logFlushTime) { Game::logger->Flush(); framesSinceLastFlush = 0; } else framesSinceLastFlush++; //Every 10 min we ping our sql server to keep it alive hopefully: - if (framesSinceLastSQLPing >= 40000) { + if (framesSinceLastSQLPing >= sqlPingTime) { //Find out the master's IP for absolutely no reason: std::string masterIP; - int masterPort; + uint32_t masterPort; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); auto res = stmt->executeQuery(); while (res->next()) { @@ -138,7 +142,7 @@ int main(int argc, char** argv) { } else framesSinceLastSQLPing++; //Sleep our thread since auth can afford to. - t += std::chrono::milliseconds(mediumFrameDelta); //Auth can run at a lower "fps" + t += std::chrono::milliseconds(authFrameDelta); //Auth can run at a lower "fps" std::this_thread::sleep_until(t); } diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index 8ae1a9bd..a75c4d51 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -19,6 +19,9 @@ #include "ChatPacketHandler.h" #include "Game.h" + +//RakNet includes: +#include "RakNetDefines.h" namespace Game { dLogger* logger = nullptr; dServer* server = nullptr; @@ -28,8 +31,6 @@ namespace Game { bool shouldShutdown = false; } -//RakNet includes: -#include "RakNetDefines.h" dLogger* SetupLogger(); void HandlePacket(Packet* packet); @@ -37,6 +38,8 @@ void HandlePacket(Packet* packet); PlayerContainer playerContainer; int main(int argc, char** argv) { + constexpr uint32_t chatFramerate = mediumFramerate; + constexpr uint32_t chatFrameDelta = mediumFrameDelta; Diagnostics::SetProcessName("Chat"); Diagnostics::SetProcessFileName(argv[0]); Diagnostics::Initialize(); @@ -65,7 +68,7 @@ int main(int argc, char** argv) { Game::assetManager = new AssetManager(clientPath); } catch (std::runtime_error& ex) { Game::logger->Log("ChatServer", "Got an error while setting up assets: %s", ex.what()); - + return EXIT_FAILURE; } @@ -87,7 +90,7 @@ int main(int argc, char** argv) { //Find out the master's IP: std::string masterIP; - int masterPort = 1000; + uint32_t masterPort = 1000; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); auto res = stmt->executeQuery(); while (res->next()) { @@ -99,8 +102,8 @@ int main(int argc, char** argv) { delete stmt; //It's safe to pass 'localhost' here, as the IP is only used as the external IP. - int maxClients = 50; - int ourPort = 1501; + uint32_t maxClients = 50; + uint32_t ourPort = 1501; if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str()); @@ -111,16 +114,18 @@ int main(int argc, char** argv) { //Run it until server gets a kill message from Master: auto t = std::chrono::high_resolution_clock::now(); Packet* packet = nullptr; - int framesSinceLastFlush = 0; - int framesSinceMasterDisconnect = 0; - int framesSinceLastSQLPing = 0; + constexpr uint32_t logFlushTime = 30 * chatFramerate; // 30 seconds in frames + constexpr uint32_t sqlPingTime = 10 * 60 * chatFramerate; // 10 minutes in frames + uint32_t framesSinceLastFlush = 0; + uint32_t framesSinceMasterDisconnect = 0; + uint32_t framesSinceLastSQLPing = 0; while (!Game::shouldShutdown) { //Check if we're still connected to master: if (!Game::server->GetIsConnectedToMaster()) { framesSinceMasterDisconnect++; - if (framesSinceMasterDisconnect >= 30) + if (framesSinceMasterDisconnect >= chatFramerate) break; //Exit our loop, shut down. } else framesSinceMasterDisconnect = 0; @@ -136,16 +141,16 @@ int main(int argc, char** argv) { } //Push our log every 30s: - if (framesSinceLastFlush >= 900) { + if (framesSinceLastFlush >= logFlushTime) { Game::logger->Flush(); framesSinceLastFlush = 0; } else framesSinceLastFlush++; //Every 10 min we ping our sql server to keep it alive hopefully: - if (framesSinceLastSQLPing >= 40000) { + if (framesSinceLastSQLPing >= sqlPingTime) { //Find out the master's IP for absolutely no reason: std::string masterIP; - int masterPort; + uint32_t masterPort; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); auto res = stmt->executeQuery(); while (res->next()) { @@ -160,7 +165,7 @@ int main(int argc, char** argv) { } else framesSinceLastSQLPing++; //Sleep our thread since auth can afford to. - t += std::chrono::milliseconds(mediumFrameDelta); //Chat can run at a lower "fps" + t += std::chrono::milliseconds(chatFrameDelta); //Chat can run at a lower "fps" std::this_thread::sleep_until(t); } diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index ed94ff83..5bbe7a8c 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -52,8 +52,8 @@ namespace Game { } //namespace Game bool shutdownSequenceStarted = false; -void ShutdownSequence(int signal = -1); -int FinalizeShutdown(int signal = -1); +void ShutdownSequence(int32_t signal = -1); +int32_t FinalizeShutdown(int32_t signal = -1); dLogger* SetupLogger(); void StartAuthServer(); void StartChatServer(); @@ -75,8 +75,8 @@ int main(int argc, char** argv) { //Triggers the shutdown sequence at application exit std::atexit([]() { ShutdownSequence(); }); - signal(SIGINT, [](int signal) { ShutdownSequence(EXIT_FAILURE); }); - signal(SIGTERM, [](int signal) { ShutdownSequence(EXIT_FAILURE); }); + signal(SIGINT, [](int32_t signal) { ShutdownSequence(EXIT_FAILURE); }); + signal(SIGTERM, [](int32_t signal) { ShutdownSequence(EXIT_FAILURE); }); //Create all the objects we need to run our service: Game::logger = SetupLogger(); @@ -239,8 +239,8 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } - int maxClients = 999; - int ourPort = 1000; + uint32_t maxClients = 999; + uint32_t ourPort = 1000; if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port")); @@ -293,9 +293,9 @@ int main(int argc, char** argv) { constexpr uint32_t sqlPingTime = 10 * 60 * masterFramerate; constexpr uint32_t shutdownUniverseTime = 10 * 60 * masterFramerate; constexpr uint32_t instanceReadyTimeout = 30 * masterFramerate; - int framesSinceLastFlush = 0; - int framesSinceLastSQLPing = 0; - int framesSinceKillUniverseCommand = 0; + uint32_t framesSinceLastFlush = 0; + uint32_t framesSinceLastSQLPing = 0; + uint32_t framesSinceKillUniverseCommand = 0; while (true) { //In world we'd update our other systems here. @@ -319,7 +319,7 @@ int main(int argc, char** argv) { if (framesSinceLastSQLPing >= sqlPingTime) { //Find out the master's IP for absolutely no reason: std::string masterIP; - int masterPort; + uint32_t masterPort; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); auto res = stmt->executeQuery(); while (res->next()) { @@ -652,7 +652,7 @@ void HandlePacket(Packet* packet) { uint32_t len; inStream.Read(len); - for (int i = 0; len > i; i++) { + for (uint32_t i = 0; len > i; i++) { char character; inStream.Read(character); password += character; @@ -678,7 +678,7 @@ void HandlePacket(Packet* packet) { uint32_t len; inStream.Read(len); - for (int i = 0; i < len; i++) { + for (uint32_t i = 0; i < len; i++) { char character; inStream.Read(character); password += character; } @@ -726,7 +726,7 @@ void HandlePacket(Packet* packet) { RakNet::BitStream inStream(packet->data, packet->length, false); uint64_t header = inStream.Read(header); - int zoneID; + int32_t zoneID; inStream.Read(zoneID); if (shutdownSequenceStarted) { Game::logger->Log("MasterServer", "Shutdown sequence has been started. Not prepping a new zone."); @@ -822,7 +822,7 @@ void StartAuthServer() { #endif } -void ShutdownSequence(int signal) { +void ShutdownSequence(int32_t signal) { if (shutdownSequenceStarted) { return; } @@ -905,7 +905,7 @@ void ShutdownSequence(int signal) { FinalizeShutdown(signal); } -int FinalizeShutdown(int signal) { +int32_t FinalizeShutdown(int32_t signal) { //Delete our objects here: Database::Destroy("MasterServer"); if (Game::config) delete Game::config; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index c531595f..c8826efe 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -81,7 +81,7 @@ void WorldShutdownProcess(uint32_t zoneId); void FinalizeShutdown(); void SendShutdownMessageToMaster(); -dLogger* SetupLogger(int zoneID, int instanceID); +dLogger* SetupLogger(uint32_t zoneID, uint32_t instanceID); void HandlePacketChat(Packet* packet); void HandlePacket(Packet* packet); @@ -91,8 +91,8 @@ struct tempSessionInfo { }; std::map m_PendingUsers; -int instanceID = 0; -int g_CloneID = 0; +uint32_t instanceID = 0; +uint32_t g_CloneID = 0; std::string databaseChecksum = ""; int main(int argc, char** argv) { @@ -106,13 +106,13 @@ int main(int argc, char** argv) { signal(SIGINT, [](int) { WorldShutdownSequence(); }); signal(SIGTERM, [](int) { WorldShutdownSequence(); }); - int zoneID = 1000; - int cloneID = 0; - int maxClients = 8; - int ourPort = 2007; + uint32_t zoneID = 1000; + uint32_t cloneID = 0; + uint32_t maxClients = 8; + uint32_t ourPort = 2007; //Check our arguments: - for (int i = 0; i < argc; ++i) { + for (int32_t i = 0; i < argc; ++i) { std::string argument(argv[i]); if (argument == "-zone") zoneID = atoi(argv[i + 1]); @@ -184,7 +184,7 @@ int main(int argc, char** argv) { //Find out the master's IP: std::string masterIP = "localhost"; - int masterPort = 1000; + uint32_t masterPort = 1000; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); auto res = stmt->executeQuery(); while (res->next()) { @@ -203,7 +203,7 @@ int main(int argc, char** argv) { Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, &Game::shouldShutdown, zoneID); //Connect to the chat server: - int chatPort = 1501; + uint32_t chatPort = 1501; if (Game::config->GetValue("chat_server_port") != "") chatPort = std::atoi(Game::config->GetValue("chat_server_port").c_str()); auto chatSock = SocketDescriptor(uint16_t(ourPort + 2), 0); @@ -219,22 +219,22 @@ int main(int argc, char** argv) { auto t = std::chrono::high_resolution_clock::now(); Packet* packet = nullptr; - int framesSinceLastFlush = 0; - int framesSinceMasterDisconnect = 0; - int framesSinceChatDisconnect = 0; - int framesSinceLastUsersSave = 0; - int framesSinceLastSQLPing = 0; - int framesSinceLastUser = 0; + uint32_t framesSinceLastFlush = 0; + uint32_t framesSinceMasterDisconnect = 0; + uint32_t framesSinceChatDisconnect = 0; + uint32_t framesSinceLastUsersSave = 0; + uint32_t framesSinceLastSQLPing = 0; + uint32_t framesSinceLastUser = 0; const float maxPacketProcessingTime = 1.5f; //0.015f; - const int maxPacketsToProcess = 1024; + const uint32_t maxPacketsToProcess = 1024; bool ready = false; - int framesSinceMasterStatus = 0; - int framesSinceShutdownSequence = 0; - int currentFramerate = highFrameDelta; + uint32_t framesSinceMasterStatus = 0; + uint32_t framesSinceShutdownSequence = 0; + uint32_t currentFramerate = highFrameDelta; - int ghostingStepCount = 0; + uint32_t ghostingStepCount = 0; auto ghostingLastTime = std::chrono::high_resolution_clock::now(); PerformanceManager::SelectProfile(zoneID); @@ -263,7 +263,7 @@ int main(int argc, char** argv) { } } - const int bufferSize = 1024; + const int32_t bufferSize = 1024; MD5* md5 = new MD5(); char fileStreamBuffer[1024] = {}; @@ -314,7 +314,7 @@ int main(int argc, char** argv) { if (!Game::server->GetIsConnectedToMaster()) { framesSinceMasterDisconnect++; - int framesToWaitForMaster = ready ? 10 : 200; + uint32_t framesToWaitForMaster = ready ? 10 : 200; if (framesSinceMasterDisconnect >= framesToWaitForMaster && !Game::shouldShutdown) { Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", framesToWaitForMaster); Game::shouldShutdown = true; @@ -378,7 +378,7 @@ int main(int argc, char** argv) { UserManager::Instance()->DeletePendingRemovals(); auto t1 = std::chrono::high_resolution_clock::now(); - for (int curPacket = 0; curPacket < maxPacketsToProcess && timeSpent < maxPacketProcessingTime; curPacket++) { + for (uint32_t curPacket = 0; curPacket < maxPacketsToProcess && timeSpent < maxPacketProcessingTime; curPacket++) { packet = Game::server->Receive(); if (packet) { auto t1 = std::chrono::high_resolution_clock::now(); @@ -433,7 +433,7 @@ int main(int argc, char** argv) { if (framesSinceLastSQLPing >= 40000) { //Find out the master's IP for absolutely no reason: std::string masterIP; - int masterPort; + uint32_t masterPort; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); auto res = stmt->executeQuery(); while (res->next()) { @@ -482,7 +482,7 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } -dLogger* SetupLogger(int zoneID, int instanceID) { +dLogger* SetupLogger(uint32_t zoneID, uint32_t instanceID) { std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(instanceID) + "_" + std::to_string(time(nullptr)) + ".log")).string(); bool logToConsole = false; bool logDebugStatements = false; @@ -524,7 +524,7 @@ void HandlePacketChat(Packet* packet) { //Write our stream outwards: CBITSTREAM; - for (int i = 0; i < inStream.GetNumberOfBytesUsed(); i++) { + for (BitSize_t i = 0; i < inStream.GetNumberOfBytesUsed(); i++) { bitStream.Write(packet->data[i + 16]); //16 bytes == header + playerID to skip } @@ -543,7 +543,7 @@ void HandlePacketChat(Packet* packet) { uint32_t len; inStream.Read(len); - for (int i = 0; len > i; i++) { + for (uint32_t i = 0; len > i; i++) { char character; inStream.Read(character); title += character; @@ -551,7 +551,7 @@ void HandlePacketChat(Packet* packet) { len = 0; inStream.Read(len); - for (int i = 0; len > i; i++) { + for (uint32_t i = 0; len > i; i++) { char character; inStream.Read(character); msg += character; @@ -804,7 +804,7 @@ void HandlePacket(Packet* packet) { uint32_t len; inStream.Read(len); - for (int i = 0; i < len; i++) { + for (uint32_t i = 0; i < len; i++) { char character; inStream.Read(character); username += character; } @@ -1027,7 +1027,7 @@ void HandlePacket(Packet* packet) { //Check for BBB models: auto stmt = Database::CreatePreppedStmt("SELECT ugc_id FROM properties_contents WHERE lot=14 AND property_id=?"); - int templateId = result.getIntField(0); + int32_t templateId = result.getIntField(0); result.finalize(); From 0d460c0eb30c31d7b3e2ff1c520400b9a43281ae Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 16 Dec 2022 03:46:38 -0800 Subject: [PATCH 054/166] Update WorldServer timings --- dCommon/dEnums/dCommonVars.h | 3 ++ dWorldServer/PerformanceManager.cpp | 6 ++-- dWorldServer/PerformanceManager.h | 4 +-- dWorldServer/WorldServer.cpp | 48 ++++++++++++++++++++--------- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index f3d02bf7..68339032 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -12,7 +12,10 @@ typedef int RESTICKET; +// These are the same define, but they mean two different things in different contexts +// so a different define to distinguish what calculation is happening will help clarity. #define FRAMES_TO_MS(x) 1000 / x +#define MS_TO_FRAMES(x) 1000 / x //=========== FRAME TIMINGS =========== constexpr uint32_t highFramerate = 60; diff --git a/dWorldServer/PerformanceManager.cpp b/dWorldServer/PerformanceManager.cpp index 66dcb615..19f38d00 100644 --- a/dWorldServer/PerformanceManager.cpp +++ b/dWorldServer/PerformanceManager.cpp @@ -79,10 +79,10 @@ void PerformanceManager::SelectProfile(LWOMAPID mapID) { m_CurrentProfile = pair->second; } -uint32_t PerformanceManager::GetServerFramerate() { +uint32_t PerformanceManager::GetServerFrameDelta() { if (UserManager::Instance()->GetUserCount() == 0) { - return m_InactiveProfile.serverFramerate; + return m_InactiveProfile.serverFrameDelta; } - return m_CurrentProfile.serverFramerate; + return m_CurrentProfile.serverFrameDelta; } diff --git a/dWorldServer/PerformanceManager.h b/dWorldServer/PerformanceManager.h index 3d8517eb..c584d4ac 100644 --- a/dWorldServer/PerformanceManager.h +++ b/dWorldServer/PerformanceManager.h @@ -5,14 +5,14 @@ #include "dCommonVars.h" struct PerformanceProfile { - uint32_t serverFramerate; + uint32_t serverFrameDelta; }; class PerformanceManager { public: static void SelectProfile(LWOMAPID mapID); - static uint32_t GetServerFramerate(); + static uint32_t GetServerFrameDelta(); private: static PerformanceProfile m_CurrentProfile; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index c8826efe..0ed994fe 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -232,7 +232,7 @@ int main(int argc, char** argv) { bool ready = false; uint32_t framesSinceMasterStatus = 0; uint32_t framesSinceShutdownSequence = 0; - uint32_t currentFramerate = highFrameDelta; + uint32_t currentFramerate = highFramerate; uint32_t ghostingStepCount = 0; auto ghostingLastTime = std::chrono::high_resolution_clock::now(); @@ -287,6 +287,14 @@ int main(int argc, char** argv) { } } + uint32_t currentFrameDelta = highFrameDelta; + // These values are adjust them selves to the current framerate should it update. + uint32_t logFlushTime = 15 * currentFramerate; // 15 seconds in frames + uint32_t shutdownTimeout = 10 * 60 * currentFramerate; // 10 minutes in frames + uint32_t noMasterConnectionTimeout = 5 * currentFramerate; // 5 seconds in frames + uint32_t chatReconnectionTime = 30 * currentFramerate; // 30 seconds in frames + uint32_t saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames + uint32_t sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames while (true) { Metrics::StartMeasurement(MetricVariable::Frame); Metrics::StartMeasurement(MetricVariable::GameLoop); @@ -299,24 +307,37 @@ int main(int argc, char** argv) { const auto occupied = UserManager::Instance()->GetUserCount() != 0; + uint32_t newFrameDelta = currentFrameDelta; if (!ready) { - currentFramerate = highFrameDelta; + newFrameDelta = highFrameDelta; } else { - currentFramerate = PerformanceManager::GetServerFramerate(); + newFrameDelta = PerformanceManager::GetServerFrameDelta(); + } + + // Update to the new framerate + if (newFrameDelta != currentFrameDelta) { + currentFrameDelta = newFrameDelta; + currentFramerate = MS_TO_FRAMES(newFrameDelta); + Game::logger->LogDebug("WorldServer", "Framerate for zone/instance/clone %i/%i/%i is now %i", zoneID, instanceID, cloneID, currentFramerate); + logFlushTime = 15 * currentFramerate; // 15 seconds in frames + shutdownTimeout = 10 * 60 * currentFramerate; // 10 minutes in frames + noMasterConnectionTimeout = 5 * currentFramerate; // 5 seconds in frames + chatReconnectionTime = 30 * currentFramerate; // 30 seconds in frames + saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames + sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames } //Warning if we ran slow - if (deltaTime > currentFramerate) { - Game::logger->Log("WorldServer", "We're running behind, dT: %f > %f (framerate)", deltaTime, currentFramerate); + if (deltaTime > currentFrameDelta) { + Game::logger->Log("WorldServer", "We're running behind, dT: %f > %f (framerate %i)", deltaTime, currentFrameDelta, currentFramerate); } //Check if we're still connected to master: if (!Game::server->GetIsConnectedToMaster()) { framesSinceMasterDisconnect++; - uint32_t framesToWaitForMaster = ready ? 10 : 200; - if (framesSinceMasterDisconnect >= framesToWaitForMaster && !Game::shouldShutdown) { - Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", framesToWaitForMaster); + if (framesSinceMasterDisconnect >= noMasterConnectionTimeout && !Game::shouldShutdown) { + Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", noMasterConnectionTimeout); Game::shouldShutdown = true; } } else framesSinceMasterDisconnect = 0; @@ -325,8 +346,7 @@ int main(int argc, char** argv) { if (!chatConnected) { framesSinceChatDisconnect++; - // Attempt to reconnect every 30 seconds. - if (framesSinceChatDisconnect >= 2000) { + if (framesSinceChatDisconnect >= chatReconnectionTime) { framesSinceChatDisconnect = 0; Game::chatServer->Connect(masterIP.c_str(), chatPort, "3.25 ND1", 8); @@ -403,7 +423,7 @@ int main(int argc, char** argv) { Metrics::EndMeasurement(MetricVariable::UpdateReplica); //Push our log every 15s: - if (framesSinceLastFlush >= 1000) { + if (framesSinceLastFlush >= logFlushTime) { Game::logger->Flush(); framesSinceLastFlush = 0; } else framesSinceLastFlush++; @@ -420,7 +440,7 @@ int main(int argc, char** argv) { } //Save all connected users every 10 minutes: - if (framesSinceLastUsersSave >= 40000 && zoneID != 0) { + if (framesSinceLastUsersSave >= saveTime && zoneID != 0) { UserManager::Instance()->SaveAllActiveCharacters(); framesSinceLastUsersSave = 0; @@ -430,7 +450,7 @@ int main(int argc, char** argv) { } else framesSinceLastUsersSave++; //Every 10 min we ping our sql server to keep it alive hopefully: - if (framesSinceLastSQLPing >= 40000) { + if (framesSinceLastSQLPing >= sqlPingTime) { //Find out the master's IP for absolutely no reason: std::string masterIP; uint32_t masterPort; @@ -451,7 +471,7 @@ int main(int argc, char** argv) { Metrics::StartMeasurement(MetricVariable::Sleep); - t += std::chrono::milliseconds(currentFramerate); + t += std::chrono::milliseconds(currentFrameDelta); std::this_thread::sleep_until(t); Metrics::EndMeasurement(MetricVariable::Sleep); From b33a3df012375a2ddd873f8d2f47bcbc5ba00e7e Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Fri, 16 Dec 2022 04:02:54 -0800 Subject: [PATCH 055/166] Scale timers --- dWorldServer/WorldServer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 0ed994fe..37dce5cd 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -287,7 +287,7 @@ int main(int argc, char** argv) { } } - uint32_t currentFrameDelta = highFrameDelta; + uint32_t currentFrameDelta = highFrameDelta; // These values are adjust them selves to the current framerate should it update. uint32_t logFlushTime = 15 * currentFramerate; // 15 seconds in frames uint32_t shutdownTimeout = 10 * 60 * currentFramerate; // 10 minutes in frames @@ -314,17 +314,24 @@ int main(int argc, char** argv) { newFrameDelta = PerformanceManager::GetServerFrameDelta(); } - // Update to the new framerate + // Update to the new framerate and scale all timings to said new framerate if (newFrameDelta != currentFrameDelta) { + float_t ratioBeforeToAfter = (float)currentFrameDelta / (float)newFrameDelta; currentFrameDelta = newFrameDelta; currentFramerate = MS_TO_FRAMES(newFrameDelta); Game::logger->LogDebug("WorldServer", "Framerate for zone/instance/clone %i/%i/%i is now %i", zoneID, instanceID, cloneID, currentFramerate); logFlushTime = 15 * currentFramerate; // 15 seconds in frames + framesSinceLastFlush *= ratioBeforeToAfter; shutdownTimeout = 10 * 60 * currentFramerate; // 10 minutes in frames + framesSinceLastUser *= ratioBeforeToAfter; noMasterConnectionTimeout = 5 * currentFramerate; // 5 seconds in frames + framesSinceMasterDisconnect *= ratioBeforeToAfter; chatReconnectionTime = 30 * currentFramerate; // 30 seconds in frames + framesSinceChatDisconnect *= ratioBeforeToAfter; saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames + framesSinceLastUsersSave *= ratioBeforeToAfter; sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames + framesSinceLastSQLPing *= ratioBeforeToAfter; } //Warning if we ran slow From a2ca2733702f2be1e8a0277c1f9ba64edc0c1b65 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 16 Dec 2022 13:23:02 -0800 Subject: [PATCH 056/166] Cleanup behavior bitstream reads (#888) * Add failArmor server side Address out of bounds reading in behavior Address the basicAttackBehavior reading out of bounds memory and reading bits that didnt exist, which occasionally caused crashes and also caused the behavior to do undefined behavior due to the bad reads. Tested that attacking a wall anywhere with a projectile now does not crash the game. Tested with logs that the behavior correctly returned when there were no allocated bits or returned when other states were met. Add back logs and add fail handle Remove comment block Revert "Add back logs and add fail handle" This reverts commit db19be0906fc8bf35bf89037e2bfba39f5ef9c0c. Split out checks * Cleanup Behavior streams --- dGame/dBehaviors/AirMovementBehavior.cpp | 27 +++++++++++++------ dGame/dBehaviors/AirMovementBehavior.h | 2 +- dGame/dBehaviors/AreaOfEffectBehavior.cpp | 16 ++++++++--- dGame/dBehaviors/AttackDelayBehavior.cpp | 7 +++-- dGame/dBehaviors/ChainBehavior.cpp | 15 +++++++---- dGame/dBehaviors/ChargeUpBehavior.cpp | 8 ++++-- dGame/dBehaviors/ForceMovementBehavior.cpp | 23 +++++++++++----- dGame/dBehaviors/InterruptBehavior.cpp | 15 ++++++++--- dGame/dBehaviors/KnockbackBehavior.cpp | 9 +++++-- dGame/dBehaviors/MovementSwitchBehavior.cpp | 9 ++++--- dGame/dBehaviors/ProjectileAttackBehavior.cpp | 21 ++++++++++----- dGame/dBehaviors/StunBehavior.cpp | 7 +++-- dGame/dBehaviors/SwitchBehavior.cpp | 5 +++- dGame/dBehaviors/SwitchMultipleBehavior.cpp | 12 +++++---- dGame/dBehaviors/TacArcBehavior.cpp | 18 +++++++++---- 15 files changed, 138 insertions(+), 56 deletions(-) diff --git a/dGame/dBehaviors/AirMovementBehavior.cpp b/dGame/dBehaviors/AirMovementBehavior.cpp index 469ac6e4..932297b9 100644 --- a/dGame/dBehaviors/AirMovementBehavior.cpp +++ b/dGame/dBehaviors/AirMovementBehavior.cpp @@ -2,11 +2,16 @@ #include "BehaviorBranchContext.h" #include "BehaviorContext.h" #include "EntityManager.h" +#include "Game.h" +#include "dLogger.h" void AirMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - uint32_t handle; + uint32_t handle{}; - bitStream->Read(handle); + if (!bitStream->Read(handle)) { + Game::logger->Log("AirMovementBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } context->RegisterSyncBehavior(handle, this, branch); } @@ -17,14 +22,20 @@ void AirMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream->Write(handle); } -void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) { - uint32_t behaviorId; +void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + uint32_t behaviorId{}; - bit_stream->Read(behaviorId); + if (!bitStream->Read(behaviorId)) { + Game::logger->Log("AirMovementBehavior", "Unable to read behaviorId from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } - LWOOBJID target; + LWOOBJID target{}; - bit_stream->Read(target); + if (!bitStream->Read(target)) { + Game::logger->Log("AirMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } auto* behavior = CreateBehavior(behaviorId); @@ -32,7 +43,7 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bit_ branch.target = target; } - behavior->Handle(context, bit_stream, branch); + behavior->Handle(context, bitStream, branch); } void AirMovementBehavior::Load() { diff --git a/dGame/dBehaviors/AirMovementBehavior.h b/dGame/dBehaviors/AirMovementBehavior.h index 323edf37..89dc1e05 100644 --- a/dGame/dBehaviors/AirMovementBehavior.h +++ b/dGame/dBehaviors/AirMovementBehavior.h @@ -16,7 +16,7 @@ public: void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; - void Sync(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) override; + void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; void Load() override; }; diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index 898d1f99..ca3bdf93 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -9,11 +9,16 @@ #include "BehaviorContext.h" #include "RebuildComponent.h" #include "DestroyableComponent.h" +#include "Game.h" +#include "dLogger.h" void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - uint32_t targetCount; + uint32_t targetCount{}; - bitStream->Read(targetCount); + if (!bitStream->Read(targetCount)) { + Game::logger->Log("AreaOfEffectBehavior", "Unable to read targetCount from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } if (targetCount > this->m_maxTargets) { return; @@ -24,9 +29,12 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b targets.reserve(targetCount); for (auto i = 0u; i < targetCount; ++i) { - LWOOBJID target; + LWOOBJID target{}; - bitStream->Read(target); + if (!bitStream->Read(target)) { + Game::logger->Log("AreaOfEffectBehavior", "failed to read in target %i from bitStream, aborting target Handle!", i); + return; + }; targets.push_back(target); } diff --git a/dGame/dBehaviors/AttackDelayBehavior.cpp b/dGame/dBehaviors/AttackDelayBehavior.cpp index 450741ec..201921a3 100644 --- a/dGame/dBehaviors/AttackDelayBehavior.cpp +++ b/dGame/dBehaviors/AttackDelayBehavior.cpp @@ -5,9 +5,12 @@ #include "dLogger.h" void AttackDelayBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - uint32_t handle; + uint32_t handle{}; - bitStream->Read(handle); + if (!bitStream->Read(handle)) { + Game::logger->Log("AttackDelayBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; for (auto i = 0u; i < this->m_numIntervals; ++i) { context->RegisterSyncBehavior(handle, this, branch); diff --git a/dGame/dBehaviors/ChainBehavior.cpp b/dGame/dBehaviors/ChainBehavior.cpp index 3ef8c15b..ec0f8969 100644 --- a/dGame/dBehaviors/ChainBehavior.cpp +++ b/dGame/dBehaviors/ChainBehavior.cpp @@ -4,14 +4,19 @@ #include "dLogger.h" void ChainBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - uint32_t chain_index; + uint32_t chainIndex{}; - bitStream->Read(chain_index); + if (!bitStream->Read(chainIndex)) { + Game::logger->Log("ChainBehavior", "Unable to read chainIndex from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } - chain_index--; + chainIndex--; - if (chain_index < this->m_behaviors.size()) { - this->m_behaviors.at(chain_index)->Handle(context, bitStream, branch); + if (chainIndex < this->m_behaviors.size()) { + this->m_behaviors.at(chainIndex)->Handle(context, bitStream, branch); + } else { + Game::logger->Log("ChainBehavior", "chainIndex out of bounds, aborting handle of chain %i bits unread %i", chainIndex, bitStream->GetNumberOfUnreadBits()); } } diff --git a/dGame/dBehaviors/ChargeUpBehavior.cpp b/dGame/dBehaviors/ChargeUpBehavior.cpp index fa9fa34b..1b9ba433 100644 --- a/dGame/dBehaviors/ChargeUpBehavior.cpp +++ b/dGame/dBehaviors/ChargeUpBehavior.cpp @@ -1,12 +1,16 @@ #include "ChargeUpBehavior.h" #include "BehaviorBranchContext.h" #include "BehaviorContext.h" +#include "Game.h" #include "dLogger.h" void ChargeUpBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - uint32_t handle; + uint32_t handle{}; - bitStream->Read(handle); + if (!bitStream->Read(handle)) { + Game::logger->Log("ChargeUpBehavior", "Unable to read handle from bitStream, aborting Handle! variable_type"); + return; + }; context->RegisterSyncBehavior(handle, this, branch); } diff --git a/dGame/dBehaviors/ForceMovementBehavior.cpp b/dGame/dBehaviors/ForceMovementBehavior.cpp index e1ac6133..e095447c 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.cpp +++ b/dGame/dBehaviors/ForceMovementBehavior.cpp @@ -3,23 +3,34 @@ #include "BehaviorContext.h" #include "ControllablePhysicsComponent.h" #include "EntityManager.h" +#include "Game.h" +#include "dLogger.h" void ForceMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { if (this->m_hitAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitEnemyAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitFactionAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) { return; } - uint32_t handle; - bitStream->Read(handle); + uint32_t handle{}; + if (!bitStream->Read(handle)) { + Game::logger->Log("ForceMovementBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } context->RegisterSyncBehavior(handle, this, branch); } void ForceMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - uint32_t next; - bitStream->Read(next); + uint32_t next{}; + if (!bitStream->Read(next)) { + Game::logger->Log("ForceMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } - LWOOBJID target; - bitStream->Read(target); + LWOOBJID target{}; + if (!bitStream->Read(target)) { + Game::logger->Log("ForceMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } branch.target = target; auto* behavior = CreateBehavior(next); diff --git a/dGame/dBehaviors/InterruptBehavior.cpp b/dGame/dBehaviors/InterruptBehavior.cpp index b42eadb0..9035c092 100644 --- a/dGame/dBehaviors/InterruptBehavior.cpp +++ b/dGame/dBehaviors/InterruptBehavior.cpp @@ -11,7 +11,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (branch.target != context->originator) { bool unknown = false; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("InterruptBehavior", "Unable to read unknown1 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; if (unknown) return; } @@ -19,7 +22,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (!this->m_interruptBlock) { bool unknown = false; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("InterruptBehavior", "Unable to read unknown2 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; if (unknown) return; } @@ -28,7 +34,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS { bool unknown = false; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("InterruptBehavior", "Unable to read unknown3 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } if (branch.target == context->originator) return; diff --git a/dGame/dBehaviors/KnockbackBehavior.cpp b/dGame/dBehaviors/KnockbackBehavior.cpp index 83c82010..1b878ed0 100644 --- a/dGame/dBehaviors/KnockbackBehavior.cpp +++ b/dGame/dBehaviors/KnockbackBehavior.cpp @@ -6,11 +6,16 @@ #include "EntityManager.h" #include "GameMessages.h" #include "DestroyableComponent.h" +#include "Game.h" +#include "dLogger.h" void KnockbackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - bool unknown; + bool unknown{}; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("KnockbackBehavior", "Unable to read unknown from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } void KnockbackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { diff --git a/dGame/dBehaviors/MovementSwitchBehavior.cpp b/dGame/dBehaviors/MovementSwitchBehavior.cpp index 17ed5c40..c893e6e1 100644 --- a/dGame/dBehaviors/MovementSwitchBehavior.cpp +++ b/dGame/dBehaviors/MovementSwitchBehavior.cpp @@ -13,9 +13,11 @@ void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* return; } - uint32_t movementType; - - bitStream->Read(movementType); + uint32_t movementType{}; + if (!bitStream->Read(movementType)) { + Game::logger->Log("MovementSwitchBehavior", "Unable to read movementType from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; switch (movementType) { case 1: @@ -55,4 +57,3 @@ void MovementSwitchBehavior::Load() { this->m_jumpAction = GetAction("jump_action"); } - diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.cpp b/dGame/dBehaviors/ProjectileAttackBehavior.cpp index 350234e2..c14f032d 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.cpp +++ b/dGame/dBehaviors/ProjectileAttackBehavior.cpp @@ -8,9 +8,12 @@ #include "../dWorldServer/ObjectIDManager.h" void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - LWOOBJID target; + LWOOBJID target{}; - bitStream->Read(target); + if (!bitStream->Read(target)) { + Game::logger->Log("ProjectileAttackBehavior", "Unable to read target from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; auto* entity = EntityManager::Instance()->GetEntity(context->originator); @@ -30,15 +33,21 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea if (m_useMouseposit) { NiPoint3 targetPosition = NiPoint3::ZERO; - bitStream->Read(targetPosition); + if (!bitStream->Read(targetPosition)) { + Game::logger->Log("ProjectileAttackBehavior", "Unable to read targetPosition from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } auto* targetEntity = EntityManager::Instance()->GetEntity(target); for (auto i = 0u; i < this->m_projectileCount; ++i) { - LWOOBJID projectileId; + LWOOBJID projectileId{}; - bitStream->Read(projectileId); + if (!bitStream->Read(projectileId)) { + Game::logger->Log("ProjectileAttackBehavior", "Unable to read projectileId from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; branch.target = target; branch.isProjectile = true; @@ -98,7 +107,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt for (auto i = 0u; i < this->m_projectileCount; ++i) { auto id = static_cast(ObjectIDManager::Instance()->GenerateObjectID()); - id = GeneralUtils::SetBit(id, OBJECT_BIT_CLIENT); + id = GeneralUtils::SetBit(id, OBJECT_BIT_SPAWNED); bitStream->Write(id); diff --git a/dGame/dBehaviors/StunBehavior.cpp b/dGame/dBehaviors/StunBehavior.cpp index 59a81440..065b7220 100644 --- a/dGame/dBehaviors/StunBehavior.cpp +++ b/dGame/dBehaviors/StunBehavior.cpp @@ -14,8 +14,11 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream return; } - bool blocked; - bitStream->Read(blocked); + bool blocked{}; + if (!bitStream->Read(blocked)) { + Game::logger->Log("StunBehavior", "Unable to read blocked from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; auto* target = EntityManager::Instance()->GetEntity(branch.target); diff --git a/dGame/dBehaviors/SwitchBehavior.cpp b/dGame/dBehaviors/SwitchBehavior.cpp index 78271b99..f6eb3ff5 100644 --- a/dGame/dBehaviors/SwitchBehavior.cpp +++ b/dGame/dBehaviors/SwitchBehavior.cpp @@ -10,7 +10,10 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre auto state = true; if (this->m_imagination > 0 || !this->m_isEnemyFaction) { - bitStream->Read(state); + if (!bitStream->Read(state)) { + Game::logger->Log("SwitchBehavior", "Unable to read state from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } auto* entity = EntityManager::Instance()->GetEntity(context->originator); diff --git a/dGame/dBehaviors/SwitchMultipleBehavior.cpp b/dGame/dBehaviors/SwitchMultipleBehavior.cpp index 946e5e0f..e92393fc 100644 --- a/dGame/dBehaviors/SwitchMultipleBehavior.cpp +++ b/dGame/dBehaviors/SwitchMultipleBehavior.cpp @@ -9,10 +9,12 @@ #include "EntityManager.h" -void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) { - float value; +void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + float value{}; - bit_stream->Read(value); + if (!bitStream->Read(value)) { + Game::logger->Log("SwitchMultipleBehavior", "Unable to read value from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; uint32_t trigger = 0; @@ -30,10 +32,10 @@ void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* auto* behavior = this->m_behaviors.at(trigger).second; - behavior->Handle(context, bit_stream, branch); + behavior->Handle(context, bitStream, branch); } -void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) { +void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { // TODO } diff --git a/dGame/dBehaviors/TacArcBehavior.cpp b/dGame/dBehaviors/TacArcBehavior.cpp index 8789f9b6..38efdea4 100644 --- a/dGame/dBehaviors/TacArcBehavior.cpp +++ b/dGame/dBehaviors/TacArcBehavior.cpp @@ -20,12 +20,16 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre bool hit = false; - bitStream->Read(hit); + if (!bitStream->Read(hit)) { + Game::logger->Log("TacArcBehavior", "Unable to read hit from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; if (this->m_checkEnv) { bool blocked = false; - bitStream->Read(blocked); + if (!bitStream->Read(blocked)) { + Game::logger->Log("TacArcBehavior", "Unable to read blocked from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; if (blocked) { this->m_blockedAction->Handle(context, bitStream, branch); @@ -37,7 +41,9 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre if (hit) { uint32_t count = 0; - bitStream->Read(count); + if (!bitStream->Read(count)) { + Game::logger->Log("TacArcBehavior", "Unable to read count from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; if (count > m_maxTargets && m_maxTargets > 0) { count = m_maxTargets; @@ -46,9 +52,11 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre std::vector targets; for (auto i = 0u; i < count; ++i) { - LWOOBJID id; + LWOOBJID id{}; - bitStream->Read(id); + if (!bitStream->Read(id)) { + Game::logger->Log("TacArcBehavior", "Unable to read id from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; targets.push_back(id); } From cd78a3dec72ac2e4c427ef21c9fbcb452fc02fe5 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 16 Dec 2022 13:23:09 -0800 Subject: [PATCH 057/166] Fix cannon super charge speed (#883) * Fix cannon * Update SGCannon.cpp --- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 049837a4..912b9f58 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -722,7 +722,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { Game::logger->Log("SGCannon", "Player has %d equipped items", equippedItems.size()); auto skillID = constants.cannonSkill; - auto coolDown = constants.cannonRefireRate; + auto cooldown = constants.cannonRefireRate; auto* selfInventoryComponent = self->GetComponent(); @@ -738,7 +738,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { // TODO: Equip items skillID = constants.cannonSuperChargeSkill; - coolDown = 400; + cooldown = 400; } else { selfInventoryComponent->UpdateSlot("greeble_r", { ObjectIDManager::GenerateRandomObjectID(), 0, 0, 0 }); selfInventoryComponent->UpdateSlot("greeble_l", { ObjectIDManager::GenerateRandomObjectID(), 0, 0, 0 }); @@ -761,7 +761,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { } } } - + cooldown = 800; self->SetVar(NumberOfChargesVariable, 0); } @@ -777,7 +777,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { properties.cannonFOV = 58.6f; properties.cannonVelocity = 129.0; - properties.cannonRefireRate = 800; + properties.cannonRefireRate = cooldown; properties.cannonMinDistance = 30; properties.cannonTimeout = -1; From 32f8bda53866996de7ece9cb591e2b82d1fb7e9c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 16 Dec 2022 15:23:38 -0600 Subject: [PATCH 058/166] Allow the player to be interrupted (#881) --- dGame/dComponents/SkillComponent.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index c749dbaf..445a837e 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -181,17 +181,11 @@ void SkillComponent::Reset() { } void SkillComponent::Interrupt() { - if (m_Parent->IsPlayer()) return; - + // TODO: need to check immunities on the destroyable component, but they aren't implemented auto* combat = m_Parent->GetComponent(); + if (combat != nullptr && combat->GetStunImmune()) return; - if (combat != nullptr && combat->GetStunImmune()) { - return; - } - - for (const auto& behavior : this->m_managedBehaviors) { - behavior.second->Interrupt(); - } + for (const auto& behavior : this->m_managedBehaviors) behavior.second->Interrupt(); } void SkillComponent::RegisterCalculatedProjectile(const LWOOBJID projectileId, BehaviorContext* context, const BehaviorBranchContext& branch, const LOT lot, const float maxTime, From 631365b7f70fe138fe39a390d5fac2134ffcca5e Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 16 Dec 2022 15:24:13 -0600 Subject: [PATCH 059/166] Add change idle flags behavior and GM (#871) * update naming for animation flag enum value 0 * Add change idle flags behaviors and GM * default to 0 when none is given --- dCommon/dEnums/dMessageIdentifiers.h | 1 + dCommon/dEnums/eAninmationFlags.h | 2 +- dGame/dBehaviors/Behavior.cpp | 5 ++- dGame/dBehaviors/CMakeLists.txt | 1 + dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp | 37 ++++++++++++++++++++ dGame/dBehaviors/ChangeIdleFlagsBehavior.h | 23 ++++++++++++ dGame/dBehaviors/SwitchBehavior.cpp | 2 +- dGame/dComponents/PossessableComponent.cpp | 4 +-- dGame/dComponents/PossessableComponent.h | 2 +- dGame/dGameMessages/GameMessages.cpp | 12 +++++++ dGame/dGameMessages/GameMessages.h | 10 ++++++ 11 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp create mode 100644 dGame/dBehaviors/ChangeIdleFlagsBehavior.h diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index 5a5c9088..129585a0 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -488,6 +488,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_MATCH_UPDATE = 1310, GAME_MSG_MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131, GAME_MSG_MODULE_ASSEMBLY_QUERY_DATA = 1132, + GAME_MSG_CHANGE_IDLE_FLAGS = 1338, GAME_MSG_VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340, GAME_MSG_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341, GAME_MSG_VEHICLE_NOTIFY_SERVER_ADD_PASSIVE_BOOST_ACTION = 1342, diff --git a/dCommon/dEnums/eAninmationFlags.h b/dCommon/dEnums/eAninmationFlags.h index 9b2ea3fb..ce235ae9 100644 --- a/dCommon/dEnums/eAninmationFlags.h +++ b/dCommon/dEnums/eAninmationFlags.h @@ -6,7 +6,7 @@ #include enum class eAnimationFlags : uint32_t { - IDLE_INVALID = 0, // made up, for internal use!!! + IDLE_NONE = 0, IDLE_BASIC, IDLE_SWIM, IDLE_CARRY, diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index d0d6192b..cd9304d3 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -60,6 +60,7 @@ #include "SpeedBehavior.h" #include "DamageReductionBehavior.h" #include "JetPackBehavior.h" +#include "ChangeIdleFlagsBehavior.h" //CDClient includes #include "CDBehaviorParameterTable.h" @@ -196,7 +197,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { behavior = new SkillCastFailedBehavior(behaviorId); break; case BehaviorTemplates::BEHAVIOR_IMITATION_SKUNK_STINK: break; - case BehaviorTemplates::BEHAVIOR_CHANGE_IDLE_FLAGS: break; + case BehaviorTemplates::BEHAVIOR_CHANGE_IDLE_FLAGS: + behavior = new ChangeIdleFlagsBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_APPLY_BUFF: behavior = new ApplyBuffBehavior(behaviorId); break; diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index 297c389b..40ac0a9c 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -12,6 +12,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "BuffBehavior.cpp" "CarBoostBehavior.cpp" "ChainBehavior.cpp" + "ChangeIdleFlagsBehavior.cpp" "ChangeOrientationBehavior.cpp" "ChargeUpBehavior.cpp" "ClearTargetBehavior.cpp" diff --git a/dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp b/dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp new file mode 100644 index 00000000..06a79fa7 --- /dev/null +++ b/dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp @@ -0,0 +1,37 @@ + +#include "ChangeIdleFlagsBehavior.h" +#include "BehaviorContext.h" +#include "BehaviorBranchContext.h" + +void ChangeIdleFlagsBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; + if (!target) return; + + GameMessages::SendChangeIdleFlags(target, m_FlagsOn, m_FlagsOff, UNASSIGNED_SYSTEM_ADDRESS); + + if (branch.duration > 0.0f) { + context->RegisterTimerBehavior(this, branch); + } else if (branch.start > 0) { + context->RegisterEndBehavior(this, branch); + } +} + +void ChangeIdleFlagsBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + Handle(context, bitStream, branch); +} + +void ChangeIdleFlagsBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; + if (!target) return; + // flip on and off to end behavior + GameMessages::SendChangeIdleFlags(target, m_FlagsOff, m_FlagsOn, UNASSIGNED_SYSTEM_ADDRESS); +} + +void ChangeIdleFlagsBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + End(context, branch, second); +} + +void ChangeIdleFlagsBehavior::Load() { + m_FlagsOff = static_cast(GetInt("flags_off", 0)); + m_FlagsOn = static_cast(GetInt("flags_on", 0)); +} diff --git a/dGame/dBehaviors/ChangeIdleFlagsBehavior.h b/dGame/dBehaviors/ChangeIdleFlagsBehavior.h new file mode 100644 index 00000000..91f802f4 --- /dev/null +++ b/dGame/dBehaviors/ChangeIdleFlagsBehavior.h @@ -0,0 +1,23 @@ + +#pragma once +#include "Behavior.h" +#include "eAninmationFlags.h" + +class ChangeIdleFlagsBehavior final : public Behavior { +public: + + /* + * Inherited + */ + explicit ChangeIdleFlagsBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {} + + void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void Load() override; + +private: + eAnimationFlags m_FlagsOff; + eAnimationFlags m_FlagsOn; +}; diff --git a/dGame/dBehaviors/SwitchBehavior.cpp b/dGame/dBehaviors/SwitchBehavior.cpp index f6eb3ff5..c010f31b 100644 --- a/dGame/dBehaviors/SwitchBehavior.cpp +++ b/dGame/dBehaviors/SwitchBehavior.cpp @@ -28,7 +28,7 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre return; } - Game::logger->Log("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination()); + Game::logger->LogDebug("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination()); if (state || (entity->GetLOT() == 8092 && destroyableComponent->GetImagination() >= m_imagination)) { this->m_actionTrue->Handle(context, bitStream, branch); diff --git a/dGame/dComponents/PossessableComponent.cpp b/dGame/dComponents/PossessableComponent.cpp index 37591532..5c45a6c1 100644 --- a/dGame/dComponents/PossessableComponent.cpp +++ b/dGame/dComponents/PossessableComponent.cpp @@ -34,8 +34,8 @@ void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_Possessor != LWOOBJID_EMPTY); if (m_Possessor != LWOOBJID_EMPTY) outBitStream->Write(m_Possessor); - outBitStream->Write(m_AnimationFlag != eAnimationFlags::IDLE_INVALID); - if (m_AnimationFlag != eAnimationFlags::IDLE_INVALID) outBitStream->Write(m_AnimationFlag); + outBitStream->Write(m_AnimationFlag != eAnimationFlags::IDLE_NONE); + if (m_AnimationFlag != eAnimationFlags::IDLE_NONE) outBitStream->Write(m_AnimationFlag); outBitStream->Write(m_ImmediatelyDepossess); m_ImmediatelyDepossess = false; // reset flag diff --git a/dGame/dComponents/PossessableComponent.h b/dGame/dComponents/PossessableComponent.h index 43ce8610..e1dc5ccd 100644 --- a/dGame/dComponents/PossessableComponent.h +++ b/dGame/dComponents/PossessableComponent.h @@ -109,7 +109,7 @@ private: * @brief What animaiton flag to use * */ - eAnimationFlags m_AnimationFlag = eAnimationFlags::IDLE_INVALID; + eAnimationFlags m_AnimationFlag = eAnimationFlags::IDLE_NONE; /** * @brief Should this be immediately depossessed diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index fcc25fdc..8c82f644 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3922,6 +3922,18 @@ void GameMessages::SendDisplayChatBubble(LWOOBJID objectId, const std::u16string SEND_PACKET; } + +void GameMessages::SendChangeIdleFlags(LWOOBJID objectId, eAnimationFlags FlagsOn, eAnimationFlags FlagsOff, const SystemAddress& sysAddr) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_CHANGE_IDLE_FLAGS); + bitStream.Write(FlagsOff); + bitStream.Write(FlagsOn); + + SEND_PACKET_BROADCAST; +} // Mounts void GameMessages::SendSetMountInventoryID(Entity* entity, const LWOOBJID& objectID, const SystemAddress& sysAddr) { diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index f9968d14..4f92480f 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -14,6 +14,7 @@ #include "TradingManager.h" #include "LeaderboardManager.h" #include "MovingPlatformComponent.h" +#include "eAninmationFlags.h" class NiQuaternion; class User; @@ -373,6 +374,15 @@ namespace GameMessages { void SendDisplayChatBubble(LWOOBJID objectId, const std::u16string& text, const SystemAddress& sysAddr); + /** + * @brief + * + * @param objectId ID of the entity to set idle flags + * @param FlagsOn Flag to turn on + * @param FlagsOff Flag to turn off + */ + void SendChangeIdleFlags(LWOOBJID objectId, eAnimationFlags FlagsOn, eAnimationFlags FlagsOff, const SystemAddress& sysAddr); + // Mounts /** * @brief Set the Inventory LWOOBJID of the mount From 1da2db9db60379e23d36f0971cd08392bbdea542 Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Sat, 17 Dec 2022 16:03:18 +0000 Subject: [PATCH 060/166] Resolve some string related issues for Windows Debug --- dGame/dComponents/PropertyManagementComponent.cpp | 2 +- dGame/dUtilities/Mail.cpp | 6 +++--- dMasterServer/MasterServer.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index eaade8be..648edff8 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -717,7 +717,7 @@ void PropertyManagementComponent::Save() { insertion->setDouble(9, rotation.y); insertion->setDouble(10, rotation.z); insertion->setDouble(11, rotation.w); - insertion->setString(12, "Objects_" + std::to_string(entity->GetLOT()) + "_name"); // Model name. TODO make this customizable + insertion->setString(12, ("Objects_" + std::to_string(entity->GetLOT()) + "_name").c_str()); // Model name. TODO make this customizable insertion->setString(13, ""); // Model description. TODO implement this. insertion->setDouble(14, 0); // behavior 1. TODO implement this. insertion->setDouble(15, 0); // behavior 2. TODO implement this. diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index 8280b627..7047972f 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -74,12 +74,12 @@ void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, LWOOBJ auto* ins = Database::CreatePreppedStmt("INSERT INTO `mail`(`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `time_sent`, `subject`, `body`, `attachment_id`, `attachment_lot`, `attachment_subkey`, `attachment_count`, `was_read`) VALUES (?,?,?,?,?,?,?,?,?,?,?,0)"); ins->setUInt(1, sender); - ins->setString(2, senderName); + ins->setString(2, senderName.c_str()); ins->setUInt(3, recipient); ins->setString(4, recipientName.c_str()); ins->setUInt64(5, time(nullptr)); - ins->setString(6, subject); - ins->setString(7, body); + ins->setString(6, subject.c_str()); + ins->setString(7, body.c_str()); ins->setUInt(8, 0); ins->setInt(9, attachment); ins->setInt(10, 0); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 4c18566e..3d55f046 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -220,7 +220,7 @@ int main(int argc, char** argv) { //Create account auto* statement = Database::CreatePreppedStmt("INSERT INTO accounts (name, password, ""gm_level) VALUES (?, ?, ?);"); - statement->setString(1, username); + statement->setString(1, username.c_str()); statement->setString(2, std::string(hash, BCRYPT_HASHSIZE).c_str()); statement->setInt(3, 9); From e1bcde628faa0944f0dab60a9aa46b0c62f3175e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 17 Dec 2022 20:54:41 -0800 Subject: [PATCH 061/166] Implement lower cap datagram size (#890) --- dNet/dServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 481667b8..96bb5bc8 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -67,7 +67,7 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect } else { mLogger->Log("dServer", "FAILED TO START SERVER ON IP/PORT: %s:%i", ip.c_str(), port); return; } mLogger->SetLogToConsole(prevLogSetting); - + mPeer->SetMTUSize(1228); // This is hard coded by lu for some reason. //Connect to master if we are not master: if (serverType != ServerType::Master) { SetupForMasterConnection(); From b972acbacc773f221094d61c28d5f2c385913d20 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 18 Dec 2022 06:49:13 -0800 Subject: [PATCH 062/166] Fix stream reads (#894) No changes expected --- dGame/dBehaviors/SwitchMultipleBehavior.cpp | 1 + dGame/dBehaviors/TacArcBehavior.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/dGame/dBehaviors/SwitchMultipleBehavior.cpp b/dGame/dBehaviors/SwitchMultipleBehavior.cpp index e92393fc..078464bb 100644 --- a/dGame/dBehaviors/SwitchMultipleBehavior.cpp +++ b/dGame/dBehaviors/SwitchMultipleBehavior.cpp @@ -14,6 +14,7 @@ void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* if (!bitStream->Read(value)) { Game::logger->Log("SwitchMultipleBehavior", "Unable to read value from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; }; uint32_t trigger = 0; diff --git a/dGame/dBehaviors/TacArcBehavior.cpp b/dGame/dBehaviors/TacArcBehavior.cpp index 38efdea4..91df3879 100644 --- a/dGame/dBehaviors/TacArcBehavior.cpp +++ b/dGame/dBehaviors/TacArcBehavior.cpp @@ -22,6 +22,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre if (!bitStream->Read(hit)) { Game::logger->Log("TacArcBehavior", "Unable to read hit from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; }; if (this->m_checkEnv) { @@ -29,6 +30,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre if (!bitStream->Read(blocked)) { Game::logger->Log("TacArcBehavior", "Unable to read blocked from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; }; if (blocked) { @@ -43,6 +45,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre if (!bitStream->Read(count)) { Game::logger->Log("TacArcBehavior", "Unable to read count from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; }; if (count > m_maxTargets && m_maxTargets > 0) { @@ -56,6 +59,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre if (!bitStream->Read(id)) { Game::logger->Log("TacArcBehavior", "Unable to read id from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; }; targets.push_back(id); From 84c5d74450fca63a8da9aa68de9cd1682f1b7be7 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 18 Dec 2022 07:46:04 -0800 Subject: [PATCH 063/166] Add Delete Inventory Slash Command (#865) * moving branch * Add deleteinven slash command * Change name of BRICKS_IN_BBB * Use string_view instead of strcmp * Remove GameConfig * Revert "Remove GameConfig" This reverts commit cef5cdeea2282e3fc09a118dbecb0009d851b95f. --- dCommon/GeneralUtils.h | 7 +++ dCommon/dEnums/dCommonVars.h | 20 ------- dCommon/dEnums/eInventoryType.h | 59 +++++++++++++++++++ dGame/Character.cpp | 1 + dGame/LeaderboardManager.cpp | 1 + dGame/UserManager.cpp | 1 + dGame/dBehaviors/OverTimeBehavior.cpp | 2 + dGame/dComponents/BuffComponent.cpp | 1 + dGame/dComponents/DestroyableComponent.cpp | 1 + dGame/dComponents/InventoryComponent.h | 1 + dGame/dComponents/MovementAIComponent.cpp | 1 + .../PropertyManagementComponent.cpp | 1 + .../dComponents/ScriptedActivityComponent.cpp | 1 + dGame/dGameMessages/GameMessages.cpp | 1 + dGame/dGameMessages/GameMessages.h | 3 +- dGame/dInventory/Inventory.cpp | 9 ++- dGame/dInventory/Inventory.h | 6 ++ dGame/dInventory/Item.cpp | 4 +- dGame/dInventory/Item.h | 1 + dGame/dMission/Mission.cpp | 3 +- dGame/dMission/MissionTask.cpp | 2 +- dGame/dUtilities/SlashCommandHandler.cpp | 27 +++++++++ .../02_server/Map/General/QbEnemyStunner.cpp | 1 + .../FireFirstSkillonStartup.cpp | 1 + .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 1 + dScripts/ai/NS/NsConcertInstrument.cpp | 1 + 26 files changed, 130 insertions(+), 27 deletions(-) create mode 100644 dCommon/dEnums/eInventoryType.h diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index af7c7012..d43ad9b1 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -14,6 +14,8 @@ #include "Game.h" #include "dLogger.h" +enum eInventoryType : uint32_t; + /*! \file GeneralUtils.hpp \brief A namespace containing general utility functions @@ -174,6 +176,11 @@ namespace GeneralUtils { return std::stoull(value); } + template <> + inline eInventoryType Parse(const char* value) { + return static_cast(std::stoul(value)); + } + template bool TryParse(const char* value, T& dst) { try { diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index f64d496f..d13e8b94 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -427,26 +427,6 @@ enum class UseItemResponse : uint32_t { MountsNotAllowed }; -/** - * Represents the different types of inventories an entity may have - */ -enum eInventoryType : uint32_t { - ITEMS = 0, - VAULT_ITEMS, - BRICKS, - MODELS_IN_BBB, - TEMP_ITEMS = 4, - MODELS, - TEMP_MODELS, - BEHAVIORS, - PROPERTY_DEEDS, - VENDOR_BUYBACK = 11, - HIDDEN = 12, //Used for missional items - VAULT_MODELS = 14, - ITEM_SETS, //internal - INVALID // made up, for internal use!!! -}; - enum eRebuildState : uint32_t { REBUILD_OPEN, REBUILD_COMPLETED = 2, diff --git a/dCommon/dEnums/eInventoryType.h b/dCommon/dEnums/eInventoryType.h new file mode 100644 index 00000000..12573aa4 --- /dev/null +++ b/dCommon/dEnums/eInventoryType.h @@ -0,0 +1,59 @@ +#pragma once + +#ifndef __EINVENTORYTYPE__H__ +#define __EINVENTORYTYPE__H__ + +#include +static const uint8_t NUMBER_OF_INVENTORIES = 17; +/** + * Represents the different types of inventories an entity may have + */ +enum eInventoryType : uint32_t { + ITEMS = 0, + VAULT_ITEMS, + BRICKS, + MODELS_IN_BBB, + TEMP_ITEMS, + MODELS, + TEMP_MODELS, + BEHAVIORS, + PROPERTY_DEEDS, + BRICKS_IN_BBB, + VENDOR, + VENDOR_BUYBACK, + QUEST, //Used for mission items + DONATION, + VAULT_MODELS, + ITEM_SETS, //internal, technically this is BankBehaviors. + INVALID // made up, for internal use!!!, Technically this called the ALL inventory. +}; + +class InventoryType { +public: + static const char* InventoryTypeToString(eInventoryType inventory) { + const char* eInventoryTypeTable[NUMBER_OF_INVENTORIES] = { + "ITEMS", + "VAULT_ITEMS", + "BRICKS", + "MODELS_IN_BBB", + "TEMP_ITEMS", + "MODELS", + "TEMP_MODELS", + "BEHAVIORS", + "PROPERTY_DEEDS", + "BRICKS_IN_BBB", + "VENDOR", + "VENDOR_BUYBACK", + "QUEST", //Used for mission items + "DONATION", + "VAULT_MODELS", + "ITEM_SETS", //internal, technically this is BankBehaviors. + "INVALID" // made up, for internal use!!!, Technically this called the ALL inventory. + }; + + if (inventory > NUMBER_OF_INVENTORIES - 1) return nullptr; + return eInventoryTypeTable[inventory]; + }; +}; + +#endif //!__EINVENTORYTYPE__H__ diff --git a/dGame/Character.cpp b/dGame/Character.cpp index a9cffc65..67a0bf1b 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -15,6 +15,7 @@ #include "Zone.h" #include "ChatPackets.h" #include "Inventory.h" +#include "InventoryComponent.h" Character::Character(uint32_t id, User* parentUser) { //First load the name, etc: diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index b069e761..a0df940f 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -7,6 +7,7 @@ #include "GameMessages.h" #include "dLogger.h" #include "dConfig.h" +#include "CDClientManager.h" Leaderboard::Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector entries, LWOOBJID relatedPlayer, LeaderboardType leaderboardType) { diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 6779a42c..70e76016 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -21,6 +21,7 @@ #include "EntityManager.h" #include "SkillComponent.h" #include "AssetManager.h" +#include "CDClientDatabase.h" UserManager* UserManager::m_Address = nullptr; diff --git a/dGame/dBehaviors/OverTimeBehavior.cpp b/dGame/dBehaviors/OverTimeBehavior.cpp index 43ac9bc2..20dd89af 100644 --- a/dGame/dBehaviors/OverTimeBehavior.cpp +++ b/dGame/dBehaviors/OverTimeBehavior.cpp @@ -6,6 +6,8 @@ #include "EntityManager.h" #include "SkillComponent.h" #include "DestroyableComponent.h" +#include "CDClientDatabase.h" +#include "CDClientManager.h" void OverTimeBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto originator = context->originator; diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index af20fc00..d8d7428d 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -9,6 +9,7 @@ #include "SkillComponent.h" #include "ControllablePhysicsComponent.h" #include "EntityManager.h" +#include "CDClientManager.h" std::unordered_map> BuffComponent::m_Cache{}; diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 3cf206da..c899d9e8 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -28,6 +28,7 @@ #include "CharacterComponent.h" #include "PossessableComponent.h" #include "PossessorComponent.h" +#include "InventoryComponent.h" #include "dZoneManager.h" DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index 394cb801..8ae35f6c 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -19,6 +19,7 @@ #include "ItemSetPassiveAbility.h" #include "ItemSetPassiveAbilityID.h" #include "PossessorComponent.h" +#include "eInventoryType.h" class Entity; class ItemSet; diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index ed6ed483..92397a55 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -9,6 +9,7 @@ #include "dpWorld.h" #include "EntityManager.h" #include "SimplePhysicsComponent.h" +#include "CDClientManager.h" std::map MovementAIComponent::m_PhysicsSpeedCache = {}; diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 648edff8..8d23c17e 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -17,6 +17,7 @@ #include "Player.h" #include "RocketLaunchpadControlComponent.h" #include "PropertyEntranceComponent.h" +#include "InventoryComponent.h" #include #include "CppScripts.h" diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index f6d50d66..da546910 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -16,6 +16,7 @@ #include "GeneralUtils.h" #include "dZoneManager.h" #include "dConfig.h" +#include "InventoryComponent.h" #include "DestroyableComponent.h" ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 8c82f644..9aa8eda2 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -49,6 +49,7 @@ #include "ScriptComponent.h" #include "RebuildComponent.h" #include "VendorComponent.h" +#include "InventoryComponent.h" #include "RocketLaunchpadControlComponent.h" #include "PropertyEntranceComponent.h" #include "MovingPlatformComponent.h" diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 4f92480f..8a1c2fe5 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -5,7 +5,6 @@ #include "dCommonVars.h" #include "RakNetTypes.h" #include -#include "InventoryComponent.h" #include "dMessageIdentifiers.h" #include "AMFFormat.h" #include "AMFFormat_BitStream.h" @@ -21,6 +20,8 @@ class User; class Entity; class NiPoint3; enum class eUnequippableActiveType; +enum eInventoryType : uint32_t; +class Item; namespace GameMessages { class PropertyDataMessage; diff --git a/dGame/dInventory/Inventory.cpp b/dGame/dInventory/Inventory.cpp index 151e3164..990b08f3 100644 --- a/dGame/dInventory/Inventory.cpp +++ b/dGame/dInventory/Inventory.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "Game.h" #include "Item.h" +#include "InventoryComponent.h" #include "eItemType.h" std::vector Inventory::m_GameMasterRestrictedItems = { @@ -266,7 +267,7 @@ eInventoryType Inventory::FindInventoryTypeForLot(const LOT lot) { case eItemType::ITEM_TYPE_QUEST_OBJECT: case eItemType::ITEM_TYPE_UNKNOWN: default: - return HIDDEN; + return QUEST; } } @@ -300,6 +301,12 @@ const std::vector& Inventory::GetAllGMItems() { return m_GameMasterRestrictedItems; } +void Inventory::DeleteAllItems() { + while (!this->items.empty()) { + if (items.begin()->second) items.begin()->second->SetCount(0); + } +} + Inventory::~Inventory() { for (auto item : items) { delete item.second; diff --git a/dGame/dInventory/Inventory.h b/dGame/dInventory/Inventory.h index 6c6a4306..cd381db3 100644 --- a/dGame/dInventory/Inventory.h +++ b/dGame/dInventory/Inventory.h @@ -10,6 +10,7 @@ #include "CDClientManager.h" #include "dCommonVars.h" +enum eInventoryType : uint32_t; class Item; class InventoryComponent; @@ -152,6 +153,11 @@ public: */ static const std::vector& GetAllGMItems(); + /** + * Remove ALL Items from this inventory. + */ + void DeleteAllItems(); + ~Inventory(); private: diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 02739ec2..778d8237 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -14,9 +14,7 @@ #include "CharacterComponent.h" #include "eItemType.h" #include "AssetManager.h" - -class Inventory; - +#include "InventoryComponent.h" Item::Item(const LWOOBJID id, const LOT lot, Inventory* inventory, const uint32_t slot, const uint32_t count, const bool bound, const std::vector& config, const LWOOBJID parent, LWOOBJID subKey, eLootSourceType lootSourceType) { if (!Inventory::IsValidItem(lot)) { diff --git a/dGame/dInventory/Item.h b/dGame/dInventory/Item.h index db7e246a..bb8316d7 100644 --- a/dGame/dInventory/Item.h +++ b/dGame/dInventory/Item.h @@ -6,6 +6,7 @@ #include "CDClientManager.h" #include "dLogger.h" #include "Preconditions.h" +#include "eInventoryType.h" /** * An item that can be stored in an inventory and optionally consumed or equipped diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 0a8a57fe..61b41992 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -16,6 +16,7 @@ #include "dLogger.h" #include "dServer.h" #include "dZoneManager.h" +#include "InventoryComponent.h" #include "Database.h" Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { @@ -424,7 +425,7 @@ void Mission::YieldRewards() { for (const auto target : task->GetAllTargets()) { // This is how live did it. ONLY remove item collection items from the items and hidden inventories and none of the others. inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue, eInventoryType::ITEMS); - inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue, eInventoryType::HIDDEN); + inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue, eInventoryType::QUEST); missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, target, LWOOBJID_EMPTY, "", -task->GetClientInfo().targetValue); } diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index dc2cb149..d52e6e95 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -11,9 +11,9 @@ #include "ScriptedActivityComponent.h" #include "GameMessages.h" #include "dZoneManager.h" +#include "InventoryComponent.h" #include "MissionComponent.h" - MissionTask::MissionTask(Mission* mission, CDMissionTasks* info, uint32_t mask) { this->info = info; this->mission = mission; diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 89f11346..7b1bf66c 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1803,6 +1803,33 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, message); } + if (chatCommand == "deleteinven" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + eInventoryType inventoryType = eInventoryType::INVALID; + if (!GeneralUtils::TryParse(args[0], inventoryType)) { + // In this case, we treat the input as a string and try to find it in the reflection list + std::transform(args[0].begin(), args[0].end(),args[0].begin(), ::toupper); + Game::logger->Log("SlashCommandHandler", "looking for inventory %s", args[0].c_str()); + for (uint32_t index = 0; index < NUMBER_OF_INVENTORIES; index++) { + if (std::string_view(args[0]) == std::string_view(InventoryType::InventoryTypeToString(static_cast(index)))) inventoryType = static_cast(index); + } + } + + if (inventoryType == eInventoryType::INVALID || inventoryType >= NUMBER_OF_INVENTORIES) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid inventory provided."); + return; + } + + auto* inventoryComponent = entity->GetComponent(); + if (!inventoryComponent) return; + + auto* inventoryToDelete = inventoryComponent->GetInventory(inventoryType); + if (!inventoryToDelete) return; + + inventoryToDelete->DeleteAllItems(); + Game::logger->Log("SlashCommandHandler", "Deleted inventory %s for user %llu", args[0].c_str(), entity->GetObjectID()); + ChatPackets::SendSystemMessage(sysAddr, u"Deleted inventory " + GeneralUtils::UTF8ToUTF16(args[0])); + } + if (chatCommand == "inspect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { Entity* closest = nullptr; diff --git a/dScripts/02_server/Map/General/QbEnemyStunner.cpp b/dScripts/02_server/Map/General/QbEnemyStunner.cpp index 5d31a788..2b15a056 100644 --- a/dScripts/02_server/Map/General/QbEnemyStunner.cpp +++ b/dScripts/02_server/Map/General/QbEnemyStunner.cpp @@ -1,5 +1,6 @@ #include "QbEnemyStunner.h" #include "SkillComponent.h" +#include "CDClientManager.h" #include "DestroyableComponent.h" void QbEnemyStunner::OnRebuildComplete(Entity* self, Entity* target) { diff --git a/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp b/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp index cd0d94f2..dcccc337 100644 --- a/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp +++ b/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp @@ -3,6 +3,7 @@ #include "SkillComponent.h" #include "CDClientDatabase.h" #include "CDObjectSkillsTable.h" +#include "CDClientManager.h" void FireFirstSkillonStartup::OnStartup(Entity* self) { auto skillComponent = self->GetComponent(); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 912b9f58..47bca374 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -11,6 +11,7 @@ #include "MovementAIComponent.h" #include "../dWorldServer/ObjectIDManager.h" #include "MissionComponent.h" +#include "InventoryComponent.h" void SGCannon::OnStartup(Entity* self) { Game::logger->Log("SGCannon", "OnStartup"); diff --git a/dScripts/ai/NS/NsConcertInstrument.cpp b/dScripts/ai/NS/NsConcertInstrument.cpp index 508b7b5b..bba3986d 100644 --- a/dScripts/ai/NS/NsConcertInstrument.cpp +++ b/dScripts/ai/NS/NsConcertInstrument.cpp @@ -5,6 +5,7 @@ #include "EntityManager.h" #include "RebuildComponent.h" #include "SoundTriggerComponent.h" +#include "InventoryComponent.h" #include "MissionComponent.h" // Constants are at the bottom From f311685dda33dc2d96d6840852db709e0f1227ce Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 19 Dec 2022 00:07:43 -0800 Subject: [PATCH 064/166] Fix Some missions not progressing if they are the last item in the inventory (#899) --- dGame/dGameMessages/GameMessages.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 9aa8eda2..9753868d 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5736,16 +5736,16 @@ void GameMessages::HandleClientItemConsumed(RakNet::BitStream* inStream, Entity* } auto* item = inventory->FindItemById(itemConsumed); - if (item == nullptr) { return; } + LOT itemLot = item->GetLot(); item->Consume(); auto* missions = static_cast(entity->GetComponent(COMPONENT_TYPE_MISSION)); if (missions != nullptr) { - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_FOOD, item->GetLot()); + missions->Progress(MissionTaskType::MISSION_TASK_TYPE_FOOD, itemLot); } } From 157a05239ed969b9116158147e5eb69db5be42c4 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Mon, 19 Dec 2022 13:45:50 -0600 Subject: [PATCH 065/166] Add speedbase readling and writing to the level prograssion component and impli proper character versions for fixes (#856) * Add speed base readling and writing to the level prograssion component Add retroactive fix to the world transfer TODO: see about versioning charxml fixes to make them not run every time * version all current changes * cleanup speed behavior add calculate for future use in scripts make < 1 speed multiplier possible tested wormholer and it plays anims correctly * cap the lower end of the speed multiplier until the ending the behavior on hit properly works * address feedback add emun for character version make set ignore multipliers consistent in speed behavior switch case for char version upgrades * remove the ability to stack speed boosts * update value on level ups --- dCommon/dEnums/eCharacterVersion.h | 21 ++++++ dGame/Entity.cpp | 4 +- dGame/dBehaviors/SpeedBehavior.cpp | 67 ++++--------------- dGame/dBehaviors/SpeedBehavior.h | 2 + .../ControllablePhysicsComponent.cpp | 38 ++++++++--- .../ControllablePhysicsComponent.h | 17 +++++ .../dComponents/LevelProgressionComponent.cpp | 19 +++++- dGame/dComponents/LevelProgressionComponent.h | 42 ++++++++++++ dWorldServer/WorldServer.cpp | 25 ++++++- 9 files changed, 166 insertions(+), 69 deletions(-) create mode 100644 dCommon/dEnums/eCharacterVersion.h diff --git a/dCommon/dEnums/eCharacterVersion.h b/dCommon/dEnums/eCharacterVersion.h new file mode 100644 index 00000000..0fab4498 --- /dev/null +++ b/dCommon/dEnums/eCharacterVersion.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef __ECHARACTERVERSION__H__ +#define __ECHARACTERVERSION__H__ + +#include + +enum class eCharacterVersion : uint32_t { +// Versions from the live game + RELEASE = 0, // Initial release of the game + LIVE, // Fixes for the 1.9 release bug fixes for missions leading up to joining a faction +// New versions for DLU fixes + // Fixes the "Joined a faction" player flag not being set properly + PLAYER_FACTION_FLAGS, + // Fixes vault size value + VAULT_SIZE, + // Fixes speed base value in level component + UP_TO_DATE, // will become SPEED_BASE +}; + +#endif //!__ECHARACTERVERSION__H__ diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 1f094291..cbab87db 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -769,8 +769,8 @@ no_ghosting: auto* controllablePhysicsComponent = GetComponent(); auto* levelComponent = GetComponent(); - if (controllablePhysicsComponent != nullptr && levelComponent->GetLevel() >= 20) { - controllablePhysicsComponent->SetSpeedMultiplier(525.0f / 500.0f); + if (controllablePhysicsComponent && levelComponent) { + controllablePhysicsComponent->SetSpeedMultiplier(levelComponent->GetSpeedBase() / 500.0f); } } } diff --git a/dGame/dBehaviors/SpeedBehavior.cpp b/dGame/dBehaviors/SpeedBehavior.cpp index c7855557..bec2b1cb 100644 --- a/dGame/dBehaviors/SpeedBehavior.cpp +++ b/dGame/dBehaviors/SpeedBehavior.cpp @@ -7,85 +7,44 @@ void SpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - if (m_AffectsCaster) { - branch.target = context->caster; - } + if (m_AffectsCaster) branch.target = context->caster; auto* target = EntityManager::Instance()->GetEntity(branch.target); - - if (target == nullptr) { - return; - } + if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); + if (!controllablePhysicsComponent) return; - if (controllablePhysicsComponent == nullptr) { - return; - } - - const auto current = controllablePhysicsComponent->GetSpeedMultiplier(); - - controllablePhysicsComponent->SetSpeedMultiplier(current + ((m_RunSpeed - 500.0f) / 500.0f)); - + controllablePhysicsComponent->AddSpeedboost(m_RunSpeed); EntityManager::Instance()->SerializeEntity(target); if (branch.duration > 0.0f) { context->RegisterTimerBehavior(this, branch); } else if (branch.start > 0) { - controllablePhysicsComponent->SetIgnoreMultipliers(true); - context->RegisterEndBehavior(this, branch); } } -void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); - - if (target == nullptr) { - return; - } - - auto* controllablePhysicsComponent = target->GetComponent(); - - if (controllablePhysicsComponent == nullptr) { - return; - } - - const auto current = controllablePhysicsComponent->GetSpeedMultiplier(); - - controllablePhysicsComponent->SetSpeedMultiplier(current - ((m_RunSpeed - 500.0f) / 500.0f)); - - EntityManager::Instance()->SerializeEntity(target); +void SpeedBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + Handle(context, bitStream, branch); } void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { auto* target = EntityManager::Instance()->GetEntity(branch.target); - - if (target == nullptr) { - return; - } + if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); + if (!controllablePhysicsComponent) return; - if (controllablePhysicsComponent == nullptr) { - return; - } - - const auto current = controllablePhysicsComponent->GetSpeedMultiplier(); - - controllablePhysicsComponent->SetIgnoreMultipliers(false); - - controllablePhysicsComponent->SetSpeedMultiplier(current - ((m_RunSpeed - 500.0f) / 500.0f)); - + controllablePhysicsComponent->RemoveSpeedboost(m_RunSpeed); EntityManager::Instance()->SerializeEntity(target); } +void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + End(context, branch, second); +} + void SpeedBehavior::Load() { m_RunSpeed = GetFloat("run_speed"); - - if (m_RunSpeed < 500.0f) { - m_RunSpeed = 500.0f; - } - m_AffectsCaster = GetBoolean("affects_caster"); } diff --git a/dGame/dBehaviors/SpeedBehavior.h b/dGame/dBehaviors/SpeedBehavior.h index 04c0090f..57c46842 100644 --- a/dGame/dBehaviors/SpeedBehavior.h +++ b/dGame/dBehaviors/SpeedBehavior.h @@ -13,6 +13,8 @@ public: void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index d7caf6a9..a5e447c8 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -12,6 +12,7 @@ #include "EntityManager.h" #include "Character.h" #include "dZoneManager.h" +#include "LevelProgressionComponent.h" ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Component(entity) { m_Position = {}; @@ -73,13 +74,7 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bo outBitStream->Write0(); //This contains info about immunities, but for now I'm leaving it out. } - if (m_SpeedMultiplier < 1.0f) { - m_DirtyCheats = false; - } - - if (m_IgnoreMultipliers) { - m_DirtyCheats = false; - } + if (m_IgnoreMultipliers) m_DirtyCheats = false; outBitStream->Write(m_DirtyCheats); if (m_DirtyCheats) { @@ -263,7 +258,7 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) { if (pos != m_ActivePickupRadiusScales.end()) { m_ActivePickupRadiusScales.erase(pos); } else { - Game::logger->Log("ControllablePhysicsComponent", "Warning: Could not find pickup radius %f in list of active radii. List has %i active radii.", value, m_ActivePickupRadiusScales.size()); + Game::logger->LogDebug("ControllablePhysicsComponent", "Warning: Could not find pickup radius %f in list of active radii. List has %i active radii.", value, m_ActivePickupRadiusScales.size()); return; } @@ -276,3 +271,30 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) { } EntityManager::Instance()->SerializeEntity(m_Parent); } + +void ControllablePhysicsComponent::AddSpeedboost(float value) { + m_ActiveSpeedBoosts.push_back(value); + m_SpeedBoost = value; + SetSpeedMultiplier(value / 500.0f); // 500 being the base speed +} + +void ControllablePhysicsComponent::RemoveSpeedboost(float value) { + const auto pos = std::find(m_ActiveSpeedBoosts.begin(), m_ActiveSpeedBoosts.end(), value); + if (pos != m_ActiveSpeedBoosts.end()) { + m_ActiveSpeedBoosts.erase(pos); + } else { + Game::logger->LogDebug("ControllablePhysicsComponent", "Warning: Could not find speedboost %f in list of active speedboosts. List has %i active speedboosts.", value, m_ActiveSpeedBoosts.size()); + return; + } + + // Recalculate speedboost since we removed one + m_SpeedBoost = 0.0f; + if (m_ActiveSpeedBoosts.size() == 0) { // no active speed boosts left, so return to base speed + auto* levelProgressionComponent = m_Parent->GetComponent(); + if (levelProgressionComponent) m_SpeedBoost = levelProgressionComponent->GetSpeedBase(); + } else { // Used the last applied speedboost + m_SpeedBoost = m_ActiveSpeedBoosts.back(); + } + SetSpeedMultiplier(m_SpeedBoost / 500.0f); // 500 being the base speed + EntityManager::Instance()->SerializeEntity(m_Parent); +} diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index ac481b9f..e029d607 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -257,6 +257,13 @@ public: */ std::vector GetActivePickupRadiusScales() { return m_ActivePickupRadiusScales; }; + + void AddSpeedboost(float value); + + void RemoveSpeedboost(float value); + + std::vector GetActiveSpeedboosts() { return m_ActivePickupRadiusScales; }; + private: /** * The entity that owns this component @@ -372,6 +379,16 @@ private: * If the entity is teleporting */ bool m_IsTeleporting; + + /** + * The list of speed boosts for this entity + */ + std::vector m_ActiveSpeedBoosts; + + /** + * The active speed boost for this entity + */ + float m_SpeedBoost; }; #endif // CONTROLLABLEPHYSICSCOMPONENT_H diff --git a/dGame/dComponents/LevelProgressionComponent.cpp b/dGame/dComponents/LevelProgressionComponent.cpp index ee3cfc6b..6e6b823e 100644 --- a/dGame/dComponents/LevelProgressionComponent.cpp +++ b/dGame/dComponents/LevelProgressionComponent.cpp @@ -7,6 +7,8 @@ LevelProgressionComponent::LevelProgressionComponent(Entity* parent) : Component(parent) { m_Parent = parent; m_Level = 1; + m_SpeedBase = 500.0f; + m_CharacterVersion = eCharacterVersion::LIVE; } void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument* doc) { @@ -16,7 +18,8 @@ void LevelProgressionComponent::UpdateXml(tinyxml2::XMLDocument* doc) { return; } level->SetAttribute("l", m_Level); - + level->SetAttribute("sb", m_SpeedBase); + level->SetAttribute("cv", static_cast(m_CharacterVersion)); } void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { @@ -26,7 +29,10 @@ void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { return; } level->QueryAttribute("l", &m_Level); - + level->QueryAttribute("sb", &m_SpeedBase); + uint32_t characterVersion; + level->QueryAttribute("cv", &characterVersion); + m_CharacterVersion = static_cast(characterVersion); } void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { @@ -60,7 +66,8 @@ void LevelProgressionComponent::HandleLevelUp() { } break; case 9: - controllablePhysicsComponent->SetSpeedMultiplier(static_cast(reward->value) / 500.0f); + SetSpeedBase(static_cast(reward->value) ); + controllablePhysicsComponent->SetSpeedMultiplier(GetSpeedBase() / 500.0f); break; case 11: case 12: @@ -72,3 +79,9 @@ void LevelProgressionComponent::HandleLevelUp() { // Tell the client we have finished sending level rewards. if (rewardingItem) GameMessages::NotifyLevelRewards(m_Parent->GetObjectID(), m_Parent->GetSystemAddress(), m_Level, !rewardingItem); } + +void LevelProgressionComponent::SetRetroactiveBaseSpeed(){ + if (m_Level >= 20) m_SpeedBase = 525.0f; + auto* controllablePhysicsComponent = m_Parent->GetComponent(); + if (controllablePhysicsComponent) controllablePhysicsComponent->SetSpeedMultiplier(m_SpeedBase / 500.0f); +} diff --git a/dGame/dComponents/LevelProgressionComponent.h b/dGame/dComponents/LevelProgressionComponent.h index 53f6693e..dd3fbfbb 100644 --- a/dGame/dComponents/LevelProgressionComponent.h +++ b/dGame/dComponents/LevelProgressionComponent.h @@ -3,11 +3,13 @@ #include "Entity.h" #include "GameMessages.h" #include "Component.h" +#include "eCharacterVersion.h" /** * Component that handles level progression and serilization. * */ + class LevelProgressionComponent : public Component { public: static const uint32_t ComponentType = eReplicaComponentType::COMPONENT_TYPE_LEVEL_PROGRESSION; @@ -44,11 +46,40 @@ public: */ void SetLevel(uint32_t level) { m_Level = level; m_DirtyLevelInfo = true; } + /** + * Gets the current Speed Base of the entity + * @return the current Speed Base of the entity + */ + const uint32_t GetSpeedBase() const { return m_SpeedBase; } + + /** + * Sets the Speed Base of the entity + * @param SpeedBase the Speed Base to set + */ + void SetSpeedBase(uint32_t SpeedBase) { m_SpeedBase = SpeedBase; } + /** * Gives the player rewards for the last level that they leveled up from */ void HandleLevelUp(); + /** + * Gets the current Character Version of the entity + * @return the current Character Version of the entity + */ + const eCharacterVersion GetCharacterVersion() const { return m_CharacterVersion; } + + /** + * Sets the Character Version of the entity + * @param CharacterVersion the Character Version to set + */ + void SetCharacterVersion(eCharacterVersion CharacterVersion) { m_CharacterVersion = CharacterVersion; } + + /** + * Set the Base Speed retroactively of the entity + */ + void SetRetroactiveBaseSpeed(); + private: /** * whether the level is dirty @@ -59,4 +90,15 @@ private: * Level of the entity */ uint32_t m_Level; + + /** + * The base speed of the entity + */ + float m_SpeedBase; + + /** + * The Character format version + */ + eCharacterVersion m_CharacterVersion; + }; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 594d3dc7..d204d5c9 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -56,6 +56,7 @@ #include "Player.h" #include "PropertyManagementComponent.h" #include "AssetManager.h" +#include "LevelProgressionComponent.h" #include "eBlueprintSaveResponseType.h" #include "ZCompression.h" @@ -993,9 +994,29 @@ void HandlePacket(Packet* packet) { player->GetComponent()->RocketUnEquip(player); } - c->SetRetroactiveFlags(); + // Do charxml fixes here + auto* levelComponent = player->GetComponent(); + if (!levelComponent) return; - player->RetroactiveVaultSize(); + auto version = levelComponent->GetCharacterVersion(); + switch(version) { + case eCharacterVersion::RELEASE: + // TODO: Implement, super low priority + case eCharacterVersion::LIVE: + Game::logger->Log("WorldServer", "Updating Character Flags"); + c->SetRetroactiveFlags(); + levelComponent->SetCharacterVersion(eCharacterVersion::PLAYER_FACTION_FLAGS); + case eCharacterVersion::PLAYER_FACTION_FLAGS: + Game::logger->Log("WorldServer", "Updating Vault Size"); + player->RetroactiveVaultSize(); + levelComponent->SetCharacterVersion(eCharacterVersion::VAULT_SIZE); + case eCharacterVersion::VAULT_SIZE: + Game::logger->Log("WorldServer", "Updaing Speedbase"); + levelComponent->SetRetroactiveBaseSpeed(); + levelComponent->SetCharacterVersion(eCharacterVersion::UP_TO_DATE); + case eCharacterVersion::UP_TO_DATE: + break; + } player->GetCharacter()->SetTargetScene(""); From d69f733772d3bca27261aaf11b72c96754123724 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 19 Dec 2022 12:51:44 -0800 Subject: [PATCH 066/166] Fix trading taking the wrong item (#900) * Fix trading taking the wrong item * Add missing returns * Improve further Do all verification first. Then actually do the trade. Prevents possible cheating attempts --- dGame/TradingManager.cpp | 53 ++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/dGame/TradingManager.cpp b/dGame/TradingManager.cpp index e49cca70..ed55f217 100644 --- a/dGame/TradingManager.cpp +++ b/dGame/TradingManager.cpp @@ -103,6 +103,7 @@ void Trade::SetAccepted(LWOOBJID participant, bool value) { } Complete(); + TradingManager::Instance()->CancelTrade(m_TradeId); } } @@ -121,33 +122,59 @@ void Trade::Complete() { if (inventoryA == nullptr || inventoryB == nullptr || characterA == nullptr || characterB == nullptr || missionsA == nullptr || missionsB == nullptr) return; + // First verify both players have the coins and items requested for the trade. + if (characterA->GetCoins() < m_CoinsA || characterB->GetCoins() < m_CoinsB) { + Game::logger->Log("TradingManager", "Possible coin trade cheating attempt! Aborting trade."); + return; + } + + for (const auto& tradeItem : m_ItemsA) { + auto* itemToRemove = inventoryA->FindItemById(tradeItem.itemId); + if (itemToRemove) { + if (itemToRemove->GetCount() < tradeItem.itemCount) { + Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading!!! Aborting trade", characterA->GetName().c_str()); + return; + } + } else { + Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading due to item not being available!!!", characterA->GetName().c_str()); + return; + } + } + + for (const auto& tradeItem : m_ItemsB) { + auto* itemToRemove = inventoryB->FindItemById(tradeItem.itemId); + if (itemToRemove) { + if (itemToRemove->GetCount() < tradeItem.itemCount) { + Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading!!! Aborting trade", characterB->GetName().c_str()); + return; + } + } else { + Game::logger->Log("TradingManager", "Possible cheating attempt from %s in trading due to item not being available!!! Aborting trade", characterB->GetName().c_str()); + return; + } + } + + // Now actually do the trade. characterA->SetCoins(characterA->GetCoins() - m_CoinsA + m_CoinsB, eLootSourceType::LOOT_SOURCE_TRADE); characterB->SetCoins(characterB->GetCoins() - m_CoinsB + m_CoinsA, eLootSourceType::LOOT_SOURCE_TRADE); for (const auto& tradeItem : m_ItemsA) { - inventoryA->RemoveItem(tradeItem.itemLot, tradeItem.itemCount, INVALID, true); - + auto* itemToRemove = inventoryA->FindItemById(tradeItem.itemId); + if (itemToRemove) itemToRemove->SetCount(itemToRemove->GetCount() - tradeItem.itemCount); missionsA->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); - } - - for (const auto& tradeItem : m_ItemsB) { - inventoryB->RemoveItem(tradeItem.itemLot, tradeItem.itemCount, INVALID, true); - - missionsB->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); - } - - for (const auto& tradeItem : m_ItemsA) { inventoryB->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE); } for (const auto& tradeItem : m_ItemsB) { + auto* itemToRemove = inventoryB->FindItemById(tradeItem.itemId); + if (itemToRemove) itemToRemove->SetCount(itemToRemove->GetCount() - tradeItem.itemCount); + missionsB->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); inventoryA->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE); } - TradingManager::Instance()->CancelTrade(m_TradeId); - characterA->SaveXMLToDatabase(); characterB->SaveXMLToDatabase(); + return; } void Trade::Cancel() { From 2fdcf62ec61ca551ff4bca4ca68d47891d1e7ceb Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 19 Dec 2022 12:52:00 -0800 Subject: [PATCH 067/166] Fix overread in projectile behavior and address broken stuns (#898) * Fix overread in projectile behavior * Fix stuns * Correctly read in bitStream --- dGame/dBehaviors/AttackDelayBehavior.cpp | 2 +- dGame/dBehaviors/BehaviorContext.cpp | 3 ++- dGame/dBehaviors/BehaviorContext.h | 2 +- dGame/dBehaviors/ProjectileAttackBehavior.cpp | 4 +++- dGame/dBehaviors/ProjectileAttackBehavior.h | 2 ++ 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/dGame/dBehaviors/AttackDelayBehavior.cpp b/dGame/dBehaviors/AttackDelayBehavior.cpp index 201921a3..ccea5fd9 100644 --- a/dGame/dBehaviors/AttackDelayBehavior.cpp +++ b/dGame/dBehaviors/AttackDelayBehavior.cpp @@ -13,7 +13,7 @@ void AttackDelayBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi }; for (auto i = 0u; i < this->m_numIntervals; ++i) { - context->RegisterSyncBehavior(handle, this, branch); + context->RegisterSyncBehavior(handle, this, branch, m_ignoreInterrupts); } } diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index 4cd9e415..c2f0c88e 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -45,12 +45,13 @@ uint32_t BehaviorContext::GetUniqueSkillId() const { } -void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext) { +void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, bool ignoreInterrupts) { auto entry = BehaviorSyncEntry(); entry.handle = syncId; entry.behavior = behavior; entry.branchContext = branchContext; + entry.ignoreInterrupts = ignoreInterrupts; this->syncEntries.push_back(entry); } diff --git a/dGame/dBehaviors/BehaviorContext.h b/dGame/dBehaviors/BehaviorContext.h index 0462d97f..dbba4d91 100644 --- a/dGame/dBehaviors/BehaviorContext.h +++ b/dGame/dBehaviors/BehaviorContext.h @@ -80,7 +80,7 @@ struct BehaviorContext uint32_t GetUniqueSkillId() const; - void RegisterSyncBehavior(uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext); + void RegisterSyncBehavior(uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, bool ignoreInterrupts = false); void RegisterTimerBehavior(Behavior* behavior, const BehaviorBranchContext& branchContext, LWOOBJID second = LWOOBJID_EMPTY); diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.cpp b/dGame/dBehaviors/ProjectileAttackBehavior.cpp index c14f032d..2b38db8f 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.cpp +++ b/dGame/dBehaviors/ProjectileAttackBehavior.cpp @@ -31,7 +31,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea return; } - if (m_useMouseposit) { + if (m_ProjectileType == 1) { NiPoint3 targetPosition = NiPoint3::ZERO; if (!bitStream->Read(targetPosition)) { Game::logger->Log("ProjectileAttackBehavior", "Unable to read targetPosition from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); @@ -157,4 +157,6 @@ void ProjectileAttackBehavior::Load() { this->m_trackRadius = GetFloat("track_radius"); this->m_useMouseposit = GetBoolean("use_mouseposit"); + + this->m_ProjectileType = GetInt("projectile_type"); } diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.h b/dGame/dBehaviors/ProjectileAttackBehavior.h index 17353a2a..b307e66c 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.h +++ b/dGame/dBehaviors/ProjectileAttackBehavior.h @@ -23,6 +23,8 @@ public: bool m_useMouseposit; + int32_t m_ProjectileType; + /* * Inherited */ From f2fa81b5c3b4be084b2664b83debc26ac5d0a8dd Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 20 Dec 2022 13:20:44 -0800 Subject: [PATCH 068/166] Fix lobbies (#901) --- dGame/dComponents/ScriptedActivityComponent.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index da546910..ee7ca22e 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -208,7 +208,7 @@ void ScriptedActivityComponent::PlayerLeave(LWOOBJID playerID) { } void ScriptedActivityComponent::Update(float deltaTime) { - + std::vector lobbiesToRemove{}; // Ticks all the lobbies, not applicable for non-instance activities for (Lobby* lobby : m_Queue) { for (LobbyPlayer* player : lobby->players) { @@ -219,6 +219,11 @@ void ScriptedActivityComponent::Update(float deltaTime) { } } + if (lobby->players.empty()) { + lobbiesToRemove.push_back(lobby); + continue; + } + // Update the match time for all players if (m_ActivityInfo.maxTeamSize != 1 && lobby->players.size() >= m_ActivityInfo.minTeamSize || m_ActivityInfo.maxTeamSize == 1 && lobby->players.size() >= m_ActivityInfo.minTeams) { @@ -262,13 +267,17 @@ void ScriptedActivityComponent::Update(float deltaTime) { // The timer has elapsed, start the instance if (lobby->timer <= 0.0f) { Game::logger->Log("ScriptedActivityComponent", "Setting up instance."); - ActivityInstance* instance = NewInstance(); LoadPlayersIntoInstance(instance, lobby->players); - RemoveLobby(lobby); instance->StartZone(); + lobbiesToRemove.push_back(lobby); } } + + while (!lobbiesToRemove.empty()) { + RemoveLobby(lobbiesToRemove.front()); + lobbiesToRemove.erase(lobbiesToRemove.begin()); + } } void ScriptedActivityComponent::RemoveLobby(Lobby* lobby) { From 0a31db9d4410d2ca28b12f3fab2631a580d1ae2d Mon Sep 17 00:00:00 2001 From: Neal Spellman Date: Tue, 20 Dec 2022 17:10:54 -0500 Subject: [PATCH 069/166] Updated README and CREDITS (#904) - README now has proper capitalization for categories in the credits. - New layout with former contributors moved to below active contributors. - LEGO Universe credits linked for the special thanks. - Aronwk properly recognized as DLU team member after mistakenly not included. - Vanity credits updated to more closely mirror categories in README's credits. --- README.md | 26 +++++++++++++------------- vanity/CREDITS.md | 13 ++++++------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 87319c10..bd9dd6b7 100644 --- a/README.md +++ b/README.md @@ -422,11 +422,6 @@ Here is a summary of the commands available in-game. All commands are prefixed b # Credits -## Active Contributors -* [EmosewaMC](https://github.com/EmosewaMC) -* [Jettford](https://github.com/Jettford) -* [Aaron K.](https://github.com/aronwk-aaron) - ## DLU Team * [DarwinAnim8or](https://github.com/DarwinAnim8or) * [Wincent01](https://github.com/Wincent01) @@ -434,25 +429,30 @@ Here is a summary of the commands available in-game. All commands are prefixed b * [averysumner](https://github.com/codeshaunted) * [Jon002](https://github.com/jaller200) * [Jonny](https://github.com/cuzitsjonny) +* [Aaron K.](https://github.com/aronwk-aaron) -### Research and tools +### Research and Tools * [lcdr](https://github.com/lcdr) * [Xiphoseer](https://github.com/Xiphoseer) -### Community management +### Community Management * [Neal](https://github.com/NealSpellman) -### Former contributors +### Logo +* Cole Peterson (BlasterBuilder) + +## Active Contributors +* [EmosewaMC](https://github.com/EmosewaMC) +* [Jettford](https://github.com/Jettford) + +## Former Contributors * TheMachine * Matthew * [Raine](https://github.com/Rainebannister) * Bricknave -### Logo -* Cole Peterson (BlasterBuilder) - -## Special thanks +## Special Thanks * humanoid24 * pwjones1969 * [Simon](https://github.com/SimonNitzsche) -* ALL OF THE NETDEVIL AND LEGO TEAMS! +* [ALL OF THE NETDEVIL AND LEGO TEAMS!](https://www.mobygames.com/game/macintosh/lego-universe/credits) diff --git a/vanity/CREDITS.md b/vanity/CREDITS.md index e130cfb3..6780cff7 100644 --- a/vanity/CREDITS.md +++ b/vanity/CREDITS.md @@ -1,18 +1,17 @@ # CREDITS -## Developers +## DLU Team DarwinAnim8or (Max) Wincent01 Mick averysumner (codeshaunted) Jon002 Jonny -EmosewaMC -Jettford - -## Research & Tooling Xiphoseer lcdr - -## Community Management +Aaron K. Neal + +## Active Contributors +EmosewaMC +Jettford \ No newline at end of file From 38eb441ca14037b626339f17fd40bdc870f9fc84 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 21 Dec 2022 00:26:17 -0800 Subject: [PATCH 070/166] Correct Projectile behavior bitStream reads (#907) --- dGame/dBehaviors/BehaviorBranchContext.h | 2 ++ dGame/dBehaviors/BehaviorContext.cpp | 1 + dGame/dBehaviors/ProjectileAttackBehavior.cpp | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dGame/dBehaviors/BehaviorBranchContext.h b/dGame/dBehaviors/BehaviorBranchContext.h index 5b2ec595..2e56cd35 100644 --- a/dGame/dBehaviors/BehaviorBranchContext.h +++ b/dGame/dBehaviors/BehaviorBranchContext.h @@ -15,6 +15,8 @@ struct BehaviorBranchContext uint32_t start = 0; + bool isSync = false; + BehaviorBranchContext(); BehaviorBranchContext(LWOOBJID target, float duration = 0, const NiPoint3& referencePosition = NiPoint3(0, 0, 0)); diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index c2f0c88e..ebed10ba 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -51,6 +51,7 @@ void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* beha entry.handle = syncId; entry.behavior = behavior; entry.branchContext = branchContext; + entry.branchContext.isSync = true; entry.ignoreInterrupts = ignoreInterrupts; this->syncEntries.push_back(entry); diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.cpp b/dGame/dBehaviors/ProjectileAttackBehavior.cpp index 2b38db8f..3ce6c415 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.cpp +++ b/dGame/dBehaviors/ProjectileAttackBehavior.cpp @@ -31,7 +31,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea return; } - if (m_ProjectileType == 1) { + if (m_useMouseposit && !branch.isSync) { NiPoint3 targetPosition = NiPoint3::ZERO; if (!bitStream->Read(targetPosition)) { Game::logger->Log("ProjectileAttackBehavior", "Unable to read targetPosition from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); From 51dd56f0a0479eae60da3d09279b6c2685b96a70 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 21 Dec 2022 08:51:27 -0800 Subject: [PATCH 071/166] Add MTU config option (#908) * Add config option * Add reloading --- dGame/dUtilities/SlashCommandHandler.cpp | 1 + dNet/dServer.cpp | 8 +++++++- dNet/dServer.h | 1 + resources/sharedconfig.ini | 10 +++++++++- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 7b1bf66c..9a63f83c 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1762,6 +1762,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit scriptedActivityComponent->ReloadConfig(); } + Game::server->UpdateMaximumMtuSize(); Game::server->UpdateBandwidthLimit(); ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!"); } diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 55e07da3..a3961d45 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -68,7 +68,7 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect } else { mLogger->Log("dServer", "FAILED TO START SERVER ON IP/PORT: %s:%i", ip.c_str(), port); return; } mLogger->SetLogToConsole(prevLogSetting); - mPeer->SetMTUSize(1228); // This is hard coded by lu for some reason. + //Connect to master if we are not master: if (serverType != ServerType::Master) { SetupForMasterConnection(); @@ -188,6 +188,7 @@ bool dServer::Startup() { mPeer->SetIncomingPassword("3.25 DARKFLAME1", 15); } else { UpdateBandwidthLimit(); + UpdateMaximumMtuSize(); mPeer->SetIncomingPassword("3.25 ND1", 8); } @@ -197,6 +198,11 @@ bool dServer::Startup() { return true; } +void dServer::UpdateMaximumMtuSize() { + auto maxMtuSize = mConfig->GetValue("maximum_mtu_size"); + mPeer->SetMTUSize(maxMtuSize.empty() ? 1228 : std::stoi(maxMtuSize)); +} + void dServer::UpdateBandwidthLimit() { auto newBandwidth = mConfig->GetValue("maximum_outgoing_bandwidth"); mPeer->SetPerConnectionOutgoingBandwidthLimit(!newBandwidth.empty() ? std::stoi(newBandwidth) : 0); diff --git a/dNet/dServer.h b/dNet/dServer.h index af4c8322..d9e74d2e 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -57,6 +57,7 @@ public: ReplicaManager* GetReplicaManager() { return mReplicaManager; } void UpdateReplica(); void UpdateBandwidthLimit(); + void UpdateMaximumMtuSize(); int GetPing(const SystemAddress& sysAddr) const; int GetLatestPing(const SystemAddress& sysAddr) const; diff --git a/resources/sharedconfig.ini b/resources/sharedconfig.ini index 439ffe2f..d2c43d11 100644 --- a/resources/sharedconfig.ini +++ b/resources/sharedconfig.ini @@ -26,5 +26,13 @@ dump_folder= # Either the folder with /res or with /client and /versions client_location= -# The maximum outgoing bandwidth in bits +# The maximum outgoing bandwidth in bits. If your clients are having +# issues with enemies taking a while to catch up to them, increse this value. maximum_outgoing_bandwidth=80000 + +# The Maximum Translation Unit (MTU) size for packets. If players are +# getting stuck at 55% on the loading screen, lower this number to +# reduce the chances of packet loss. This value only has an effect +# from 512 <= maximum_mtu_size <= 1492 so make sure to keep this +# value within that range. +maximum_mtu_size=1228 From bd7f532a280e959c622685b53aa325f56226087f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 21 Dec 2022 14:33:41 -0800 Subject: [PATCH 072/166] Implement the Imaginite Backpack and Shard armor scripts (#886) * Imaginite Pack now works * Remove unused params * Address issues * Add TeslaPack script Co-authored-by: aronwk-aaron --- CMakeLists.txt | 1 + dGame/Entity.cpp | 16 ++++++++ dGame/Entity.h | 8 ++++ dGame/dComponents/DestroyableComponent.cpp | 24 ++++++++++++ dGame/dComponents/DestroyableComponent.h | 20 ++++++++++ dGame/dComponents/InventoryComponent.cpp | 38 ++++++++++++++++++- dGame/dComponents/InventoryComponent.h | 14 +++++++ dScripts/CMakeLists.txt | 6 +++ dScripts/CppScripts.cpp | 9 +++++ dScripts/CppScripts.h | 23 +++++++++++ dScripts/EquipmentTriggers/CMakeLists.txt | 3 ++ .../EquipmentTriggers/CoilBackpackBase.cpp | 25 ++++++++++++ dScripts/EquipmentTriggers/CoilBackpackBase.h | 21 ++++++++++ dScripts/EquipmentTriggers/GemPack.h | 14 +++++++ dScripts/EquipmentTriggers/ShardArmor.h | 14 +++++++ dScripts/EquipmentTriggers/TeslaPack.h | 14 +++++++ 16 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 dScripts/EquipmentTriggers/CMakeLists.txt create mode 100644 dScripts/EquipmentTriggers/CoilBackpackBase.cpp create mode 100644 dScripts/EquipmentTriggers/CoilBackpackBase.h create mode 100644 dScripts/EquipmentTriggers/GemPack.h create mode 100644 dScripts/EquipmentTriggers/ShardArmor.h create mode 100644 dScripts/EquipmentTriggers/TeslaPack.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 163196fb..b9596649 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,7 @@ set(INCLUDED_DIRECTORIES "dScripts/ai" "dScripts/client" "dScripts/EquipmentScripts" + "dScripts/EquipmentTriggers" "dScripts/zone" "dScripts/02_server/DLU" "dScripts/02_server/Enemy" diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index cbab87db..16b2c5a1 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -824,6 +824,22 @@ std::vector Entity::GetScriptComponents() { return comps; } +void Entity::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName) { + if (notificationName == "HitOrHealResult" || notificationName == "Hit") { + auto* destroyableComponent = GetComponent(); + if (!destroyableComponent) return; + destroyableComponent->Subscribe(scriptObjId, scriptToAdd); + } +} + +void Entity::Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName) { + if (notificationName == "HitOrHealResult" || notificationName == "Hit") { + auto* destroyableComponent = GetComponent(); + if (!destroyableComponent) return; + destroyableComponent->Unsubscribe(scriptObjId); + } +} + void Entity::SetProximityRadius(float proxRadius, std::string name) { ProximityMonitorComponent* proxMon = GetComponent(); if (!proxMon) { diff --git a/dGame/Entity.h b/dGame/Entity.h index 6c0968f8..e0d38308 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -26,8 +26,13 @@ class Spawner; class ScriptComponent; class dpEntity; class Component; +class Item; class Character; +namespace CppScripts { + class Script; +}; + /** * An entity in the world. Has multiple components. */ @@ -139,6 +144,9 @@ public: std::vector GetScriptComponents(); + void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName); + void Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName); + void SetProximityRadius(float proxRadius, std::string name); void SetProximityRadius(dpEntity* entity, std::string name); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index c899d9e8..6902917f 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -631,6 +631,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 auto* attacker = EntityManager::Instance()->GetEntity(source); m_Parent->OnHit(attacker); m_Parent->OnHitOrHealResult(attacker, sourceDamage); + NotifySubscribers(attacker, sourceDamage); for (const auto& cb : m_OnHitCallbacks) { cb(attacker); @@ -648,6 +649,29 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 Smash(source, eKillType::VIOLENT, u"", skillID); } +void DestroyableComponent::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd) { + m_SubscribedScripts.insert(std::make_pair(scriptObjId, scriptToAdd)); + Game::logger->LogDebug("DestroyableComponent", "Added script %llu to entity %llu", scriptObjId, m_Parent->GetObjectID()); + Game::logger->LogDebug("DestroyableComponent", "Number of subscribed scripts %i", m_SubscribedScripts.size()); +} + +void DestroyableComponent::Unsubscribe(LWOOBJID scriptObjId) { + auto foundScript = m_SubscribedScripts.find(scriptObjId); + if (foundScript != m_SubscribedScripts.end()) { + m_SubscribedScripts.erase(foundScript); + Game::logger->LogDebug("DestroyableComponent", "Removed script %llu from entity %llu", scriptObjId, m_Parent->GetObjectID()); + } else { + Game::logger->LogDebug("DestroyableComponent", "Tried to remove a script for Entity %llu but script %llu didnt exist", m_Parent->GetObjectID(), scriptObjId); + } + Game::logger->LogDebug("DestroyableComponent", "Number of subscribed scripts %i", m_SubscribedScripts.size()); +} + +void DestroyableComponent::NotifySubscribers(Entity* attacker, uint32_t damage) { + for (auto script : m_SubscribedScripts) { + script.second->NotifyHitOrHealResult(m_Parent, attacker, damage); + } +} + void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType, uint32_t skillID) { if (m_iHealth > 0) { SetArmor(0); diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index b8e81b33..5bb990a7 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -7,6 +7,10 @@ #include "Entity.h" #include "Component.h" +namespace CppScripts { + class Script; +}; //! namespace CppScripts + /** * Represents the stats of an entity, for example its health, imagination and armor. Also handles factions, which * indicate which enemies this entity has. @@ -422,6 +426,17 @@ public: */ void AddFactionNoLookup(int32_t faction) { m_FactionIDs.push_back(faction); }; + /** + * Notify subscribed scripts of Damage actions. + * + * @param attacker The attacking Entity + * @param damage The amount of damage that was done + */ + void NotifySubscribers(Entity* attacker, uint32_t damage); + + void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd); + void Unsubscribe(LWOOBJID scriptObjId); + private: /** * Whether or not the health should be serialized @@ -557,6 +572,11 @@ private: * The list of callbacks that will be called when this entity gets hit */ std::vector> m_OnHitCallbacks; + + /** + * The list of scripts subscribed to this components actions + */ + std::map m_SubscribedScripts; }; #endif // DESTROYABLECOMPONENT_H diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 8215664c..eeb6afa7 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -27,8 +27,9 @@ #include "dConfig.h" #include "eItemType.h" #include "eUnequippableActiveType.h" +#include "CppScripts.h" -InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) { +InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) { this->m_Dirty = true; this->m_Equipped = {}; this->m_Pushed = {}; @@ -867,6 +868,8 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { AddItemSkills(item->GetLot()); + EquipScripts(item); + EntityManager::Instance()->SerializeEntity(m_Parent); } @@ -895,6 +898,8 @@ void InventoryComponent::UnEquipItem(Item* item) { PurgeProxies(item); + UnequipScripts(item); + EntityManager::Instance()->SerializeEntity(m_Parent); // Trigger property event @@ -904,6 +909,37 @@ void InventoryComponent::UnEquipItem(Item* item) { } } + +void InventoryComponent::EquipScripts(Item* equippedItem) { + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable("ComponentsRegistry"); + if (!compRegistryTable) return; + int32_t scriptComponentID = compRegistryTable->GetByIDAndType(equippedItem->GetLot(), COMPONENT_TYPE_SCRIPT, -1); + if (scriptComponentID > -1) { + CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable("ScriptComponent"); + CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID); + auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name); + if (!itemScript) { + Game::logger->Log("InventoryComponent", "null script?"); + } + itemScript->OnFactionTriggerItemEquipped(m_Parent, equippedItem->GetId()); + } +} + +void InventoryComponent::UnequipScripts(Item* unequippedItem) { + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable("ComponentsRegistry"); + if (!compRegistryTable) return; + int32_t scriptComponentID = compRegistryTable->GetByIDAndType(unequippedItem->GetLot(), COMPONENT_TYPE_SCRIPT, -1); + if (scriptComponentID > -1) { + CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable("ScriptComponent"); + CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID); + auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name); + if (!itemScript) { + Game::logger->Log("InventoryComponent", "null script?"); + } + itemScript->OnFactionTriggerItemUnequipped(m_Parent, unequippedItem->GetId()); + } +} + void InventoryComponent::HandlePossession(Item* item) { auto* characterComponent = m_Parent->GetComponent(); if (!characterComponent) return; diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index 8ae35f6c..44636d95 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -352,6 +352,20 @@ public: */ static uint32_t FindSkill(LOT lot); + /** + * Call this when you equip an item. This calls OnFactionTriggerItemEquipped for any scripts found on the items. + * + * @param equippedItem The item script to lookup and call equip on + */ + void EquipScripts(Item* equippedItem); + + /** + * Call this when you unequip an item. This calls OnFactionTriggerItemUnequipped for any scripts found on the items. + * + * @param unequippedItem The item script to lookup and call unequip on + */ + void UnequipScripts(Item* unequippedItem); + ~InventoryComponent() override; private: diff --git a/dScripts/CMakeLists.txt b/dScripts/CMakeLists.txt index fce3b721..ac600dbc 100644 --- a/dScripts/CMakeLists.txt +++ b/dScripts/CMakeLists.txt @@ -39,6 +39,12 @@ foreach(file ${DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS}) set(DSCRIPTS_SOURCES ${DSCRIPTS_SOURCES} "EquipmentScripts/${file}") endforeach() +add_subdirectory(EquipmentTriggers) + +foreach(file ${DSCRIPTS_SOURCES_EQUIPMENTTRIGGERSSCRIPTS}) + set(DSCRIPTS_SOURCES ${DSCRIPTS_SOURCES} "EquipmentTriggers/${file}") +endforeach() + add_subdirectory(zone) foreach(file ${DSCRIPTS_SOURCES_ZONE}) diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index dce77e4b..745a74ae 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -278,6 +278,9 @@ #include "ImaginationBackpackHealServer.h" #include "LegoDieRoll.h" #include "BuccaneerValiantShip.h" +#include "GemPack.h" +#include "ShardArmor.h" +#include "TeslaPack.h" // Survival scripts #include "AgSurvivalStromling.h" @@ -837,6 +840,12 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr script = new BuccaneerValiantShip(); else if (scriptName == "scripts\\EquipmentScripts\\FireFirstSkillonStartup.lua") script = new FireFirstSkillonStartup(); + else if (scriptName == "scripts\\equipmenttriggers\\gempack.lua") + script = new GemPack(); + else if (scriptName == "scripts\\equipmenttriggers\\shardarmor.lua") + script = new ShardArmor(); + else if (scriptName == "scripts\\equipmenttriggers\\coilbackpack.lua") + script = new TeslaPack(); // FB else if (scriptName == "scripts\\ai\\NS\\WH\\L_ROCKHYDRANT_BROKEN.lua") diff --git a/dScripts/CppScripts.h b/dScripts/CppScripts.h index 916d2638..e4a6d655 100644 --- a/dScripts/CppScripts.h +++ b/dScripts/CppScripts.h @@ -172,6 +172,13 @@ namespace CppScripts { */ virtual void OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) {}; + /** + * Invoked when self has received either a hit or heal. Only used for scripts subscribed to an entity. + * + * Equivalent to 'function notifyHitOrHealResult(self, msg)' + */ + virtual void NotifyHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) {}; + /** * Invoked when a player has responsed to a mission. * @@ -316,6 +323,22 @@ namespace CppScripts { virtual void OnCinematicUpdate(Entity* self, Entity* sender, eCinematicEvent event, const std::u16string& pathName, float_t pathTime, float_t totalTime, int32_t waypoint) { }; + + /** + * Used by items to tell their owner that they were equipped. + * + * @param itemOwner The owner of the item + * @param itemObjId The items Object ID + */ + virtual void OnFactionTriggerItemEquipped(Entity* itemOwner, LWOOBJID itemObjId) {}; + + /** + * Used by items to tell their owner that they were unequipped. + * + * @param itemOwner The owner of the item + * @param itemObjId The items Object ID + */ + virtual void OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) {}; }; Script* GetScript(Entity* parent, const std::string& scriptName); diff --git a/dScripts/EquipmentTriggers/CMakeLists.txt b/dScripts/EquipmentTriggers/CMakeLists.txt new file mode 100644 index 00000000..416ef553 --- /dev/null +++ b/dScripts/EquipmentTriggers/CMakeLists.txt @@ -0,0 +1,3 @@ +set(DSCRIPTS_SOURCES_EQUIPMENTTRIGGERSSCRIPTS + "CoilBackpackBase.cpp" + PARENT_SCOPE) diff --git a/dScripts/EquipmentTriggers/CoilBackpackBase.cpp b/dScripts/EquipmentTriggers/CoilBackpackBase.cpp new file mode 100644 index 00000000..d3102e0e --- /dev/null +++ b/dScripts/EquipmentTriggers/CoilBackpackBase.cpp @@ -0,0 +1,25 @@ +#include "CoilBackpackBase.h" + +#include "Entity.h" +#include "SkillComponent.h" + +void CoilBackpackBase::OnFactionTriggerItemEquipped(Entity* itemOwner, LWOOBJID itemObjId) { + itemOwner->Subscribe(itemObjId, this, "HitOrHealResult"); + itemOwner->SetVar(u"coilCount", 0); +} + +void CoilBackpackBase::NotifyHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { + if (damage > 0) { + self->SetVar(u"coilCount", self->GetVar(u"coilCount") + 1); + if (self->GetVar(u"coilCount") > 4) { + auto* skillComponent = self->GetComponent(); + if (!skillComponent) return; + skillComponent->CalculateBehavior(m_SkillId, m_BehaviorId, self->GetObjectID()); + self->SetVar(u"coilCount", 0); + } + } +} + +void CoilBackpackBase::OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) { + itemOwner->Unsubscribe(itemObjId, "HitOrHealResult"); +} diff --git a/dScripts/EquipmentTriggers/CoilBackpackBase.h b/dScripts/EquipmentTriggers/CoilBackpackBase.h new file mode 100644 index 00000000..290c6c0f --- /dev/null +++ b/dScripts/EquipmentTriggers/CoilBackpackBase.h @@ -0,0 +1,21 @@ +#ifndef __GemPackBase__H__ +#define __GemPackBase__H__ + +#include "CppScripts.h" + +class CoilBackpackBase: public CppScripts::Script { +public: + CoilBackpackBase(uint32_t skillId, uint32_t behaviorId) { + m_SkillId = skillId; + m_BehaviorId = behaviorId; + }; + + void OnFactionTriggerItemEquipped(Entity* itemOwner, LWOOBJID itemObjId) override; + void NotifyHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) override; + void OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) override; +private: + uint32_t m_SkillId = 0; + uint32_t m_BehaviorId = 0; +}; + +#endif //!__GemPackBase__H__ diff --git a/dScripts/EquipmentTriggers/GemPack.h b/dScripts/EquipmentTriggers/GemPack.h new file mode 100644 index 00000000..13bf7b0b --- /dev/null +++ b/dScripts/EquipmentTriggers/GemPack.h @@ -0,0 +1,14 @@ +#ifndef __GEMPACK__H__ +#define __GEMPACK__H__ + +#include "CoilBackpackBase.h" + +class GemPack : public CoilBackpackBase { +public: + GemPack() : CoilBackpackBase(skillId, behaviorId) {}; +private: + static const uint32_t skillId = 1488; + static const uint32_t behaviorId = 36779; +}; + +#endif //!__GEMPACK__H__ diff --git a/dScripts/EquipmentTriggers/ShardArmor.h b/dScripts/EquipmentTriggers/ShardArmor.h new file mode 100644 index 00000000..01d2fe33 --- /dev/null +++ b/dScripts/EquipmentTriggers/ShardArmor.h @@ -0,0 +1,14 @@ +#ifndef __SHARDARMOR__H__ +#define __SHARDARMOR__H__ + +#include "CoilBackpackBase.h" + +class ShardArmor : public CoilBackpackBase { +public: + ShardArmor() : CoilBackpackBase(skillId, behaviorId) {}; +private: + static const uint32_t skillId = 1249; + static const uint32_t behaviorId = 29086; +}; + +#endif //!__SHARDARMOR__H__ diff --git a/dScripts/EquipmentTriggers/TeslaPack.h b/dScripts/EquipmentTriggers/TeslaPack.h new file mode 100644 index 00000000..6e8bc9a4 --- /dev/null +++ b/dScripts/EquipmentTriggers/TeslaPack.h @@ -0,0 +1,14 @@ +#ifndef __TESLAPACK__H__ +#define __TESLAPACK__H__ + +#include "CoilBackpackBase.h" + +class TeslaPack : public CoilBackpackBase { +public: + TeslaPack() : CoilBackpackBase(skillId, behaviorId) {}; +private: + static const uint32_t skillId = 1001; + static const uint32_t behaviorId = 20917; +}; + +#endif //!__TESLAPACK__H__ From fd9757d1215dd6dafe6431aa4aeb556902f3c4b2 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 21 Dec 2022 22:34:11 -0800 Subject: [PATCH 073/166] Implement a server res directory for server required client files (#891) --- CMakeLists.txt | 4 +- dCommon/FdbToSqlite.cpp | 73 +++++++++++---------- dCommon/FdbToSqlite.h | 116 +++++++++++++++++++++++++++++++-- dMasterServer/MasterServer.cpp | 40 ++++++++---- dWorldServer/WorldServer.cpp | 2 +- 5 files changed, 176 insertions(+), 59 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9596649..54f0d0dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,8 +89,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -# Create a /res directory -make_directory(${CMAKE_BINARY_DIR}/res) +# Create a /resServer directory +make_directory(${CMAKE_BINARY_DIR}/resServer) # Create a /logs directory make_directory(${CMAKE_BINARY_DIR}/logs) diff --git a/dCommon/FdbToSqlite.cpp b/dCommon/FdbToSqlite.cpp index 6015fd3a..80251e89 100644 --- a/dCommon/FdbToSqlite.cpp +++ b/dCommon/FdbToSqlite.cpp @@ -13,7 +13,7 @@ #include "eSqliteDataType.h" -std::map FdbToSqlite::Convert::sqliteType = { +std::map FdbToSqlite::Convert::m_SqliteType = { { eSqliteDataType::NONE, "none"}, { eSqliteDataType::INT32, "int32"}, { eSqliteDataType::REAL, "real"}, @@ -23,15 +23,21 @@ std::map FdbToSqlite::Convert::sqliteType = { { eSqliteDataType::TEXT_8, "text_8"} }; -FdbToSqlite::Convert::Convert(std::string basePath) { - this->basePath = basePath; +FdbToSqlite::Convert::Convert(std::string basePath, std::string binaryOutPath) { + this->m_BasePath = basePath; + this->m_BinaryOutPath = binaryOutPath; + m_Fdb.open(m_BasePath + "/cdclient.fdb", std::ios::binary); +} + +FdbToSqlite::Convert::~Convert() { + this->m_Fdb.close(); } bool FdbToSqlite::Convert::ConvertDatabase() { - fdb.open(basePath + "/cdclient.fdb", std::ios::binary); - + if (m_ConversionStarted) return false; + this->m_ConversionStarted = true; try { - CDClientDatabase::Connect(basePath + "/CDServer.sqlite"); + CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite"); CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;"); @@ -44,13 +50,12 @@ bool FdbToSqlite::Convert::ConvertDatabase() { return false; } - fdb.close(); return true; } int32_t FdbToSqlite::Convert::ReadInt32() { int32_t nextInt{}; - BinaryIO::BinaryRead(fdb, nextInt); + BinaryIO::BinaryRead(m_Fdb, nextInt); return nextInt; } @@ -58,26 +63,26 @@ int64_t FdbToSqlite::Convert::ReadInt64() { int32_t prevPosition = SeekPointer(); int64_t value{}; - BinaryIO::BinaryRead(fdb, value); + BinaryIO::BinaryRead(m_Fdb, value); - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); return value; } std::string FdbToSqlite::Convert::ReadString() { int32_t prevPosition = SeekPointer(); - auto readString = BinaryIO::ReadString(fdb); + auto readString = BinaryIO::ReadString(m_Fdb); - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); return readString; } int32_t FdbToSqlite::Convert::SeekPointer() { int32_t position{}; - BinaryIO::BinaryRead(fdb, position); - int32_t prevPosition = fdb.tellg(); - fdb.seekg(position); + BinaryIO::BinaryRead(m_Fdb, position); + int32_t prevPosition = m_Fdb.tellg(); + m_Fdb.seekg(position); return prevPosition; } @@ -91,7 +96,7 @@ std::string FdbToSqlite::Convert::ReadColumnHeader() { std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");"; CDClientDatabase::ExecuteDML(newTable); - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); return tableName; } @@ -104,7 +109,7 @@ void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables) { ReadRowHeader(columnHeader); } - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); } std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns) { @@ -117,10 +122,10 @@ std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns) { if (i != 0) columnsToCreate << ", "; dataType = static_cast(ReadInt32()); name = ReadString(); - columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::sqliteType[dataType]; + columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::m_SqliteType[dataType]; } - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); return columnsToCreate.str(); } @@ -131,7 +136,7 @@ void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName) { if (numberOfAllocatedRows != 0) assert((numberOfAllocatedRows & (numberOfAllocatedRows - 1)) == 0); // assert power of 2 allocation size ReadRows(numberOfAllocatedRows, tableName); - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); } void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName) { @@ -141,28 +146,24 @@ void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& for (int32_t row = 0; row < numberOfAllocatedRows; row++) { int32_t rowPointer = ReadInt32(); if (rowPointer == -1) rowid++; - else ReadRow(rowid, rowPointer, tableName); + else ReadRow(rowPointer, tableName); } - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); } -void FdbToSqlite::Convert::ReadRow(int32_t& rowid, int32_t& position, std::string& tableName) { - int32_t prevPosition = fdb.tellg(); - fdb.seekg(position); +void FdbToSqlite::Convert::ReadRow(int32_t& position, std::string& tableName) { + int32_t prevPosition = m_Fdb.tellg(); + m_Fdb.seekg(position); while (true) { ReadRowInfo(tableName); int32_t linked = ReadInt32(); - - rowid += 1; - if (linked == -1) break; - - fdb.seekg(linked); + m_Fdb.seekg(linked); } - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); } void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName) { @@ -171,7 +172,7 @@ void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName) { int32_t numberOfColumns = ReadInt32(); ReadRowValues(numberOfColumns, tableName); - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); } void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName) { @@ -191,7 +192,7 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& if (i != 0) insertedRow << ", "; // Only append comma and space after first entry in row. switch (static_cast(ReadInt32())) { case eSqliteDataType::NONE: - BinaryIO::BinaryRead(fdb, emptyValue); + BinaryIO::BinaryRead(m_Fdb, emptyValue); assert(emptyValue == 0); insertedRow << "NULL"; break; @@ -202,7 +203,7 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& break; case eSqliteDataType::REAL: - BinaryIO::BinaryRead(fdb, floatValue); + BinaryIO::BinaryRead(m_Fdb, floatValue); insertedRow << std::fixed << std::setprecision(34) << floatValue; // maximum precision of floating point number break; @@ -224,7 +225,7 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& } case eSqliteDataType::INT_BOOL: - BinaryIO::BinaryRead(fdb, boolValue); + BinaryIO::BinaryRead(m_Fdb, boolValue); insertedRow << static_cast(boolValue); break; @@ -244,5 +245,5 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& auto copiedString = insertedRow.str(); CDClientDatabase::ExecuteDML(copiedString); - fdb.seekg(prevPosition); + m_Fdb.seekg(prevPosition); } diff --git a/dCommon/FdbToSqlite.h b/dCommon/FdbToSqlite.h index a9611220..cfa5263b 100644 --- a/dCommon/FdbToSqlite.h +++ b/dCommon/FdbToSqlite.h @@ -12,38 +12,142 @@ enum class eSqliteDataType : int32_t; namespace FdbToSqlite { class Convert { public: - Convert(std::string inputFile); + /** + * Create a new convert object with an input .fdb file and an output binary path. + * + * @param inputFile The file which ends in .fdb to be converted + * @param binaryPath The base path where the file will be saved + */ + Convert(std::string inputFile, std::string binaryOutPath); + /** + * Destroy the convert object and close the fdb file. + */ + ~Convert(); + + /** + * Converts the input file to sqlite. Calling multiple times is safe. + * + * @return true if the database was converted properly, false otherwise. + */ bool ConvertDatabase(); + /** + * @brief Reads a 32 bit int from the fdb file. + * + * @return The read value + */ int32_t ReadInt32(); + /** + * @brief Reads a 64 bit integer from the fdb file. + * + * @return The read value + */ int64_t ReadInt64(); + /** + * @brief Reads a string from the fdb file. + * + * @return The read string + * + * TODO This needs to be translated to latin-1! + */ std::string ReadString(); + /** + * @brief Seeks to a pointer position. + * + * @return The previous position before the seek + */ int32_t SeekPointer(); + /** + * @brief Reads a column header from the fdb file and creates the table in the database + * + * @return The table name + */ std::string ReadColumnHeader(); + /** + * @brief Read the tables from the fdb file. + * + * @param numberOfTables The number of tables to read + */ void ReadTables(int32_t& numberOfTables); + /** + * @brief Reads the columns from the fdb file. + * + * @param numberOfColumns The number of columns to read + * @return All columns of the table formatted for a sql query + */ std::string ReadColumns(int32_t& numberOfColumns); + /** + * @brief Reads the row header from the fdb file. + * + * @param tableName The tables name + */ void ReadRowHeader(std::string& tableName); + /** + * @brief Read the rows from the fdb file., + * + * @param numberOfAllocatedRows The number of rows that were allocated. Always a power of 2! + * @param tableName The tables name. + */ void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName); - void ReadRow(int32_t& rowid, int32_t& position, std::string& tableName); + /** + * @brief Reads a row from the fdb file. + * + * @param position The position to seek in the fdb to + * @param tableName The tables name + */ + void ReadRow(int32_t& position, std::string& tableName); + /** + * @brief Reads the row info from the fdb file. + * + * @param tableName The tables name + */ void ReadRowInfo(std::string& tableName); + /** + * @brief Reads each row and its values from the fdb file and inserts them into the database + * + * @param numberOfColumns The number of columns to read in + * @param tableName The tables name + */ void ReadRowValues(int32_t& numberOfColumns, std::string& tableName); private: - static std::map sqliteType; - std::string basePath{}; - std::ifstream fdb{}; - }; // class FdbToSqlite + + /** + * Maps each sqlite data type to its string equivalent. + */ + static std::map m_SqliteType; + + /** + * Base path of the folder containing the fdb file + */ + std::string m_BasePath{}; + + /** + * ifstream containing the fdb file + */ + std::ifstream m_Fdb{}; + + /** + * Whether or not a conversion was started. If one was started, do not attempt to convert the file again. + */ + bool m_ConversionStarted{}; + + /** + * The path where the CDServer will be stored + */ + std::string m_BinaryOutPath{}; + }; //! class FdbToSqlite }; //! namespace FdbToSqlite #endif //!__FDBTOSQLITE__H__ diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index ba36247c..34ce59c7 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -146,26 +146,38 @@ int main(int argc, char** argv) { MigrationRunner::RunMigrations(); - // Check CDClient exists - if (!std::filesystem::exists(Game::assetManager->GetResPath() / "CDServer.sqlite")) { - Game::logger->Log("WorldServer", "CDServer.sqlite could not be opened. Looking for cdclient.fdb to convert to sqlite."); + const bool cdServerExists = std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite"); + const bool oldCDServerExists = std::filesystem::exists(Game::assetManager->GetResPath() / "CDServer.sqlite"); + const bool fdbExists = std::filesystem::exists(Game::assetManager->GetResPath() / "cdclient.fdb"); - if (!std::filesystem::exists(Game::assetManager->GetResPath() / "cdclient.fdb")) { - Game::logger->Log("WorldServer", "cdclient.fdb could not be opened. Please move a cdclient.fdb or an already converted database to build/res."); - return EXIT_FAILURE; - } - - Game::logger->Log("WorldServer", "Found cdclient.fdb. Converting to SQLite"); - - if (FdbToSqlite::Convert(Game::assetManager->GetResPath().string()).ConvertDatabase() == false) { - Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite"); - return EXIT_FAILURE; + if (!cdServerExists) { + if (oldCDServerExists) { + // If the file doesn't exist in the new CDServer location, copy it there. We copy because we may not have write permissions from the previous directory. + Game::logger->Log("MasterServer", "CDServer.sqlite is not located at resServer, but is located at res path. Copying file..."); + std::filesystem::copy_file(Game::assetManager->GetResPath() / "CDServer.sqlite", BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite"); + } else { + Game::logger->Log("WorldServer", + "%s could not be found in resServer or res. Looking for %s to convert to sqlite.", + (BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(), + (Game::assetManager->GetResPath() / "cdclient.fdb").c_str()); + if (!fdbExists) { + Game::logger->Log("WorldServer", + "%s could not be opened. Please move cdclient.fdb to %s", + (Game::assetManager->GetResPath() / "cdclient.fdb").c_str(), + (Game::assetManager->GetResPath().c_str())); + return FinalizeShutdown(); + } + Game::logger->Log("WorldServer", "Found cdclient.fdb. Converting to SQLite"); + if (FdbToSqlite::Convert(Game::assetManager->GetResPath().string(), (BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase() == false) { + Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite."); + return FinalizeShutdown(); + } } } //Connect to CDClient try { - CDClientDatabase::Connect((Game::assetManager->GetResPath() / "CDServer.sqlite").string()); + CDClientDatabase::Connect((BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").string()); } catch (CppSQLite3Exception& e) { Game::logger->Log("WorldServer", "Unable to connect to CDServer SQLite Database"); Game::logger->Log("WorldServer", "Error: %s", e.errorMessage()); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index adb87ba0..32060a51 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -154,7 +154,7 @@ int main(int argc, char** argv) { // Connect to CDClient try { - CDClientDatabase::Connect((Game::assetManager->GetResPath() / "CDServer.sqlite").string()); + CDClientDatabase::Connect((BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").string()); } catch (CppSQLite3Exception& e) { Game::logger->Log("WorldServer", "Unable to connect to CDServer SQLite Database"); Game::logger->Log("WorldServer", "Error: %s", e.errorMessage()); From d052ed6a631341d89b9eb395b9936c9a25f9c13e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 22 Dec 2022 04:06:59 -0800 Subject: [PATCH 074/166] Update MigrationRunner.cpp (#911) --- dDatabase/MigrationRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dDatabase/MigrationRunner.cpp b/dDatabase/MigrationRunner.cpp index 54def9e2..5e70c401 100644 --- a/dDatabase/MigrationRunner.cpp +++ b/dDatabase/MigrationRunner.cpp @@ -54,7 +54,7 @@ void MigrationRunner::RunMigrations() { if (doExit) continue; Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str()); - if (migration.name == "5_brick_model_sd0.sql") { + if (migration.name == "dlu/5_brick_model_sd0.sql") { runSd0Migrations = true; } else { finalSQL.append(migration.data.c_str()); From dff02773a0d3904e2682ff483a5d8ae9b44f00fb Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 22 Dec 2022 05:16:08 -0800 Subject: [PATCH 075/166] Fix dragon stuns (#915) --- dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp | 5 ++++- dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp index 8ec49d3e..9e0570ef 100644 --- a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp +++ b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp @@ -63,10 +63,11 @@ void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t if (skillComponent != nullptr) { skillComponent->Interrupt(); + skillComponent->Reset(); } self->SetVar(u"weakpoint", 2); - + GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendPlayAnimation(self, u"stunstart", 1.7f); self->AddTimer("timeToStunLoop", 1); @@ -131,7 +132,9 @@ void AmDarklingDragon::OnTimerDone(Entity* self, std::string timerName) { } if (skillComponent != nullptr) { skillComponent->Interrupt(); + skillComponent->Reset(); } + GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_COMBAT, eAnimationFlags::IDLE_NONE, UNASSIGNED_SYSTEM_ADDRESS); self->SetVar(u"weakspot", -1); GameMessages::SendNotifyObject(self->GetObjectID(), self->GetObjectID(), u"DragonRevive", UNASSIGNED_SYSTEM_ADDRESS); } diff --git a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp index 47ddb4bf..ec513694 100644 --- a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp +++ b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp @@ -59,8 +59,6 @@ void FvMaelstromDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_ auto* destroyableComponent = self->GetComponent(); if (destroyableComponent != nullptr) { - Game::logger->Log("FvMaelstromDragon", "Hit %i", destroyableComponent->GetArmor()); - if (destroyableComponent->GetArmor() > 0) return; auto weakpoint = self->GetVar(u"weakpoint"); @@ -80,10 +78,12 @@ void FvMaelstromDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_ if (skillComponent != nullptr) { skillComponent->Interrupt(); + skillComponent->Reset(); } self->SetVar(u"weakpoint", 2); + GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendPlayAnimation(self, u"stunstart", 1.7f); self->AddTimer("timeToStunLoop", 1); @@ -150,8 +150,9 @@ void FvMaelstromDragon::OnTimerDone(Entity* self, std::string timerName) { if (skillComponent != nullptr) { skillComponent->Interrupt(); + skillComponent->Reset(); } - + GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_COMBAT, eAnimationFlags::IDLE_NONE, UNASSIGNED_SYSTEM_ADDRESS); self->SetVar(u"weakspot", -1); GameMessages::SendNotifyObject(self->GetObjectID(), self->GetObjectID(), u"DragonRevive", UNASSIGNED_SYSTEM_ADDRESS); From 015cbc06ea020c391bce22d1d6c56023c2daa84e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 22 Dec 2022 05:16:18 -0800 Subject: [PATCH 076/166] Fix racing spawn positions (#913) --- dGame/dComponents/RacingControlComponent.cpp | 47 +++++++------------- dGame/dComponents/RacingControlComponent.h | 2 +- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 75465669..4b5743cd 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -98,7 +98,7 @@ void RacingControlComponent::OnPlayerLoaded(Entity* player) { } void RacingControlComponent::LoadPlayerVehicle(Entity* player, - bool initialLoad) { + uint32_t positionNumber, bool initialLoad) { // Load the player's vehicle. if (player == nullptr) { @@ -126,33 +126,18 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, auto* path = dZoneManager::Instance()->GetZone()->GetPath( GeneralUtils::UTF16ToWTF8(m_PathName)); - auto startPosition = path->pathWaypoints[0].position + NiPoint3::UNIT_Y * 3; - - const auto spacing = 15; - - // This sometimes spawns the vehicle out of the map if there are lots of - // players loaded. - - const auto range = m_LoadedPlayers * spacing; - - startPosition = - startPosition + NiPoint3::UNIT_Z * ((m_LeadingPlayer / 2) + - m_RacingPlayers.size() * spacing); - - auto startRotation = - NiQuaternion::LookAt(startPosition, startPosition + NiPoint3::UNIT_X); - - auto angles = startRotation.GetEulerAngles(); - - angles.y -= M_PI; - - startRotation = NiQuaternion::FromEulerAngles(angles); - - Game::logger->Log("RacingControlComponent", - "Start position <%f, %f, %f>, <%f, %f, %f>", - startPosition.x, startPosition.y, startPosition.z, - angles.x * (180.0f / M_PI), angles.y * (180.0f / M_PI), - angles.z * (180.0f / M_PI)); + auto spawnPointEntities = EntityManager::Instance()->GetEntitiesByLOT(4843); + auto startPosition = NiPoint3::ZERO; + auto startRotation = NiQuaternion::IDENTITY; + const std::string placementAsString = std::to_string(positionNumber); + for (auto entity : spawnPointEntities) { + if (!entity) continue; + if (entity->GetVarAsString(u"placement") == placementAsString) { + startPosition = entity->GetPosition(); + startRotation = entity->GetRotation(); + break; + } + } // Make sure the player is at the correct position. @@ -567,12 +552,12 @@ void RacingControlComponent::Update(float deltaTime) { Game::logger->Log("RacingControlComponent", "Loading all players..."); - for (size_t i = 0; i < m_LobbyPlayers.size(); i++) { + for (size_t positionNumber = 0; positionNumber < m_LobbyPlayers.size(); positionNumber++) { Game::logger->Log("RacingControlComponent", "Loading player now!"); auto* player = - EntityManager::Instance()->GetEntity(m_LobbyPlayers[i]); + EntityManager::Instance()->GetEntity(m_LobbyPlayers[positionNumber]); if (player == nullptr) { return; @@ -581,7 +566,7 @@ void RacingControlComponent::Update(float deltaTime) { Game::logger->Log("RacingControlComponent", "Loading player now NOW!"); - LoadPlayerVehicle(player, true); + LoadPlayerVehicle(player, positionNumber + 1, true); m_Loaded = true; } diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index dac60962..933178cc 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -123,7 +123,7 @@ public: * @param player The player who's vehicle to initialize. * @param initialLoad Is this the first time the player is loading in this race? */ - void LoadPlayerVehicle(Entity* player, bool initialLoad = false); + void LoadPlayerVehicle(Entity* player, uint32_t positionNumber, bool initialLoad = false); /** * Invoked when the client says it has loaded in. From 96313ecd695de9ad60b4634ea90919fa4f2f4328 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 22 Dec 2022 05:16:35 -0800 Subject: [PATCH 077/166] Calculate world shutdown timer (#910) --- dWorldServer/WorldServer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 32060a51..de6deb2a 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -296,6 +296,7 @@ int main(int argc, char** argv) { uint32_t chatReconnectionTime = 30 * currentFramerate; // 30 seconds in frames uint32_t saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames uint32_t sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames + uint32_t emptyShutdownTime = (cloneID == 0 ? 30 : 5) * 60 * currentFramerate; // 30 minutes for main worlds, 5 for all others. while (true) { Metrics::StartMeasurement(MetricVariable::Frame); Metrics::StartMeasurement(MetricVariable::GameLoop); @@ -333,6 +334,8 @@ int main(int argc, char** argv) { framesSinceLastUsersSave *= ratioBeforeToAfter; sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames framesSinceLastSQLPing *= ratioBeforeToAfter; + emptyShutdownTime = (cloneID == 0 ? 30 : 5) * 60 * currentFramerate; // 30 minutes for main worlds, 5 for all others. + framesSinceLastUser *= ratioBeforeToAfter; } //Warning if we ran slow @@ -440,7 +443,7 @@ int main(int argc, char** argv) { framesSinceLastUser++; //If we haven't had any players for a while, time out and shut down: - if (framesSinceLastUser == (cloneID != 0 ? 4000 : 40000)) { + if (framesSinceLastUser >= emptyShutdownTime) { Game::shouldShutdown = true; } } else { From 9ebb06ba24d3b7e26d6270d7efbaa46ee975cfee Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 22 Dec 2022 07:24:59 -0600 Subject: [PATCH 078/166] Qb team credit (#912) * give credit to whole team for qb's * fix compiling --- dGame/dComponents/RebuildComponent.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 6ec9b964..c7c4e3a5 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -14,6 +14,7 @@ #include "Spawner.h" #include "MovingPlatformComponent.h" #include "Preconditions.h" +#include "TeamManager.h" #include "CppScripts.h" @@ -464,12 +465,20 @@ void RebuildComponent::CompleteRebuild(Entity* user) { auto* builder = GetBuilder(); - if (builder != nullptr) { - auto* missionComponent = builder->GetComponent(); - if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ACTIVITY, m_ActivityId); + if (builder) { + auto* team = TeamManager::Instance()->GetTeam(builder->GetObjectID()); + if (team) { + for (const auto memberId : team->members) { // progress missions for all team members + auto* member = EntityManager::Instance()->GetEntity(memberId); + if (member) { + auto* missionComponent = member->GetComponent(); + if (missionComponent) missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ACTIVITY, m_ActivityId); + } + } + } else{ + auto* missionComponent = builder->GetComponent(); + if (missionComponent) missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ACTIVITY, m_ActivityId); } - LootGenerator::Instance().DropActivityLoot(builder, m_Parent, m_ActivityId, 1); } From 675cf1d2a4f5a6955959e4884193fd733ea6185f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 22 Dec 2022 22:14:51 -0800 Subject: [PATCH 079/166] Fix baseEnemyApe stuns and fix IdleFlags serialization (#914) * Fix baseEnemyApe stuns * Correct serialization --- dGame/dGameMessages/GameMessages.cpp | 8 +++++--- dScripts/02_server/Enemy/General/BaseEnemyApe.cpp | 8 ++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 9753868d..c3b86647 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3924,14 +3924,16 @@ void GameMessages::SendDisplayChatBubble(LWOOBJID objectId, const std::u16string } -void GameMessages::SendChangeIdleFlags(LWOOBJID objectId, eAnimationFlags FlagsOn, eAnimationFlags FlagsOff, const SystemAddress& sysAddr) { +void GameMessages::SendChangeIdleFlags(LWOOBJID objectId, eAnimationFlags flagsOn, eAnimationFlags flagsOff, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectId); bitStream.Write(GAME_MSG::GAME_MSG_CHANGE_IDLE_FLAGS); - bitStream.Write(FlagsOff); - bitStream.Write(FlagsOn); + bitStream.Write(flagsOff != eAnimationFlags::IDLE_NONE); + if (flagsOff != eAnimationFlags::IDLE_NONE) bitStream.Write(flagsOff); + bitStream.Write(flagsOn != eAnimationFlags::IDLE_NONE); + if (flagsOn != eAnimationFlags::IDLE_NONE) bitStream.Write(flagsOn); SEND_PACKET_BROADCAST; } diff --git a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp index 3d0b8e25..96419c08 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp @@ -31,9 +31,12 @@ void BaseEnemyApe::OnHit(Entity* self, Entity* attacker) { if (destroyableComponent != nullptr && destroyableComponent->GetArmor() < 1 && !self->GetBoolean(u"knockedOut")) { StunApe(self, true); self->CancelTimer("spawnQBTime"); - + auto* skillComponent = self->GetComponent(); + if (skillComponent) { + skillComponent->Reset(); + } GameMessages::SendPlayAnimation(self, u"disable", 1.7f); - + GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); const auto reviveTime = self->GetVar(u"reviveTime") != 0.0f ? self->GetVar(u"reviveTime") : 12.0f; self->AddTimer("reviveTime", reviveTime); @@ -50,6 +53,7 @@ void BaseEnemyApe::OnTimerDone(Entity* self, std::string timerName) { destroyableComponent->SetArmor(destroyableComponent->GetMaxArmor() / timesStunned); } EntityManager::Instance()->SerializeEntity(self); + GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_COMBAT, eAnimationFlags::IDLE_NONE, UNASSIGNED_SYSTEM_ADDRESS); self->SetVar(u"timesStunned", timesStunned + 1); StunApe(self, false); From bbd5a49ea2c682469a1c3f48e418c93d932dec1c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 23 Dec 2022 18:05:30 -0800 Subject: [PATCH 080/166] Update DarkInspirationBehavior.cpp (#897) --- dGame/dBehaviors/AreaOfEffectBehavior.cpp | 5 +- dGame/dBehaviors/Behavior.cpp | 5 +- dGame/dBehaviors/CMakeLists.txt | 1 + dGame/dBehaviors/DarkInspirationBehavior.cpp | 52 ++++++++++++++++++++ dGame/dBehaviors/DarkInspirationBehavior.h | 22 +++++++++ dGame/dComponents/DestroyableComponent.cpp | 2 +- dGame/dComponents/InventoryComponent.cpp | 4 +- dGame/dComponents/InventoryComponent.h | 2 +- dGame/dInventory/ItemSet.cpp | 4 +- dGame/dInventory/ItemSet.h | 2 +- dGame/dInventory/ItemSetPassiveAbility.cpp | 14 +++--- dGame/dInventory/ItemSetPassiveAbility.h | 6 +-- 12 files changed, 98 insertions(+), 21 deletions(-) create mode 100644 dGame/dBehaviors/DarkInspirationBehavior.cpp create mode 100644 dGame/dBehaviors/DarkInspirationBehavior.h diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index ca3bdf93..dedede2a 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -48,9 +48,8 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { auto* self = EntityManager::Instance()->GetEntity(context->caster); - if (self == nullptr) { - Game::logger->Log("TacArcBehavior", "Invalid self for (%llu)!", context->originator); + Game::logger->Log("AreaOfEffectBehavior", "Invalid self for (%llu)!", context->originator); return; } @@ -79,7 +78,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream auto* entity = EntityManager::Instance()->GetEntity(validTarget); if (entity == nullptr) { - Game::logger->Log("TacArcBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator); + Game::logger->Log("AreaOfEffectBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator); continue; } diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index cd9304d3..568780d0 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -61,6 +61,7 @@ #include "DamageReductionBehavior.h" #include "JetPackBehavior.h" #include "ChangeIdleFlagsBehavior.h" +#include "DarkInspirationBehavior.h" //CDClient includes #include "CDBehaviorParameterTable.h" @@ -169,7 +170,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { case BehaviorTemplates::BEHAVIOR_SPEED: behavior = new SpeedBehavior(behaviorId); break; - case BehaviorTemplates::BEHAVIOR_DARK_INSPIRATION: break; + case BehaviorTemplates::BEHAVIOR_DARK_INSPIRATION: + behavior = new DarkInspirationBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_LOOT_BUFF: behavior = new LootBuffBehavior(behaviorId); break; diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index 40ac0a9c..e274872d 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -18,6 +18,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "ClearTargetBehavior.cpp" "DamageAbsorptionBehavior.cpp" "DamageReductionBehavior.cpp" + "DarkInspirationBehavior.cpp" "DurationBehavior.cpp" "EmptyBehavior.cpp" "EndBehavior.cpp" diff --git a/dGame/dBehaviors/DarkInspirationBehavior.cpp b/dGame/dBehaviors/DarkInspirationBehavior.cpp new file mode 100644 index 00000000..ea80cbba --- /dev/null +++ b/dGame/dBehaviors/DarkInspirationBehavior.cpp @@ -0,0 +1,52 @@ +#include "DarkInspirationBehavior.h" + +#include "BehaviorBranchContext.h" +#include "Entity.h" +#include "DestroyableComponent.h" +#include "EntityManager.h" +#include "BehaviorContext.h" + +void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { + auto* target = EntityManager::Instance()->GetEntity(branch.target); + + if (target == nullptr) { + Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target); + return; + } + + auto* destroyableComponent = target->GetComponent(); + + if (destroyableComponent == nullptr) { + return; + } + + if (destroyableComponent->HasFaction(m_FactionList)) { + this->m_ActionIfFactionMatches->Handle(context, bitStream, branch); + } +} + +void DarkInspirationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + auto* target = EntityManager::Instance()->GetEntity(branch.target); + + if (target == nullptr) { + Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target); + + return; + } + + auto* destroyableComponent = target->GetComponent(); + + if (destroyableComponent == nullptr) { + return; + } + + if (destroyableComponent->HasFaction(m_FactionList)) { + this->m_ActionIfFactionMatches->Calculate(context, bitStream, branch); + } +} + +void DarkInspirationBehavior::Load() { + this->m_ActionIfFactionMatches = GetAction("action"); + + this->m_FactionList = GetInt("faction_list"); +} diff --git a/dGame/dBehaviors/DarkInspirationBehavior.h b/dGame/dBehaviors/DarkInspirationBehavior.h new file mode 100644 index 00000000..f8298742 --- /dev/null +++ b/dGame/dBehaviors/DarkInspirationBehavior.h @@ -0,0 +1,22 @@ +#pragma once +#include "Behavior.h" + +class DarkInspirationBehavior final : public Behavior +{ +public: + /* + * Inherited + */ + + explicit DarkInspirationBehavior(const uint32_t behaviorId) : Behavior(behaviorId) { + } + + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + + void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + + void Load() override; +private: + Behavior* m_ActionIfFactionMatches; + uint32_t m_FactionList; +}; diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 6902917f..d832ef93 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -694,7 +694,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType auto* inventoryComponent = owner->GetComponent(); if (inventoryComponent != nullptr && isEnemy) { - inventoryComponent->TriggerPassiveAbility(PassiveAbilityTrigger::EnemySmashed); + inventoryComponent->TriggerPassiveAbility(PassiveAbilityTrigger::EnemySmashed, m_Parent); } auto* missions = owner->GetComponent(); diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index eeb6afa7..6247f32d 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -1196,9 +1196,9 @@ void InventoryComponent::RemoveItemSkills(const LOT lot) { } } -void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger) { +void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger, Entity* target) { for (auto* set : m_Itemsets) { - set->TriggerPassiveAbility(trigger); + set->TriggerPassiveAbility(trigger, target); } } diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index 44636d95..f63a8d70 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -283,7 +283,7 @@ public: * Triggers one of the passive abilities from the equipped item set * @param trigger the trigger to fire */ - void TriggerPassiveAbility(PassiveAbilityTrigger trigger); + void TriggerPassiveAbility(PassiveAbilityTrigger trigger, Entity* target = nullptr); /** * Returns if the entity has any of the passed passive abilities equipped diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index 5063139e..1c67f6d6 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -180,9 +180,9 @@ void ItemSet::Update(float deltaTime) { } } -void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger) { +void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger, Entity* target) { for (auto& passiveAbility : m_PassiveAbilities) { - passiveAbility.Trigger(trigger); + passiveAbility.Trigger(trigger, target); } } diff --git a/dGame/dInventory/ItemSet.h b/dGame/dInventory/ItemSet.h index 7c713f03..d167cfaa 100644 --- a/dGame/dInventory/ItemSet.h +++ b/dGame/dInventory/ItemSet.h @@ -52,7 +52,7 @@ public: * Triggers all the passive abilities in this item set that match this trigger * @param trigger the trigger to use to trigger passive abilities */ - void TriggerPassiveAbility(PassiveAbilityTrigger trigger); + void TriggerPassiveAbility(PassiveAbilityTrigger trigger, Entity* target = nullptr); /** * Returns the skills that can be equipped for a specified amount of equipped items diff --git a/dGame/dInventory/ItemSetPassiveAbility.cpp b/dGame/dInventory/ItemSetPassiveAbility.cpp index d90f6e4e..83db4405 100644 --- a/dGame/dInventory/ItemSetPassiveAbility.cpp +++ b/dGame/dInventory/ItemSetPassiveAbility.cpp @@ -16,12 +16,12 @@ ItemSetPassiveAbility::ItemSetPassiveAbility(PassiveAbilityTrigger trigger, Enti ItemSetPassiveAbility::~ItemSetPassiveAbility() { } -void ItemSetPassiveAbility::Trigger(PassiveAbilityTrigger trigger) { +void ItemSetPassiveAbility::Trigger(PassiveAbilityTrigger trigger, Entity* target) { if (m_Trigger != trigger || m_Cooldown > 0.0f) { return; } - Activate(); + Activate(target); } void ItemSetPassiveAbility::Update(float deltaTime) { @@ -30,9 +30,9 @@ void ItemSetPassiveAbility::Update(float deltaTime) { } } -void ItemSetPassiveAbility::Activate() { +void ItemSetPassiveAbility::Activate(Entity* target) { if (m_Trigger == PassiveAbilityTrigger::EnemySmashed) { - OnEnemySmshed(); + OnEnemySmshed(target); return; } @@ -195,7 +195,7 @@ std::vector ItemSetPassiveAbility::FindAbilities(uint32_t return abilities; } -void ItemSetPassiveAbility::OnEnemySmshed() { +void ItemSetPassiveAbility::OnEnemySmshed(Entity* target) { auto* destroyableComponent = m_Parent->GetComponent(); auto* skillComponent = m_Parent->GetComponent(); @@ -293,8 +293,8 @@ void ItemSetPassiveAbility::OnEnemySmshed() { break; } case ItemSetPassiveAbilityID::ShinobiRank3: { - if (equippedCount < 4) return; - destroyableComponent->Imagine(3); + if (equippedCount < 4 || !target) return; + skillComponent->CalculateBehavior(695, 11399, target->GetObjectID()); break; } diff --git a/dGame/dInventory/ItemSetPassiveAbility.h b/dGame/dInventory/ItemSetPassiveAbility.h index ff945df2..8735e695 100644 --- a/dGame/dInventory/ItemSetPassiveAbility.h +++ b/dGame/dInventory/ItemSetPassiveAbility.h @@ -30,12 +30,12 @@ public: * Attempts to trigger a passive ability for this item set, if this is the wrong trigger this is a no-op * @param trigger the trigger to attempt to fire */ - void Trigger(PassiveAbilityTrigger trigger); + void Trigger(PassiveAbilityTrigger trigger, Entity* target = nullptr); /** * Activates the passive ability */ - void Activate(); + void Activate(Entity* target = nullptr); /** * Finds all the passive abilities associated with a certain item set @@ -47,7 +47,7 @@ public: static std::vector FindAbilities(uint32_t itemSetID, Entity* parent, ItemSet* itemSet); private: - void OnEnemySmshed(); + void OnEnemySmshed(Entity* target = nullptr); /** * The means of triggering this ability From 6ec921025deb43a43f2413e150b121250f635df4 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 24 Dec 2022 02:49:31 -0600 Subject: [PATCH 081/166] Use new logic for applying speed changes in ApplyBuff (#919) --- dGame/dComponents/BuffComponent.cpp | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index d8d7428d..974d0bd2 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -170,17 +170,10 @@ void BuffComponent::ApplyBuffEffect(int32_t id) { destroyable->SetMaxImagination(destroyable->GetMaxImagination() + maxImagination); } else if (parameter.name == "speed") { - const auto speed = parameter.value; - auto* controllablePhysicsComponent = this->GetParent()->GetComponent(); - - if (controllablePhysicsComponent == nullptr) return; - - const auto current = controllablePhysicsComponent->GetSpeedMultiplier(); - - controllablePhysicsComponent->SetSpeedMultiplier(current + ((speed - 500.0f) / 500.0f)); - - EntityManager::Instance()->SerializeEntity(this->GetParent()); + if (!controllablePhysicsComponent) return; + const auto speed = parameter.value; + controllablePhysicsComponent->AddSpeedboost(speed); } } } @@ -213,17 +206,10 @@ void BuffComponent::RemoveBuffEffect(int32_t id) { destroyable->SetMaxImagination(destroyable->GetMaxImagination() - maxImagination); } else if (parameter.name == "speed") { - const auto speed = parameter.value; - auto* controllablePhysicsComponent = this->GetParent()->GetComponent(); - - if (controllablePhysicsComponent == nullptr) return; - - const auto current = controllablePhysicsComponent->GetSpeedMultiplier(); - - controllablePhysicsComponent->SetSpeedMultiplier(current - ((speed - 500.0f) / 500.0f)); - - EntityManager::Instance()->SerializeEntity(this->GetParent()); + if (!controllablePhysicsComponent) return; + const auto speed = parameter.value; + controllablePhysicsComponent->RemoveSpeedboost(speed); } } } From 85ab573665e8ed17ab1ef4c05b4f707253b53673 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 24 Dec 2022 00:51:59 -0800 Subject: [PATCH 082/166] Fix duping issue (#921) --- dGame/dGameMessages/GameMessages.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c3b86647..26b1bb3c 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4728,13 +4728,13 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit float sellScalar = vend->GetSellScalar(); if (Inventory::IsValidItem(itemComp.currencyLOT)) { - const auto altCurrency = (itemComp.altCurrencyCost * sellScalar) * count; + const auto altCurrency = static_cast(itemComp.altCurrencyCost * sellScalar) * count; inv->AddItem(itemComp.currencyLOT, std::floor(altCurrency), eLootSourceType::LOOT_SOURCE_VENDOR); // Return alt currencies like faction tokens. } //inv->RemoveItem(count, -1, iObjID); inv->MoveItemToInventory(item, eInventoryType::VENDOR_BUYBACK, count, true, false, true); - character->SetCoins(std::floor(character->GetCoins() + ((itemComp.baseValue * sellScalar) * count)), eLootSourceType::LOOT_SOURCE_VENDOR); + character->SetCoins(std::floor(character->GetCoins() + (static_cast(itemComp.baseValue * sellScalar) * count)), eLootSourceType::LOOT_SOURCE_VENDOR); //EntityManager::Instance()->SerializeEntity(player); // so inventory updates GameMessages::SendVendorTransactionResult(entity, sysAddr); } From 1470af99c3454424264f3dcb1e71a1f3332eb20d Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 24 Dec 2022 04:06:27 -0800 Subject: [PATCH 083/166] Correct Property FX incorrect skill cast (#920) --- dScripts/ai/PROPERTY/PropertyFXDamage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dScripts/ai/PROPERTY/PropertyFXDamage.cpp b/dScripts/ai/PROPERTY/PropertyFXDamage.cpp index d12cc9e1..56079384 100644 --- a/dScripts/ai/PROPERTY/PropertyFXDamage.cpp +++ b/dScripts/ai/PROPERTY/PropertyFXDamage.cpp @@ -12,7 +12,7 @@ void PropertyFXDamage::OnCollisionPhantom(Entity* self, Entity* target) { if (skills != nullptr && targetStats != nullptr) { auto targetFactions = targetStats->GetFactionIDs(); if (std::find(targetFactions.begin(), targetFactions.end(), 1) != targetFactions.end()) { - skills->CalculateBehavior(11386, 692, target->GetObjectID()); + skills->CalculateBehavior(692, 11386, target->GetObjectID()); } } } From 5cc7d470743694e21b6960a065fc3fba202ccd2a Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 24 Dec 2022 16:41:13 -0600 Subject: [PATCH 084/166] sanity check on opening packages (#923) --- dGame/dGameMessages/GameMessages.cpp | 6 +-- dGame/dInventory/Item.cpp | 68 +++++++++++++++------------- dGame/dInventory/Item.h | 2 +- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 26b1bb3c..37aeb093 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5763,11 +5763,7 @@ void GameMessages::HandleUseNonEquipmentItem(RakNet::BitStream* inStream, Entity auto* item = inv->FindItemById(itemConsumed); - if (item == nullptr) { - return; - } - - item->UseNonEquip(); + if (item) item->UseNonEquip(item); } void GameMessages::HandleMatchRequest(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 778d8237..a3d4cfc0 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -262,7 +262,7 @@ bool Item::Consume() { return success; } -void Item::UseNonEquip() { +void Item::UseNonEquip(Item* item) { LOT thisLot = this->GetLot(); if (!GetInventory()) { Game::logger->LogDebug("Item", "item %i has no inventory??", this->GetLot()); @@ -292,45 +292,49 @@ void Item::UseNonEquip() { } // This precondition response is taken care of in SpawnPet(). } else { - auto* compRegistryTable = CDClientManager::Instance()->GetTable("ComponentsRegistry"); - const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_PACKAGE); + bool success = false; + auto inventory = item->GetInventory(); + if (inventory && inventory->GetType() == eInventoryType::ITEMS) { + auto* compRegistryTable = CDClientManager::Instance()->GetTable("ComponentsRegistry"); + const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_PACKAGE); - if (packageComponentId == 0) return; + if (packageComponentId == 0) return; - auto* packCompTable = CDClientManager::Instance()->GetTable("PackageComponent"); - auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast(packageComponentId); }); + auto* packCompTable = CDClientManager::Instance()->GetTable("PackageComponent"); + auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast(packageComponentId); }); - auto success = !packages.empty(); - if (success) { - if (this->GetPreconditionExpression()->Check(playerInventoryComponent->GetParent())) { - auto* entityParent = playerInventoryComponent->GetParent(); - // Roll the loot for all the packages then see if it all fits. If it fits, give it to the player, otherwise don't. - std::unordered_map rolledLoot{}; - for (auto& pack : packages) { - auto thisPackage = LootGenerator::Instance().RollLootMatrix(entityParent, pack.LootMatrixIndex); - for (auto& loot : thisPackage) { - // If we already rolled this lot, add it to the existing one, otherwise create a new entry. - auto existingLoot = rolledLoot.find(loot.first); - if (existingLoot == rolledLoot.end()) { - rolledLoot.insert(loot); - } else { - existingLoot->second += loot.second; + auto success = !packages.empty(); + if (success) { + if (this->GetPreconditionExpression()->Check(playerInventoryComponent->GetParent())) { + auto* entityParent = playerInventoryComponent->GetParent(); + // Roll the loot for all the packages then see if it all fits. If it fits, give it to the player, otherwise don't. + std::unordered_map rolledLoot{}; + for (auto& pack : packages) { + auto thisPackage = LootGenerator::Instance().RollLootMatrix(entityParent, pack.LootMatrixIndex); + for (auto& loot : thisPackage) { + // If we already rolled this lot, add it to the existing one, otherwise create a new entry. + auto existingLoot = rolledLoot.find(loot.first); + if (existingLoot == rolledLoot.end()) { + rolledLoot.insert(loot); + } else { + existingLoot->second += loot.second; + } } } - } - if (playerInventoryComponent->HasSpaceForLoot(rolledLoot)) { - LootGenerator::Instance().GiveLoot(playerInventoryComponent->GetParent(), rolledLoot, eLootSourceType::LOOT_SOURCE_CONSUMPTION); - playerInventoryComponent->RemoveItem(lot, 1); + if (playerInventoryComponent->HasSpaceForLoot(rolledLoot)) { + LootGenerator::Instance().GiveLoot(playerInventoryComponent->GetParent(), rolledLoot, eLootSourceType::LOOT_SOURCE_CONSUMPTION); + item->SetCount(item->GetCount() - 1); + } else { + success = false; + } } else { + GameMessages::SendUseItemRequirementsResponse( + playerInventoryComponent->GetParent()->GetObjectID(), + playerInventoryComponent->GetParent()->GetSystemAddress(), + UseItemResponse::FailedPrecondition + ); success = false; } - } else { - GameMessages::SendUseItemRequirementsResponse( - playerInventoryComponent->GetParent()->GetObjectID(), - playerInventoryComponent->GetParent()->GetSystemAddress(), - UseItemResponse::FailedPrecondition - ); - success = false; } } Game::logger->LogDebug("Item", "Player %llu %s used item %i", playerEntity->GetObjectID(), success ? "successfully" : "unsuccessfully", thisLot); diff --git a/dGame/dInventory/Item.h b/dGame/dInventory/Item.h index bb8316d7..6993a0ba 100644 --- a/dGame/dInventory/Item.h +++ b/dGame/dInventory/Item.h @@ -195,7 +195,7 @@ public: /** * Uses this item if its non equip, essentially an interface for the linked GM */ - void UseNonEquip(); + void UseNonEquip(Item* item); /** * Disassembles the part LOTs of this item back into the inventory, if it has any From e41ed684475db90a59e1d70fc31ab2d7b39ac1b8 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 28 Dec 2022 13:58:53 -0800 Subject: [PATCH 085/166] Update README (#806) * Update README The README is very out of date, the following changes have been made - Update what the file tree should look like - Remove client Avant Gardens Survival script fix - Update some incorrect commands or commands that were missing packages. - Add packed client setup instructions - Add *config.ini setup instructions - Describe what configs should be modified and what you may want to change - More detail in the verify step - Change Account Manager link to Nexus Dashboard - Remove table of commands and reference Commands.md instead - Specify that UGCSERVERIP may need to be changed to localhost as well * Fix Avant Gardens Survival This addresses the Avant Gardens Survival bug. Squeezing it in with the README changes since it is a small change. * Remove Locale * Update README.md Co-authored-by: Jonathan Romano * Remove dLocale again? * Saving for the night * Revert "Fix Avant Gardens Survival" This reverts commit b1a1ce2d84e870c328a039673c9b77859e6e3dbd. * Update Mission.cpp * Update README.md Move comments and add pre-processor define Update README.md Update README.md Update CMakePresets.json Update CMakeVariables.txt Update README.md i love readmes Update README.md Update README.md Update README.md Update README.md Update README.md Update README.md Update README.md * Update README.md Co-authored-by: Daniel Seiler * Address feedback * Update README.md * Update Database.cpp * Update README.md * Revert tcp specification Co-authored-by: Jonathan Romano Co-authored-by: Aaron Kimbrell Co-authored-by: Daniel Seiler --- CMakePresets.json | 5 +- CMakeVariables.txt | 14 +- README.md | 587 +++++++++++++++++++-------------------------- docs/Commands.md | 4 +- 4 files changed, 257 insertions(+), 353 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 3968b3ce..f8170755 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -23,10 +23,7 @@ "name": "ci-macos-11", "displayName": "CI configure step for MacOS", "description": "Same as default, Used in GitHub actions workflow", - "inherits": "default", - "cacheVariables": { - "OPENSSL_ROOT_DIR": "/usr/local/opt/openssl@3/" - } + "inherits": "default" }, { "name": "ci-windows-2022", diff --git a/CMakeVariables.txt b/CMakeVariables.txt index 94e9cd20..d3c8b36f 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -8,15 +8,17 @@ LICENSE=AGPL-3.0 # 171022 - Unmodded client NET_VERSION=171022 # Debugging -__dynamic=1 # Set __dynamic to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs. -# __ggdb=1 +__dynamic=1 # Set __ggdb to 1 to enable the -ggdb flag for the linker, including more debug info. -# __include_backtrace__=1 +# __ggdb=1 # Set __include_backtrace__ to 1 to includes the backtrace library for better crashlogs. -# __compile_backtrace__=1 +# __include_backtrace__=1 # Set __compile_backtrace__ to 1 to compile the backtrace library instead of using system libraries. -__maria_db_connector_compile_jobs__=1 +# __compile_backtrace__=1 # Set to the number of jobs (make -j equivalent) to compile the mariadbconn files with. -__enable_testing__=1 +__maria_db_connector_compile_jobs__=1 # When set to 1 and uncommented, compiling and linking testing folders and libraries will be done. +__enable_testing__=1 +# The path to OpenSSL. Change this if your OpenSSL install path is different than the default. +OPENSSL_ROOT_DIR=/usr/local/opt/openssl@3/ diff --git a/README.md b/README.md index bd9dd6b7..27de7d6d 100644 --- a/README.md +++ b/README.md @@ -18,210 +18,188 @@ Darkflame Universe is licensed under AGPLv3, please read [LICENSE](LICENSE). Som Throughout the entire build and setup process a level of familiarity with the command line and preferably a Unix-like development environment is greatly advantageous. ### Hosting a server -We do not recommend hosting public servers. DLU is intended for small scale deployment, for example within a group of friends. It has not been tested for large scale deployment which comes with additional security risks. +We do not recommend hosting public servers. Darkflame Universe is intended for small scale deployment, for example within a group of friends. It has not been tested for large scale deployment which comes with additional security risks. ### Supply of resource files -Darkflame Universe is a server emulator and does not distribute any LEGO® Universe files. A separate game client is required to setup this server emulator and play the game, which we cannot supply. Users are strongly suggested to refer to the safe checksums listed in the resources tab below when checking if a client will work. +Darkflame Universe is a server emulator and does not distribute any LEGO® Universe files. A separate game client is required to setup this server emulator and play the game, which we cannot supply. Users are strongly suggested to refer to the safe checksums listed [here](#verifying-your-client-files) to see if a client will work. -## Build -Development of the latest iteration of Darkflame Universe has been done primarily in a Unix-like environment and is where it has been tested and designed for deployment. It is therefore highly recommended that Darkflame Universe be built and deployed using a Unix-like environment for the most streamlined experience. +## Steps to setup server +* [Clone this repository](#clone-the-repository) +* [Install dependencies](#install-dependencies) +* [Database setup](#database-setup) +* [Build the server](#build-the-server) +* [Configuring your server](#configuring-your-server) + * [Required Configuration](#required-configuration) + * [Optional Configuration](#optional-configuration) +* [Verify your setup](#verify-your-setup) +* [Running the server](#running-the-server) +* [User Guide](#user-guide) -### Prerequisites -#### Clone the repository +## Clone the repository +If you are on Windows, you will need to download and install git from [here](https://git-scm.com/download/win) + +Then run the following command ```bash git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer ``` -#### Python -Some tools utilized to streamline the setup process require Python 3, make sure you have it installed. +## Install dependencies +### Windows packages +Ensure that you have either the [MSVC C++ compiler](https://visualstudio.microsoft.com/vs/features/cplusplus/) (recommended) or the [Clang compiler](https://github.com/llvm/llvm-project/releases/) installed. +You'll also need to download and install [CMake](https://cmake.org/download/) (version **CMake version 3.18** or later!). -### Choosing the right version for your client -DLU clients identify themselves using a higher version number than the regular live clients out there. -This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client. +### MacOS packages +Ensure you have [brew](https://brew.sh) installed. +You will need to install the following packages +```bash +brew install cmake gcc mariadb openssl zlib +``` -If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number. +### Linux packages +Make sure packages like `gcc`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required as well as `openssl`. You will also need a MySQL database solution to use. We recommend using `mariadb-server`. -### Enabling testing -While it is highly recommended to enable testing, if you would like to save compilation time, you'll want to comment out the enable_testing variable in CMakeVariables.txt. -It is recommended that after building and if testing is enabled, to run `ctest` and make sure all the tests pass. +For Ubuntu, you would run the following commands. On other systems, the package install command will differ. -### Using Docker -Refer to [Docker.md](/Docker.md). +```bash +sudo apt update && sudo apt upgrade -For Windows, refer to [Docker_Windows.md](/Docker_Windows.md). +# Install packages +sudo apt install build-essential gcc zlib1g-dev libssl-dev openssl mariadb-server cmake +``` -### Linux builds -Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required as well as `openssl`. +#### Required CMake version +This project uses **CMake version 3.18** or higher and as such you will need to ensure you have this version installed. +You can check your CMake version by using the following command in a terminal. +```bash +cmake --version +``` -CMake must be version 3.14 or higher! +If you are going to be using an Ubuntu environment to run the server, you may need to get a more recent version of `cmake` than the packages available may provide. -#### Build the repository +The general approach to do so would be to obtain a copy of the signing key and then add the CMake repository to your apt. +You can do so with the following commands. +[Source of the below commands](https://askubuntu.com/questions/355565/how-do-i-install-the-latest-version-of-cmake-from-the-command-line) + +```bash +# Remove the old version of CMake +sudo apt purge --auto-remove cmake + +# Prepare for installation +sudo apt update && sudo apt install -y software-properties-common lsb-release && sudo apt clean all + +# Obtain a copy of the signing key +wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null + +# Add the repository to your sources list. +sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" + +# Next you'll want to ensure that Kitware's keyring stays up to date +sudo apt update +sudo apt install kitware-archive-keyring +sudo rm /etc/apt/trusted.gpg.d/kitware.gpg + +# If sudo apt update above returned an error, copy the public key at the end of the error message and run the following command +# if the error message was "The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 6AF7F09730B3F0A4" +# then the below command would be "sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6AF7F09730B3F0A4" +sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys + +# Finally update and install +sudo apt update +sudo apt install cmake +``` + +## Database setup +First you'll need to start MariaDB. + +For Windows the service is always running by default. + +For MacOS, run the following command +```bash +brew services start mariadb +``` + +For Linux, run the following command +```bash +sudo systemctl start mysql +# If systemctl is not a known command on your distribution, try the following instead +sudo service mysql start +``` + +**You will need to run this command every time you restart your environment** + +If you are using Linux and `systemctl` and want the MariaDB instance to start on startup, run the following command +```bash +sudo systemctl enable --now mysql +``` + +Once MariaDB is started, you'll need to create a user and an empty database for Darkflame Universe to use. + +First, login to the MariaDB instance. + +To do this on Ubuntu/Linux, MacOS, or another Unix like operating system, run the following command in a terminal +```bash +# Logs you into the MariaDB instance as root +sudo mysql +``` + +For Windows, run the following command in the `Command Prompt (MariaDB xx.xx)` terminal +```bash +# Logs you into the mysql instance +mysql -u root -p +# You will then be prompted for the password you set for root during installation of MariaDB +``` + +Now that you are logged in, run the following commands. + +```bash +# Creates a user for this computer which uses a password and grant said user all privileges. +# Change mydarkflameuser to a custom username and password to a custom password. +GRANT ALL ON *.* TO 'mydarkflameuser'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; +FLUSH PRIVILEGES; + +# Then create a database for Darkflame Universe to use. +CREATE DATABASE darkflame; +``` + +## Build the server You can either run `build.sh` when in the root folder of the repository: ```bash ./build.sh ``` -Or manually run the commands used in `build.sh`: +Or manually run the commands used in [build.sh](build.sh). -```bash -# Create the build directory, preserving it if it already exists -mkdir -p build -cd build +### Notes +Depending on your operating system, you may need to adjust some pre-processor defines in [CMakeVariables.txt](./CMakeVariables.txt) before building: +* If you are on MacOS, ensure OPENSSL_ROOT_DIR is pointing to the openssl root directory. +* If you are using a Darkflame Universe client, ensure NET_VERSION is changed to 171023. -# Run CMake to generate make files -cmake .. +## Configuring your server +This server has a few steps that need to be taken to configure the server for your use case. -# To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8' -cmake --build . --config Release -``` +### Required Configuration +Darkflame Universe can run with either a packed or an unpacked client. +Navigate to `build/sharedconfig.ini` and fill in the following fields: +* `mysql_host` (This is the IP address or hostname of your MariaDB server. This is highly likely `localhost`) + * If you setup your MariaDB instance on a port other than 3306, which can be done on a Windows install, you will need to make this value `tcp://localhost:portNum` where portNum is replaced with the port you chose to run MariaDB on. +* `mysql_database` (This is the database you created for the server) +* `mysql_username` (This is the user you created for the server) +* `mysql_password` (This is the password for the user you created for the server) +* `client_location` (This is the location of the client files. This should be the folder path of a packed or unpacked client) + * Ideally the path to the client should not contain any spaces. -### MacOS builds -Ensure `cmake`, `zlib` and `open ssl` are installed as well as a compiler (e.g `clang` or `gcc`). - -In the repository root folder run the following. Ensure -DOPENSSL_ROOT_DIR=/path/to/openssl points to your openssl install location -```bash -# Create the build directory, preserving it if it already exists -mkdir -p build -cd build - -# Run CMake to generate build files -cmake .. -DOPENSSL_ROOT_DIR=/path/to/openssl - -# Get cmake to build the project. If make files are being used then using make and appending `-j` and the amount of cores to utilize may be preferable, for example `make -j8` -cmake --build . --config Release -``` - -### Windows builds (native) -Ensure that you have either the [MSVC](https://visualstudio.microsoft.com/vs/) or the [Clang](https://github.com/llvm/llvm-project/releases/) (recommended) compiler installed. You will also need to install [CMake](https://cmake.org/download/). Currently on native Windows the server will only work in Release mode. - -#### Build the repository -```batch -:: Create the build directory -mkdir build -cd build - -:: Run CMake to generate make files -cmake .. - -:: Run CMake with build flag to build -cmake --build . --config Release -``` -#### Windows for ARM has not been tested but should build by doing the following -```batch -:: Create the build directory -mkdir build -cd build - -:: Run CMake to generate make files -cmake .. -DMARIADB_BUILD_SOURCE=ON - -:: Run CMake with build flag to build -cmake --build . --config Release -``` - -### Windows builds (WSL) -This section will go through how to install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) and building in a Linux environment under Windows. WSL requires Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11. - -#### Open the Command Prompt application with Administrator permissions and run the following: -```bash -# Installing Windows Subsystem for Linux -wsl --install -``` - -#### Open the Ubuntu application and run the following: -```bash -# Make sure the install is up to date -apt update && apt upgrade - -# Make sure the gcc, cmake, and build-essentials are installed -sudo apt install gcc -sudo apt install cmake -sudo apt install build-essential -``` - -[**Follow the Linux instructions**](#linux-builds) - -### ARM builds -AArch64 builds should work on linux and MacOS using their respective build steps. Windows ARM should build but it has not been tested - -### Updating your build -To update your server to the latest version navigate to your cloned directory -```bash -cd /path/to/DarkflameServer -``` -run the following commands to update to the latest changes -```bash -git pull -git submodule update --init --recursive -``` -now follow the build section for your system - -## Setting up the environment - -### Resources - -#### LEGO® Universe 1.10.64 - -This repository does not distribute any LEGO® Universe files. A full install of LEGO® Universe version 1.10.64 (latest) is required to finish setting up Darkflame Universe. - -Known good SHA256 checksums of the client: -- `8f6c7e84eca3bab93232132a88c4ae6f8367227d7eafeaa0ef9c40e86c14edf5` (packed client, rar compressed) -- `c1531bf9401426042e8bab2de04ba1b723042dc01d9907c2635033d417de9e05` (packed client, includes extra locales, rar compressed) -- `0d862f71eedcadc4494c4358261669721b40b2131101cbd6ef476c5a6ec6775b` (unpacked client, includes extra locales, rar compressed) - -Known good *SHA1* checksum of the DLU client: -- `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed) - -How to generate a SHA256 checksum: -```bash -# Replace with the file path to the client - -# If on Linux or MacOS -shasum -a 256 - -# If on Windows -certutil -hashfile SHA256 -``` - -#### Unpacking the client -* Clone lcdr's utilities repository [here](https://github.com/lcdr/utils) -* Use `pkextractor.pyw` to unpack the client files if they are not already unpacked - -#### Setup resource directory -* In the `build` directory create a `res` directory if it does not already exist. -* Copy over or create symlinks from `macros`, `BrickModels`, `chatplus_en_us.txt`, `names`, and `maps` in your client `res` directory to the server `build/res` directory -* Unzip the navmeshes [here](./resources/navmeshes.zip) and place them in `build/res/maps/navmeshes` - -#### Setup locale -* In the `build` directory create a `locale` directory if it does not already exist -* Copy over or create symlinks from `locale.xml` in your client `locale` directory to the `build/locale` directory - -#### Client database -* Move the file `res/cdclient.fdb` from the unpacked client to the `build/res` folder on the server. -* The server will automatically copy and convert the file from fdb to sqlite should `CDServer.sqlite` not already exist. -* You can also convert the database manually using `fdb_to_sqlite.py` using lcdr's utilities. Just make sure to rename the file to `CDServer.sqlite` instead of `cdclient.sqlite`. -* Migrations to the database are automatically run on server start. When migrations are needed to be ran, the server may take a bit longer to start. - -### Database -Darkflame Universe utilizes a MySQL/MariaDB database for account and character information. - -Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running. - -* All that you need to do is create a database to connect to. As long as the server can connect to the database, the schema will always be kept up to date when you start the server. - -#### Configuration - -After the server has been built there should be four `ini` files in the build director: `sharedconfig.ini`, `authconfig.ini`, `chatconfig.ini`, `masterconfig.ini`, and `worldconfig.ini`. Go through them and fill in the database credentials and configure other settings if necessary. - -#### Migrations - -The database is automatically setup and migrated to what it should look like for the latest commit whenever you start the server. - -#### Verify +### Optional Configuration +* After the server has been built there should be five `ini` files in the build directory: `sharedconfig.ini`, `authconfig.ini`, `chatconfig.ini`, `masterconfig.ini`, and `worldconfig.ini`. +* `authconfig.ini` contains an option to enable or disable play keys on your server. Do not change the default port for auth. +* `chatconfig.ini` contains a port option. +* `masterconfig.ini` contains options related to permissions you want to run your servers with. +* `sharedconfig.ini` contains several options that are shared across all servers +* `worldconfig.ini` contains several options to turn on QOL improvements should you want them. If you would like the most vanilla experience possible, you will need to turn some of these settings off. +## Verify your setup Your build directory should now look like this: * AuthServer * ChatServer @@ -230,42 +208,35 @@ Your build directory should now look like this: * authconfig.ini * chatconfig.ini * masterconfig.ini +* sharedconfig.ini * worldconfig.ini -* **locale/** - * locale.xml -* **res/** - * cdclient.fdb - * chatplus_en_us.txt - * **macros/** - * ... - * **BrickModels/** - * ... - * **maps/** - * **navmeshes/** - * ... - * ... * ... ## Running the server -If everything has been configured correctly you should now be able to run the `MasterServer` binary. Darkflame Universe utilizes port numbers under 1024, so under Linux you either have to give the binary network permissions or run it under sudo. +If everything has been configured correctly you should now be able to run the `MasterServer` binary which is located in the `build` directory. Darkflame Universe utilizes port numbers under 1024, so under Linux you either have to give the `AuthServer` binary network permissions or run it under sudo. +To give `AuthServer` network permissions and not require sudo, run the following command +```bash +sudo setcap 'cap_net_bind_service=+ep' AuthServer +``` +and then go to `build/masterconfig.ini` and change `use_sudo_auth` to 0. ### First admin user Run `MasterServer -a` to get prompted to create an admin account. This method is only intended for the system administrator as a means to get started, do NOT use this method to create accounts for other users! -### Account Manager +### Account management tool (Nexus Dashboard) +**If you are just using this server for yourself, you can skip setting up Nexus Dashboard** -Follow the instructions [here](https://github.com/DarkflameUniverse/AccountManager) to setup the DLU account management Python web application. This is the intended way for users to create accounts. +Follow the instructions [here](https://github.com/DarkflameUniverse/NexusDashboard) to setup the DLU Nexus Dashboard web application. This is the intended way for users to create accounts and the intended way for moderators to approve names/pets/properties and do other moderation actions. ### Admin levels +The admin level, or Game Master level (hereafter referred to as gmlevel), is specified in the `accounts.gm_level` column in the MySQL database. Normal players should have this set to `0`, which comes with no special privileges. The system administrator will have this set to `9`, which comes will all privileges. gmlevel `8` should be used to give a player a majority of privileges without the safety critical once. -The admin level, or game master level, is specified in the `accounts.gm_level` column in the MySQL database. Normal players should have this set to `0`, which comes with no special privileges. The system administrator will have this set to `9`, which comes will all privileges. Admin level `8` should be used to give a player a majority of privileges without the safety critical once. +While a character has a gmlevel of anything but `0`, some gameplay behavior will change. When testing gameplay, you should always use a character with a gmlevel of `0`. -While a character has a gmlevel of anything but 0, some gameplay behavior will change. When testing gameplay, you should always use a character with a gmlevel of 0. +# User guide +Some changes to the client `boot.cfg` file are needed to play on your server. -## User guide -A few modifications have to be made to the client. - -### Client configuration +## Allowing a user to connect to your server To connect to a server follow these steps: * In the client directory, locate `boot.cfg` * Open it in a text editor and locate where it says `AUTHSERVERIP=0:` @@ -273,155 +244,89 @@ To connect to a server follow these steps: * Launch `legouniverse.exe`, through `wine` if on a Unix-like operating system * Note that if you are on WSL2, you will need to configure the public IP in the server and client to be the IP of the WSL2 instance and not localhost, which can be found by running `ifconfig` in the terminal. Windows defaults to WSL1, so this will not apply to most users. -### Brick-By-Brick building +## Brick-By-Brick building +Should you choose to do any brick building, you will want to have some form of a http server that returns a 404 error since we are unable to emulate live User Generated Content at the moment. If you attempt to do any brick building without a 404 server running properly, you will be unable to load into your game. Python is the easiest way to do this, but any thing that returns a 404 should work fine. +* Note: the client hard codes this request on port 80. -Brick-By-Brick building requires `PATCHSERVERIP=0:` in the `boot.cfg` to point to a HTTP server which always returns `HTTP 404 - Not Found` for all requests. This can be achieved by pointing it to `localhost` while having `sudo python -m http.server 80` running in the background. +**If you do not plan on doing any Brick Building, then you can skip this step.** -### In-game commands -Here is a summary of the commands available in-game. All commands are prefixed by `/` and typed in the in-game chat window. Some commands requires admin privileges. Operands within `<>` are required, operands within `()` are not. For the full list of in-game commands, please checkout [the source file](./dGame/dUtilities/SlashCommandHandler.cpp). +The easiest way to do this is to install [python](https://www.python.org/downloads/). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Command - - Usage - - Description - - Admin Level Requirement -
- info - - /info - - Displays server info to the user, including where to find the server's source code. - -
- credits - - /credits - - Displays the names of the people behind Darkflame Universe. - -
- instanceinfo - - /instanceinfo - - Displays in the chat the current zone, clone, and instance id. - -
- gmlevel - - /gmlevel <level> - - Within the authorized range of levels for the current account, changes the character's game master level to the specified value. This is required to use certain commands. - -
- testmap - - /testmap <zone> (clone-id) - - Transfers you to the given zone by id and clone id. - - 1 -
- ban - - /ban <username> - - Bans a user from the server. - - 4 -
- gmadditem - - /gmadditem <id> (count) - - Adds the given item to your inventory by id. - - 8 -
- spawn - - /spawn <id> - - Spawns an object at your location by id. - - 8 -
- metrics - - /metrics - - Prints some information about the server's performance. - - 8 -
+### Allowing a user to build in Brick-by-Brick mode +Brick-By-Brick building requires `PATCHSERVERIP=0:` and `UGCSERVERIP=0:` in the `boot.cfg` to point to a HTTP server which always returns `HTTP 404 - Not Found` for all requests. This can be most easily achieved by pointing both of those variables to `localhost` while having running in the background. +Each client must have their own 404 server running if they are using a locally hosted 404 server. +```bash +# If on linux run this command. Because this is run on a port below 1024, binary network permissions are needed. +sudo python3 -m http.server 80 + +# If on windows one of the following will work when run through Powershell or Command Prompt assuming python is installed +python3 -m http.server 80 +python http.server 80 +py -m http.server 80 +``` + +## Updating your server +To update your server to the latest version navigate to your cloned directory +```bash +cd path/to/DarkflameServer +``` +Run the following commands to update to the latest changes +```bash +git pull +git submodule update --init --recursive +``` +Now follow the [build](#build-the-server) section for your system and your server is up to date. + +## In-game commands +* A list of all in-game commands can be found [here](./docs/Commands.md). + +## Verifying your client files + +### LEGO® Universe 1.10.64 +To verify that you are indeed using a LEGO® Universe 1.10.64 client, make sure you have the full client compressed **in a rar file** and run the following command. +```bash +# Replace with the file path to the zipped client + +# If on Linux or MacOS +shasum -a 256 + +# If on Windows using the Command Prompt +certutil -hashfile SHA256 +``` + +Below are known good SHA256 checksums of the client: +* `8f6c7e84eca3bab93232132a88c4ae6f8367227d7eafeaa0ef9c40e86c14edf5` (packed client, rar compressed) +* `c1531bf9401426042e8bab2de04ba1b723042dc01d9907c2635033d417de9e05` (packed client, includes extra locales, rar compressed) +* `0d862f71eedcadc4494c4358261669721b40b2131101cbd6ef476c5a6ec6775b` (unpacked client, includes extra locales, rar compressed) + +If the returned hash matches one of the lines above then you can continue with setting up the server. If you are using a fully downloaded and complete client from live, then it will work, but the hash above may not match. Otherwise you must obtain a full install of LEGO® Universe 1.10.64. + +### Darkflame Universe Client +Darkflame Universe clients identify themselves using a higher version number than the regular live clients out there. +This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client. + +To verify that you are indeed using a Darkflame Universe client, make sure you have the full client compressed **in a zip file** and run the following command. + +```bash +# Replace with the file path to the zipped client + +# If on Linux or MacOS +shasum -a 1 + +# If on Windows using the Command Prompt +certutil -hashfile SHA1 +``` + +Known good *SHA1* checksum of the Darkflame Universe client: +- `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed) + +# Development Documentation +This is a Work in Progress, but below are some quick links to documentaion for systems and structs in the server +[Networked message structs](https://lcdruniverse.org/lu_packets/lu_packets/index.html) +[General system documentation](https://docs.lu-dev.net/en/latest/index.html) # Credits + ## DLU Team * [DarwinAnim8or](https://github.com/DarwinAnim8or) * [Wincent01](https://github.com/Wincent01) diff --git a/docs/Commands.md b/docs/Commands.md index 7a15bf37..060c2ba0 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -1,6 +1,5 @@ # In-game commands - -Here is a summary of the commands available in-game. All commands are prefixed by `/` and typed in the in-game chat window. Some commands requires admin privileges. Operands within `<>` are required, operands within `()` are not. For the full list of in-game commands, please checkout [the source file](../dGame/dUtilities/SlashCommandHandler.cpp). +* All commands are prefixed by `/` and typed in the in-game chat window. Some commands require elevated gmlevel privileges. Operands within `<>` are required, operands within `()` are not. ## General Commands @@ -71,6 +70,7 @@ These commands are primarily for development and testing. The usage of many of t |createprivate|`/createprivate `|Creates a private zone with password.|8| |debugui|`/debugui`|Toggle Debug UI.|8| |dismount|`/dismount`|Dismounts you from the vehicle or mount.|8| +|reloadconfig|`/reloadconfig`|Reloads the server with the new config values.|8| |force-save|`/force-save`|While saving to database usually happens on regular intervals and when you disconnect from the server, this command saves your player's data to the database.|8| |freecam|`/freecam`|Toggles freecam mode.|8| |freemoney|`/freemoney `|Gives coins.|8| From 0e9c0a8917f3afbcfda452ab9e8c66504aad15d9 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 28 Dec 2022 14:03:07 -0800 Subject: [PATCH 086/166] Fix MovementSwitch Behavior (#927) --- dGame/dBehaviors/MovementSwitchBehavior.cpp | 55 ++++++++++++--------- dGame/dBehaviors/MovementSwitchBehavior.h | 13 ++++- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/dGame/dBehaviors/MovementSwitchBehavior.cpp b/dGame/dBehaviors/MovementSwitchBehavior.cpp index c893e6e1..0c11380f 100644 --- a/dGame/dBehaviors/MovementSwitchBehavior.cpp +++ b/dGame/dBehaviors/MovementSwitchBehavior.cpp @@ -4,17 +4,17 @@ #include "dLogger.h" void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - if (this->m_groundAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && - this->m_jumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && - this->m_fallingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && - this->m_doubleJumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && - this->m_airAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && - this->m_jetpackAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) { - return; - } - uint32_t movementType{}; if (!bitStream->Read(movementType)) { + if (this->m_groundAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && + this->m_jumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && + this->m_fallingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && + this->m_doubleJumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && + this->m_airAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && + this->m_jetpackAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && + this->m_movingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) { + return; + } Game::logger->Log("MovementSwitchBehavior", "Unable to read movementType from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); return; }; @@ -27,33 +27,40 @@ void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* this->m_jumpAction->Handle(context, bitStream, branch); break; case 3: - this->m_fallingAction->Handle(context, bitStream, branch); + this->m_airAction->Handle(context, bitStream, branch); break; case 4: this->m_doubleJumpAction->Handle(context, bitStream, branch); break; case 5: - this->m_airAction->Handle(context, bitStream, branch); + this->m_fallingAction->Handle(context, bitStream, branch); break; case 6: this->m_jetpackAction->Handle(context, bitStream, branch); break; default: - Game::logger->Log("MovementSwitchBehavior", "Invalid movement behavior type (%i)!", movementType); + this->m_groundAction->Handle(context, bitStream, branch); break; } } -void MovementSwitchBehavior::Load() { - this->m_airAction = GetAction("air_action"); - - this->m_doubleJumpAction = GetAction("double_jump_action"); - - this->m_fallingAction = GetAction("falling_action"); - - this->m_groundAction = GetAction("ground_action"); - - this->m_jetpackAction = GetAction("jetpack_action"); - - this->m_jumpAction = GetAction("jump_action"); +Behavior* MovementSwitchBehavior::LoadMovementType(std::string movementType) { + float actionValue = GetFloat(movementType, -1.0f); + auto loadedBehavior = GetAction(actionValue != -1.0f ? actionValue : 0.0f); + if (actionValue == -1.0f && loadedBehavior->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) { + loadedBehavior = this->m_groundAction; + } + return loadedBehavior; +} + +void MovementSwitchBehavior::Load() { + float groundActionValue = GetFloat("ground_action", -1.0f); + this->m_groundAction = GetAction(groundActionValue != -1.0f ? groundActionValue : 0.0f); + + this->m_airAction = LoadMovementType("air_action"); + this->m_doubleJumpAction = LoadMovementType("double_jump_action"); + this->m_fallingAction = LoadMovementType("falling_action"); + this->m_jetpackAction = LoadMovementType("jetpack_action"); + this->m_jumpAction = LoadMovementType("jump_action"); + this->m_movingAction = LoadMovementType("moving_action"); } diff --git a/dGame/dBehaviors/MovementSwitchBehavior.h b/dGame/dBehaviors/MovementSwitchBehavior.h index 82e1a9e9..e6ff96f6 100644 --- a/dGame/dBehaviors/MovementSwitchBehavior.h +++ b/dGame/dBehaviors/MovementSwitchBehavior.h @@ -3,7 +3,7 @@ class MovementSwitchBehavior final : public Behavior { -public: +private: /* * Members */ @@ -19,6 +19,17 @@ public: Behavior* m_jumpAction; + Behavior* m_movingAction; + + /** + * @brief Loads a movement type from the database into a behavior + * + * @param movementType The movement type to lookup in the database + * @param behaviorToLoad The Behavior where the result will be stored + */ + Behavior* LoadMovementType(std::string movementType); + +public: /* * Inherited */ From 99c0ca253cb587f3f43b440d39f9ce331748f62a Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 28 Dec 2022 14:04:37 -0800 Subject: [PATCH 087/166] Basic Attack Behavior Live Accuracy Improvements (#926) * Overhaul BasicAttack Behavior so it matches the live 1.10.64 client --- dCommon/dEnums/eBasicAttackSuccessTypes.h | 12 ++ dGame/dBehaviors/BasicAttackBehavior.cpp | 232 +++++++++++++++------- dGame/dBehaviors/BasicAttackBehavior.h | 39 ++++ 3 files changed, 206 insertions(+), 77 deletions(-) create mode 100644 dCommon/dEnums/eBasicAttackSuccessTypes.h diff --git a/dCommon/dEnums/eBasicAttackSuccessTypes.h b/dCommon/dEnums/eBasicAttackSuccessTypes.h new file mode 100644 index 00000000..8c06da8a --- /dev/null +++ b/dCommon/dEnums/eBasicAttackSuccessTypes.h @@ -0,0 +1,12 @@ +#ifndef __EBASICATTACKSUCCESSTYPES__H__ +#define __EBASICATTACKSUCCESSTYPES__H__ + +#include + +enum class eBasicAttackSuccessTypes : uint8_t { + SUCCESS = 1, + FAILARMOR, + FAILIMMUNE +}; + +#endif //!__EBASICATTACKSUCCESSTYPES__H__ diff --git a/dGame/dBehaviors/BasicAttackBehavior.cpp b/dGame/dBehaviors/BasicAttackBehavior.cpp index f166f00c..0378cb5e 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.cpp +++ b/dGame/dBehaviors/BasicAttackBehavior.cpp @@ -5,7 +5,7 @@ #include "EntityManager.h" #include "DestroyableComponent.h" #include "BehaviorContext.h" - +#include "eBasicAttackSuccessTypes.h" void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { if (context->unmanaged) { @@ -31,130 +31,120 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi } Game::logger->LogDebug("BasicAttackBehavior", "Number of allocated bits %i", allocatedBits); const auto baseAddress = bitStream->GetReadOffset(); + + DoHandleBehavior(context, bitStream, branch); + + bitStream->SetReadOffset(baseAddress + allocatedBits); +} + +void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target); + if (!targetEntity) { + Game::logger->Log("BasicAttackBehavior", "Target targetEntity %i not found.", branch.target); + return; + } + + auto* destroyableComponent = targetEntity->GetComponent(); + if (!destroyableComponent) { + Game::logger->Log("BasicAttackBehavior", "No destroyable found on the obj/lot %llu/%i", branch.target, targetEntity->GetLOT()); + return; + } + bool isBlocked{}; bool isImmune{}; bool isSuccess{}; if (!bitStream->Read(isBlocked)) { - Game::logger->LogDebug("BasicAttackBehavior", "Unable to read isBlocked"); + Game::logger->Log("BasicAttackBehavior", "Unable to read isBlocked"); return; } - if (isBlocked) return; + if (isBlocked) { + destroyableComponent->SetAttacksToBlock(std::min(destroyableComponent->GetAttacksToBlock() - 1, 0U)); + EntityManager::Instance()->SerializeEntity(targetEntity); + this->m_OnFailBlocked->Handle(context, bitStream, branch); + return; + } if (!bitStream->Read(isImmune)) { - Game::logger->LogDebug("BasicAttackBehavior", "Unable to read isImmune"); + Game::logger->Log("BasicAttackBehavior", "Unable to read isImmune"); return; } - if (isImmune) return; + if (isImmune) { + this->m_OnFailImmune->Handle(context, bitStream, branch); + return; + } - if (bitStream->Read(isSuccess) && isSuccess) { // Success - uint32_t unknown{}; - if (!bitStream->Read(unknown)) { - Game::logger->LogDebug("BasicAttackBehavior", "Unable to read unknown"); + if (!bitStream->Read(isSuccess)) { + Game::logger->Log("BasicAttackBehavior", "failed to read success from bitstream"); + return; + } + + if (isSuccess) { + uint32_t armorDamageDealt{}; + if (!bitStream->Read(armorDamageDealt)) { + Game::logger->Log("BasicAttackBehavior", "Unable to read armorDamageDealt"); return; } - uint32_t damageDealt{}; - if (!bitStream->Read(damageDealt)) { - Game::logger->LogDebug("BasicAttackBehavior", "Unable to read damageDealt"); + uint32_t healthDamageDealt{}; + if (!bitStream->Read(healthDamageDealt)) { + Game::logger->Log("BasicAttackBehavior", "Unable to read healthDamageDealt"); return; } - // A value that's too large may be a cheating attempt, so we set it to MIN too - if (damageDealt > this->m_MaxDamage || damageDealt < this->m_MinDamage) { - damageDealt = this->m_MinDamage; + uint32_t totalDamageDealt = armorDamageDealt + healthDamageDealt; + + // A value that's too large may be a cheating attempt, so we set it to MIN + if (totalDamageDealt > this->m_MaxDamage) { + totalDamageDealt = this->m_MinDamage; } - auto* entity = EntityManager::Instance()->GetEntity(branch.target); bool died{}; if (!bitStream->Read(died)) { - Game::logger->LogDebug("BasicAttackBehavior", "Unable to read died"); + Game::logger->Log("BasicAttackBehavior", "Unable to read died"); return; } - - if (entity != nullptr) { - auto* destroyableComponent = entity->GetComponent(); - if (destroyableComponent != nullptr) { - PlayFx(u"onhit", entity->GetObjectID()); - destroyableComponent->Damage(damageDealt, context->originator, context->skillID); - } - } + auto previousArmor = destroyableComponent->GetArmor(); + auto previousHealth = destroyableComponent->GetHealth(); + PlayFx(u"onhit", targetEntity->GetObjectID()); + destroyableComponent->Damage(totalDamageDealt, context->originator, context->skillID); } uint8_t successState{}; if (!bitStream->Read(successState)) { - Game::logger->LogDebug("BasicAttackBehavior", "Unable to read success state"); + Game::logger->Log("BasicAttackBehavior", "Unable to read success state"); return; } - switch (successState) { - case 1: + switch (static_cast(successState)) { + case eBasicAttackSuccessTypes::SUCCESS: this->m_OnSuccess->Handle(context, bitStream, branch); break; + case eBasicAttackSuccessTypes::FAILARMOR: + this->m_OnFailArmor->Handle(context, bitStream, branch); + break; default: - Game::logger->LogDebug("BasicAttackBehavior", "Unknown success state (%i)!", successState); + if (static_cast(successState) != eBasicAttackSuccessTypes::FAILIMMUNE) { + Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState); + return; + } + this->m_OnFailImmune->Handle(context, bitStream, branch); break; } - - bitStream->SetReadOffset(baseAddress + allocatedBits); } void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* self = EntityManager::Instance()->GetEntity(context->originator); - if (self == nullptr) { - Game::logger->LogDebug("BasicAttackBehavior", "Invalid self entity (%llu)!", context->originator); - return; - } - bitStream->AlignWriteToByteBoundary(); const auto allocatedAddress = bitStream->GetWriteOffset(); - bitStream->Write(uint16_t(0)); + bitStream->Write(0); const auto startAddress = bitStream->GetWriteOffset(); - bitStream->Write0(); // Blocked - bitStream->Write0(); // Immune - bitStream->Write1(); // Success - - if (true) { - uint32_t unknown3 = 0; - bitStream->Write(unknown3); - - auto damage = this->m_MinDamage; - auto* entity = EntityManager::Instance()->GetEntity(branch.target); - - if (entity == nullptr) { - damage = 0; - bitStream->Write(damage); - bitStream->Write(false); - } else { - bitStream->Write(damage); - bitStream->Write(true); - - auto* destroyableComponent = entity->GetComponent(); - if (damage != 0 && destroyableComponent != nullptr) { - PlayFx(u"onhit", entity->GetObjectID(), 1); - destroyableComponent->Damage(damage, context->originator, context->skillID, false); - context->ScheduleUpdate(branch.target); - } - } - } - - uint8_t successState = 1; - bitStream->Write(successState); - - switch (successState) { - case 1: - this->m_OnSuccess->Calculate(context, bitStream, branch); - break; - default: - Game::logger->LogDebug("BasicAttackBehavior", "Unknown success state (%i)!", successState); - break; - } + DoBehaviorCalculation(context, bitStream, branch); const auto endAddress = bitStream->GetWriteOffset(); const uint16_t allocate = endAddress - startAddress + 1; @@ -164,6 +154,87 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream->SetWriteOffset(startAddress + allocate); } +void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target); + if (!targetEntity) { + Game::logger->Log("BasicAttackBehavior", "Target entity %llu is null!", branch.target); + return; + } + + auto* destroyableComponent = targetEntity->GetComponent(); + if (!destroyableComponent || !destroyableComponent->GetParent()) { + Game::logger->Log("BasicAttackBehavior", "No destroyable component on %llu", branch.target); + return; + } + + const bool isBlocking = destroyableComponent->GetAttacksToBlock() > 0; + + bitStream->Write(isBlocking); + + if (isBlocking) { + destroyableComponent->SetAttacksToBlock(destroyableComponent->GetAttacksToBlock() - 1); + EntityManager::Instance()->SerializeEntity(targetEntity); + this->m_OnFailBlocked->Calculate(context, bitStream, branch); + return; + } + + const bool isImmune = destroyableComponent->IsImmune(); + + bitStream->Write(isImmune); + + if (isImmune) { + this->m_OnFailImmune->Calculate(context, bitStream, branch); + return; + } + + bool isSuccess = false; + const uint32_t previousHealth = destroyableComponent->GetHealth(); + const uint32_t previousArmor = destroyableComponent->GetArmor(); + + const auto damage = this->m_MinDamage; + + PlayFx(u"onhit", targetEntity->GetObjectID(), 1); + destroyableComponent->Damage(damage, context->originator, context->skillID, false); + context->ScheduleUpdate(branch.target); + + const uint32_t armorDamageDealt = previousArmor - destroyableComponent->GetArmor(); + const uint32_t healthDamageDealt = previousHealth - destroyableComponent->GetHealth(); + isSuccess = armorDamageDealt > 0 || healthDamageDealt > 0 || (armorDamageDealt + healthDamageDealt) > 0; + + bitStream->Write(isSuccess); + + eBasicAttackSuccessTypes successState = eBasicAttackSuccessTypes::FAILIMMUNE; + if (isSuccess) { + if (healthDamageDealt >= 1) { + successState = eBasicAttackSuccessTypes::SUCCESS; + } else if (armorDamageDealt >= 1) { + successState = this->m_OnFailArmor->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY ? eBasicAttackSuccessTypes::FAILIMMUNE : eBasicAttackSuccessTypes::FAILARMOR; + } + + bitStream->Write(armorDamageDealt); + bitStream->Write(healthDamageDealt); + bitStream->Write(targetEntity->GetIsDead()); + } + + bitStream->Write(successState); + + switch (static_cast(successState)) { + case eBasicAttackSuccessTypes::SUCCESS: + this->m_OnSuccess->Calculate(context, bitStream, branch); + break; + case eBasicAttackSuccessTypes::FAILARMOR: + this->m_OnFailArmor->Calculate(context, bitStream, branch); + break; + default: + if (static_cast(successState) != eBasicAttackSuccessTypes::FAILIMMUNE) { + Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState); + break; + } + this->m_OnFailImmune->Calculate(context, bitStream, branch); + break; + } +} + void BasicAttackBehavior::Load() { this->m_MinDamage = GetInt("min damage"); if (this->m_MinDamage == 0) this->m_MinDamage = 1; @@ -171,7 +242,14 @@ void BasicAttackBehavior::Load() { this->m_MaxDamage = GetInt("max damage"); if (this->m_MaxDamage == 0) this->m_MaxDamage = 1; + // The client sets the minimum damage to maximum, so we'll do the same. These are usually the same value anyways. + if (this->m_MinDamage < this->m_MaxDamage) this->m_MinDamage = this->m_MaxDamage; + this->m_OnSuccess = GetAction("on_success"); this->m_OnFailArmor = GetAction("on_fail_armor"); + + this->m_OnFailImmune = GetAction("on_fail_immune"); + + this->m_OnFailBlocked = GetAction("on_fail_blocked"); } diff --git a/dGame/dBehaviors/BasicAttackBehavior.h b/dGame/dBehaviors/BasicAttackBehavior.h index 9c08141c..f6e3fa28 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.h +++ b/dGame/dBehaviors/BasicAttackBehavior.h @@ -7,10 +7,45 @@ public: explicit BasicAttackBehavior(const uint32_t behaviorId) : Behavior(behaviorId) { } + /** + * @brief Reads a 16bit short from the bitStream and when the actual behavior handling finishes with all of its branches, the bitStream + * is then offset to after the allocated bits for this stream. + * + */ + void DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch); + + /** + * @brief Handles a client initialized Basic Attack Behavior cast to be deserialized and verified on the server. + * + * @param context The Skill's Behavior context. All behaviors in the same tree share the same context + * @param bitStream The bitStream to deserialize. BitStreams will always check their bounds before reading in a behavior + * and will fail gracefully if an overread is detected. + * @param branch The context of this specific branch of the Skill Behavior. Changes based on which branch you are going down. + */ void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + /** + * @brief Writes a 16bit short to the bitStream and when the actual behavior calculation finishes with all of its branches, the number + * of bits used is then written to where the 16bit short initially was. + * + */ void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + /** + * @brief Calculates a server initialized Basic Attack Behavior cast to be serialized to the client + * + * @param context The Skill's Behavior context. All behaviors in the same tree share the same context + * @param bitStream The bitStream to serialize to. + * @param branch The context of this specific branch of the Skill Behavior. Changes based on which branch you are going down. + */ + void DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch); + + /** + * @brief Loads this Behaviors parameters from the database. For this behavior specifically: + * max and min damage will always be the same. If min is less than max, they are both set to max. + * If an action is not in the database, then no action is taken for that result. + * + */ void Load() override; private: uint32_t m_MinDamage; @@ -20,4 +55,8 @@ private: Behavior* m_OnSuccess; Behavior* m_OnFailArmor; + + Behavior* m_OnFailImmune; + + Behavior* m_OnFailBlocked; }; From bd28e4051fa5eb003c4a29366dd03c75eeeeb021 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 29 Dec 2022 01:43:52 -0800 Subject: [PATCH 088/166] Fix Hash Collisions in CDBehaviorParameter table (#930) * Fix hashing * Update CDBehaviorParameterTable.cpp --- dDatabase/Tables/CDBehaviorParameterTable.cpp | 41 ++++++++----------- dDatabase/Tables/CDBehaviorParameterTable.h | 12 +++--- dGame/dBehaviors/Behavior.cpp | 2 +- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index 96015896..d09a71b2 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -4,9 +4,9 @@ //! Constructor CDBehaviorParameterTable::CDBehaviorParameterTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); - size_t hash = 0; + uint32_t uniqueParameterId = 0; + uint64_t hash = 0; while (!tableData.eof()) { - hash = 0; CDBehaviorParameter entry; entry.behaviorID = tableData.getIntField(0, -1); auto candidateStringToAdd = std::string(tableData.getStringField(1, "")); @@ -14,15 +14,13 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { if (parameter != m_ParametersList.end()) { entry.parameterID = parameter; } else { - entry.parameterID = m_ParametersList.insert(candidateStringToAdd).first; + entry.parameterID = m_ParametersList.insert(std::make_pair(candidateStringToAdd, uniqueParameterId)).first; + uniqueParameterId++; } + hash = entry.behaviorID; + hash = (hash << 31U) | entry.parameterID->second; entry.value = tableData.getFloatField(2, -1.0f); - GeneralUtils::hash_combine(hash, entry.behaviorID); - GeneralUtils::hash_combine(hash, *entry.parameterID); - - auto it = m_Entries.find(entry.behaviorID); - m_ParametersList.insert(*entry.parameterID); m_Entries.insert(std::make_pair(hash, entry)); tableData.nextRow(); @@ -38,31 +36,28 @@ std::string CDBehaviorParameterTable::GetName(void) const { return "BehaviorParameter"; } -CDBehaviorParameter CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue) { - CDBehaviorParameter returnValue; - returnValue.behaviorID = 0; - returnValue.parameterID = m_ParametersList.end(); - returnValue.value = defaultValue; +float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) { + auto parameterID = this->m_ParametersList.find(name); + if (parameterID == this->m_ParametersList.end()) return defaultValue; - size_t hash = 0; - GeneralUtils::hash_combine(hash, behaviorID); - GeneralUtils::hash_combine(hash, name); + uint64_t hash = behaviorID; + + hash = (hash << 31U) | parameterID->second; // Search for specific parameter const auto& it = m_Entries.find(hash); - return it != m_Entries.end() ? it->second : returnValue; + return it != m_Entries.end() ? it->second.value : defaultValue; } std::map CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) { - size_t hash; + uint64_t hashBase = behaviorID; std::map returnInfo; - for (auto parameterCandidate : m_ParametersList) { - hash = 0; - GeneralUtils::hash_combine(hash, behaviorID); - GeneralUtils::hash_combine(hash, parameterCandidate); + uint64_t hash; + for (auto& parameterCandidate : m_ParametersList) { + hash = (hashBase << 31U) | parameterCandidate.second; auto infoCandidate = m_Entries.find(hash); if (infoCandidate != m_Entries.end()) { - returnInfo.insert(std::make_pair(*(infoCandidate->second.parameterID), infoCandidate->second.value)); + returnInfo.insert(std::make_pair(infoCandidate->second.parameterID->first, infoCandidate->second.value)); } } return returnInfo; diff --git a/dDatabase/Tables/CDBehaviorParameterTable.h b/dDatabase/Tables/CDBehaviorParameterTable.h index f067e7d2..5d0d8b72 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.h +++ b/dDatabase/Tables/CDBehaviorParameterTable.h @@ -12,16 +12,16 @@ //! BehaviorParameter Entry Struct struct CDBehaviorParameter { - unsigned int behaviorID; //!< The Behavior ID - std::unordered_set::iterator parameterID; //!< The Parameter ID - float value; //!< The value of the behavior template + unsigned int behaviorID; //!< The Behavior ID + std::unordered_map::iterator parameterID; //!< The Parameter ID + float value; //!< The value of the behavior template }; //! BehaviorParameter table class CDBehaviorParameterTable : public CDTable { private: - std::unordered_map m_Entries; - std::unordered_set m_ParametersList; + std::unordered_map m_Entries; + std::unordered_map m_ParametersList; public: //! Constructor @@ -36,7 +36,7 @@ public: */ std::string GetName(void) const override; - CDBehaviorParameter GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); + float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); std::map GetParametersByBehaviorID(uint32_t behaviorID); }; diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 568780d0..40c37a95 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -439,7 +439,7 @@ Behavior::Behavior(const uint32_t behaviorId) { float Behavior::GetFloat(const std::string& name, const float defaultValue) const { // Get the behavior parameter entry and return its value. if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable("BehaviorParameter"); - return BehaviorParameterTable->GetEntry(this->m_behaviorId, name, defaultValue).value; + return BehaviorParameterTable->GetValue(this->m_behaviorId, name, defaultValue); } From 9adbb7aa86a134707a9b5470d1bf83fb24ba5f90 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 29 Dec 2022 06:34:53 -0800 Subject: [PATCH 089/166] Address World Server Packet timing and erroneous log (#929) * Fix overread in projectile behavior * Fix stuns * Correctly read in bitStream * Fix projectile behavior * Address movement type issues * Update shutdown time to be accurate * Fix small issues --- dGame/dBehaviors/BasicAttackBehavior.cpp | 2 +- dWorldServer/WorldServer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/dBehaviors/BasicAttackBehavior.cpp b/dGame/dBehaviors/BasicAttackBehavior.cpp index 0378cb5e..97068d91 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.cpp +++ b/dGame/dBehaviors/BasicAttackBehavior.cpp @@ -40,7 +40,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target); if (!targetEntity) { - Game::logger->Log("BasicAttackBehavior", "Target targetEntity %i not found.", branch.target); + Game::logger->Log("BasicAttackBehavior", "Target targetEntity %llu not found.", branch.target); return; } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index de6deb2a..73157c09 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -416,7 +416,7 @@ int main(int argc, char** argv) { HandlePacket(packet); auto t2 = std::chrono::high_resolution_clock::now(); - timeSpent += std::chrono::duration_cast(t2 - t1).count(); + timeSpent += std::chrono::duration_cast>(t2 - t1).count(); Game::server->DeallocatePacket(packet); packet = nullptr; } else { From 34b5f0f9d646623f6cd8ee4f3183eef865629425 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 31 Dec 2022 02:46:25 -0600 Subject: [PATCH 090/166] add uncast to speed behavior (#932) --- dGame/dBehaviors/SpeedBehavior.cpp | 12 ++++++++---- dGame/dBehaviors/SpeedBehavior.h | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/dGame/dBehaviors/SpeedBehavior.cpp b/dGame/dBehaviors/SpeedBehavior.cpp index bec2b1cb..d326aa45 100644 --- a/dGame/dBehaviors/SpeedBehavior.cpp +++ b/dGame/dBehaviors/SpeedBehavior.cpp @@ -29,6 +29,14 @@ void SpeedBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt Handle(context, bitStream, branch); } +void SpeedBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { + End(context, branch, LWOOBJID_EMPTY); +} + +void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + End(context, branch, second); +} + void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { auto* target = EntityManager::Instance()->GetEntity(branch.target); if (!target) return; @@ -40,10 +48,6 @@ void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, EntityManager::Instance()->SerializeEntity(target); } -void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { - End(context, branch, second); -} - void SpeedBehavior::Load() { m_RunSpeed = GetFloat("run_speed"); m_AffectsCaster = GetBoolean("affects_caster"); diff --git a/dGame/dBehaviors/SpeedBehavior.h b/dGame/dBehaviors/SpeedBehavior.h index 57c46842..88b85820 100644 --- a/dGame/dBehaviors/SpeedBehavior.h +++ b/dGame/dBehaviors/SpeedBehavior.h @@ -15,6 +15,8 @@ public: void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void UnCast(BehaviorContext* context, BehaviorBranchContext branch) override; + void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; From fab44142042789493667d4b5677c10f4663d91be Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 31 Dec 2022 03:56:12 -0800 Subject: [PATCH 091/166] Fix serratorizer chargeup time (#931) --- migrations/cdserver/5_serratorizer_chargeup_fix.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 migrations/cdserver/5_serratorizer_chargeup_fix.sql diff --git a/migrations/cdserver/5_serratorizer_chargeup_fix.sql b/migrations/cdserver/5_serratorizer_chargeup_fix.sql new file mode 100644 index 00000000..a61da2c2 --- /dev/null +++ b/migrations/cdserver/5_serratorizer_chargeup_fix.sql @@ -0,0 +1 @@ +UPDATE behaviorParameter SET value = 20 WHERE behaviorID = 21001 AND parameterID = "value 2"; From 737eaba54d3d96a2643b4f804c366c7c44883f92 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 31 Dec 2022 03:56:30 -0800 Subject: [PATCH 092/166] Serialize target with GameMessageStartSkill (#933) --- dGame/dComponents/SkillComponent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 445a837e..0608c63b 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -246,6 +246,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c start.skillID = skillId; start.uiSkillHandle = context->skillUId; start.optionalOriginatorID = context->originator; + start.optionalTargetID = target; auto* originator = EntityManager::Instance()->GetEntity(context->originator); From 09157506bf503913a0199b86678ca26f7980677d Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 31 Dec 2022 11:44:09 -0800 Subject: [PATCH 093/166] Fix Complete Overhaul (#934) Check your pointers :) --- dGame/dGameMessages/GameMessages.cpp | 15 +++++++++++++-- dGame/dInventory/Item.cpp | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 37aeb093..2423915e 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -28,6 +28,7 @@ #include "GameConfig.h" #include "RocketLaunchLupComponent.h" #include "eUnequippableActiveType.h" +#include "RacingTaskParam.h" #include #include @@ -5482,7 +5483,8 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* auto* temp = inv->GetInventory(TEMP_MODELS); std::vector modList; - + auto& oldPartList = character->GetVar(u"currentModifiedBuild"); + bool everyPieceSwapped = !oldPartList.empty(); // If the player didn't put a build in initially, then they should not get this achievement. if (count >= 3) { std::u16string modules; @@ -5490,7 +5492,8 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* uint32_t mod; inStream->Read(mod); modList.push_back(mod); - modules += u"1:" + (GeneralUtils::to_u16string(mod)); + auto modToStr = GeneralUtils::to_u16string(mod); + modules += u"1:" + (modToStr); if (k + 1 != count) modules += u"+"; if (temp->GetLotCount(mod) > 0) { @@ -5498,6 +5501,13 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* } else { inv->RemoveItem(mod, 1); } + + // Doing this check for 1 singular mission that needs to know when you've swapped every part out during a car modular build. + // since all 8129's are the same, skip checking that + if (mod != 8129) { + if (oldPartList.find(GeneralUtils::UTF16ToWTF8(modToStr)) != std::string::npos) everyPieceSwapped = false; + + } } const auto moduleAssembly = new LDFData(u"assemblyPartLOTs", modules); @@ -5516,6 +5526,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* if (entity->GetLOT() != 9980 || Game::server->GetZoneID() != 1200) { if (missionComponent != nullptr) { missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, entity->GetLOT(), entity->GetObjectID()); + if (count >= 7 && everyPieceSwapped) missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, LWOOBJID_EMPTY, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_MODULAR_BUILDING); } } } diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index a3d4cfc0..4f3626e3 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -347,6 +347,15 @@ void Item::Disassemble(const eInventoryType inventoryType) { if (data->GetKey() == u"assemblyPartLOTs") { auto modStr = data->GetValueAsString(); + // This shouldn't be null but always check your pointers. + if (GetInventory()) { + auto inventoryComponent = GetInventory()->GetComponent(); + if (inventoryComponent) { + auto entity = inventoryComponent->GetParent(); + if (entity) entity->SetVar(u"currentModifiedBuild", modStr); + } + } + std::vector modArray; std::stringstream ssData(modStr); From 19be0a61b2f4a9823796539e9e81a0effb7b0592 Mon Sep 17 00:00:00 2001 From: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 1 Jan 2023 04:51:22 -0800 Subject: [PATCH 094/166] Eliminate WorldConfig Magic Numbers Add comments for fields Use the name directly --- dGame/dComponents/DestroyableComponent.cpp | 19 ++--- dGame/dMission/Mission.cpp | 5 +- dGame/dUtilities/Mail.cpp | 6 +- dZoneManager/WorldConfig.h | 67 +++++++++++++++ dZoneManager/dZoneManager.cpp | 96 ++++++++++++++++++---- dZoneManager/dZoneManager.h | 31 +++---- 6 files changed, 177 insertions(+), 47 deletions(-) create mode 100644 dZoneManager/WorldConfig.h diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index d832ef93..aab4d670 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -30,6 +30,7 @@ #include "PossessorComponent.h" #include "InventoryComponent.h" #include "dZoneManager.h" +#include "WorldConfig.h" DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_iArmor = 0; @@ -765,20 +766,16 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType uint64_t coinsTotal = character->GetCoins(); if (coinsTotal > 0) { - uint64_t coinsToLoose = 1; + const uint64_t minCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMin; + const uint64_t maxCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMax; + const float coinPercentageToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathPercent; - if (coinsTotal >= 200) { - float hundreth = (coinsTotal / 100.0f); - coinsToLoose = static_cast(hundreth); - } + uint64_t coinsToLose = std::max(static_cast(coinsTotal * coinPercentageToLose), minCoinsToLose); + coinsToLose = std::min(maxCoinsToLose, coinsToLose); - if (coinsToLoose > 10000) { - coinsToLoose = 10000; - } + coinsTotal -= coinsToLose; - coinsTotal -= coinsToLoose; - - LootGenerator::Instance().DropLoot(m_Parent, m_Parent, -1, coinsToLoose, coinsToLoose); + LootGenerator::Instance().DropLoot(m_Parent, m_Parent, -1, coinsToLose, coinsToLose); character->SetCoins(coinsTotal, eLootSourceType::LOOT_SOURCE_PICKUP); } } diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 61b41992..a1ae724a 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -18,6 +18,7 @@ #include "dZoneManager.h" #include "InventoryComponent.h" #include "Database.h" +#include "WorldConfig.h" Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_MissionComponent = missionComponent; @@ -435,9 +436,9 @@ void Mission::YieldRewards() { int32_t coinsToSend = 0; if (info->LegoScore > 0) { eLootSourceType lootSource = info->isMission ? eLootSourceType::LOOT_SOURCE_MISSION : eLootSourceType::LOOT_SOURCE_ACHIEVEMENT; - if (levelComponent->GetLevel() >= dZoneManager::Instance()->GetMaxLevel()) { + if (levelComponent->GetLevel() >= dZoneManager::Instance()->GetWorldConfig()->levelCap) { // Since the character is at the level cap we reward them with coins instead of UScore. - coinsToSend += info->LegoScore * dZoneManager::Instance()->GetLevelCapCurrencyConversion(); + coinsToSend += info->LegoScore * dZoneManager::Instance()->GetWorldConfig()->levelCapCurrencyConversion; } else { characterComponent->SetUScore(characterComponent->GetUScore() + info->LegoScore); GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), info->LegoScore, lootSource); diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index 7047972f..a4ac63e1 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -22,6 +22,8 @@ #include "MissionComponent.h" #include "ChatPackets.h" #include "Character.h" +#include "dZoneManager.h" +#include "WorldConfig.h" void Mail::SendMail(const Entity* recipient, const std::string& subject, const std::string& body, const LOT attachment, const uint16_t attachmentCount) { @@ -191,7 +193,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd uint32_t itemID = static_cast(attachmentID); LOT itemLOT = 0; //Inventory::InventoryType itemType; - int mailCost = 25; + int mailCost = dZoneManager::Instance()->GetWorldConfig()->mailBaseFee; int stackSize = 0; auto inv = static_cast(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); Item* item = nullptr; @@ -199,7 +201,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd if (itemID > 0 && attachmentCount > 0 && inv) { item = inv->FindItemById(attachmentID); if (item) { - mailCost += (item->GetInfo().baseValue * 0.1f); + mailCost += (item->GetInfo().baseValue * dZoneManager::Instance()->GetWorldConfig()->mailPercentAttachmentFee); stackSize = item->GetCount(); itemLOT = item->GetLot(); } else { diff --git a/dZoneManager/WorldConfig.h b/dZoneManager/WorldConfig.h new file mode 100644 index 00000000..a98433a1 --- /dev/null +++ b/dZoneManager/WorldConfig.h @@ -0,0 +1,67 @@ +#ifndef __WORLDCONFIG__H__ +#define __WORLDCONFIG__H__ + +#include +#include + +struct WorldConfig { + int32_t worldConfigID{}; //! Primary key for WorlcConfig table + float peGravityValue{}; //! Unknown + float peBroadphaseWorldSize{}; //! Unknown + float peGameObjScaleFactor{}; //! Unknown + float characterRotationSpeed{}; //! The players' rotation speed + float characterWalkForwardSpeed{}; //! The players' walk forward speed + float characterWalkBackwardSpeed{}; //! The players' walk backwards speed + float characterWalkStrafeSpeed{}; //! The players' strafe speed + float characterWalkStrafeForwardSpeed{}; //! The players' walk strafe forward speed + float characterWalkStrafeBackwardSpeed{}; //! The players' walk strage backwards speed + float characterRunBackwardSpeed{}; //! The players' run backwards speed + float characterRunStrafeSpeed{}; //! The players' run strafe speed + float characterRunStrafeForwardSpeed{}; //! The players' run strafe forward speed + float characterRunStrafeBackwardSpeed{}; //! The players' run strage backwards speed + float globalCooldown{}; //! The global ability cooldown + float characterGroundedTime{}; //! Unknown + float characterGroundedSpeed{}; //! Unknown + float globalImmunityTime{}; //! Unknown + float characterMaxSlope{}; //! Unknown + float defaultRespawnTime{}; //! Unknown + float missionTooltipTimeout{}; + float vendorBuyMultiplier{}; //! The buy scalar for buying from vendors + float petFollowRadius{}; //! The players' pet follow radius + float characterEyeHeight{}; //! The players' eye height + float flightVerticalVelocity{}; //! Unknown + float flightAirspeed{}; //! Unknown + float flightFuelRatio{}; //! Unknown + float flightMaxAirspeed{}; //! Unknown + float fReputationPerVote{}; //! Unknown + int32_t propertyCloneLimit{}; //! Unknown + int32_t defaultHomespaceTemplate{}; //! Unknown + float coinsLostOnDeathPercent{}; //! The percentage of coins to lose on a player death + int32_t coinsLostOnDeathMin{}; //! The minimum number of coins to lose on a player death + int32_t coinsLostOnDeathMax{}; //! The maximum number of coins to lose on a player death + int32_t characterVotesPerDay{}; //! Unknown + int32_t propertyModerationRequestApprovalCost{};//! Unknown + int32_t propertyModerationRequestReviewCost{}; //! Unknown + int32_t propertyModRequestsAllowedSpike{}; //! Unknown + int32_t propertyModRequestsAllowedInterval{}; //! Unknown + int32_t propertyModRequestsAllowedTotal{}; //! Unknown + int32_t propertyModRequestsSpikeDuration{}; //! Unknown + int32_t propertyModRequestsIntervalDuration{}; //! Unknown + bool modelModerateOnCreate{}; //! Unknown + float defaultPropertyMaxHeight{}; //! Unknown + float reputationPerVoteCast{}; //! Unknown + float reputationPerVoteReceived{}; //! Unknown + int32_t showcaseTopModelConsiderationBattles{}; //! Unknown + float reputationPerBattlePromotion{}; //! Unknown + float coinsLostOnDeathMinTimeout{}; //! Unknown + float coinsLostOnDeathMaxTimeout{}; //! Unknown + int32_t mailBaseFee{}; //! The base fee to take when a player sends mail + float mailPercentAttachmentFee{}; //! The scalar multiplied by an items base cost to determine how much that item costs to be mailed + int32_t propertyReputationDelay{}; //! Unknown + int32_t levelCap{}; //! The maximum player level + std::string levelUpBehaviorEffect{}; //! Unknown + int32_t characterVersion{}; //! Unknown + int32_t levelCapCurrencyConversion{}; //! The ratio of UScore (LEGO Score) to coins +}; + +#endif //! __WORLDCONFIG__H__ diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 102fb3af..0b7844a3 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -8,6 +8,7 @@ #include "DestroyableComponent.h" #include "GameMessages.h" #include "VanityUtilities.h" +#include "WorldConfig.h" #include #include "../dWorldServer/ObjectIDManager.h" @@ -53,6 +54,8 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); + LoadWorldConfig(); + Game::logger->Log("dZoneManager", "Zone prepared in: %llu ms", (endTime - startTime)); VanityUtilities::SpawnVanity(); @@ -69,6 +72,7 @@ dZoneManager::~dZoneManager() { m_Spawners.erase(p.first); } + if (m_WorldConfig) delete m_WorldConfig; } Zone* dZoneManager::GetZone() { @@ -117,24 +121,6 @@ LWOZONEID dZoneManager::GetZoneID() const { return m_ZoneID; } -uint32_t dZoneManager::GetMaxLevel() { - if (m_MaxLevel == 0) { - auto tableData = CDClientDatabase::ExecuteQuery("SELECT LevelCap FROM WorldConfig WHERE WorldConfigID = 1 LIMIT 1;"); - m_MaxLevel = tableData.getIntField(0, -1); - tableData.finalize(); - } - return m_MaxLevel; -} - -int32_t dZoneManager::GetLevelCapCurrencyConversion() { - if (m_CurrencyConversionRate == 0) { - auto tableData = CDClientDatabase::ExecuteQuery("SELECT LevelCapCurrencyConversion FROM WorldConfig WHERE WorldConfigID = 1 LIMIT 1;"); - m_CurrencyConversionRate = tableData.getIntField(0, -1); - tableData.finalize(); - } - return m_CurrencyConversionRate; -} - void dZoneManager::Update(float deltaTime) { for (auto spawner : m_Spawners) { spawner.second->Update(deltaTime); @@ -249,3 +235,77 @@ uint32_t dZoneManager::GetUniqueMissionIdStartingValue() { } return m_UniqueMissionIdStart; } + +void dZoneManager::LoadWorldConfig() { + Game::logger->Log("dZoneManager", "Loading WorldConfig into memory"); + + auto worldConfig = CDClientDatabase::ExecuteQuery("SELECT * FROM WorldConfig;"); + + if (!m_WorldConfig) m_WorldConfig = new WorldConfig(); + + if (worldConfig.eof()) { + Game::logger->Log("dZoneManager", "WorldConfig table is empty. Is this intended?"); + return; + } + + // Now read in the giant table + m_WorldConfig->worldConfigID = worldConfig.getIntField("WorldConfigID"); + m_WorldConfig->peGravityValue = worldConfig.getFloatField("pegravityvalue"); + m_WorldConfig->peBroadphaseWorldSize = worldConfig.getFloatField("pebroadphaseworldsize"); + m_WorldConfig->peGameObjScaleFactor = worldConfig.getFloatField("pegameobjscalefactor"); + m_WorldConfig->characterRotationSpeed = worldConfig.getFloatField("character_rotation_speed"); + m_WorldConfig->characterWalkForwardSpeed = worldConfig.getFloatField("character_walk_forward_speed"); + m_WorldConfig->characterWalkBackwardSpeed = worldConfig.getFloatField("character_walk_backward_speed"); + m_WorldConfig->characterWalkStrafeSpeed = worldConfig.getFloatField("character_walk_strafe_speed"); + m_WorldConfig->characterWalkStrafeForwardSpeed = worldConfig.getFloatField("character_walk_strafe_forward_speed"); + m_WorldConfig->characterWalkStrafeBackwardSpeed = worldConfig.getFloatField("character_walk_strafe_backward_speed"); + m_WorldConfig->characterRunBackwardSpeed = worldConfig.getFloatField("character_run_backward_speed"); + m_WorldConfig->characterRunStrafeSpeed = worldConfig.getFloatField("character_run_strafe_speed"); + m_WorldConfig->characterRunStrafeForwardSpeed = worldConfig.getFloatField("character_run_strafe_forward_speed"); + m_WorldConfig->characterRunStrafeBackwardSpeed = worldConfig.getFloatField("character_run_strafe_backward_speed"); + m_WorldConfig->globalCooldown = worldConfig.getFloatField("global_cooldown"); + m_WorldConfig->characterGroundedTime = worldConfig.getFloatField("characterGroundedTime"); + m_WorldConfig->characterGroundedSpeed = worldConfig.getFloatField("characterGroundedSpeed"); + m_WorldConfig->globalImmunityTime = worldConfig.getFloatField("globalImmunityTime"); + m_WorldConfig->characterMaxSlope = worldConfig.getFloatField("character_max_slope"); + m_WorldConfig->defaultRespawnTime = worldConfig.getFloatField("defaultrespawntime"); + m_WorldConfig->missionTooltipTimeout = worldConfig.getFloatField("mission_tooltip_timeout"); + m_WorldConfig->vendorBuyMultiplier = worldConfig.getFloatField("vendor_buy_multiplier"); + m_WorldConfig->petFollowRadius = worldConfig.getFloatField("pet_follow_radius"); + m_WorldConfig->characterEyeHeight = worldConfig.getFloatField("character_eye_height"); + m_WorldConfig->flightVerticalVelocity = worldConfig.getFloatField("flight_vertical_velocity"); + m_WorldConfig->flightAirspeed = worldConfig.getFloatField("flight_airspeed"); + m_WorldConfig->flightFuelRatio = worldConfig.getFloatField("flight_fuel_ratio"); + m_WorldConfig->flightMaxAirspeed = worldConfig.getFloatField("flight_max_airspeed"); + m_WorldConfig->fReputationPerVote = worldConfig.getFloatField("fReputationPerVote"); + m_WorldConfig->propertyCloneLimit = worldConfig.getIntField("nPropertyCloneLimit"); + m_WorldConfig->defaultHomespaceTemplate = worldConfig.getIntField("defaultHomespaceTemplate"); + m_WorldConfig->coinsLostOnDeathPercent = worldConfig.getFloatField("coins_lost_on_death_percent"); + m_WorldConfig->coinsLostOnDeathMin = worldConfig.getIntField("coins_lost_on_death_min"); + m_WorldConfig->coinsLostOnDeathMax = worldConfig.getIntField("coins_lost_on_death_max"); + m_WorldConfig->characterVotesPerDay = worldConfig.getIntField("character_votes_per_day"); + m_WorldConfig->propertyModerationRequestApprovalCost = worldConfig.getIntField("property_moderation_request_approval_cost"); + m_WorldConfig->propertyModerationRequestReviewCost = worldConfig.getIntField("property_moderation_request_review_cost"); + m_WorldConfig->propertyModRequestsAllowedSpike = worldConfig.getIntField("propertyModRequestsAllowedSpike"); + m_WorldConfig->propertyModRequestsAllowedInterval = worldConfig.getIntField("propertyModRequestsAllowedInterval"); + m_WorldConfig->propertyModRequestsAllowedTotal = worldConfig.getIntField("propertyModRequestsAllowedTotal"); + m_WorldConfig->propertyModRequestsSpikeDuration = worldConfig.getIntField("propertyModRequestsSpikeDuration"); + m_WorldConfig->propertyModRequestsIntervalDuration = worldConfig.getIntField("propertyModRequestsIntervalDuration"); + m_WorldConfig->modelModerateOnCreate = worldConfig.getIntField("modelModerateOnCreate") != 0; + m_WorldConfig->defaultPropertyMaxHeight = worldConfig.getFloatField("defaultPropertyMaxHeight"); + m_WorldConfig->reputationPerVoteCast = worldConfig.getFloatField("reputationPerVoteCast"); + m_WorldConfig->reputationPerVoteReceived = worldConfig.getFloatField("reputationPerVoteReceived"); + m_WorldConfig->showcaseTopModelConsiderationBattles = worldConfig.getIntField("showcaseTopModelConsiderationBattles"); + m_WorldConfig->reputationPerBattlePromotion = worldConfig.getFloatField("reputationPerBattlePromotion"); + m_WorldConfig->coinsLostOnDeathMinTimeout = worldConfig.getFloatField("coins_lost_on_death_min_timeout"); + m_WorldConfig->coinsLostOnDeathMaxTimeout = worldConfig.getFloatField("coins_lost_on_death_max_timeout"); + m_WorldConfig->mailBaseFee = worldConfig.getIntField("mail_base_fee"); + m_WorldConfig->mailPercentAttachmentFee = worldConfig.getFloatField("mail_percent_attachment_fee"); + m_WorldConfig->propertyReputationDelay = worldConfig.getIntField("propertyReputationDelay"); + m_WorldConfig->levelCap = worldConfig.getIntField("LevelCap"); + m_WorldConfig->levelUpBehaviorEffect = worldConfig.getStringField("LevelUpBehaviorEffect"); + m_WorldConfig->characterVersion = worldConfig.getIntField("CharacterVersion"); + m_WorldConfig->levelCapCurrencyConversion = worldConfig.getIntField("LevelCapCurrencyConversion"); + worldConfig.finalize(); + Game::logger->Log("dZoneManager", "Loaded WorldConfig into memory"); +} diff --git a/dZoneManager/dZoneManager.h b/dZoneManager/dZoneManager.h index b2fef1e3..c1776e79 100644 --- a/dZoneManager/dZoneManager.h +++ b/dZoneManager/dZoneManager.h @@ -4,6 +4,8 @@ #include "Spawner.h" #include +class WorldConfig; + class dZoneManager { public: enum class dZoneNotifier { @@ -16,6 +18,12 @@ public: InvalidNotifier }; +private: + /** + * Reads the WorldConfig from the CDClientDatabase into memory + */ + void LoadWorldConfig(); + public: static dZoneManager* Instance() { if (!m_Address) { @@ -33,8 +41,6 @@ public: void NotifyZone(const dZoneNotifier& notifier, const LWOOBJID& objectID); //Notifies the zone of a certain event or command. void AddSpawner(LWOOBJID id, Spawner* spawner); LWOZONEID GetZoneID() const; - uint32_t GetMaxLevel(); - int32_t GetLevelCapCurrencyConversion(); LWOOBJID MakeSpawner(SpawnerInfo info); Spawner* GetSpawner(LWOOBJID id); void RemoveSpawner(LWOOBJID id); @@ -45,27 +51,24 @@ public: bool GetPlayerLoseCoinOnDeath() { return m_PlayerLoseCoinsOnDeath; } uint32_t GetUniqueMissionIdStartingValue(); + // The world config should not be modified by a caller. + const WorldConfig* GetWorldConfig() { + if (!m_WorldConfig) LoadWorldConfig(); + return m_WorldConfig; + }; + private: - /** - * The maximum level of the world. - */ - uint32_t m_MaxLevel = 0; - - /** - * The ratio of LEGO Score to currency when the character has hit the max level. - */ - int32_t m_CurrencyConversionRate = 0; - /** * The starting unique mission ID. */ uint32_t m_UniqueMissionIdStart = 0; static dZoneManager* m_Address; //Singleton - Zone* m_pZone; + Zone* m_pZone = nullptr; LWOZONEID m_ZoneID; bool m_PlayerLoseCoinsOnDeath; //Do players drop coins in this zone when smashed std::map m_Spawners; + WorldConfig* m_WorldConfig = nullptr; - Entity* m_ZoneControlObject; + Entity* m_ZoneControlObject = nullptr; }; From 203a150a56688e5cbfdefa500fae80ada4fab40b Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 1 Jan 2023 16:36:10 -0800 Subject: [PATCH 095/166] Update DestroyableComponent.cpp --- dGame/dComponents/DestroyableComponent.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index aab4d670..8d8ed42a 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -764,9 +764,8 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType if (dZoneManager::Instance()->GetPlayerLoseCoinOnDeath()) { auto* character = m_Parent->GetCharacter(); uint64_t coinsTotal = character->GetCoins(); - - if (coinsTotal > 0) { - const uint64_t minCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMin; + const uint64_t minCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMin; + if (coinsTotal >= minCoinsToLose) { const uint64_t maxCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMax; const float coinPercentageToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathPercent; From dc7d0ce142f3badfaf362846a10179b22fca1086 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 3 Jan 2023 09:21:57 -0800 Subject: [PATCH 096/166] Fix Stuns of duration zero (#938) --- dGame/dComponents/BaseCombatAIComponent.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index c035a807..478058a7 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -179,7 +179,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) { if (m_Disabled || m_Parent->GetIsDead()) return; - + bool stunnedThisFrame = m_Stunned; CalculateCombat(deltaTime); // Putting this here for now if (m_StartPosition == NiPoint3::ZERO) { @@ -192,7 +192,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) { return; } - if (m_Stunned) { + if (stunnedThisFrame) { m_MovementAI->Stop(); return; @@ -248,13 +248,13 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { if (m_Disabled) return; - if (m_StunTime > 0.0f) { + if (m_Stunned) { m_StunTime -= deltaTime; if (m_StunTime > 0.0f) { return; } - + m_StunTime = 0.0f; m_Stunned = false; } From 1789ec7f20380376444d93064fc7dbaeee9bbe92 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 3 Jan 2023 09:22:04 -0800 Subject: [PATCH 097/166] delta compression fixes (#937) --- dGame/dComponents/BaseCombatAIComponent.cpp | 36 ++++++++++----- dGame/dComponents/BaseCombatAIComponent.h | 12 +++++ dGame/dComponents/PetComponent.cpp | 44 ++++++++++--------- .../PlayerForcedMovementComponent.cpp | 4 +- 4 files changed, 61 insertions(+), 35 deletions(-) diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 478058a7..081496a4 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -23,9 +23,9 @@ #include "RebuildComponent.h" #include "DestroyableComponent.h" -BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) : Component(parent) { +BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): Component(parent) { m_Target = LWOOBJID_EMPTY; - m_State = AiState::spawn; + SetAiState(AiState::spawn); m_Timer = 1.0f; m_StartPosition = parent->GetPosition(); m_MovementAI = nullptr; @@ -206,7 +206,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) { switch (m_State) { case AiState::spawn: Stun(2.0f); - m_State = AiState::idle; + SetAiState(AiState::idle); break; case AiState::idle: @@ -320,9 +320,9 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { m_Timer = 0; } - m_State = AiState::aggro; + SetAiState(AiState::aggro); } else { - m_State = AiState::idle; + SetAiState(AiState::idle); } for (auto i = 0; i < m_SkillEntries.size(); ++i) { @@ -348,7 +348,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { } if (m_Target == LWOOBJID_EMPTY) { - m_State = AiState::idle; + SetAiState(AiState::idle); return; } @@ -375,7 +375,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { m_MovementAI->Stop(); } - m_State = AiState::aggro; + SetAiState(AiState::aggro); m_Timer = 0; @@ -532,11 +532,20 @@ bool BaseCombatAIComponent::IsMech() { void BaseCombatAIComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - outBitStream->Write1(); - outBitStream->Write(uint32_t(m_State)); - outBitStream->Write(m_Target); + outBitStream->Write(m_DirtyStateOrTarget || bIsInitialUpdate); + if (m_DirtyStateOrTarget || bIsInitialUpdate) { + outBitStream->Write(uint32_t(m_State)); + outBitStream->Write(m_Target); + m_DirtyStateOrTarget = false; + } } +void BaseCombatAIComponent::SetAiState(AiState newState) { + if (newState == this->m_State) return; + this->m_State = newState; + m_DirtyStateOrTarget = true; + EntityManager::Instance()->SerializeEntity(m_Parent); +} bool BaseCombatAIComponent::IsEnemy(LWOOBJID target) const { auto* entity = EntityManager::Instance()->GetEntity(target); @@ -585,7 +594,10 @@ bool BaseCombatAIComponent::IsEnemy(LWOOBJID target) const { } void BaseCombatAIComponent::SetTarget(const LWOOBJID target) { + if (this->m_Target == target) return; m_Target = target; + m_DirtyStateOrTarget = true; + EntityManager::Instance()->SerializeEntity(m_Parent); } Entity* BaseCombatAIComponent::GetTargetEntity() const { @@ -700,7 +712,7 @@ void BaseCombatAIComponent::OnAggro() { m_MovementAI->SetDestination(targetPos); - m_State = AiState::tether; + SetAiState(AiState::tether); } m_Timer += 0.5f; @@ -726,7 +738,7 @@ void BaseCombatAIComponent::OnTether() { m_MovementAI->SetDestination(m_StartPosition); - m_State = AiState::aggro; + SetAiState(AiState::aggro); } else { if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return; diff --git a/dGame/dComponents/BaseCombatAIComponent.h b/dGame/dComponents/BaseCombatAIComponent.h index 70a88a42..1f17d562 100644 --- a/dGame/dComponents/BaseCombatAIComponent.h +++ b/dGame/dComponents/BaseCombatAIComponent.h @@ -243,6 +243,12 @@ private: */ std::vector GetTargetWithinAggroRange() const; + /** + * @brief Sets the AiState and prepares the entity for serialization next frame. + * + */ + void SetAiState(AiState newState); + /** * The current state of the AI */ @@ -374,6 +380,12 @@ private: */ bool m_DirtyThreat = false; + /** + * Whether or not the Component has dirty information and should update next frame + * + */ + bool m_DirtyStateOrTarget = false; + /** * Whether the current entity is a mech enemy, needed as mechs tether radius works differently * @return whether this entity is a mech diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 0b136a5c..d11331e7 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -59,7 +59,7 @@ std::map PetComponent::petFlags = { { 13067, 838 }, // Skeleton dragon }; -PetComponent::PetComponent(Entity* parent, uint32_t componentId) : Component(parent) { +PetComponent::PetComponent(Entity* parent, uint32_t componentId): Component(parent) { m_ComponentId = componentId; m_Interaction = LWOOBJID_EMPTY; @@ -118,21 +118,23 @@ void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpd outBitStream->Write(m_Owner); } - outBitStream->Write(tamed); - if (tamed) { - outBitStream->Write(m_ModerationStatus); + if (bIsInitialUpdate) { + outBitStream->Write(tamed); + if (tamed) { + outBitStream->Write(m_ModerationStatus); - const auto nameData = GeneralUtils::UTF8ToUTF16(m_Name); - const auto ownerNameData = GeneralUtils::UTF8ToUTF16(m_OwnerName); + const auto nameData = GeneralUtils::UTF8ToUTF16(m_Name); + const auto ownerNameData = GeneralUtils::UTF8ToUTF16(m_OwnerName); - outBitStream->Write(static_cast(nameData.size())); - for (const auto c : nameData) { - outBitStream->Write(c); - } + outBitStream->Write(static_cast(nameData.size())); + for (const auto c : nameData) { + outBitStream->Write(c); + } - outBitStream->Write(static_cast(ownerNameData.size())); - for (const auto c : ownerNameData) { - outBitStream->Write(c); + outBitStream->Write(static_cast(ownerNameData.size())); + for (const auto c : ownerNameData) { + outBitStream->Write(c); + } } } } @@ -916,16 +918,16 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) { return; } - // If we are out of imagination despawn the pet. - if (playerDestroyableComponent->GetImagination() == 0) { - this->Deactivate(); - auto playerEntity = playerDestroyableComponent->GetParent(); - if (!playerEntity) return; + // If we are out of imagination despawn the pet. + if (playerDestroyableComponent->GetImagination() == 0) { + this->Deactivate(); + auto playerEntity = playerDestroyableComponent->GetParent(); + if (!playerEntity) return; - GameMessages::SendUseItemRequirementsResponse(playerEntity->GetObjectID(), playerEntity->GetSystemAddress(), UseItemResponse::NoImaginationForPet); - } + GameMessages::SendUseItemRequirementsResponse(playerEntity->GetObjectID(), playerEntity->GetSystemAddress(), UseItemResponse::NoImaginationForPet); + } - this->AddDrainImaginationTimer(item); + this->AddDrainImaginationTimer(item); }); } diff --git a/dGame/dComponents/PlayerForcedMovementComponent.cpp b/dGame/dComponents/PlayerForcedMovementComponent.cpp index 3bcad677..76993507 100644 --- a/dGame/dComponents/PlayerForcedMovementComponent.cpp +++ b/dGame/dComponents/PlayerForcedMovementComponent.cpp @@ -7,8 +7,8 @@ PlayerForcedMovementComponent::PlayerForcedMovementComponent(Entity* parent) : C PlayerForcedMovementComponent::~PlayerForcedMovementComponent() {} void PlayerForcedMovementComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - outBitStream->Write(m_DirtyInfo); - if (m_DirtyInfo) { + outBitStream->Write(m_DirtyInfo || bIsInitialUpdate); + if (m_DirtyInfo || bIsInitialUpdate) { outBitStream->Write(m_PlayerOnRail); outBitStream->Write(m_ShowBillboard); } From 1a34f6f74adcadcb32af136831daf33475afe629 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 4 Jan 2023 06:15:06 -0800 Subject: [PATCH 098/166] Fix debug logging newline (#940) --- dCommon/dLogger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dCommon/dLogger.cpp b/dCommon/dLogger.cpp index d4e6a96e..7785a070 100644 --- a/dCommon/dLogger.cpp +++ b/dCommon/dLogger.cpp @@ -89,7 +89,7 @@ void dLogger::Log(const std::string& className, const std::string& message) { void dLogger::LogDebug(const char* className, const char* format, ...) { if (!m_logDebugStatements) return; va_list args; - std::string log = "[" + std::string(className) + "] " + std::string(format); + std::string log = "[" + std::string(className) + "] " + std::string(format) + "\n"; va_start(args, format); vLog(log.c_str(), args); va_end(args); From bad3845d83712eaed717b29dab819e5f396d6866 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:04:20 -0800 Subject: [PATCH 099/166] Address Docker issues and remove need to extract cdclient.fdb (#895) * Implement a server res directory * Only convert if neither exist * Remove unzip, Update RegEx * readme updates Run setup after setting working dir Address several docker issues Revert "Run setup after setting working dir" This reverts commit fd2fb9228e82a350204c1ef61f7ba059479bb12f. Fix docker * Remove extra submodules * Rework logic * Switch if block * Remove need to extract fdb from client * Change log name * Update FdbToSqlite.cpp --- .gitmodules | 6 -- Docker.md | 2 +- Docker_Windows.md | 2 +- dCommon/FdbToSqlite.cpp | 142 +++++++++++++++---------------- dCommon/FdbToSqlite.h | 40 ++++----- dCommon/dClient/AssetManager.cpp | 28 ------ dCommon/dClient/AssetManager.h | 1 - dMasterServer/MasterServer.cpp | 23 ++--- docker/Dockerfile | 7 +- docker/setup.Dockerfile | 15 +--- docker/setup.sh | 55 +----------- docker/start_server.sh | 29 +------ thirdparty/LUnpack | 1 - thirdparty/docker-utils | 1 - 14 files changed, 109 insertions(+), 243 deletions(-) mode change 100644 => 100755 docker/start_server.sh delete mode 160000 thirdparty/LUnpack delete mode 160000 thirdparty/docker-utils diff --git a/.gitmodules b/.gitmodules index 6fb56bde..33193447 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,12 +14,6 @@ path = thirdparty/mariadb-connector-cpp url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git ignore = dirty -[submodule "thirdparty/docker-utils"] - path = thirdparty/docker-utils - url = https://github.com/lcdr/utils.git -[submodule "thirdparty/LUnpack"] - path = thirdparty/LUnpack - url = https://github.com/Xiphoseer/LUnpack.git [submodule "thirdparty/AccountManager"] path = thirdparty/AccountManager url = https://github.com/DarkflameUniverse/AccountManager diff --git a/Docker.md b/Docker.md index 54d0ce19..b06bd0fe 100644 --- a/Docker.md +++ b/Docker.md @@ -4,7 +4,7 @@ - [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker) - [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop) -- LEGO® Universe packed Client. Check the main [README](./README.md) for details on this. +- LEGO® Universe Client. Check the main [README](./README.md) for details on this. ## Run server inside Docker diff --git a/Docker_Windows.md b/Docker_Windows.md index 1cc633cc..984bbe57 100644 --- a/Docker_Windows.md +++ b/Docker_Windows.md @@ -25,7 +25,7 @@ 11. Once the command has completed (you can see you path again and can enter commands), close the window. 12. Inside the downloaded folder, copy `.env.example` and name the copy `.env` 13. Open `.env` with Notepad by right-clicking it and selecting _Open With_ -> _More apps_ -> _Notepad_. -14. Change the text after `CLIENT_PATH=` to the location of your client. The folder you are pointing to must contain a folder called `client` which should contain the client files. +14. Change the text after `CLIENT_PATH=` to the location of your client. This folder must contain either a folder `client` or `legouniverse.exe`. > If you need the extra performance, place the client files in `\\wsl$\\...` to avoid working across file systems, see [Docker Best Practices](https://docs.docker.com/desktop/windows/wsl/#best-practices) and [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/filesystems#file-storage-and-performance-across-file-systems). 15. Optionally, you can change the number after `BUILD_THREADS=` to the number of cores / threads your processor has. If your computer crashes while building, you can try to reduce this value. diff --git a/dCommon/FdbToSqlite.cpp b/dCommon/FdbToSqlite.cpp index 80251e89..e05286a9 100644 --- a/dCommon/FdbToSqlite.cpp +++ b/dCommon/FdbToSqlite.cpp @@ -10,6 +10,7 @@ #include "GeneralUtils.h" #include "Game.h" #include "dLogger.h" +#include "AssetManager.h" #include "eSqliteDataType.h" @@ -23,26 +24,23 @@ std::map FdbToSqlite::Convert::m_SqliteType = { { eSqliteDataType::TEXT_8, "text_8"} }; -FdbToSqlite::Convert::Convert(std::string basePath, std::string binaryOutPath) { - this->m_BasePath = basePath; +FdbToSqlite::Convert::Convert(std::string binaryOutPath) { this->m_BinaryOutPath = binaryOutPath; - m_Fdb.open(m_BasePath + "/cdclient.fdb", std::ios::binary); } -FdbToSqlite::Convert::~Convert() { - this->m_Fdb.close(); -} - -bool FdbToSqlite::Convert::ConvertDatabase() { +bool FdbToSqlite::Convert::ConvertDatabase(AssetMemoryBuffer& buffer) { if (m_ConversionStarted) return false; + + std::istream cdClientBuffer(&buffer); + this->m_ConversionStarted = true; try { CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite"); CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;"); - int32_t numberOfTables = ReadInt32(); - ReadTables(numberOfTables); + int32_t numberOfTables = ReadInt32(cdClientBuffer); + ReadTables(numberOfTables, cdClientBuffer); CDClientDatabase::ExecuteQuery("COMMIT;"); } catch (CppSQLite3Exception& e) { @@ -53,130 +51,130 @@ bool FdbToSqlite::Convert::ConvertDatabase() { return true; } -int32_t FdbToSqlite::Convert::ReadInt32() { +int32_t FdbToSqlite::Convert::ReadInt32(std::istream& cdClientBuffer) { int32_t nextInt{}; - BinaryIO::BinaryRead(m_Fdb, nextInt); + BinaryIO::BinaryRead(cdClientBuffer, nextInt); return nextInt; } -int64_t FdbToSqlite::Convert::ReadInt64() { - int32_t prevPosition = SeekPointer(); +int64_t FdbToSqlite::Convert::ReadInt64(std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); int64_t value{}; - BinaryIO::BinaryRead(m_Fdb, value); + BinaryIO::BinaryRead(cdClientBuffer, value); - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); return value; } -std::string FdbToSqlite::Convert::ReadString() { - int32_t prevPosition = SeekPointer(); +std::string FdbToSqlite::Convert::ReadString(std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); - auto readString = BinaryIO::ReadString(m_Fdb); + auto readString = BinaryIO::ReadString(cdClientBuffer); - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); return readString; } -int32_t FdbToSqlite::Convert::SeekPointer() { +int32_t FdbToSqlite::Convert::SeekPointer(std::istream& cdClientBuffer) { int32_t position{}; - BinaryIO::BinaryRead(m_Fdb, position); - int32_t prevPosition = m_Fdb.tellg(); - m_Fdb.seekg(position); + BinaryIO::BinaryRead(cdClientBuffer, position); + int32_t prevPosition = cdClientBuffer.tellg(); + cdClientBuffer.seekg(position); return prevPosition; } -std::string FdbToSqlite::Convert::ReadColumnHeader() { - int32_t prevPosition = SeekPointer(); +std::string FdbToSqlite::Convert::ReadColumnHeader(std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); - int32_t numberOfColumns = ReadInt32(); - std::string tableName = ReadString(); + int32_t numberOfColumns = ReadInt32(cdClientBuffer); + std::string tableName = ReadString(cdClientBuffer); - auto columns = ReadColumns(numberOfColumns); + auto columns = ReadColumns(numberOfColumns, cdClientBuffer); std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");"; CDClientDatabase::ExecuteDML(newTable); - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); return tableName; } -void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables) { - int32_t prevPosition = SeekPointer(); +void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables, std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); for (int32_t i = 0; i < numberOfTables; i++) { - auto columnHeader = ReadColumnHeader(); - ReadRowHeader(columnHeader); + auto columnHeader = ReadColumnHeader(cdClientBuffer); + ReadRowHeader(columnHeader, cdClientBuffer); } - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); } -std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns) { +std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns, std::istream& cdClientBuffer) { std::stringstream columnsToCreate; - int32_t prevPosition = SeekPointer(); + int32_t prevPosition = SeekPointer(cdClientBuffer); std::string name{}; eSqliteDataType dataType{}; for (int32_t i = 0; i < numberOfColumns; i++) { if (i != 0) columnsToCreate << ", "; - dataType = static_cast(ReadInt32()); - name = ReadString(); + dataType = static_cast(ReadInt32(cdClientBuffer)); + name = ReadString(cdClientBuffer); columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::m_SqliteType[dataType]; } - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); return columnsToCreate.str(); } -void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName) { - int32_t prevPosition = SeekPointer(); +void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName, std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); - int32_t numberOfAllocatedRows = ReadInt32(); + int32_t numberOfAllocatedRows = ReadInt32(cdClientBuffer); if (numberOfAllocatedRows != 0) assert((numberOfAllocatedRows & (numberOfAllocatedRows - 1)) == 0); // assert power of 2 allocation size - ReadRows(numberOfAllocatedRows, tableName); + ReadRows(numberOfAllocatedRows, tableName, cdClientBuffer); - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); } -void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName) { - int32_t prevPosition = SeekPointer(); +void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName, std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); int32_t rowid = 0; for (int32_t row = 0; row < numberOfAllocatedRows; row++) { - int32_t rowPointer = ReadInt32(); + int32_t rowPointer = ReadInt32(cdClientBuffer); if (rowPointer == -1) rowid++; - else ReadRow(rowPointer, tableName); + else ReadRow(rowPointer, tableName, cdClientBuffer); } - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); } -void FdbToSqlite::Convert::ReadRow(int32_t& position, std::string& tableName) { - int32_t prevPosition = m_Fdb.tellg(); - m_Fdb.seekg(position); +void FdbToSqlite::Convert::ReadRow(int32_t& position, std::string& tableName, std::istream& cdClientBuffer) { + int32_t prevPosition = cdClientBuffer.tellg(); + cdClientBuffer.seekg(position); while (true) { - ReadRowInfo(tableName); - int32_t linked = ReadInt32(); + ReadRowInfo(tableName, cdClientBuffer); + int32_t linked = ReadInt32(cdClientBuffer); if (linked == -1) break; - m_Fdb.seekg(linked); + cdClientBuffer.seekg(linked); } - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); } -void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName) { - int32_t prevPosition = SeekPointer(); +void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName, std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); - int32_t numberOfColumns = ReadInt32(); - ReadRowValues(numberOfColumns, tableName); + int32_t numberOfColumns = ReadInt32(cdClientBuffer); + ReadRowValues(numberOfColumns, tableName, cdClientBuffer); - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); } -void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName) { - int32_t prevPosition = SeekPointer(); +void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName, std::istream& cdClientBuffer) { + int32_t prevPosition = SeekPointer(cdClientBuffer); int32_t emptyValue{}; int32_t intValue{}; @@ -190,26 +188,26 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& for (int32_t i = 0; i < numberOfColumns; i++) { if (i != 0) insertedRow << ", "; // Only append comma and space after first entry in row. - switch (static_cast(ReadInt32())) { + switch (static_cast(ReadInt32(cdClientBuffer))) { case eSqliteDataType::NONE: - BinaryIO::BinaryRead(m_Fdb, emptyValue); + BinaryIO::BinaryRead(cdClientBuffer, emptyValue); assert(emptyValue == 0); insertedRow << "NULL"; break; case eSqliteDataType::INT32: - intValue = ReadInt32(); + intValue = ReadInt32(cdClientBuffer); insertedRow << intValue; break; case eSqliteDataType::REAL: - BinaryIO::BinaryRead(m_Fdb, floatValue); + BinaryIO::BinaryRead(cdClientBuffer, floatValue); insertedRow << std::fixed << std::setprecision(34) << floatValue; // maximum precision of floating point number break; case eSqliteDataType::TEXT_4: case eSqliteDataType::TEXT_8: { - stringValue = ReadString(); + stringValue = ReadString(cdClientBuffer); size_t position = 0; // Need to escape quote with a double of ". @@ -225,12 +223,12 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& } case eSqliteDataType::INT_BOOL: - BinaryIO::BinaryRead(m_Fdb, boolValue); + BinaryIO::BinaryRead(cdClientBuffer, boolValue); insertedRow << static_cast(boolValue); break; case eSqliteDataType::INT64: - int64Value = ReadInt64(); + int64Value = ReadInt64(cdClientBuffer); insertedRow << std::to_string(int64Value); break; @@ -245,5 +243,5 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& auto copiedString = insertedRow.str(); CDClientDatabase::ExecuteDML(copiedString); - m_Fdb.seekg(prevPosition); + cdClientBuffer.seekg(prevPosition); } diff --git a/dCommon/FdbToSqlite.h b/dCommon/FdbToSqlite.h index cfa5263b..7aad2703 100644 --- a/dCommon/FdbToSqlite.h +++ b/dCommon/FdbToSqlite.h @@ -7,6 +7,8 @@ #include #include +class AssetMemoryBuffer; + enum class eSqliteDataType : int32_t; namespace FdbToSqlite { @@ -18,33 +20,28 @@ namespace FdbToSqlite { * @param inputFile The file which ends in .fdb to be converted * @param binaryPath The base path where the file will be saved */ - Convert(std::string inputFile, std::string binaryOutPath); - - /** - * Destroy the convert object and close the fdb file. - */ - ~Convert(); + Convert(std::string binaryOutPath); /** * Converts the input file to sqlite. Calling multiple times is safe. * * @return true if the database was converted properly, false otherwise. */ - bool ConvertDatabase(); + bool ConvertDatabase(AssetMemoryBuffer& buffer); /** * @brief Reads a 32 bit int from the fdb file. * * @return The read value */ - int32_t ReadInt32(); + int32_t ReadInt32(std::istream& cdClientBuffer); /** * @brief Reads a 64 bit integer from the fdb file. * * @return The read value */ - int64_t ReadInt64(); + int64_t ReadInt64(std::istream& cdClientBuffer); /** * @brief Reads a string from the fdb file. @@ -53,28 +50,28 @@ namespace FdbToSqlite { * * TODO This needs to be translated to latin-1! */ - std::string ReadString(); + std::string ReadString(std::istream& cdClientBuffer); /** * @brief Seeks to a pointer position. * * @return The previous position before the seek */ - int32_t SeekPointer(); + int32_t SeekPointer(std::istream& cdClientBuffer); /** * @brief Reads a column header from the fdb file and creates the table in the database * * @return The table name */ - std::string ReadColumnHeader(); + std::string ReadColumnHeader(std::istream& cdClientBuffer); /** * @brief Read the tables from the fdb file. * * @param numberOfTables The number of tables to read */ - void ReadTables(int32_t& numberOfTables); + void ReadTables(int32_t& numberOfTables, std::istream& cdClientBuffer); /** * @brief Reads the columns from the fdb file. @@ -82,14 +79,14 @@ namespace FdbToSqlite { * @param numberOfColumns The number of columns to read * @return All columns of the table formatted for a sql query */ - std::string ReadColumns(int32_t& numberOfColumns); + std::string ReadColumns(int32_t& numberOfColumns, std::istream& cdClientBuffer); /** * @brief Reads the row header from the fdb file. * * @param tableName The tables name */ - void ReadRowHeader(std::string& tableName); + void ReadRowHeader(std::string& tableName, std::istream& cdClientBuffer); /** * @brief Read the rows from the fdb file., @@ -97,7 +94,7 @@ namespace FdbToSqlite { * @param numberOfAllocatedRows The number of rows that were allocated. Always a power of 2! * @param tableName The tables name. */ - void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName); + void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName, std::istream& cdClientBuffer); /** * @brief Reads a row from the fdb file. @@ -105,14 +102,14 @@ namespace FdbToSqlite { * @param position The position to seek in the fdb to * @param tableName The tables name */ - void ReadRow(int32_t& position, std::string& tableName); + void ReadRow(int32_t& position, std::string& tableName, std::istream& cdClientBuffer); /** * @brief Reads the row info from the fdb file. * * @param tableName The tables name */ - void ReadRowInfo(std::string& tableName); + void ReadRowInfo(std::string& tableName, std::istream& cdClientBuffer); /** * @brief Reads each row and its values from the fdb file and inserts them into the database @@ -120,7 +117,7 @@ namespace FdbToSqlite { * @param numberOfColumns The number of columns to read in * @param tableName The tables name */ - void ReadRowValues(int32_t& numberOfColumns, std::string& tableName); + void ReadRowValues(int32_t& numberOfColumns, std::string& tableName, std::istream& cdClientBuffer); private: /** @@ -132,11 +129,6 @@ namespace FdbToSqlite { * Base path of the folder containing the fdb file */ std::string m_BasePath{}; - - /** - * ifstream containing the fdb file - */ - std::ifstream m_Fdb{}; /** * Whether or not a conversion was started. If one was started, do not attempt to convert the file again. diff --git a/dCommon/dClient/AssetManager.cpp b/dCommon/dClient/AssetManager.cpp index dc3db0a1..ed86d719 100644 --- a/dCommon/dClient/AssetManager.cpp +++ b/dCommon/dClient/AssetManager.cpp @@ -45,9 +45,6 @@ AssetManager::AssetManager(const std::filesystem::path& path) { switch (m_AssetBundleType) { case eAssetBundleType::Packed: { this->LoadPackIndex(); - - this->UnpackRequiredAssets(); - break; } } @@ -160,31 +157,6 @@ AssetMemoryBuffer AssetManager::GetFileAsBuffer(const char* name) { return AssetMemoryBuffer(buf, len, success); } -void AssetManager::UnpackRequiredAssets() { - if (std::filesystem::exists(m_ResPath / "cdclient.fdb")) return; - - char* data; - uint32_t size; - - bool success = this->GetFile("cdclient.fdb", &data, &size); - - if (!success) { - Game::logger->Log("AssetManager", "Failed to extract required files from the packs."); - - delete data; - - return; - } - - std::ofstream cdclientOutput(m_ResPath / "cdclient.fdb", std::ios::out | std::ios::binary); - cdclientOutput.write(data, size); - cdclientOutput.close(); - - delete data; - - return; -} - uint32_t AssetManager::crc32b(uint32_t base, uint8_t* message, size_t l) { size_t i, j; uint32_t crc, msb; diff --git a/dCommon/dClient/AssetManager.h b/dCommon/dClient/AssetManager.h index 73b24f18..bc7e5ff7 100644 --- a/dCommon/dClient/AssetManager.h +++ b/dCommon/dClient/AssetManager.h @@ -60,7 +60,6 @@ public: private: void LoadPackIndex(); - void UnpackRequiredAssets(); // Modified crc algorithm (mpeg2) // Reference: https://stackoverflow.com/questions/54339800/how-to-modify-crc-32-to-crc-32-mpeg-2 diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 34ce59c7..82645797 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -156,22 +156,25 @@ int main(int argc, char** argv) { Game::logger->Log("MasterServer", "CDServer.sqlite is not located at resServer, but is located at res path. Copying file..."); std::filesystem::copy_file(Game::assetManager->GetResPath() / "CDServer.sqlite", BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite"); } else { - Game::logger->Log("WorldServer", + Game::logger->Log("MasterServer", "%s could not be found in resServer or res. Looking for %s to convert to sqlite.", (BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(), (Game::assetManager->GetResPath() / "cdclient.fdb").c_str()); - if (!fdbExists) { - Game::logger->Log("WorldServer", - "%s could not be opened. Please move cdclient.fdb to %s", - (Game::assetManager->GetResPath() / "cdclient.fdb").c_str(), - (Game::assetManager->GetResPath().c_str())); - return FinalizeShutdown(); + + AssetMemoryBuffer cdClientBuffer = Game::assetManager->GetFileAsBuffer("cdclient.fdb"); + if (!cdClientBuffer.m_Success) { + Game::logger->Log("MasterServer", "Failed to load %s", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str()); + throw std::runtime_error("Aborting initialization due to missing cdclient.fdb."); } - Game::logger->Log("WorldServer", "Found cdclient.fdb. Converting to SQLite"); - if (FdbToSqlite::Convert(Game::assetManager->GetResPath().string(), (BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase() == false) { + + Game::logger->Log("MasterServer", "Found %s. Converting to SQLite", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str()); + Game::logger->Flush(); + + if (FdbToSqlite::Convert((BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase(cdClientBuffer) == false) { Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite."); - return FinalizeShutdown(); + return EXIT_FAILURE; } + cdClientBuffer.close(); } } diff --git a/docker/Dockerfile b/docker/Dockerfile index 50f5b083..a7d91855 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -6,7 +6,7 @@ RUN --mount=type=cache,id=build-apt-cache,target=/var/cache/apt \ echo "Install build dependencies" && \ apt update && \ apt remove -y libmysqlcppconn7v5 libmysqlcppconn-dev && \ - apt install cmake zlib1g zlib1g-dev unzip -yqq --no-install-recommends && \ + apt install cmake zlib1g zlib1g-dev -yqq --no-install-recommends && \ rm -rf /var/lib/apt/lists/* COPY dAuthServer/ /build/dAuthServer @@ -35,12 +35,11 @@ ARG BUILD_VERSION=171022 RUN echo "Build server" && \ mkdir -p cmake_build && \ cd cmake_build && \ - sed -i -e "s/171022/${BUILD_VERSION}/g" ../CMakeVariables.txt && \ + sed -i -e "s/NET_VERSION=.*/NET_VERSION=${BUILD_VERSION}/g" ../CMakeVariables.txt && \ + sed -i -e "s/__maria_db_connector_compile_jobs__=.*/__maria_db_connector_compile_jobs__=${BUILD_THREADS}/g" ../CMakeVariables.txt && \ cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \ make -j $BUILD_THREADS -RUN unzip /build/resources/navmeshes.zip -d /build/cmake_build/res/maps - FROM gcc:11 as runtime RUN --mount=type=cache,id=runtime-apt-cache,target=/var/cache/apt \ diff --git a/docker/setup.Dockerfile b/docker/setup.Dockerfile index 2664e2fa..18bb2d06 100644 --- a/docker/setup.Dockerfile +++ b/docker/setup.Dockerfile @@ -1,23 +1,12 @@ -FROM rust:alpine3.14 as LUnpack - -WORKDIR /build_LUnpack - -COPY ./thirdparty/LUnpack . - -RUN apk add musl-dev --no-cache && cargo build --release - FROM python:3.10-alpine3.14 as prep -RUN apk add sqlite bash --no-cache +RUN apk add bash --no-cache WORKDIR /setup # copy needed files from repo COPY resources/ resources/ -COPY migrations/cdserver/ migrations/cdserver -COPY --from=LUnpack /build_LUnpack/target/release/lunpack /usr/local/bin/lunpack -ADD thirdparty/docker-utils/utils/*.py utils/ COPY docker/setup.sh /setup.sh -CMD [ "/setup.sh" ] \ No newline at end of file +CMD [ "/setup.sh" ] diff --git a/docker/setup.sh b/docker/setup.sh index 0f5c0d2e..ade67d2e 100755 --- a/docker/setup.sh +++ b/docker/setup.sh @@ -7,7 +7,7 @@ function update_ini() { FILE="/docker/configs/$1" KEY=$2 NEW_VALUE=$3 - sed -i "/^$KEY=/s/=.*/=$NEW_VALUE/" $FILE + sed -i "s~$2=.*~$2=$3~" $FILE } function update_database_ini_values_for() { @@ -32,62 +32,11 @@ function update_ini_values() { cp resources/worldconfig.ini /docker/configs/ cp resources/sharedconfig.ini /docker/configs/ - update_ini worldconfig.ini chat_server_port $CHAT_SERVER_PORT - update_ini worldconfig.ini max_clients $MAX_CLIENTS - # always use the internal docker hostname update_ini masterconfig.ini master_ip "darkflame" + update_ini sharedconfig.ini client_location "/client" update_database_ini_values_for sharedconfig.ini } -function fdb_to_sqlite() { - echo "Run fdb_to_sqlite" - python3 utils/fdb_to_sqlite.py /client/client/res/cdclient.fdb --sqlite_path /client/client/res/CDServer.sqlite - - ( - cd migrations/cdserver - readarray -d '' entries < <(printf '%s\0' *.sql | sort -zV) - for entry in "${entries[@]}"; do - echo "Execute $entry" - sqlite3 /client/client/res/CDServer.sqlite < $entry - done - ) -} - update_ini_values - -if [[ ! -d "/client" ]]; then - echo "Client not found." - echo "Did you forget to mount the client into the \"/client\" directory?" - exit 1 -fi - -if [[ ! -f "/client/extracted" ]]; then - echo "Start client resource extraction" - - touch globs.txt - - echo "client/res/macros/**" >> globs.txt - echo "client/res/BrickModels/**" >> globs.txt - echo "client/res/maps/**" >> globs.txt - echo "*.fdb" >> globs.txt - - lunpack -g ./globs.txt /client/ - - touch /client/extracted -else - echo "Client already extracted. Skip this step..." - echo "If you want to force a re-extract, just delete the file called \"extracted\" in the client directory" -fi - -if [[ ! -f "/client/migrated" ]]; then - echo "Start client db migration" - - fdb_to_sqlite - - touch /client/migrated -else - echo "Client db already migrated. Skip this step..." - echo "If you want to force a re-migrate, just delete the file called \"migrated\" in the client directory" -fi diff --git a/docker/start_server.sh b/docker/start_server.sh old mode 100644 new mode 100755 index 4fd6e2be..2e2e8c28 --- a/docker/start_server.sh +++ b/docker/start_server.sh @@ -1,25 +1,5 @@ #!/bin/bash -function symlink_client_files() { - echo "Creating symlinks for client files" - ln -s /client/client/res/macros/ /app/res/macros - ln -s /client/client/res/BrickModels/ /app/res/BrickModels - ln -s /client/client/res/chatplus_en_us.txt /app/res/chatplus_en_us.txt - ln -s /client/client/res/names/ /app/res/names - ln -s /client/client/res/CDServer.sqlite /app/res/CDServer.sqlite - - # need to create this file so the server knows the client is unpacked (see `dCommon/dClient/AssetManager.cpp`) - touch /app/res/cdclient.fdb - # need to iterate over entries in maps due to maps already being a directory with navmeshes/ in it - ( - cd /client/client/res/maps - readarray -d '' entries < <(printf '%s\0' * | sort -zV) - for entry in "${entries[@]}"; do - ln -s /client/client/res/maps/$entry /app/res/maps/ - done - ) -} - function symlink_config_files() { echo "Creating symlinks for config files" rm /app/*.ini @@ -30,15 +10,8 @@ function symlink_config_files() { ln -s /shared_configs/configs/sharedconfig.ini /app/sharedconfig.ini } -# check to make sure the setup has completed -while [ ! -f "/client/extracted" ] || [ ! -f "/client/migrated" ]; do - echo "Client setup not finished. Waiting for setup container to complete..." - sleep 5 -done - if [[ ! -f "/app/initialized" ]]; then # setup symlinks for volume files - symlink_client_files symlink_config_files # do not run symlinks more than once touch /app/initialized @@ -49,4 +22,4 @@ fi # start the server echo "Starting MasterServer" ./MasterServer -tail -f /dev/null \ No newline at end of file +tail -f /dev/null diff --git a/thirdparty/LUnpack b/thirdparty/LUnpack deleted file mode 160000 index f8d7e442..00000000 --- a/thirdparty/LUnpack +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f8d7e442a78910b298fe1cd5780f07c9c9285b8c diff --git a/thirdparty/docker-utils b/thirdparty/docker-utils deleted file mode 160000 index 3f0129e0..00000000 --- a/thirdparty/docker-utils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3f0129e0939ce5ccf41f0808dcbbe71a6243e37f From 8bcb4bd36d12282707776b3995dd946990768c81 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:06:24 -0800 Subject: [PATCH 100/166] Fix smashables not counting towards whole team (#944) --- dGame/dComponents/DestroyableComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 8d8ed42a..1b127c41 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -701,7 +701,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType auto* missions = owner->GetComponent(); if (missions != nullptr) { - if (team != nullptr && isEnemy) { + if (team != nullptr) { for (const auto memberId : team->members) { auto* member = EntityManager::Instance()->GetEntity(memberId); From fc75d6048fbd917586c5b7a75551dbe09288c495 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:17:05 -0800 Subject: [PATCH 101/166] dGame Precompiled header improvements (#876) * moving branch * Add deleteinven slash command * Change name of BRICKS_IN_BBB * Use string_view instead of strcmp * Clean up include tree * Remove unneeded headers from PCH files Removes unneeded headers from pre-compiled headers. This increases compile time, however reduces development time for most files. * Update Entity.h * Update EntityManager.h * Update GameMessages.cpp * There it compiles now Co-authored-by: Aaron Kimbrell --- dCommon/dEnums/MissionState.h | 2 +- dCommon/{ => dEnums}/PermissionMap.h | 0 .../{ => dEnums}/eBlueprintSaveResponseType.h | 0 dCommon/dEnums/eMovementPlatformState.h | 16 + dGame/Entity.cpp | 5 + dGame/Entity.h | 25 +- dGame/EntityManager.cpp | 1 + dGame/EntityManager.h | 10 +- dGame/Player.cpp | 2 + dGame/UserManager.cpp | 1 + dGame/dBehaviors/BehaviorContext.cpp | 5 +- dGame/dBehaviors/SpawnBehavior.cpp | 2 + dGame/dComponents/CharacterComponent.cpp | 1 + dGame/dComponents/MovingPlatformComponent.cpp | 15 +- dGame/dComponents/MovingPlatformComponent.h | 17 +- dGame/dComponents/PetComponent.cpp | 1 + dGame/dComponents/PhantomPhysicsComponent.cpp | 1 + .../dComponents/PropertyEntranceComponent.cpp | 1 + dGame/dComponents/RacingControlComponent.cpp | 1 + dGame/dComponents/RebuildComponent.cpp | 1 + .../dComponents/ScriptedActivityComponent.cpp | 2 + dGame/dComponents/SkillComponent.cpp | 8 +- .../dGameMessages/DoClientProjectileImpact.h | 83 +++ dGame/dGameMessages/EchoStartSkill.h | 132 ++++ dGame/dGameMessages/EchoSyncSkill.h | 70 +++ dGame/dGameMessages/GameMessageHandler.cpp | 15 +- dGame/dGameMessages/GameMessages.cpp | 13 +- dGame/dGameMessages/GameMessages.h | 577 +----------------- .../RequestServerProjectileImpact.h | 74 +++ dGame/dGameMessages/StartSkill.h | 144 +++++ dGame/dGameMessages/SyncSkill.h | 68 +++ dGame/dInventory/Item.cpp | 1 + dGame/dMission/Mission.cpp | 1 + dGame/dMission/Mission.h | 6 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 1 + dGame/dUtilities/BrickDatabase.cpp | 1 + dGame/dUtilities/SlashCommandHandler.cpp | 6 + dGame/dUtilities/VanityUtilities.cpp | 1 + dNet/ClientPackets.cpp | 2 +- .../02_server/Enemy/AM/AmDarklingDragon.cpp | 2 + .../02_server/Enemy/FV/FvMaelstromDragon.cpp | 2 + .../02_server/Enemy/General/BaseEnemyApe.cpp | 2 + .../02_server/Enemy/General/BaseEnemyMech.cpp | 1 + .../General/TreasureChestDragonServer.cpp | 1 + .../02_server/Equipment/BootyDigServer.cpp | 1 + dScripts/02_server/Map/AG/NpcPirateServer.cpp | 1 + dScripts/02_server/Map/AG/NpcWispServer.cpp | 1 + .../02_server/Map/AG/RemoveRentalGear.cpp | 1 + .../Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp | 1 + dScripts/02_server/Map/AM/AmBlueX.cpp | 1 + .../02_server/Map/AM/AmShieldGenerator.cpp | 1 + .../Map/AM/AmShieldGeneratorQuickbuild.cpp | 1 + dScripts/02_server/Map/AM/AmSkullkinDrill.cpp | 1 + dScripts/02_server/Map/AM/AmSkullkinTower.cpp | 1 + .../02_server/Map/FV/EnemyRoninSpawner.cpp | 1 + .../Map/General/BankInteractServer.cpp | 2 + .../02_server/Map/General/GrowingFlower.cpp | 1 + .../02_server/Map/General/PetDigServer.cpp | 1 + .../Map/General/PropertyPlatform.cpp | 5 +- dScripts/02_server/Map/General/QbSpawner.cpp | 2 +- .../Map/General/WishingWellServer.cpp | 2 + .../Map/NS/NsConcertChoiceBuildManager.cpp | 1 + dScripts/02_server/Map/NS/NsLegoClubDoor.h | 1 + dScripts/02_server/Map/NS/NsLupTeleport.h | 1 + .../Map/NT/NtCombatChallengeServer.cpp | 1 + dScripts/02_server/Map/NT/NtVandaServer.cpp | 1 + .../Property/AG_Small/EnemySpiderSpawner.cpp | 1 + .../Map/Property/PropertyBankInteract.cpp | 1 + dScripts/02_server/Map/VE/VeEpsilonServer.cpp | 2 + .../02_server/Map/VE/VeMissionConsole.cpp | 1 + .../Map/njhub/EnemySkeletonSpawner.cpp | 1 + .../Map/njhub/NjDragonEmblemChestServer.cpp | 3 + .../Map/njhub/NjNPCMissionSpinjitzuServer.cpp | 1 + dScripts/02_server/Map/njhub/RainOfArrows.cpp | 1 + .../General/MinigameTreasureChestServer.cpp | 1 + .../02_server/Objects/StinkyFishTarget.cpp | 1 + dScripts/ActivityManager.cpp | 1 + dScripts/CppScripts.h | 5 +- dScripts/NPCAddRemoveItem.cpp | 1 + dScripts/ScriptedPowerupSpawner.cpp | 1 + dScripts/SpawnPetBaseServer.cpp | 1 + dScripts/ai/AG/AgImagSmashable.cpp | 1 + dScripts/ai/AG/AgPicnicBlanket.cpp | 2 + dScripts/ai/AG/AgQbElevator.cpp | 6 +- dScripts/ai/AG/AgSpaceStuff.cpp | 1 + dScripts/ai/FV/FvPandaSpawnerServer.cpp | 1 + dScripts/ai/GF/GfBanana.cpp | 1 + dScripts/ai/GF/PetDigBuild.cpp | 1 + dScripts/ai/GF/PirateRep.cpp | 2 + .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 1 + dScripts/ai/NS/WH/RockHydrantSmashable.cpp | 1 + dScripts/ai/PETS/HydrantSmashable.cpp | 1 + dScripts/ai/PROPERTY/AgPropguards.cpp | 1 + dWorldServer/WorldServer.cpp | 5 + dZoneManager/LUTriggers.h | 30 + dZoneManager/Spawner.h | 1 + dZoneManager/Zone.cpp | 1 + dZoneManager/Zone.h | 41 +- tests/dGameTests/GameDependencies.h | 1 + 99 files changed, 821 insertions(+), 648 deletions(-) rename dCommon/{ => dEnums}/PermissionMap.h (100%) rename dCommon/{ => dEnums}/eBlueprintSaveResponseType.h (100%) create mode 100644 dCommon/dEnums/eMovementPlatformState.h create mode 100644 dGame/dGameMessages/DoClientProjectileImpact.h create mode 100644 dGame/dGameMessages/EchoStartSkill.h create mode 100644 dGame/dGameMessages/EchoSyncSkill.h create mode 100644 dGame/dGameMessages/RequestServerProjectileImpact.h create mode 100644 dGame/dGameMessages/StartSkill.h create mode 100644 dGame/dGameMessages/SyncSkill.h create mode 100644 dZoneManager/LUTriggers.h diff --git a/dCommon/dEnums/MissionState.h b/dCommon/dEnums/MissionState.h index fb1841d3..f040d33a 100644 --- a/dCommon/dEnums/MissionState.h +++ b/dCommon/dEnums/MissionState.h @@ -6,7 +6,7 @@ /** * Represents the possible states a mission can be in */ -enum class MissionState : int { +enum class MissionState : int32_t { /** * The mission state is unknown */ diff --git a/dCommon/PermissionMap.h b/dCommon/dEnums/PermissionMap.h similarity index 100% rename from dCommon/PermissionMap.h rename to dCommon/dEnums/PermissionMap.h diff --git a/dCommon/eBlueprintSaveResponseType.h b/dCommon/dEnums/eBlueprintSaveResponseType.h similarity index 100% rename from dCommon/eBlueprintSaveResponseType.h rename to dCommon/dEnums/eBlueprintSaveResponseType.h diff --git a/dCommon/dEnums/eMovementPlatformState.h b/dCommon/dEnums/eMovementPlatformState.h new file mode 100644 index 00000000..1df437d8 --- /dev/null +++ b/dCommon/dEnums/eMovementPlatformState.h @@ -0,0 +1,16 @@ +#ifndef __EMOVEMENTPLATFORMSTATE__H__ +#define __EMOVEMENTPLATFORMSTATE__H__ + +#include + +/** + * The different types of platform movement state, supposedly a bitmap + */ +enum class eMovementPlatformState : uint32_t +{ + Moving = 0b00010, + Stationary = 0b11001, + Stopped = 0b01100 +}; + +#endif //!__EMOVEMENTPLATFORMSTATE__H__ diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 16b2c5a1..c0f71324 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -17,6 +17,11 @@ #include "UserManager.h" #include "dpWorld.h" #include "Player.h" +#include "LUTriggers.h" +#include "User.h" +#include "EntityTimer.h" +#include "EntityCallbackTimer.h" +#include "Loot.h" //Component includes: #include "Component.h" diff --git a/dGame/Entity.h b/dGame/Entity.h index e0d38308..248018c0 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -4,30 +4,35 @@ #include #include #include +#include #include -#include "../thirdparty/raknet/Source/Replica.h" -#include "../thirdparty/raknet/Source/ReplicaManager.h" - -#include "dCommonVars.h" -#include "User.h" #include "NiPoint3.h" #include "NiQuaternion.h" #include "LDFFormat.h" -#include "Loot.h" -#include "Zone.h" -#include "EntityTimer.h" -#include "EntityCallbackTimer.h" -#include "EntityInfo.h" +namespace Loot { + class Info; +}; + +namespace tinyxml2 { + class XMLDocument; +}; +namespace LUTriggers { + struct Trigger; +}; class Player; +class EntityInfo; +class User; class Spawner; class ScriptComponent; class dpEntity; +class EntityTimer; class Component; class Item; class Character; +class EntityCallbackTimer; namespace CppScripts { class Script; diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 02b8b59e..99ead79d 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -17,6 +17,7 @@ #include "MissionComponent.h" #include "Game.h" #include "dLogger.h" +#include "MessageIdentifiers.h" EntityManager* EntityManager::m_Address = nullptr; diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 40a98076..36bc5962 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -2,15 +2,17 @@ #define ENTITYMANAGER_H #include "dCommonVars.h" -#include "../thirdparty/raknet/Source/Replica.h" #include #include - -#include "Entity.h" #include +#include + +class Entity; +class EntityInfo; +class Player; +class User; struct SystemAddress; -class User; class EntityManager { public: diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 5306584e..4f4bc951 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -13,7 +13,9 @@ #include "dZoneManager.h" #include "CharacterComponent.h" #include "Mail.h" +#include "User.h" #include "CppScripts.h" +#include "Loot.h" std::vector Player::m_Players = {}; diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 70e76016..93469daa 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -22,6 +22,7 @@ #include "SkillComponent.h" #include "AssetManager.h" #include "CDClientDatabase.h" +#include "dMessageIdentifiers.h" UserManager* UserManager::m_Address = nullptr; diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index ebed10ba..26d1e9e6 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -10,8 +10,9 @@ #include - +#include "dMessageIdentifiers.h" #include "DestroyableComponent.h" +#include "EchoSyncSkill.h" #include "PhantomPhysicsComponent.h" #include "RebuildComponent.h" @@ -216,7 +217,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) { } // Echo sync - GameMessages::EchoSyncSkill echo; + EchoSyncSkill echo; echo.bDone = true; echo.uiBehaviorHandle = entry.handle; diff --git a/dGame/dBehaviors/SpawnBehavior.cpp b/dGame/dBehaviors/SpawnBehavior.cpp index ac7bb797..8b2020b1 100644 --- a/dGame/dBehaviors/SpawnBehavior.cpp +++ b/dGame/dBehaviors/SpawnBehavior.cpp @@ -7,6 +7,8 @@ #include "dLogger.h" #include "DestroyableComponent.h" #include "RebuildComponent.h" +#include "Entity.h" +#include "EntityInfo.h" void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { auto* origin = EntityManager::Instance()->GetEntity(context->originator); diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 424be0ac..ecd5e7b2 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -13,6 +13,7 @@ #include "VehiclePhysicsComponent.h" #include "GameMessages.h" #include "Item.h" +#include "AMFFormat.h" CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) { m_Character = character; diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 42699672..2666c60c 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -12,11 +12,12 @@ #include "GameMessages.h" #include "CppScripts.h" #include "SimplePhysicsComponent.h" +#include "Zone.h" MoverSubComponent::MoverSubComponent(const NiPoint3& startPos) { mPosition = {}; - mState = MovementPlatformState::Stopped; + mState = eMovementPlatformState::Stopped; mDesiredWaypointIndex = 0; // -1; mInReverse = false; mShouldStopAtDesiredWaypoint = false; @@ -127,7 +128,7 @@ void MovingPlatformComponent::OnCompleteRebuild() { StartPathing(); } -void MovingPlatformComponent::SetMovementState(MovementPlatformState value) { +void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) { auto* subComponent = static_cast(m_MoverSubComponent); subComponent->mState = value; @@ -152,7 +153,7 @@ void MovingPlatformComponent::StartPathing() { auto* subComponent = static_cast(m_MoverSubComponent); subComponent->mShouldStopAtDesiredWaypoint = true; - subComponent->mState = MovementPlatformState::Stationary; + subComponent->mState = eMovementPlatformState::Stationary; NiPoint3 targetPosition; @@ -174,7 +175,7 @@ void MovingPlatformComponent::StartPathing() { } m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { - SetMovementState(MovementPlatformState::Moving); + SetMovementState(eMovementPlatformState::Moving); }); const auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5f; @@ -199,7 +200,7 @@ void MovingPlatformComponent::StartPathing() { void MovingPlatformComponent::ContinuePathing() { auto* subComponent = static_cast(m_MoverSubComponent); - subComponent->mState = MovementPlatformState::Stationary; + subComponent->mState = eMovementPlatformState::Stationary; subComponent->mCurrentWaypointIndex = subComponent->mNextWaypointIndex; @@ -282,7 +283,7 @@ void MovingPlatformComponent::ContinuePathing() { m_Parent->CancelCallbackTimers(); m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] { - SetMovementState(MovementPlatformState::Moving); + SetMovementState(eMovementPlatformState::Moving); }); auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5; @@ -313,7 +314,7 @@ void MovingPlatformComponent::StopPathing() { m_PathingStopped = true; - subComponent->mState = MovementPlatformState::Stopped; + subComponent->mState = eMovementPlatformState::Stopped; subComponent->mDesiredWaypointIndex = -1; subComponent->mShouldStopAtDesiredWaypoint = false; diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index efa3a4cf..38b15143 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -13,6 +13,9 @@ #include "dCommonVars.h" #include "EntityManager.h" #include "Component.h" +#include "eMovementPlatformState.h" + +class Path; /** * Different types of available platforms @@ -26,16 +29,6 @@ enum class eMoverSubComponentType : uint32_t { simpleMover = 5, }; -/** - * The different types of platform movement state, supposedly a bitmap - */ -enum class MovementPlatformState : uint32_t -{ - Moving = 0b00010, - Stationary = 0b11001, - Stopped = 0b01100 -}; - /** * Sub component for moving platforms that determine the actual current movement state */ @@ -49,7 +42,7 @@ public: /** * The state the platform is currently in */ - MovementPlatformState mState = MovementPlatformState::Stationary; + eMovementPlatformState mState = eMovementPlatformState::Stationary; /** * The waypoint this platform currently wants to traverse to @@ -133,7 +126,7 @@ public: * Updates the movement state for the moving platform * @param value the movement state to set */ - void SetMovementState(MovementPlatformState value); + void SetMovementState(eMovementPlatformState value); /** * Instructs the moving platform to go to some waypoint diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index d11331e7..771a9cc1 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -20,6 +20,7 @@ #include "dConfig.h" #include "dChatFilter.h" #include "Database.h" +#include "EntityInfo.h" std::unordered_map PetComponent::buildCache{}; std::unordered_map PetComponent::currentActivities{}; diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index cef9cc36..aa3ced46 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -19,6 +19,7 @@ #include "CDComponentsRegistryTable.h" #include "CDPhysicsComponentTable.h" #include "dServer.h" +#include "EntityInfo.h" #include "dpWorld.h" #include "dpEntity.h" diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index e6540417..9498a903 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -11,6 +11,7 @@ #include "CharacterComponent.h" #include "UserManager.h" #include "dLogger.h" +#include "AMFFormat.h" PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) { this->propertyQueries = {}; diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 4b5743cd..f64dbc15 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -21,6 +21,7 @@ #include "dServer.h" #include "dZoneManager.h" #include "dConfig.h" +#include "Loot.h" #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index c7c4e3a5..83ae818e 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -14,6 +14,7 @@ #include "Spawner.h" #include "MovingPlatformComponent.h" #include "Preconditions.h" +#include "Loot.h" #include "TeamManager.h" #include "CppScripts.h" diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index ee7ca22e..a03dddbe 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -18,6 +18,8 @@ #include "dConfig.h" #include "InventoryComponent.h" #include "DestroyableComponent.h" +#include "dMessageIdentifiers.h" +#include "Loot.h" ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { m_ActivityID = activityID; diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 0608c63b..562c284a 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -19,7 +19,9 @@ #include "BaseCombatAIComponent.h" #include "ScriptComponent.h" #include "BuffComponent.h" - +#include "EchoStartSkill.h" +#include "dMessageIdentifiers.h" +#include "DoClientProjectileImpact.h" ProjectileSyncEntry::ProjectileSyncEntry() { } @@ -240,7 +242,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c if (!clientInitalized) { // Echo start skill - GameMessages::EchoStartSkill start; + EchoStartSkill start; start.iCastType = 0; start.skillID = skillId; @@ -384,7 +386,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) behavior->Calculate(entry.context, bitStream, entry.branchContext); - GameMessages::DoClientProjectileImpact projectileImpact; + DoClientProjectileImpact projectileImpact; projectileImpact.sBitStream.assign((char*)bitStream->GetData(), bitStream->GetNumberOfBytesUsed()); projectileImpact.i64OwnerID = this->m_Parent->GetObjectID(); diff --git a/dGame/dGameMessages/DoClientProjectileImpact.h b/dGame/dGameMessages/DoClientProjectileImpact.h new file mode 100644 index 00000000..436e3dd2 --- /dev/null +++ b/dGame/dGameMessages/DoClientProjectileImpact.h @@ -0,0 +1,83 @@ +#ifndef __DOCLIENTPROJECTILEIMPACT__H__ +#define __DOCLIENTPROJECTILEIMPACT__H__ + +#include "dMessageIdentifiers.h" +#include "dCommonVars.h" + +/* Tell a client local projectile to impact */ +class DoClientProjectileImpact { + static const GAME_MSG MsgID = GAME_MSG_DO_CLIENT_PROJECTILE_IMPACT; + +public: + DoClientProjectileImpact() { + i64OrgID = LWOOBJID_EMPTY; + i64OwnerID = LWOOBJID_EMPTY; + i64TargetID = LWOOBJID_EMPTY; + } + + DoClientProjectileImpact(std::string _sBitStream, LWOOBJID _i64OrgID = LWOOBJID_EMPTY, LWOOBJID _i64OwnerID = LWOOBJID_EMPTY, LWOOBJID _i64TargetID = LWOOBJID_EMPTY) { + i64OrgID = _i64OrgID; + i64OwnerID = _i64OwnerID; + i64TargetID = _i64TargetID; + sBitStream = _sBitStream; + } + + DoClientProjectileImpact(RakNet::BitStream* stream) : DoClientProjectileImpact() { + Deserialize(stream); + } + + ~DoClientProjectileImpact() { + } + + void Serialize(RakNet::BitStream* stream) { + stream->Write(MsgID); + + stream->Write(i64OrgID != LWOOBJID_EMPTY); + if (i64OrgID != LWOOBJID_EMPTY) stream->Write(i64OrgID); + + stream->Write(i64OwnerID != LWOOBJID_EMPTY); + if (i64OwnerID != LWOOBJID_EMPTY) stream->Write(i64OwnerID); + + stream->Write(i64TargetID != LWOOBJID_EMPTY); + if (i64TargetID != LWOOBJID_EMPTY) stream->Write(i64TargetID); + + uint32_t sBitStreamLength = sBitStream.length(); + stream->Write(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + stream->Write(sBitStream[k]); + } + + } + + bool Deserialize(RakNet::BitStream* stream) { + bool i64OrgIDIsDefault{}; + stream->Read(i64OrgIDIsDefault); + if (i64OrgIDIsDefault != 0) stream->Read(i64OrgID); + + bool i64OwnerIDIsDefault{}; + stream->Read(i64OwnerIDIsDefault); + if (i64OwnerIDIsDefault != 0) stream->Read(i64OwnerID); + + bool i64TargetIDIsDefault{}; + stream->Read(i64TargetIDIsDefault); + if (i64TargetIDIsDefault != 0) stream->Read(i64TargetID); + + uint32_t sBitStreamLength{}; + stream->Read(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + unsigned char character; + stream->Read(character); + sBitStream.push_back(character); + } + + + return true; + } + + LWOOBJID i64OrgID; + LWOOBJID i64OwnerID; + LWOOBJID i64TargetID; + std::string sBitStream; +}; + +#endif //!__DOCLIENTPROJECTILEIMPACT__H__ diff --git a/dGame/dGameMessages/EchoStartSkill.h b/dGame/dGameMessages/EchoStartSkill.h new file mode 100644 index 00000000..6d912798 --- /dev/null +++ b/dGame/dGameMessages/EchoStartSkill.h @@ -0,0 +1,132 @@ +#ifndef __ECHOSTARTSKILL__H__ +#define __ECHOSTARTSKILL__H__ + +#include "dCommonVars.h" +#include "dMessageIdentifiers.h" +#include "NiPoint3.h" +#include "NiQuaternion.h" + +/* Same as start skill but with different network options. An echo down to other clients that need to play the skill. */ +class EchoStartSkill { + static const GAME_MSG MsgID = GAME_MSG_ECHO_START_SKILL; + +public: + EchoStartSkill() { + bUsedMouse = false; + fCasterLatency = 0.0f; + iCastType = 0; + lastClickedPosit = NiPoint3::ZERO; + optionalTargetID = LWOOBJID_EMPTY; + originatorRot = NiQuaternion::IDENTITY; + uiSkillHandle = 0; + } + + EchoStartSkill(LWOOBJID _optionalOriginatorID, std::string _sBitStream, TSkillID _skillID, bool _bUsedMouse = false, float _fCasterLatency = 0.0f, int32_t _iCastType = 0, NiPoint3 _lastClickedPosit = NiPoint3::ZERO, LWOOBJID _optionalTargetID = LWOOBJID_EMPTY, NiQuaternion _originatorRot = NiQuaternion::IDENTITY, uint32_t _uiSkillHandle = 0) { + bUsedMouse = _bUsedMouse; + fCasterLatency = _fCasterLatency; + iCastType = _iCastType; + lastClickedPosit = _lastClickedPosit; + optionalOriginatorID = _optionalOriginatorID; + optionalTargetID = _optionalTargetID; + originatorRot = _originatorRot; + sBitStream = _sBitStream; + skillID = _skillID; + uiSkillHandle = _uiSkillHandle; + } + + EchoStartSkill(RakNet::BitStream* stream) : EchoStartSkill() { + Deserialize(stream); + } + + ~EchoStartSkill() { + } + + void Serialize(RakNet::BitStream* stream) { + stream->Write(MsgID); + + stream->Write(bUsedMouse); + + stream->Write(fCasterLatency != 0.0f); + if (fCasterLatency != 0.0f) stream->Write(fCasterLatency); + + stream->Write(iCastType != 0); + if (iCastType != 0) stream->Write(iCastType); + + stream->Write(lastClickedPosit != NiPoint3::ZERO); + if (lastClickedPosit != NiPoint3::ZERO) stream->Write(lastClickedPosit); + + stream->Write(optionalOriginatorID); + + stream->Write(optionalTargetID != LWOOBJID_EMPTY); + if (optionalTargetID != LWOOBJID_EMPTY) stream->Write(optionalTargetID); + + stream->Write(originatorRot != NiQuaternion::IDENTITY); + if (originatorRot != NiQuaternion::IDENTITY) stream->Write(originatorRot); + + uint32_t sBitStreamLength = sBitStream.length(); + stream->Write(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + stream->Write(sBitStream[k]); + } + + stream->Write(skillID); + + stream->Write(uiSkillHandle != 0); + if (uiSkillHandle != 0) stream->Write(uiSkillHandle); + } + + bool Deserialize(RakNet::BitStream* stream) { + stream->Read(bUsedMouse); + + bool fCasterLatencyIsDefault{}; + stream->Read(fCasterLatencyIsDefault); + if (fCasterLatencyIsDefault != 0) stream->Read(fCasterLatency); + + bool iCastTypeIsDefault{}; + stream->Read(iCastTypeIsDefault); + if (iCastTypeIsDefault != 0) stream->Read(iCastType); + + bool lastClickedPositIsDefault{}; + stream->Read(lastClickedPositIsDefault); + if (lastClickedPositIsDefault != 0) stream->Read(lastClickedPosit); + + stream->Read(optionalOriginatorID); + + bool optionalTargetIDIsDefault{}; + stream->Read(optionalTargetIDIsDefault); + if (optionalTargetIDIsDefault != 0) stream->Read(optionalTargetID); + + bool originatorRotIsDefault{}; + stream->Read(originatorRotIsDefault); + if (originatorRotIsDefault != 0) stream->Read(originatorRot); + + uint32_t sBitStreamLength{}; + stream->Read(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + unsigned char character; + stream->Read(character); + sBitStream.push_back(character); + } + + stream->Read(skillID); + + bool uiSkillHandleIsDefault{}; + stream->Read(uiSkillHandleIsDefault); + if (uiSkillHandleIsDefault != 0) stream->Read(uiSkillHandle); + + return true; + } + + bool bUsedMouse; + float fCasterLatency; + int32_t iCastType; + NiPoint3 lastClickedPosit; + LWOOBJID optionalOriginatorID; + LWOOBJID optionalTargetID; + NiQuaternion originatorRot; + std::string sBitStream; + TSkillID skillID; + uint32_t uiSkillHandle; +}; + +#endif //!__ECHOSTARTSKILL__H__ diff --git a/dGame/dGameMessages/EchoSyncSkill.h b/dGame/dGameMessages/EchoSyncSkill.h new file mode 100644 index 00000000..b56beae8 --- /dev/null +++ b/dGame/dGameMessages/EchoSyncSkill.h @@ -0,0 +1,70 @@ +#ifndef __ECHOSYNCSKILL__H__ +#define __ECHOSYNCSKILL__H__ + +#include + +#include "BitStream.h" + +#include "dMessageIdentifiers.h" + +/* Message to synchronize a skill cast */ +class EchoSyncSkill { + static const GAME_MSG MsgID = GAME_MSG_ECHO_SYNC_SKILL; + +public: + EchoSyncSkill() { + bDone = false; + } + + EchoSyncSkill(std::string _sBitStream, uint32_t _uiBehaviorHandle, uint32_t _uiSkillHandle, bool _bDone = false) { + bDone = _bDone; + sBitStream = _sBitStream; + uiBehaviorHandle = _uiBehaviorHandle; + uiSkillHandle = _uiSkillHandle; + } + + EchoSyncSkill(RakNet::BitStream* stream) : EchoSyncSkill() { + Deserialize(stream); + } + + ~EchoSyncSkill() { + } + + void Serialize(RakNet::BitStream* stream) { + stream->Write(MsgID); + + stream->Write(bDone); + uint32_t sBitStreamLength = sBitStream.length(); + stream->Write(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + stream->Write(sBitStream[k]); + } + + stream->Write(uiBehaviorHandle); + stream->Write(uiSkillHandle); + } + + bool Deserialize(RakNet::BitStream* stream) { + stream->Read(bDone); + + uint32_t sBitStreamLength{}; + stream->Read(sBitStreamLength); + for (unsigned int k = 0; k < sBitStreamLength; k++) { + unsigned char character; + stream->Read(character); + sBitStream.push_back(character); + } + + stream->Read(uiBehaviorHandle); + stream->Read(uiSkillHandle); + + return true; + } + + bool bDone{}; + std::string sBitStream{}; + uint32_t uiBehaviorHandle{}; + uint32_t uiSkillHandle{}; +}; + +#endif //!__ECHOSYNCSKILL__H__ diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index b7687c19..c03f58db 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -26,6 +26,11 @@ #include "CDSkillBehaviorTable.h" #include "SkillComponent.h" #include "RacingControlComponent.h" +#include "RequestServerProjectileImpact.h" +#include "SyncSkill.h" +#include "StartSkill.h" +#include "EchoStartSkill.h" +#include "EchoSyncSkill.h" using namespace std; @@ -251,7 +256,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case GAME_MSG_REQUEST_SERVER_PROJECTILE_IMPACT: { - auto message = GameMessages::RequestServerProjectileImpact(); + auto message = RequestServerProjectileImpact(); message.Deserialize(inStream); @@ -269,7 +274,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System } case GAME_MSG_START_SKILL: { - GameMessages::StartSkill startSkill = GameMessages::StartSkill(); + StartSkill startSkill = StartSkill(); startSkill.Deserialize(inStream); // inStream replaces &bitStream if (startSkill.skillID == 1561 || startSkill.skillID == 1562 || startSkill.skillID == 1541) return; @@ -309,7 +314,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System PacketUtils::WriteHeader(bitStreamLocal, CLIENT, MSG_CLIENT_GAME_MSG); bitStreamLocal.Write(entity->GetObjectID()); - GameMessages::EchoStartSkill echoStartSkill; + EchoStartSkill echoStartSkill; echoStartSkill.bUsedMouse = startSkill.bUsedMouse; echoStartSkill.fCasterLatency = startSkill.fCasterLatency; echoStartSkill.iCastType = startSkill.iCastType; @@ -333,7 +338,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System //bitStreamLocal.Write((unsigned short)GAME_MSG_ECHO_SYNC_SKILL); //bitStreamLocal.Write(inStream); - GameMessages::SyncSkill sync = GameMessages::SyncSkill(inStream); // inStream replaced &bitStream + SyncSkill sync = SyncSkill(inStream); // inStream replaced &bitStream //sync.Serialize(&bitStreamLocal); ostringstream buffer; @@ -356,7 +361,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System delete bs; } - GameMessages::EchoSyncSkill echo = GameMessages::EchoSyncSkill(); + EchoSyncSkill echo = EchoSyncSkill(); echo.bDone = sync.bDone; echo.sBitStream = sync.sBitStream; echo.uiBehaviorHandle = sync.uiBehaviorHandle; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 2423915e..24f0816d 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -28,6 +28,10 @@ #include "GameConfig.h" #include "RocketLaunchLupComponent.h" #include "eUnequippableActiveType.h" +#include "eMovementPlatformState.h" +#include "LeaderboardManager.h" +#include "AMFFormat.h" +#include "Loot.h" #include "RacingTaskParam.h" #include @@ -73,6 +77,7 @@ #include "ControlBehaviors.h" #include "AMFDeserialize.h" #include "eBlueprintSaveResponseType.h" +#include "eAninmationFlags.h" void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) { CBITSTREAM; @@ -330,7 +335,7 @@ void GameMessages::SendStartPathing(Entity* entity) { void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, bool bStopAtDesiredWaypoint, int iIndex, int iDesiredWaypointIndex, int nextIndex, - MovementPlatformState movementState) { + eMovementPlatformState movementState) { CBITSTREAM; CMSGHEADER; @@ -341,7 +346,7 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd iIndex = 0; nextIndex = 0; bStopAtDesiredWaypoint = true; - movementState = MovementPlatformState::Stationary; + movementState = eMovementPlatformState::Stationary; } bitStream.Write(entity->GetObjectID()); @@ -575,7 +580,7 @@ void GameMessages::SendModifyLEGOScore(Entity* entity, const SystemAddress& sysA SEND_PACKET; } -void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, NDGFxValue args) { +void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFValue* args) { CBITSTREAM; CMSGHEADER; @@ -593,7 +598,7 @@ void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const Syste SEND_PACKET; } -void GameMessages::SendUIMessageServerToAllClients(const std::string& message, NDGFxValue args) { +void GameMessages::SendUIMessageServerToAllClients(const std::string& message, AMFValue* args) { CBITSTREAM; CMSGHEADER; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 8a1c2fe5..6575ad85 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -1,27 +1,26 @@ - #ifndef GAMEMESSAGES_H #define GAMEMESSAGES_H #include "dCommonVars.h" -#include "RakNetTypes.h" +#include #include -#include "dMessageIdentifiers.h" -#include "AMFFormat.h" -#include "AMFFormat_BitStream.h" -#include "NiQuaternion.h" -#include "PropertySelectQueryProperty.h" -#include "TradingManager.h" -#include "LeaderboardManager.h" -#include "MovingPlatformComponent.h" -#include "eAninmationFlags.h" +#include +#include "eMovementPlatformState.h" +#include "NiPoint3.h" +class AMFValue; +class Entity; +class Item; class NiQuaternion; class User; -class Entity; -class NiPoint3; +class Leaderboard; +class PropertySelectQueryProperty; +class TradeItem; + +enum class eAnimationFlags : uint32_t; + enum class eUnequippableActiveType; enum eInventoryType : uint32_t; -class Item; namespace GameMessages { class PropertyDataMessage; @@ -57,7 +56,7 @@ namespace GameMessages { void SendStartPathing(Entity* entity); void SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, bool bStopAtDesiredWaypoint = false, int iIndex = 0, int iDesiredWaypointIndex = 1, int nextIndex = 1, - MovementPlatformState movementState = MovementPlatformState::Moving); + eMovementPlatformState movementState = eMovementPlatformState::Moving); void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr); void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr); @@ -74,8 +73,8 @@ namespace GameMessages { void NotifyLevelRewards(LWOOBJID objectID, const SystemAddress& sysAddr, int level, bool sending_rewards); void SendModifyLEGOScore(Entity* entity, const SystemAddress& sysAddr, int64_t score, eLootSourceType sourceType); - void SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, NDGFxValue args); - void SendUIMessageServerToAllClients(const std::string& message, NDGFxValue args); + void SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFValue* args); + void SendUIMessageServerToAllClients(const std::string& message, AMFValue* args); void SendPlayEmbeddedEffectOnAllClientsNearObject(Entity* entity, std::u16string effectName, const LWOOBJID& fromObjectID, float radius); void SendPlayFXEffect(Entity* entity, int32_t effectID, const std::u16string& effectType, const std::string& name, LWOOBJID secondary, float priority = 1, float scale = 1, bool serialize = true); @@ -589,550 +588,6 @@ namespace GameMessages { void HandleReportBug(RakNet::BitStream* inStream, Entity* entity); void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId); - - /* Message to synchronize a skill cast */ - class EchoSyncSkill { - static const GAME_MSG MsgID = GAME_MSG_ECHO_SYNC_SKILL; - - public: - EchoSyncSkill() { - bDone = false; - } - - EchoSyncSkill(std::string _sBitStream, unsigned int _uiBehaviorHandle, unsigned int _uiSkillHandle, bool _bDone = false) { - bDone = _bDone; - sBitStream = _sBitStream; - uiBehaviorHandle = _uiBehaviorHandle; - uiSkillHandle = _uiSkillHandle; - } - - EchoSyncSkill(RakNet::BitStream* stream) { - bDone = false; - - Deserialize(stream); - } - - ~EchoSyncSkill() { - } - - void Serialize(RakNet::BitStream* stream) { - stream->Write((unsigned short)MsgID); - - stream->Write(bDone); - uint32_t sBitStreamLength = sBitStream.length(); - stream->Write(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - stream->Write(sBitStream[k]); - } - - stream->Write(uiBehaviorHandle); - stream->Write(uiSkillHandle); - } - - bool Deserialize(RakNet::BitStream* stream) { - stream->Read(bDone); - uint32_t sBitStreamLength{}; - stream->Read(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - unsigned char character; - stream->Read(character); - sBitStream.push_back(character); - } - - stream->Read(uiBehaviorHandle); - stream->Read(uiSkillHandle); - - return true; - } - - bool bDone{}; - std::string sBitStream{}; - unsigned int uiBehaviorHandle{}; - unsigned int uiSkillHandle{}; - }; - - /* Message to synchronize a skill cast */ - class SyncSkill { - static const GAME_MSG MsgID = GAME_MSG_SYNC_SKILL; - - public: - SyncSkill() { - bDone = false; - } - - SyncSkill(std::string _sBitStream, unsigned int _uiBehaviorHandle, unsigned int _uiSkillHandle, bool _bDone = false) { - bDone = _bDone; - sBitStream = _sBitStream; - uiBehaviorHandle = _uiBehaviorHandle; - uiSkillHandle = _uiSkillHandle; - } - - SyncSkill(RakNet::BitStream* stream) { - bDone = false; - Deserialize(stream); - } - - ~SyncSkill() { - } - - void Serialize(RakNet::BitStream* stream) { - stream->Write((unsigned short)MsgID); - - stream->Write(bDone); - uint32_t sBitStreamLength = sBitStream.length(); - stream->Write(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - stream->Write(sBitStream[k]); - } - - stream->Write(uiBehaviorHandle); - stream->Write(uiSkillHandle); - } - - bool Deserialize(RakNet::BitStream* stream) { - stream->Read(bDone); - uint32_t sBitStreamLength{}; - stream->Read(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - unsigned char character; - stream->Read(character); - sBitStream.push_back(character); - } - - stream->Read(uiBehaviorHandle); - stream->Read(uiSkillHandle); - - return true; - } - - bool bDone{}; - std::string sBitStream{}; - unsigned int uiBehaviorHandle{}; - unsigned int uiSkillHandle{}; - }; - - /* Notifying the server that a locally owned projectil impacted. Sent to the caster of the projectile - should always be the local char. */ - class RequestServerProjectileImpact { - static const GAME_MSG MsgID = GAME_MSG_REQUEST_SERVER_PROJECTILE_IMPACT; - - public: - RequestServerProjectileImpact() { - i64LocalID = LWOOBJID_EMPTY; - i64TargetID = LWOOBJID_EMPTY; - } - - RequestServerProjectileImpact(std::string _sBitStream, LWOOBJID _i64LocalID = LWOOBJID_EMPTY, LWOOBJID _i64TargetID = LWOOBJID_EMPTY) { - i64LocalID = _i64LocalID; - i64TargetID = _i64TargetID; - sBitStream = _sBitStream; - } - - RequestServerProjectileImpact(RakNet::BitStream* stream) { - i64LocalID = LWOOBJID_EMPTY; - i64TargetID = LWOOBJID_EMPTY; - - Deserialize(stream); - } - - ~RequestServerProjectileImpact() { - } - - void Serialize(RakNet::BitStream* stream) { - stream->Write((unsigned short)MsgID); - - stream->Write(i64LocalID != LWOOBJID_EMPTY); - if (i64LocalID != LWOOBJID_EMPTY) stream->Write(i64LocalID); - - stream->Write(i64TargetID != LWOOBJID_EMPTY); - if (i64TargetID != LWOOBJID_EMPTY) stream->Write(i64TargetID); - - uint32_t sBitStreamLength = sBitStream.length(); - stream->Write(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - stream->Write(sBitStream[k]); - } - - } - - bool Deserialize(RakNet::BitStream* stream) { - bool i64LocalIDIsDefault{}; - stream->Read(i64LocalIDIsDefault); - if (i64LocalIDIsDefault != 0) stream->Read(i64LocalID); - - bool i64TargetIDIsDefault{}; - stream->Read(i64TargetIDIsDefault); - if (i64TargetIDIsDefault != 0) stream->Read(i64TargetID); - - uint32_t sBitStreamLength{}; - stream->Read(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - unsigned char character; - stream->Read(character); - sBitStream.push_back(character); - } - - - return true; - } - - LWOOBJID i64LocalID; - LWOOBJID i64TargetID; - std::string sBitStream; - }; - - /* Tell a client local projectile to impact */ - class DoClientProjectileImpact { - static const GAME_MSG MsgID = GAME_MSG_DO_CLIENT_PROJECTILE_IMPACT; - - public: - DoClientProjectileImpact() { - i64OrgID = LWOOBJID_EMPTY; - i64OwnerID = LWOOBJID_EMPTY; - i64TargetID = LWOOBJID_EMPTY; - } - - DoClientProjectileImpact(std::string _sBitStream, LWOOBJID _i64OrgID = LWOOBJID_EMPTY, LWOOBJID _i64OwnerID = LWOOBJID_EMPTY, LWOOBJID _i64TargetID = LWOOBJID_EMPTY) { - i64OrgID = _i64OrgID; - i64OwnerID = _i64OwnerID; - i64TargetID = _i64TargetID; - sBitStream = _sBitStream; - } - - DoClientProjectileImpact(RakNet::BitStream* stream) { - i64OrgID = LWOOBJID_EMPTY; - i64OwnerID = LWOOBJID_EMPTY; - i64TargetID = LWOOBJID_EMPTY; - - Deserialize(stream); - } - - ~DoClientProjectileImpact() { - } - - void Serialize(RakNet::BitStream* stream) { - stream->Write((unsigned short)MsgID); - - stream->Write(i64OrgID != LWOOBJID_EMPTY); - if (i64OrgID != LWOOBJID_EMPTY) stream->Write(i64OrgID); - - stream->Write(i64OwnerID != LWOOBJID_EMPTY); - if (i64OwnerID != LWOOBJID_EMPTY) stream->Write(i64OwnerID); - - stream->Write(i64TargetID != LWOOBJID_EMPTY); - if (i64TargetID != LWOOBJID_EMPTY) stream->Write(i64TargetID); - - uint32_t sBitStreamLength = sBitStream.length(); - stream->Write(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - stream->Write(sBitStream[k]); - } - - } - - bool Deserialize(RakNet::BitStream* stream) { - bool i64OrgIDIsDefault{}; - stream->Read(i64OrgIDIsDefault); - if (i64OrgIDIsDefault != 0) stream->Read(i64OrgID); - - bool i64OwnerIDIsDefault{}; - stream->Read(i64OwnerIDIsDefault); - if (i64OwnerIDIsDefault != 0) stream->Read(i64OwnerID); - - bool i64TargetIDIsDefault{}; - stream->Read(i64TargetIDIsDefault); - if (i64TargetIDIsDefault != 0) stream->Read(i64TargetID); - - uint32_t sBitStreamLength{}; - stream->Read(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - unsigned char character; - stream->Read(character); - sBitStream.push_back(character); - } - - - return true; - } - - LWOOBJID i64OrgID; - LWOOBJID i64OwnerID; - LWOOBJID i64TargetID; - std::string sBitStream; - }; - - /* Same as start skill but with different network options. An echo down to other clients that need to play the skill. */ - class EchoStartSkill { - static const GAME_MSG MsgID = GAME_MSG_ECHO_START_SKILL; - - public: - EchoStartSkill() { - bUsedMouse = false; - fCasterLatency = 0.0f; - iCastType = 0; - lastClickedPosit = NiPoint3::ZERO; - optionalTargetID = LWOOBJID_EMPTY; - originatorRot = NiQuaternion::IDENTITY; - uiSkillHandle = 0; - } - - EchoStartSkill(LWOOBJID _optionalOriginatorID, std::string _sBitStream, TSkillID _skillID, bool _bUsedMouse = false, float _fCasterLatency = 0.0f, int _iCastType = 0, NiPoint3 _lastClickedPosit = NiPoint3::ZERO, LWOOBJID _optionalTargetID = LWOOBJID_EMPTY, NiQuaternion _originatorRot = NiQuaternion::IDENTITY, unsigned int _uiSkillHandle = 0) { - bUsedMouse = _bUsedMouse; - fCasterLatency = _fCasterLatency; - iCastType = _iCastType; - lastClickedPosit = _lastClickedPosit; - optionalOriginatorID = _optionalOriginatorID; - optionalTargetID = _optionalTargetID; - originatorRot = _originatorRot; - sBitStream = _sBitStream; - skillID = _skillID; - uiSkillHandle = _uiSkillHandle; - } - - EchoStartSkill(RakNet::BitStream* stream) { - bUsedMouse = false; - fCasterLatency = 0.0f; - iCastType = 0; - lastClickedPosit = NiPoint3::ZERO; - optionalTargetID = LWOOBJID_EMPTY; - originatorRot = NiQuaternion::IDENTITY; - uiSkillHandle = 0; - - Deserialize(stream); - } - - ~EchoStartSkill() { - } - - void Serialize(RakNet::BitStream* stream) { - stream->Write((unsigned short)MsgID); - - stream->Write(bUsedMouse); - - stream->Write(fCasterLatency != 0.0f); - if (fCasterLatency != 0.0f) stream->Write(fCasterLatency); - - stream->Write(iCastType != 0); - if (iCastType != 0) stream->Write(iCastType); - - stream->Write(lastClickedPosit != NiPoint3::ZERO); - if (lastClickedPosit != NiPoint3::ZERO) stream->Write(lastClickedPosit); - - stream->Write(optionalOriginatorID); - - stream->Write(optionalTargetID != LWOOBJID_EMPTY); - if (optionalTargetID != LWOOBJID_EMPTY) stream->Write(optionalTargetID); - - stream->Write(originatorRot != NiQuaternion::IDENTITY); - if (originatorRot != NiQuaternion::IDENTITY) stream->Write(originatorRot); - - uint32_t sBitStreamLength = sBitStream.length(); - stream->Write(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - stream->Write(sBitStream[k]); - } - - stream->Write(skillID); - - stream->Write(uiSkillHandle != 0); - if (uiSkillHandle != 0) stream->Write(uiSkillHandle); - } - - bool Deserialize(RakNet::BitStream* stream) { - stream->Read(bUsedMouse); - - bool fCasterLatencyIsDefault{}; - stream->Read(fCasterLatencyIsDefault); - if (fCasterLatencyIsDefault != 0) stream->Read(fCasterLatency); - - bool iCastTypeIsDefault{}; - stream->Read(iCastTypeIsDefault); - if (iCastTypeIsDefault != 0) stream->Read(iCastType); - - bool lastClickedPositIsDefault{}; - stream->Read(lastClickedPositIsDefault); - if (lastClickedPositIsDefault != 0) stream->Read(lastClickedPosit); - - stream->Read(optionalOriginatorID); - - bool optionalTargetIDIsDefault{}; - stream->Read(optionalTargetIDIsDefault); - if (optionalTargetIDIsDefault != 0) stream->Read(optionalTargetID); - - bool originatorRotIsDefault{}; - stream->Read(originatorRotIsDefault); - if (originatorRotIsDefault != 0) stream->Read(originatorRot); - - uint32_t sBitStreamLength{}; - stream->Read(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - unsigned char character; - stream->Read(character); - sBitStream.push_back(character); - } - - stream->Read(skillID); - - bool uiSkillHandleIsDefault{}; - stream->Read(uiSkillHandleIsDefault); - if (uiSkillHandleIsDefault != 0) stream->Read(uiSkillHandle); - - return true; - } - - bool bUsedMouse; - float fCasterLatency; - int iCastType; - NiPoint3 lastClickedPosit; - LWOOBJID optionalOriginatorID; - LWOOBJID optionalTargetID; - NiQuaternion originatorRot; - std::string sBitStream; - TSkillID skillID; - unsigned int uiSkillHandle; - }; - - /* Same as sync skill but with different network options. An echo down to other clients that need to play the skill. */ - class StartSkill { - static const GAME_MSG MsgID = GAME_MSG_START_SKILL; - - public: - StartSkill() { - bUsedMouse = false; - consumableItemID = LWOOBJID_EMPTY; - fCasterLatency = 0.0f; - iCastType = 0; - lastClickedPosit = NiPoint3::ZERO; - optionalTargetID = LWOOBJID_EMPTY; - originatorRot = NiQuaternion::IDENTITY; - uiSkillHandle = 0; - } - - StartSkill(LWOOBJID _optionalOriginatorID, std::string _sBitStream, TSkillID _skillID, bool _bUsedMouse = false, LWOOBJID _consumableItemID = LWOOBJID_EMPTY, float _fCasterLatency = 0.0f, int _iCastType = 0, NiPoint3 _lastClickedPosit = NiPoint3::ZERO, LWOOBJID _optionalTargetID = LWOOBJID_EMPTY, NiQuaternion _originatorRot = NiQuaternion::IDENTITY, unsigned int _uiSkillHandle = 0) { - bUsedMouse = _bUsedMouse; - consumableItemID = _consumableItemID; - fCasterLatency = _fCasterLatency; - iCastType = _iCastType; - lastClickedPosit = _lastClickedPosit; - optionalOriginatorID = _optionalOriginatorID; - optionalTargetID = _optionalTargetID; - originatorRot = _originatorRot; - sBitStream = _sBitStream; - skillID = _skillID; - uiSkillHandle = _uiSkillHandle; - } - - StartSkill(RakNet::BitStream* stream) { - bUsedMouse = false; - consumableItemID = LWOOBJID_EMPTY; - fCasterLatency = 0.0f; - iCastType = 0; - lastClickedPosit = NiPoint3::ZERO; - optionalTargetID = LWOOBJID_EMPTY; - originatorRot = NiQuaternion::IDENTITY; - uiSkillHandle = 0; - - Deserialize(stream); - } - - ~StartSkill() { - } - - void Serialize(RakNet::BitStream* stream) { - stream->Write((unsigned short)MsgID); - - stream->Write(bUsedMouse); - - stream->Write(consumableItemID != LWOOBJID_EMPTY); - if (consumableItemID != LWOOBJID_EMPTY) stream->Write(consumableItemID); - - stream->Write(fCasterLatency != 0.0f); - if (fCasterLatency != 0.0f) stream->Write(fCasterLatency); - - stream->Write(iCastType != 0); - if (iCastType != 0) stream->Write(iCastType); - - stream->Write(lastClickedPosit != NiPoint3::ZERO); - if (lastClickedPosit != NiPoint3::ZERO) stream->Write(lastClickedPosit); - - stream->Write(optionalOriginatorID); - - stream->Write(optionalTargetID != LWOOBJID_EMPTY); - if (optionalTargetID != LWOOBJID_EMPTY) stream->Write(optionalTargetID); - - stream->Write(originatorRot != NiQuaternion::IDENTITY); - if (originatorRot != NiQuaternion::IDENTITY) stream->Write(originatorRot); - - uint32_t sBitStreamLength = sBitStream.length(); - stream->Write(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - stream->Write(sBitStream[k]); - } - - stream->Write(skillID); - - stream->Write(uiSkillHandle != 0); - if (uiSkillHandle != 0) stream->Write(uiSkillHandle); - } - - bool Deserialize(RakNet::BitStream* stream) { - stream->Read(bUsedMouse); - - bool consumableItemIDIsDefault{}; - stream->Read(consumableItemIDIsDefault); - if (consumableItemIDIsDefault != 0) stream->Read(consumableItemID); - - bool fCasterLatencyIsDefault{}; - stream->Read(fCasterLatencyIsDefault); - if (fCasterLatencyIsDefault != 0) stream->Read(fCasterLatency); - - bool iCastTypeIsDefault{}; - stream->Read(iCastTypeIsDefault); - if (iCastTypeIsDefault != 0) stream->Read(iCastType); - - bool lastClickedPositIsDefault{}; - stream->Read(lastClickedPositIsDefault); - if (lastClickedPositIsDefault != 0) stream->Read(lastClickedPosit); - - stream->Read(optionalOriginatorID); - - bool optionalTargetIDIsDefault{}; - stream->Read(optionalTargetIDIsDefault); - if (optionalTargetIDIsDefault != 0) stream->Read(optionalTargetID); - - bool originatorRotIsDefault{}; - stream->Read(originatorRotIsDefault); - if (originatorRotIsDefault != 0) stream->Read(originatorRot); - - uint32_t sBitStreamLength{}; - stream->Read(sBitStreamLength); - for (unsigned int k = 0; k < sBitStreamLength; k++) { - unsigned char character; - stream->Read(character); - sBitStream.push_back(character); - } - - stream->Read(skillID); - - bool uiSkillHandleIsDefault{}; - stream->Read(uiSkillHandleIsDefault); - if (uiSkillHandleIsDefault != 0) stream->Read(uiSkillHandle); - - return true; - } - - bool bUsedMouse = false; - LWOOBJID consumableItemID{}; - float fCasterLatency{}; - int iCastType{}; - NiPoint3 lastClickedPosit{}; - LWOOBJID optionalOriginatorID{}; - LWOOBJID optionalTargetID{}; - NiQuaternion originatorRot{}; - std::string sBitStream = ""; - TSkillID skillID = 0; - unsigned int uiSkillHandle = 0; - }; }; #endif // GAMEMESSAGES_H diff --git a/dGame/dGameMessages/RequestServerProjectileImpact.h b/dGame/dGameMessages/RequestServerProjectileImpact.h new file mode 100644 index 00000000..01426361 --- /dev/null +++ b/dGame/dGameMessages/RequestServerProjectileImpact.h @@ -0,0 +1,74 @@ +#ifndef __REQUESTSERVERPROJECTILEIMPACT__H__ +#define __REQUESTSERVERPROJECTILEIMPACT__H__ + +#include "dCommonVars.h" +#include "dMessageIdentifiers.h" + +/* Notifying the server that a locally owned projectile impacted. Sent to the caster of the projectile + should always be the local char. */ +class RequestServerProjectileImpact { + static const GAME_MSG MsgID = GAME_MSG_REQUEST_SERVER_PROJECTILE_IMPACT; + +public: + RequestServerProjectileImpact() { + i64LocalID = LWOOBJID_EMPTY; + i64TargetID = LWOOBJID_EMPTY; + } + + RequestServerProjectileImpact(std::string _sBitStream, LWOOBJID _i64LocalID = LWOOBJID_EMPTY, LWOOBJID _i64TargetID = LWOOBJID_EMPTY) { + i64LocalID = _i64LocalID; + i64TargetID = _i64TargetID; + sBitStream = _sBitStream; + } + + RequestServerProjectileImpact(RakNet::BitStream* stream) : RequestServerProjectileImpact() { + Deserialize(stream); + } + + ~RequestServerProjectileImpact() { + } + + void Serialize(RakNet::BitStream* stream) { + stream->Write(MsgID); + + stream->Write(i64LocalID != LWOOBJID_EMPTY); + if (i64LocalID != LWOOBJID_EMPTY) stream->Write(i64LocalID); + + stream->Write(i64TargetID != LWOOBJID_EMPTY); + if (i64TargetID != LWOOBJID_EMPTY) stream->Write(i64TargetID); + + uint32_t sBitStreamLength = sBitStream.length(); + stream->Write(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + stream->Write(sBitStream[k]); + } + + } + + bool Deserialize(RakNet::BitStream* stream) { + bool i64LocalIDIsDefault{}; + stream->Read(i64LocalIDIsDefault); + if (i64LocalIDIsDefault != 0) stream->Read(i64LocalID); + + bool i64TargetIDIsDefault{}; + stream->Read(i64TargetIDIsDefault); + if (i64TargetIDIsDefault != 0) stream->Read(i64TargetID); + + uint32_t sBitStreamLength{}; + stream->Read(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + unsigned char character; + stream->Read(character); + sBitStream.push_back(character); + } + + + return true; + } + + LWOOBJID i64LocalID; + LWOOBJID i64TargetID; + std::string sBitStream; +}; + +#endif //!__REQUESTSERVERPROJECTILEIMPACT__H__ diff --git a/dGame/dGameMessages/StartSkill.h b/dGame/dGameMessages/StartSkill.h new file mode 100644 index 00000000..af82a9b4 --- /dev/null +++ b/dGame/dGameMessages/StartSkill.h @@ -0,0 +1,144 @@ +#ifndef __STARTSKILL__H__ +#define __STARTSKILL__H__ + +#include "dCommonVars.h" +#include "dMessageIdentifiers.h" +#include "NiPoint3.h" +#include "NiQuaternion.h" + +/** + * Same as sync skill but with different network options. An echo down to other clients that need to play the skill. + */ +class StartSkill { + static const GAME_MSG MsgID = GAME_MSG_START_SKILL; + +public: + StartSkill() { + bUsedMouse = false; + consumableItemID = LWOOBJID_EMPTY; + fCasterLatency = 0.0f; + iCastType = 0; + lastClickedPosit = NiPoint3::ZERO; + optionalTargetID = LWOOBJID_EMPTY; + originatorRot = NiQuaternion::IDENTITY; + uiSkillHandle = 0; + } + + StartSkill(LWOOBJID _optionalOriginatorID, std::string _sBitStream, TSkillID _skillID, bool _bUsedMouse = false, LWOOBJID _consumableItemID = LWOOBJID_EMPTY, float _fCasterLatency = 0.0f, int32_t _iCastType = 0, NiPoint3 _lastClickedPosit = NiPoint3::ZERO, LWOOBJID _optionalTargetID = LWOOBJID_EMPTY, NiQuaternion _originatorRot = NiQuaternion::IDENTITY, uint32_t _uiSkillHandle = 0) { + bUsedMouse = _bUsedMouse; + consumableItemID = _consumableItemID; + fCasterLatency = _fCasterLatency; + iCastType = _iCastType; + lastClickedPosit = _lastClickedPosit; + optionalOriginatorID = _optionalOriginatorID; + optionalTargetID = _optionalTargetID; + originatorRot = _originatorRot; + sBitStream = _sBitStream; + skillID = _skillID; + uiSkillHandle = _uiSkillHandle; + } + + StartSkill(RakNet::BitStream* stream) : StartSkill() { + Deserialize(stream); + } + + ~StartSkill() { + } + + void Serialize(RakNet::BitStream* stream) { + stream->Write(MsgID); + + stream->Write(bUsedMouse); + + stream->Write(consumableItemID != LWOOBJID_EMPTY); + if (consumableItemID != LWOOBJID_EMPTY) stream->Write(consumableItemID); + + stream->Write(fCasterLatency != 0.0f); + if (fCasterLatency != 0.0f) stream->Write(fCasterLatency); + + stream->Write(iCastType != 0); + if (iCastType != 0) stream->Write(iCastType); + + stream->Write(lastClickedPosit != NiPoint3::ZERO); + if (lastClickedPosit != NiPoint3::ZERO) stream->Write(lastClickedPosit); + + stream->Write(optionalOriginatorID); + + stream->Write(optionalTargetID != LWOOBJID_EMPTY); + if (optionalTargetID != LWOOBJID_EMPTY) stream->Write(optionalTargetID); + + stream->Write(originatorRot != NiQuaternion::IDENTITY); + if (originatorRot != NiQuaternion::IDENTITY) stream->Write(originatorRot); + + uint32_t sBitStreamLength = sBitStream.length(); + stream->Write(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + stream->Write(sBitStream[k]); + } + + stream->Write(skillID); + + stream->Write(uiSkillHandle != 0); + if (uiSkillHandle != 0) stream->Write(uiSkillHandle); + } + + bool Deserialize(RakNet::BitStream* stream) { + stream->Read(bUsedMouse); + + bool consumableItemIDIsDefault{}; + stream->Read(consumableItemIDIsDefault); + if (consumableItemIDIsDefault != 0) stream->Read(consumableItemID); + + bool fCasterLatencyIsDefault{}; + stream->Read(fCasterLatencyIsDefault); + if (fCasterLatencyIsDefault != 0) stream->Read(fCasterLatency); + + bool iCastTypeIsDefault{}; + stream->Read(iCastTypeIsDefault); + if (iCastTypeIsDefault != 0) stream->Read(iCastType); + + bool lastClickedPositIsDefault{}; + stream->Read(lastClickedPositIsDefault); + if (lastClickedPositIsDefault != 0) stream->Read(lastClickedPosit); + + stream->Read(optionalOriginatorID); + + bool optionalTargetIDIsDefault{}; + stream->Read(optionalTargetIDIsDefault); + if (optionalTargetIDIsDefault != 0) stream->Read(optionalTargetID); + + bool originatorRotIsDefault{}; + stream->Read(originatorRotIsDefault); + if (originatorRotIsDefault != 0) stream->Read(originatorRot); + + uint32_t sBitStreamLength{}; + stream->Read(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + unsigned char character; + stream->Read(character); + sBitStream.push_back(character); + } + + stream->Read(skillID); + + bool uiSkillHandleIsDefault{}; + stream->Read(uiSkillHandleIsDefault); + if (uiSkillHandleIsDefault != 0) stream->Read(uiSkillHandle); + + return true; + } + + bool bUsedMouse = false; + LWOOBJID consumableItemID{}; + float fCasterLatency{}; + int32_t iCastType{}; + NiPoint3 lastClickedPosit{}; + LWOOBJID optionalOriginatorID{}; + LWOOBJID optionalTargetID{}; + NiQuaternion originatorRot{}; + std::string sBitStream = ""; + TSkillID skillID = 0; + uint32_t uiSkillHandle = 0; +}; + +#endif //!__STARTSKILL__H__ diff --git a/dGame/dGameMessages/SyncSkill.h b/dGame/dGameMessages/SyncSkill.h new file mode 100644 index 00000000..72a88839 --- /dev/null +++ b/dGame/dGameMessages/SyncSkill.h @@ -0,0 +1,68 @@ +#ifndef __SYNCSKILL__H__ +#define __SYNCSKILL__H__ + +#include +#include + +#include "BitStream.h" + +/* Message to synchronize a skill cast */ +class SyncSkill { + static const GAME_MSG MsgID = GAME_MSG_SYNC_SKILL; + +public: + SyncSkill() { + bDone = false; + } + + SyncSkill(std::string _sBitStream, uint32_t _uiBehaviorHandle, uint32_t _uiSkillHandle, bool _bDone = false) { + bDone = _bDone; + sBitStream = _sBitStream; + uiBehaviorHandle = _uiBehaviorHandle; + uiSkillHandle = _uiSkillHandle; + } + + SyncSkill(RakNet::BitStream* stream) : SyncSkill() { + Deserialize(stream); + } + + ~SyncSkill() { + } + + void Serialize(RakNet::BitStream* stream) { + stream->Write(MsgID); + + stream->Write(bDone); + uint32_t sBitStreamLength = sBitStream.length(); + stream->Write(sBitStreamLength); + for (unsigned int k = 0; k < sBitStreamLength; k++) { + stream->Write(sBitStream[k]); + } + + stream->Write(uiBehaviorHandle); + stream->Write(uiSkillHandle); + } + + bool Deserialize(RakNet::BitStream* stream) { + stream->Read(bDone); + uint32_t sBitStreamLength{}; + stream->Read(sBitStreamLength); + for (uint32_t k = 0; k < sBitStreamLength; k++) { + unsigned char character; + stream->Read(character); + sBitStream.push_back(character); + } + + stream->Read(uiBehaviorHandle); + stream->Read(uiSkillHandle); + + return true; + } + + bool bDone{}; + std::string sBitStream{}; + uint32_t uiBehaviorHandle{}; + uint32_t uiSkillHandle{}; +}; + +#endif //!__SYNCSKILL__H__ diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 4f3626e3..d6721bdd 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -15,6 +15,7 @@ #include "eItemType.h" #include "AssetManager.h" #include "InventoryComponent.h" +#include "Loot.h" Item::Item(const LWOOBJID id, const LOT lot, Inventory* inventory, const uint32_t slot, const uint32_t count, const bool bound, const std::vector& config, const LWOOBJID parent, LWOOBJID subKey, eLootSourceType lootSourceType) { if (!Inventory::IsValidItem(lot)) { diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index a1ae724a..df1b16d7 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -17,6 +17,7 @@ #include "dServer.h" #include "dZoneManager.h" #include "InventoryComponent.h" +#include "User.h" #include "Database.h" #include "WorldConfig.h" diff --git a/dGame/dMission/Mission.h b/dGame/dMission/Mission.h index b8892f3d..f9902a06 100644 --- a/dGame/dMission/Mission.h +++ b/dGame/dMission/Mission.h @@ -13,6 +13,10 @@ #include "MissionState.h" #include "MissionLockState.h" +namespace tinyxml2 { + class XMLElement; +}; + class MissionComponent; /** @@ -223,7 +227,7 @@ public: /** * @brief Returns the unique mission order ID - * + * * @return The unique order ID */ uint32_t GetUniqueMissionOrderID() { return m_UniqueMissionID; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index d5b71a3a..278b6929 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -7,6 +7,7 @@ #include "ModelComponent.h" #include "../../dWorldServer/ObjectIDManager.h" #include "dLogger.h" +#include "User.h" uint32_t GetBehaviorIDFromArgument(AMFArrayValue* arguments, const std::string& key = "BehaviorID") { auto* behaviorIDValue = arguments->FindValue(key); diff --git a/dGame/dUtilities/BrickDatabase.cpp b/dGame/dUtilities/BrickDatabase.cpp index 6d1e380c..a6c43d52 100644 --- a/dGame/dUtilities/BrickDatabase.cpp +++ b/dGame/dUtilities/BrickDatabase.cpp @@ -4,6 +4,7 @@ #include "BrickDatabase.h" #include "Game.h" #include "AssetManager.h" +#include "tinyxml2.h" std::vector BrickDatabase::emptyCache{}; BrickDatabase* BrickDatabase::m_Address = nullptr; diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 9a63f83c..2192fafb 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -50,6 +50,9 @@ #include "Item.h" #include "PropertyManagementComponent.h" #include "PacketUtils.h" +#include "Loot.h" +#include "EntityInfo.h" +#include "LUTriggers.h" #include "Player.h" #include "PhantomPhysicsComponent.h" #include "ProximityMonitorComponent.h" @@ -66,6 +69,9 @@ #include "AssetManager.h" #include "BinaryPathFinder.h" #include "dConfig.h" +#include "AMFFormat.h" +#include "MovingPlatformComponent.h" +#include "dMessageIdentifiers.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 3a1259a2..74fd0f67 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -14,6 +14,7 @@ #include "Game.h" #include "dLogger.h" #include "BinaryPathFinder.h" +#include "EntityInfo.h" #include diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 39e835d2..61267971 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -31,7 +31,7 @@ #include "dConfig.h" #include "CharacterComponent.h" #include "Database.h" - +#include "dMessageIdentifiers.h" void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) { diff --git a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp index 9e0570ef..28ba0044 100644 --- a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp +++ b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp @@ -5,6 +5,8 @@ #include "GameMessages.h" #include "SkillComponent.h" #include "BaseCombatAIComponent.h" +#include "EntityInfo.h" +#include "eAninmationFlags.h" void AmDarklingDragon::OnStartup(Entity* self) { self->SetVar(u"weakspot", 0); diff --git a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp index ec513694..e78f537f 100644 --- a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp +++ b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp @@ -3,6 +3,8 @@ #include "SkillComponent.h" #include "BaseCombatAIComponent.h" #include "DestroyableComponent.h" +#include "eAninmationFlags.h" +#include "EntityInfo.h" void FvMaelstromDragon::OnStartup(Entity* self) { self->SetVar(u"weakspot", 0); diff --git a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp index 96419c08..d3c59448 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp @@ -3,7 +3,9 @@ #include "DestroyableComponent.h" #include "GameMessages.h" #include "EntityManager.h" +#include "EntityInfo.h" #include "SkillComponent.h" +#include "eAninmationFlags.h" void BaseEnemyApe::OnStartup(Entity* self) { self->SetVar(u"timesStunned", 2); diff --git a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp index 8017be2c..8c200566 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp @@ -3,6 +3,7 @@ #include "ControllablePhysicsComponent.h" #include "EntityManager.h" #include "dpWorld.h" +#include "EntityInfo.h" #include "GeneralUtils.h" #include "DestroyableComponent.h" diff --git a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp index 15f0709c..19788677 100644 --- a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp +++ b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp @@ -2,6 +2,7 @@ #include "ScriptedActivityComponent.h" #include "TeamManager.h" #include "EntityManager.h" +#include "Loot.h" void TreasureChestDragonServer::OnStartup(Entity* self) { diff --git a/dScripts/02_server/Equipment/BootyDigServer.cpp b/dScripts/02_server/Equipment/BootyDigServer.cpp index d38791d8..73d96b1f 100644 --- a/dScripts/02_server/Equipment/BootyDigServer.cpp +++ b/dScripts/02_server/Equipment/BootyDigServer.cpp @@ -3,6 +3,7 @@ #include "RenderComponent.h" #include "MissionComponent.h" #include "MissionTaskType.h" +#include "Loot.h" void BootyDigServer::OnStartup(Entity* self) { auto* zoneControlObject = EntityManager::Instance()->GetZoneControlEntity(); diff --git a/dScripts/02_server/Map/AG/NpcPirateServer.cpp b/dScripts/02_server/Map/AG/NpcPirateServer.cpp index 47571fa6..154fe2bc 100644 --- a/dScripts/02_server/Map/AG/NpcPirateServer.cpp +++ b/dScripts/02_server/Map/AG/NpcPirateServer.cpp @@ -1,4 +1,5 @@ #include "NpcPirateServer.h" +#include "MissionState.h" #include "InventoryComponent.h" void NpcPirateServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { diff --git a/dScripts/02_server/Map/AG/NpcWispServer.cpp b/dScripts/02_server/Map/AG/NpcWispServer.cpp index cd4a4d9c..d6eab34c 100644 --- a/dScripts/02_server/Map/AG/NpcWispServer.cpp +++ b/dScripts/02_server/Map/AG/NpcWispServer.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "Entity.h" #include "GameMessages.h" +#include "MissionState.h" void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { if (missionID != 1849 && missionID != 1883) diff --git a/dScripts/02_server/Map/AG/RemoveRentalGear.cpp b/dScripts/02_server/Map/AG/RemoveRentalGear.cpp index 06d964b9..fbb00c79 100644 --- a/dScripts/02_server/Map/AG/RemoveRentalGear.cpp +++ b/dScripts/02_server/Map/AG/RemoveRentalGear.cpp @@ -1,6 +1,7 @@ #include "RemoveRentalGear.h" #include "InventoryComponent.h" #include "Item.h" +#include "MissionState.h" #include "Character.h" /* diff --git a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp index ea517448..5996548f 100644 --- a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp +++ b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "ZoneAgProperty.h" #include "DestroyableComponent.h" +#include "EntityInfo.h" void ZoneAgSpiderQueen::SetGameVariables(Entity* self) { ZoneAgProperty::SetGameVariables(self); diff --git a/dScripts/02_server/Map/AM/AmBlueX.cpp b/dScripts/02_server/Map/AM/AmBlueX.cpp index 97f80e77..8e32694c 100644 --- a/dScripts/02_server/Map/AM/AmBlueX.cpp +++ b/dScripts/02_server/Map/AM/AmBlueX.cpp @@ -1,6 +1,7 @@ #include "AmBlueX.h" #include "SkillComponent.h" #include "EntityManager.h" +#include "EntityInfo.h" #include "Character.h" void AmBlueX::OnUse(Entity* self, Entity* user) { diff --git a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp index d16acb87..5d1b7d08 100644 --- a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp @@ -2,6 +2,7 @@ #include "EntityManager.h" #include "DestroyableComponent.h" #include "GameMessages.h" +#include "EntityInfo.h" #include "MovementAIComponent.h" #include "BaseCombatAIComponent.h" #include "SkillComponent.h" diff --git a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp index 9f27b904..3188db33 100644 --- a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp @@ -5,6 +5,7 @@ #include "MovementAIComponent.h" #include "BaseCombatAIComponent.h" #include "SkillComponent.h" +#include "EntityInfo.h" #include "RebuildComponent.h" #include "MissionComponent.h" diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp index 321660e2..9b85cf85 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp @@ -4,6 +4,7 @@ #include "DestroyableComponent.h" #include "ProximityMonitorComponent.h" #include "MissionComponent.h" +#include "EntityInfo.h" void AmSkullkinDrill::OnStartup(Entity* self) { self->SetNetworkVar(u"bIsInUse", false); diff --git a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp index 180bbdac..01acdeaf 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp @@ -2,6 +2,7 @@ #include "EntityManager.h" #include "DestroyableComponent.h" #include "MovingPlatformComponent.h" +#include "EntityInfo.h" #include "GameMessages.h" #include "MissionComponent.h" diff --git a/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp b/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp index b6cae3bb..cfc58fa0 100644 --- a/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp +++ b/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp @@ -1,6 +1,7 @@ #include "EnemyRoninSpawner.h" #include "SkillComponent.h" #include "RenderComponent.h" +#include "EntityInfo.h" #include "EntityManager.h" void EnemyRoninSpawner::OnStartup(Entity* self) { diff --git a/dScripts/02_server/Map/General/BankInteractServer.cpp b/dScripts/02_server/Map/General/BankInteractServer.cpp index db5ebb98..b96187cf 100644 --- a/dScripts/02_server/Map/General/BankInteractServer.cpp +++ b/dScripts/02_server/Map/General/BankInteractServer.cpp @@ -1,5 +1,7 @@ #include "BankInteractServer.h" #include "GameMessages.h" +#include "Entity.h" +#include "AMFFormat.h" void BankInteractServer::OnUse(Entity* self, Entity* user) { AMFArrayValue args; diff --git a/dScripts/02_server/Map/General/GrowingFlower.cpp b/dScripts/02_server/Map/General/GrowingFlower.cpp index 7b495841..61bfbc30 100644 --- a/dScripts/02_server/Map/General/GrowingFlower.cpp +++ b/dScripts/02_server/Map/General/GrowingFlower.cpp @@ -1,5 +1,6 @@ #include "GrowingFlower.h" #include "MissionComponent.h" +#include "Loot.h" void GrowingFlower::OnSkillEventFired(Entity* self, Entity* target, const std::string& message) { if (!self->GetVar(u"blooming") && (message == "waterspray" || message == "shovelgrow")) { diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index e26b079a..0d62ff04 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -4,6 +4,7 @@ #include "EntityManager.h" #include "Character.h" #include "PetComponent.h" +#include "User.h" std::vector PetDigServer::treasures{}; diff --git a/dScripts/02_server/Map/General/PropertyPlatform.cpp b/dScripts/02_server/Map/General/PropertyPlatform.cpp index 89687ac3..902b9646 100644 --- a/dScripts/02_server/Map/General/PropertyPlatform.cpp +++ b/dScripts/02_server/Map/General/PropertyPlatform.cpp @@ -1,6 +1,7 @@ #include "PropertyPlatform.h" #include "RebuildComponent.h" #include "GameMessages.h" +#include "MovingPlatformComponent.h" void PropertyPlatform::OnRebuildComplete(Entity* self, Entity* target) { // auto* movingPlatform = self->GetComponent(); @@ -9,7 +10,7 @@ void PropertyPlatform::OnRebuildComplete(Entity* self, Entity* target) { // movingPlatform->SetNoAutoStart(true); // } GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 0, 0, MovementPlatformState::Stationary); + 0, 0, eMovementPlatformState::Stationary); } void PropertyPlatform::OnUse(Entity* self, Entity* user) { @@ -20,7 +21,7 @@ void PropertyPlatform::OnUse(Entity* self, Entity* user) { // movingPlatform->GotoWaypoint(1); // } GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, MovementPlatformState::Moving); + 1, 1, eMovementPlatformState::Moving); self->AddCallbackTimer(movementDelay + effectDelay, [self, this]() { self->SetNetworkVar(u"startEffect", dieDelay); diff --git a/dScripts/02_server/Map/General/QbSpawner.cpp b/dScripts/02_server/Map/General/QbSpawner.cpp index edee6148..d5c9d001 100644 --- a/dScripts/02_server/Map/General/QbSpawner.cpp +++ b/dScripts/02_server/Map/General/QbSpawner.cpp @@ -1,5 +1,6 @@ #include "QbSpawner.h" #include "BaseCombatAIComponent.h" +#include "EntityInfo.h" #include "MovementAIComponent.h" void QbSpawner::OnStartup(Entity* self) { @@ -133,4 +134,3 @@ void QbSpawner::AggroTargetObject(Entity* self, Entity* enemy) { } } - diff --git a/dScripts/02_server/Map/General/WishingWellServer.cpp b/dScripts/02_server/Map/General/WishingWellServer.cpp index 8ac9e0b2..fa3e13e0 100644 --- a/dScripts/02_server/Map/General/WishingWellServer.cpp +++ b/dScripts/02_server/Map/General/WishingWellServer.cpp @@ -1,6 +1,8 @@ #include "WishingWellServer.h" #include "ScriptedActivityComponent.h" #include "GameMessages.h" +#include "Loot.h" +#include "EntityManager.h" void WishingWellServer::OnStartup(Entity* self) { } diff --git a/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp b/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp index 33436525..a338d9c9 100644 --- a/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp +++ b/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp @@ -1,4 +1,5 @@ #include "NsConcertChoiceBuildManager.h" +#include "EntityInfo.h" #include "EntityManager.h" const std::vector NsConcertChoiceBuildManager::crates{ diff --git a/dScripts/02_server/Map/NS/NsLegoClubDoor.h b/dScripts/02_server/Map/NS/NsLegoClubDoor.h index 0a7a6ee0..db1dcae4 100644 --- a/dScripts/02_server/Map/NS/NsLegoClubDoor.h +++ b/dScripts/02_server/Map/NS/NsLegoClubDoor.h @@ -2,6 +2,7 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" +#include "AMFFormat.h" class NsLegoClubDoor : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/02_server/Map/NS/NsLupTeleport.h b/dScripts/02_server/Map/NS/NsLupTeleport.h index 35edf0bc..28bab016 100644 --- a/dScripts/02_server/Map/NS/NsLupTeleport.h +++ b/dScripts/02_server/Map/NS/NsLupTeleport.h @@ -2,6 +2,7 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" +#include "AMFFormat.h" class NsLupTeleport : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp index 2b88ccf8..d27ac1f6 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp @@ -1,6 +1,7 @@ #include "NtCombatChallengeServer.h" #include "GameMessages.h" #include "EntityManager.h" +#include "EntityInfo.h" #include "InventoryComponent.h" #include "MissionComponent.h" diff --git a/dScripts/02_server/Map/NT/NtVandaServer.cpp b/dScripts/02_server/Map/NT/NtVandaServer.cpp index bfc35203..e5653005 100644 --- a/dScripts/02_server/Map/NT/NtVandaServer.cpp +++ b/dScripts/02_server/Map/NT/NtVandaServer.cpp @@ -1,5 +1,6 @@ #include "NtVandaServer.h" #include "InventoryComponent.h" +#include "MissionState.h" void NtVandaServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { diff --git a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp index 96302a33..695bd92f 100644 --- a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp @@ -1,6 +1,7 @@ #include "EnemySpiderSpawner.h" #include "GameMessages.h" #include "EntityManager.h" +#include "EntityInfo.h" #include "DestroyableComponent.h" //---------------------------------------------- diff --git a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp index 788768ca..9e727f39 100644 --- a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp +++ b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp @@ -1,6 +1,7 @@ #include "PropertyBankInteract.h" #include "EntityManager.h" #include "GameMessages.h" +#include "AMFFormat.h" void PropertyBankInteract::OnStartup(Entity* self) { auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); diff --git a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp index cc6ecafe..4a2f1bbf 100644 --- a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp +++ b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp @@ -2,6 +2,8 @@ #include "Character.h" #include "EntityManager.h" #include "GameMessages.h" +#include "MissionState.h" +#include "Entity.h" void VeEpsilonServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { auto* character = target->GetCharacter(); diff --git a/dScripts/02_server/Map/VE/VeMissionConsole.cpp b/dScripts/02_server/Map/VE/VeMissionConsole.cpp index 2a424c4d..534f8c06 100644 --- a/dScripts/02_server/Map/VE/VeMissionConsole.cpp +++ b/dScripts/02_server/Map/VE/VeMissionConsole.cpp @@ -2,6 +2,7 @@ #include "InventoryComponent.h" #include "Character.h" #include "GameMessages.h" +#include "Loot.h" void VeMissionConsole::OnUse(Entity* self, Entity* user) { LootGenerator::Instance().DropActivityLoot(user, self, 12551); diff --git a/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp b/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp index 451fa1d5..0e2e4005 100644 --- a/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp +++ b/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp @@ -2,6 +2,7 @@ #include "SkillComponent.h" #include "RenderComponent.h" #include "EntityManager.h" +#include "EntityInfo.h" void EnemySkeletonSpawner::OnStartup(Entity* self) { self->SetProximityRadius(15, "ronin"); diff --git a/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp b/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp index fa4d8556..be9fcbd9 100644 --- a/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp +++ b/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp @@ -1,5 +1,8 @@ #include "NjDragonEmblemChestServer.h" #include "Character.h" +#include "EntityInfo.h" +#include "Loot.h" +#include "Entity.h" #include "DestroyableComponent.h" void NjDragonEmblemChestServer::OnUse(Entity* self, Entity* user) { diff --git a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp index 19f5f42a..69838dc8 100644 --- a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp +++ b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp @@ -1,6 +1,7 @@ #include "NjNPCMissionSpinjitzuServer.h" #include "Character.h" #include "EntityManager.h" +#include "MissionState.h" void NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { diff --git a/dScripts/02_server/Map/njhub/RainOfArrows.cpp b/dScripts/02_server/Map/njhub/RainOfArrows.cpp index 141cd3ab..b7c4c074 100644 --- a/dScripts/02_server/Map/njhub/RainOfArrows.cpp +++ b/dScripts/02_server/Map/njhub/RainOfArrows.cpp @@ -1,6 +1,7 @@ #include "RainOfArrows.h" #include "EntityManager.h" #include "SkillComponent.h" +#include "EntityInfo.h" #include "GameMessages.h" void RainOfArrows::OnStartup(Entity* self) { diff --git a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp index 66222d59..7df8fc12 100644 --- a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp +++ b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp @@ -3,6 +3,7 @@ #include "TeamManager.h" #include "EntityManager.h" #include "dZoneManager.h" +#include "Loot.h" void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) { auto* sac = self->GetComponent(); diff --git a/dScripts/02_server/Objects/StinkyFishTarget.cpp b/dScripts/02_server/Objects/StinkyFishTarget.cpp index 19dbce88..21d92fac 100644 --- a/dScripts/02_server/Objects/StinkyFishTarget.cpp +++ b/dScripts/02_server/Objects/StinkyFishTarget.cpp @@ -1,5 +1,6 @@ #include "StinkyFishTarget.h" #include "EntityManager.h" +#include "EntityInfo.h" void StinkyFishTarget::OnStartup(Entity* self) { auto position = self->GetPosition(); diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 36e85b11..078a7a02 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -5,6 +5,7 @@ #include "GameMessages.h" #include #include "dLogger.h" +#include "Loot.h" bool ActivityManager::IsPlayerInActivity(Entity* self, LWOOBJID playerID) { const auto* sac = self->GetComponent(); diff --git a/dScripts/CppScripts.h b/dScripts/CppScripts.h index e4a6d655..eb9b7a04 100644 --- a/dScripts/CppScripts.h +++ b/dScripts/CppScripts.h @@ -1,12 +1,13 @@ #pragma once -#include "dCommonVars.h" -#include "MissionState.h" + +#include #include #include class User; class Entity; class NiPoint3; +enum class MissionState : int32_t; namespace CppScripts { /** diff --git a/dScripts/NPCAddRemoveItem.cpp b/dScripts/NPCAddRemoveItem.cpp index ce47b12a..1985a02b 100644 --- a/dScripts/NPCAddRemoveItem.cpp +++ b/dScripts/NPCAddRemoveItem.cpp @@ -1,5 +1,6 @@ #include "NPCAddRemoveItem.h" #include "InventoryComponent.h" +#include "MissionState.h" void NPCAddRemoveItem::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { auto* inventory = target->GetComponent(); diff --git a/dScripts/ScriptedPowerupSpawner.cpp b/dScripts/ScriptedPowerupSpawner.cpp index 730e65ba..3c1d1cca 100644 --- a/dScripts/ScriptedPowerupSpawner.cpp +++ b/dScripts/ScriptedPowerupSpawner.cpp @@ -1,6 +1,7 @@ #include "ScriptedPowerupSpawner.h" #include "RenderComponent.h" #include "EntityManager.h" +#include "Loot.h" void ScriptedPowerupSpawner::OnTemplateStartup(Entity* self) { self->SetVar(u"currentCycle", 1); diff --git a/dScripts/SpawnPetBaseServer.cpp b/dScripts/SpawnPetBaseServer.cpp index 1d73a5b8..d3c87288 100644 --- a/dScripts/SpawnPetBaseServer.cpp +++ b/dScripts/SpawnPetBaseServer.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "EntityManager.h" #include "PetComponent.h" +#include "EntityInfo.h" void SpawnPetBaseServer::OnStartup(Entity* self) { SetVariables(self); diff --git a/dScripts/ai/AG/AgImagSmashable.cpp b/dScripts/ai/AG/AgImagSmashable.cpp index 593294e5..195f7b9a 100644 --- a/dScripts/ai/AG/AgImagSmashable.cpp +++ b/dScripts/ai/AG/AgImagSmashable.cpp @@ -2,6 +2,7 @@ #include "EntityManager.h" #include "GeneralUtils.h" #include "GameMessages.h" +#include "EntityInfo.h" #include "DestroyableComponent.h" void AgImagSmashable::OnDie(Entity* self, Entity* killer) { diff --git a/dScripts/ai/AG/AgPicnicBlanket.cpp b/dScripts/ai/AG/AgPicnicBlanket.cpp index 30fb2950..d2a54d57 100644 --- a/dScripts/ai/AG/AgPicnicBlanket.cpp +++ b/dScripts/ai/AG/AgPicnicBlanket.cpp @@ -1,5 +1,7 @@ #include "AgPicnicBlanket.h" +#include "Loot.h" #include "GameMessages.h" +#include "Entity.h" void AgPicnicBlanket::OnUse(Entity* self, Entity* user) { GameMessages::SendTerminateInteraction(user->GetObjectID(), FROM_INTERACTION, self->GetObjectID()); diff --git a/dScripts/ai/AG/AgQbElevator.cpp b/dScripts/ai/AG/AgQbElevator.cpp index ccb4d3b1..f1ac7bb5 100644 --- a/dScripts/ai/AG/AgQbElevator.cpp +++ b/dScripts/ai/AG/AgQbElevator.cpp @@ -15,7 +15,7 @@ void AgQbElevator::OnRebuildComplete(Entity* self, Entity* target) { if (delayTime < 1) delayTime = 1; GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 0, 0, MovementPlatformState::Stationary); + 0, 0, eMovementPlatformState::Stationary); //add a timer that will kill the QB if no players get on in the killTime self->AddTimer("startKillTimer", killTime); @@ -33,7 +33,7 @@ void AgQbElevator::OnProximityUpdate(Entity* self, Entity* entering, std::string self->CancelTimer("StartElevator"); GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, MovementPlatformState::Moving); + 1, 1, eMovementPlatformState::Moving); } else if (!self->GetBoolean(u"StartTimer")) { self->SetBoolean(u"StartTimer", true); self->AddTimer("StartElevator", startTime); @@ -45,7 +45,7 @@ void AgQbElevator::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "StartElevator") { GameMessages::SendPlatformResync(self, UNASSIGNED_SYSTEM_ADDRESS, true, 0, - 1, 1, MovementPlatformState::Moving); + 1, 1, eMovementPlatformState::Moving); } else if (timerName == "startKillTimer") { killTimerStartup(self); } else if (timerName == "KillTimer") { diff --git a/dScripts/ai/AG/AgSpaceStuff.cpp b/dScripts/ai/AG/AgSpaceStuff.cpp index 80a87e70..30929ebf 100644 --- a/dScripts/ai/AG/AgSpaceStuff.cpp +++ b/dScripts/ai/AG/AgSpaceStuff.cpp @@ -1,4 +1,5 @@ #include "AgSpaceStuff.h" +#include "EntityInfo.h" #include "GeneralUtils.h" #include "GameMessages.h" #include "EntityManager.h" diff --git a/dScripts/ai/FV/FvPandaSpawnerServer.cpp b/dScripts/ai/FV/FvPandaSpawnerServer.cpp index e1f3fb96..d7dcabcd 100644 --- a/dScripts/ai/FV/FvPandaSpawnerServer.cpp +++ b/dScripts/ai/FV/FvPandaSpawnerServer.cpp @@ -2,6 +2,7 @@ #include "Character.h" #include "EntityManager.h" #include "GameMessages.h" +#include "EntityInfo.h" #include "ScriptedActivityComponent.h" void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { diff --git a/dScripts/ai/GF/GfBanana.cpp b/dScripts/ai/GF/GfBanana.cpp index 3a71eded..95a831cd 100644 --- a/dScripts/ai/GF/GfBanana.cpp +++ b/dScripts/ai/GF/GfBanana.cpp @@ -2,6 +2,7 @@ #include "Entity.h" #include "DestroyableComponent.h" +#include "EntityInfo.h" #include "EntityManager.h" void GfBanana::SpawnBanana(Entity* self) { diff --git a/dScripts/ai/GF/PetDigBuild.cpp b/dScripts/ai/GF/PetDigBuild.cpp index ae159575..32e5b2e3 100644 --- a/dScripts/ai/GF/PetDigBuild.cpp +++ b/dScripts/ai/GF/PetDigBuild.cpp @@ -1,5 +1,6 @@ #include "PetDigBuild.h" #include "EntityManager.h" +#include "EntityInfo.h" #include "MissionComponent.h" void PetDigBuild::OnRebuildComplete(Entity* self, Entity* target) { diff --git a/dScripts/ai/GF/PirateRep.cpp b/dScripts/ai/GF/PirateRep.cpp index eb4cf510..81d69672 100644 --- a/dScripts/ai/GF/PirateRep.cpp +++ b/dScripts/ai/GF/PirateRep.cpp @@ -1,5 +1,7 @@ #include "PirateRep.h" #include "Character.h" +#include "MissionState.h" +#include "Entity.h" void PirateRep::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { if (missionID == m_PirateRepMissionID && missionState >= MissionState::MISSION_STATE_READY_TO_COMPLETE) { diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 47bca374..db914c7f 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -11,6 +11,7 @@ #include "MovementAIComponent.h" #include "../dWorldServer/ObjectIDManager.h" #include "MissionComponent.h" +#include "Loot.h" #include "InventoryComponent.h" void SGCannon::OnStartup(Entity* self) { diff --git a/dScripts/ai/NS/WH/RockHydrantSmashable.cpp b/dScripts/ai/NS/WH/RockHydrantSmashable.cpp index d76eca8d..b3a01567 100644 --- a/dScripts/ai/NS/WH/RockHydrantSmashable.cpp +++ b/dScripts/ai/NS/WH/RockHydrantSmashable.cpp @@ -1,5 +1,6 @@ #include "RockHydrantSmashable.h" #include "EntityManager.h" +#include "EntityInfo.h" #include "GeneralUtils.h" void RockHydrantSmashable::OnDie(Entity* self, Entity* killer) { diff --git a/dScripts/ai/PETS/HydrantSmashable.cpp b/dScripts/ai/PETS/HydrantSmashable.cpp index 20baa58b..1ff082ea 100644 --- a/dScripts/ai/PETS/HydrantSmashable.cpp +++ b/dScripts/ai/PETS/HydrantSmashable.cpp @@ -1,5 +1,6 @@ #include "HydrantSmashable.h" #include "EntityManager.h" +#include "EntityInfo.h" #include "GeneralUtils.h" void HydrantSmashable::OnDie(Entity* self, Entity* killer) { diff --git a/dScripts/ai/PROPERTY/AgPropguards.cpp b/dScripts/ai/PROPERTY/AgPropguards.cpp index 674c4bdd..2bcfcf94 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.cpp +++ b/dScripts/ai/PROPERTY/AgPropguards.cpp @@ -3,6 +3,7 @@ #include "GameMessages.h" #include "EntityManager.h" #include "dZoneManager.h" +#include "MissionState.h" void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { auto* character = target->GetCharacter(); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 73157c09..b655bef3 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -42,6 +42,9 @@ #include "CharacterComponent.h" #include "EntityManager.h" +#include "EntityInfo.h" +#include "User.h" +#include "Loot.h" #include "Entity.h" #include "Character.h" #include "ChatPackets.h" @@ -58,6 +61,8 @@ #include "AssetManager.h" #include "LevelProgressionComponent.h" #include "eBlueprintSaveResponseType.h" +#include "AMFFormat.h" +#include "NiPoint3.h" #include "ZCompression.h" diff --git a/dZoneManager/LUTriggers.h b/dZoneManager/LUTriggers.h new file mode 100644 index 00000000..1869b4c3 --- /dev/null +++ b/dZoneManager/LUTriggers.h @@ -0,0 +1,30 @@ +#ifndef __LUTRIGGERS__H__ +#define __LUTRIGGERS__H__ + +#include +#include + +class Command; +class Event; + +namespace LUTriggers { + struct Command { + std::string id; + std::string target; + std::string targetName; + std::string args; + }; + + struct Event { + std::string eventID; + std::vector commands; + }; + + struct Trigger { + uint32_t id; + bool enabled; + std::vector events; + }; +}; + +#endif //!__LUTRIGGERS__H__ diff --git a/dZoneManager/Spawner.h b/dZoneManager/Spawner.h index 908bb3a3..a42c8a65 100644 --- a/dZoneManager/Spawner.h +++ b/dZoneManager/Spawner.h @@ -9,6 +9,7 @@ #include #include #include "LDFFormat.h" +#include "EntityInfo.h" struct SpawnerNode { NiPoint3 position = NiPoint3::ZERO; diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index ec73237e..79d940af 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -6,6 +6,7 @@ #include "dLogger.h" #include "GeneralUtils.h" #include "BinaryIO.h" +#include "LUTriggers.h" #include "AssetManager.h" #include "CDClientManager.h" diff --git a/dZoneManager/Zone.h b/dZoneManager/Zone.h index 978438aa..9c5322a1 100644 --- a/dZoneManager/Zone.h +++ b/dZoneManager/Zone.h @@ -1,35 +1,18 @@ #pragma once + #include "dZMCommon.h" #include "LDFFormat.h" -#include "../thirdparty/tinyxml2/tinyxml2.h" +#include "tinyxml2.h" #include #include #include -class Level; - -class LUTriggers { -public: - - struct Command { - std::string id; - std::string target; - std::string targetName; - std::string args; - }; - - struct Event { - std::string eventID; - std::vector commands; - }; - - struct Trigger { - uint32_t id; - bool enabled; - std::vector events; - }; +namespace LUTriggers { + struct Trigger; }; +class Level; + struct SceneRef { std::string filename; uint32_t id; @@ -110,11 +93,11 @@ enum class PropertyPathType : int32_t { GenetatedRectangle = 2 }; -enum class PropertyType : int32_t{ +enum class PropertyType : int32_t { Premiere = 0, - Prize = 1, - LUP = 2, - Headspace = 3 + Prize = 1, + LUP = 2, + Headspace = 3 }; enum class PropertyRentalTimeUnit : int32_t { @@ -222,7 +205,7 @@ public: uint32_t GetWorldID() const { return m_WorldID; } [[nodiscard]] std::string GetZoneName() const { return m_ZoneName; } - std::string GetZoneRawPath() const { return m_ZoneRawPath;} + std::string GetZoneRawPath() const { return m_ZoneRawPath; } std::string GetZonePath() const { return m_ZonePath; } const NiPoint3& GetSpawnPos() const { return m_Spawnpoint; } @@ -254,7 +237,7 @@ private: uint32_t m_PathDataLength; uint32_t m_PathChunkVersion; - std::vector m_Paths; + std::vector m_Paths; std::map m_MapRevisions; //rhs is the revision! diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index ee52dec6..81875ab6 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -4,6 +4,7 @@ #include "Game.h" #include "dLogger.h" #include "dServer.h" +#include "EntityInfo.h" #include "EntityManager.h" #include From 1ac898ba000b7a6e075163a64c1f94c8d3682a97 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:21:40 -0800 Subject: [PATCH 102/166] Remove GameConfig (#874) * Remove GameConfig * Fully remove GmeConfig * Update worldconfig.ini Co-authored-by: Aaron Kimbrell --- dCommon/dConfig.h | 1 - dGame/dGameMessages/GameMessages.cpp | 3 +- dGame/dUtilities/CMakeLists.txt | 1 - dGame/dUtilities/GameConfig.cpp | 50 ------------------------ dGame/dUtilities/GameConfig.h | 38 ------------------ dGame/dUtilities/SlashCommandHandler.cpp | 20 ---------- docs/Commands.md | 2 - resources/worldconfig.ini | 3 ++ 8 files changed, 4 insertions(+), 114 deletions(-) delete mode 100644 dGame/dUtilities/GameConfig.cpp delete mode 100644 dGame/dUtilities/GameConfig.h diff --git a/dCommon/dConfig.h b/dCommon/dConfig.h index a6dd5df7..562c1ce9 100644 --- a/dCommon/dConfig.h +++ b/dCommon/dConfig.h @@ -24,7 +24,6 @@ public: * Reloads the config file to reset values */ void ReloadConfig(); - private: void ProcessLine(const std::string& line); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 24f0816d..634e6a1e 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -25,7 +25,6 @@ #include "dConfig.h" #include "TeamManager.h" #include "ChatPackets.h" -#include "GameConfig.h" #include "RocketLaunchLupComponent.h" #include "eUnequippableActiveType.h" #include "eMovementPlatformState.h" @@ -1005,7 +1004,7 @@ void GameMessages::SendSetNetworkScriptVar(Entity* entity, const SystemAddress& } void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, LOT item, int currency, NiPoint3 spawnPos, int count) { - if (GameConfig::GetValue("no_drops") == 1) { + if (Game::config->GetValue("disable_drops") == "1") { return; } diff --git a/dGame/dUtilities/CMakeLists.txt b/dGame/dUtilities/CMakeLists.txt index 2c453a2e..55ca5797 100644 --- a/dGame/dUtilities/CMakeLists.txt +++ b/dGame/dUtilities/CMakeLists.txt @@ -1,5 +1,4 @@ set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp" - "GameConfig.cpp" "GUID.cpp" "Loot.cpp" "Mail.cpp" diff --git a/dGame/dUtilities/GameConfig.cpp b/dGame/dUtilities/GameConfig.cpp deleted file mode 100644 index ad201e6f..00000000 --- a/dGame/dUtilities/GameConfig.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "GameConfig.h" -#include - -std::map GameConfig::m_Config{}; -std::string GameConfig::m_EmptyString{}; - -void GameConfig::Load(const std::string& filepath) { - m_EmptyString = ""; - std::ifstream in(filepath); - if (!in.good()) return; - - std::string line; - while (std::getline(in, line)) { - if (line.length() > 0) { - if (line[0] != '#') ProcessLine(line); - } - } -} - -const std::string& GameConfig::GetValue(const std::string& key) { - const auto& it = m_Config.find(key); - - if (it != m_Config.end()) { - return it->second; - } - - return m_EmptyString; -} - -void GameConfig::SetValue(const std::string& key, const std::string& value) { - m_Config.insert_or_assign(key, value); -} - -void GameConfig::ProcessLine(const std::string& line) { - std::stringstream ss(line); - std::string segment; - std::vector seglist; - - while (std::getline(ss, segment, '=')) { - seglist.push_back(segment); - } - - if (seglist.size() != 2) return; - - //Make sure that on Linux, we remove special characters: - if (!seglist[1].empty() && seglist[1][seglist[1].size() - 1] == '\r') - seglist[1].erase(seglist[1].size() - 1); - - m_Config.insert_or_assign(seglist[0], seglist[1]); -} diff --git a/dGame/dUtilities/GameConfig.h b/dGame/dUtilities/GameConfig.h deleted file mode 100644 index 55089f89..00000000 --- a/dGame/dUtilities/GameConfig.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#include "GeneralUtils.h" - -class GameConfig { -public: - static void Load(const std::string& filepath); - - static const std::string& GetValue(const std::string& key); - - static void SetValue(const std::string& key, const std::string& value); - - template - static T GetValue(const std::string& key) { - T value; - - if (GeneralUtils::TryParse(GetValue(key), value)) { - return value; - } - - return T(); - } - - template - static void SetValue(const std::string& key, const T& value) { - SetValue(key, std::to_string(value)); - } - -private: - static void ProcessLine(const std::string& line); - - static std::map m_Config; - static std::string m_EmptyString; -}; diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 2192fafb..9ee4c1e6 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -63,7 +63,6 @@ #include "BuffComponent.h" #include "SkillComponent.h" #include "VanityUtilities.h" -#include "GameConfig.h" #include "ScriptedActivityComponent.h" #include "LevelProgressionComponent.h" #include "AssetManager.h" @@ -1701,25 +1700,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "config-set" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 2) { - GameConfig::SetValue(args[0], args[1]); - - ChatPackets::SendSystemMessage( - sysAddr, u"Set config value: " + GeneralUtils::UTF8ToUTF16(args[0]) + u" to " + GeneralUtils::UTF8ToUTF16(args[1]) - ); - } - - if (chatCommand == "config-get" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { - const auto& value = GameConfig::GetValue(args[0]); - - std::u16string u16key = GeneralUtils::UTF8ToUTF16(args[0]); - if (value.empty()) { - ChatPackets::SendSystemMessage(sysAddr, u"No value found for " + u16key); - } else { - ChatPackets::SendSystemMessage(sysAddr, u"Value for " + u16key + u": " + GeneralUtils::UTF8ToUTF16(value)); - } - } - if (chatCommand == "metrics" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { for (const auto variable : Metrics::GetAllMetrics()) { auto* metric = Metrics::GetMetric(variable); diff --git a/docs/Commands.md b/docs/Commands.md index 060c2ba0..7c4f494f 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -36,8 +36,6 @@ |Command|Usage|Description|Admin Level Requirement| |--- |--- |--- |--- | |announce|`/announce`|Sends a announcement. `/setanntitle` and `/setannmsg` must be called first to configure the announcement.|8| -|config-set|`/config-set `|Set configuration item.|8| -|config-get|`/config-get `|Get current value of a configuration item.|8| |kill|`/kill `|Smashes the character whom the given user is playing.|8| |metrics|`/metrics`|Prints some information about the server's performance.|8| |setannmsg|`/setannmsg `|Sets the message of an announcement.|8| diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index ee6b6651..0c24c447 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -43,3 +43,6 @@ pets_take_imagination=1 # If you would like to increase the maximum number of best friends a player can have on the server # Change the value below to what you would like this to be (5 is live accurate) max_number_of_best_friends=5 + +# Disables loot drops +disable_drops=0 From 80f8dd800374e6cfd1597c17a8d493ca2b9cfa61 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 6 Jan 2023 23:59:19 -0600 Subject: [PATCH 103/166] Imminuty updates (#925) * WIP Immunities * Immunity getters * remove redundent variable replace it use with it's equivalent * remove unused lookups, fix typos * fix tests * added imunity test * address feedback * more immunity tests * explicit this --- dCommon/dEnums/dCommonVars.h | 2 +- dCommon/dEnums/dMessageIdentifiers.h | 2 + dGame/dBehaviors/ImmunityBehavior.cpp | 94 +++++-- dGame/dBehaviors/ImmunityBehavior.h | 23 +- .../ControllablePhysicsComponent.cpp | 58 ++++- .../ControllablePhysicsComponent.h | 35 +++ dGame/dComponents/DestroyableComponent.cpp | 77 +++++- dGame/dComponents/DestroyableComponent.h | 51 +++- dGame/dComponents/InventoryComponent.cpp | 2 +- dGame/dComponents/PossessorComponent.cpp | 2 +- dGame/dComponents/RailActivatorComponent.cpp | 4 +- dGame/dGameMessages/GameMessages.cpp | 67 ++++- dGame/dGameMessages/GameMessages.h | 31 ++- .../02_server/Enemy/General/BaseEnemyApe.cpp | 2 +- dScripts/02_server/Map/AM/AmSkullkinDrill.cpp | 6 +- .../02_server/Map/GF/GfCaptainsCannon.cpp | 4 +- dScripts/02_server/Map/GF/MastTeleport.cpp | 4 +- .../02_server/Map/NT/NtAssemblyTubeServer.cpp | 4 +- .../02_server/Map/NT/NtParadoxPanelServer.cpp | 4 +- .../02_server/Map/NT/NtParadoxTeleServer.cpp | 4 +- .../Map/NT/NtVentureCannonServer.cpp | 4 +- dScripts/BaseConsoleTeleportServer.cpp | 10 +- .../EquipmentScripts/PersonalFortress.cpp | 49 ++-- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 2 +- .../DestroyableComponentTests.cpp | 239 +++++++++++++++++- 25 files changed, 681 insertions(+), 99 deletions(-) diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 1fd5d071..9bf824e0 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -366,7 +366,7 @@ enum eControlSceme { SCHEME_WEAR_A_ROBOT //== freecam? }; -enum eStunState { +enum class eStateChangeType : uint32_t { PUSH, POP }; diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index 129585a0..ed4167c8 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -293,6 +293,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_POP_EQUIPPED_ITEMS_STATE = 192, GAME_MSG_SET_GM_LEVEL = 193, GAME_MSG_SET_STUNNED = 198, + GAME_MSG_SET_STUN_IMMUNITY = 200, GAME_MSG_KNOCKBACK = 202, GAME_MSG_REBUILD_CANCEL = 209, GAME_MSG_ENABLE_REBUILD = 213, @@ -512,6 +513,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_UPDATE_CHAT_MODE = 1395, GAME_MSG_VEHICLE_NOTIFY_FINISHED_RACE = 1396, GAME_MSG_SET_CONSUMABLE_ITEM = 1409, + GAME_MSG_SET_STATUS_IMMUNITY = 1435, GAME_MSG_SET_PET_NAME_MODERATED = 1448, GAME_MSG_MODIFY_LEGO_SCORE = 1459, GAME_MSG_RESTORE_TO_POST_LOAD_STATS = 1468, diff --git a/dGame/dBehaviors/ImmunityBehavior.cpp b/dGame/dBehaviors/ImmunityBehavior.cpp index 69c652f9..f4a41c52 100644 --- a/dGame/dBehaviors/ImmunityBehavior.cpp +++ b/dGame/dBehaviors/ImmunityBehavior.cpp @@ -6,28 +6,47 @@ #include "Game.h" #include "dLogger.h" #include "DestroyableComponent.h" +#include "ControllablePhysicsComponent.h" void ImmunityBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { auto* target = EntityManager::Instance()->GetEntity(branch.target); - if (target == nullptr) { + if (!target) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); - return; } - auto* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE)); - - if (destroyable == nullptr) { - return; + auto* destroyableComponent = target->GetComponent<DestroyableComponent>(); + if (destroyableComponent) { + destroyableComponent->SetStatusImmunity( + eStateChangeType::PUSH, + this->m_ImmuneToBasicAttack, + this->m_ImmuneToDamageOverTime, + this->m_ImmuneToKnockback, + this->m_ImmuneToInterrupt, + this->m_ImmuneToSpeed, + this->m_ImmuneToImaginationGain, + this->m_ImmuneToImaginationLoss, + this->m_ImmuneToQuickbuildInterrupt, + this->m_ImmuneToPullToPoint + ); } - if (!this->m_immuneBasicAttack) { - return; + auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>(); + if (controllablePhysicsComponent) { + controllablePhysicsComponent->SetStunImmunity( + eStateChangeType::PUSH, + context->caster, + this->m_ImmuneToStunAttack, + this->m_ImmuneToStunEquip, + this->m_ImmuneToStunInteract, + this->m_ImmuneToStunJump, + this->m_ImmuneToStunMove, + this->m_ImmuneToStunTurn, + this->m_ImmuneToStunUseItem + ); } - destroyable->PushImmunity(); - context->RegisterTimerBehavior(this, branch, target->GetObjectID()); } @@ -38,21 +57,60 @@ void ImmunityBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi void ImmunityBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) { auto* target = EntityManager::Instance()->GetEntity(second); - if (target == nullptr) { + if (!target) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second); - return; } - auto* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE)); - - if (destroyable == nullptr) { - return; + auto* destroyableComponent = target->GetComponent<DestroyableComponent>(); + if (destroyableComponent) { + destroyableComponent->SetStatusImmunity( + eStateChangeType::POP, + this->m_ImmuneToBasicAttack, + this->m_ImmuneToDamageOverTime, + this->m_ImmuneToKnockback, + this->m_ImmuneToInterrupt, + this->m_ImmuneToSpeed, + this->m_ImmuneToImaginationGain, + this->m_ImmuneToImaginationLoss, + this->m_ImmuneToQuickbuildInterrupt, + this->m_ImmuneToPullToPoint + ); + } + + auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>(); + if (controllablePhysicsComponent) { + controllablePhysicsComponent->SetStunImmunity( + eStateChangeType::POP, + context->caster, + this->m_ImmuneToStunAttack, + this->m_ImmuneToStunEquip, + this->m_ImmuneToStunInteract, + this->m_ImmuneToStunJump, + this->m_ImmuneToStunMove, + this->m_ImmuneToStunTurn, + this->m_ImmuneToStunUseItem + ); } - destroyable->PopImmunity(); } void ImmunityBehavior::Load() { - this->m_immuneBasicAttack = GetBoolean("immune_basic_attack"); + //Stun + this->m_ImmuneToStunAttack = GetBoolean("immune_stun_attack", false); + this->m_ImmuneToStunEquip = GetBoolean("immune_stun_equip", false); + this->m_ImmuneToStunInteract = GetBoolean("immune_stun_interact", false); + this->m_ImmuneToStunMove = GetBoolean("immune_stun_move", false); + this->m_ImmuneToStunTurn = GetBoolean("immune_stun_rotate", false); + + // Status + this->m_ImmuneToBasicAttack = GetBoolean("immune_basic_attack", false); + this->m_ImmuneToDamageOverTime = GetBoolean("immune_damage_over_time", false); + this->m_ImmuneToKnockback = GetBoolean("immune_knockback", false); + this->m_ImmuneToInterrupt = GetBoolean("immune_interrupt", false); + this->m_ImmuneToSpeed = GetBoolean("immune_speed", false); + this->m_ImmuneToImaginationGain = GetBoolean("immune_imagination_gain", false); + this->m_ImmuneToImaginationLoss = GetBoolean("immune_imagination_loss", false); + this->m_ImmuneToQuickbuildInterrupt = GetBoolean("immune_quickbuild_interrupts", false); + this->m_ImmuneToPullToPoint = GetBoolean("immune_pulltopoint", false); } diff --git a/dGame/dBehaviors/ImmunityBehavior.h b/dGame/dBehaviors/ImmunityBehavior.h index f9409e4c..02cc0fae 100644 --- a/dGame/dBehaviors/ImmunityBehavior.h +++ b/dGame/dBehaviors/ImmunityBehavior.h @@ -4,8 +4,6 @@ class ImmunityBehavior final : public Behavior { public: - uint32_t m_immuneBasicAttack; - /* * Inherited */ @@ -20,4 +18,25 @@ public: void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; void Load() override; + +private: + // stuns + bool m_ImmuneToStunAttack = false; + bool m_ImmuneToStunEquip = false; + bool m_ImmuneToStunInteract = false; + bool m_ImmuneToStunJump = false; // Unused + bool m_ImmuneToStunMove = false; + bool m_ImmuneToStunTurn = false; + bool m_ImmuneToStunUseItem = false; // Unused + + //status + bool m_ImmuneToBasicAttack = false; + bool m_ImmuneToDamageOverTime = false; + bool m_ImmuneToKnockback = false; + bool m_ImmuneToInterrupt = false; + bool m_ImmuneToSpeed = false; + bool m_ImmuneToImaginationGain = false; + bool m_ImmuneToImaginationLoss = false; + bool m_ImmuneToQuickbuildInterrupt = false; + bool m_ImmuneToPullToPoint = false; // Unused in cdclient, but used in client }; diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index a5e447c8..2920a84f 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -35,6 +35,14 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Com m_DirtyPickupRadiusScale = true; m_IsTeleporting = false; + m_ImmuneToStunAttackCount = 0; + m_ImmuneToStunEquipCount = 0; + m_ImmuneToStunInteractCount = 0; + m_ImmuneToStunJumpCount = 0; + m_ImmuneToStunMoveCount = 0; + m_ImmuneToStunTurnCount = 0; + m_ImmuneToStunUseItemCount = 0; + if (entity->GetLOT() != 1) // Other physics entities we care about will be added by BaseCombatAI return; @@ -71,7 +79,14 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bo outBitStream->Write(m_JetpackBypassChecks); } - outBitStream->Write0(); //This contains info about immunities, but for now I'm leaving it out. + outBitStream->Write1(); // always write these on construction + outBitStream->Write(m_ImmuneToStunMoveCount); + outBitStream->Write(m_ImmuneToStunJumpCount); + outBitStream->Write(m_ImmuneToStunTurnCount); + outBitStream->Write(m_ImmuneToStunAttackCount); + outBitStream->Write(m_ImmuneToStunUseItemCount); + outBitStream->Write(m_ImmuneToStunEquipCount); + outBitStream->Write(m_ImmuneToStunInteractCount); } if (m_IgnoreMultipliers) m_DirtyCheats = false; @@ -298,3 +313,44 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) { SetSpeedMultiplier(m_SpeedBoost / 500.0f); // 500 being the base speed EntityManager::Instance()->SerializeEntity(m_Parent); } + +void ControllablePhysicsComponent::SetStunImmunity( + const eStateChangeType state, + const LWOOBJID originator, + const bool bImmuneToStunAttack, + const bool bImmuneToStunEquip, + const bool bImmuneToStunInteract, + const bool bImmuneToStunJump, + const bool bImmuneToStunMove, + const bool bImmuneToStunTurn, + const bool bImmuneToStunUseItem){ + + if (state == eStateChangeType::POP){ + if (bImmuneToStunAttack && m_ImmuneToStunAttackCount > 0) m_ImmuneToStunAttackCount -= 1; + if (bImmuneToStunEquip && m_ImmuneToStunEquipCount > 0) m_ImmuneToStunEquipCount -= 1; + if (bImmuneToStunInteract && m_ImmuneToStunInteractCount > 0) m_ImmuneToStunInteractCount -= 1; + if (bImmuneToStunJump && m_ImmuneToStunJumpCount > 0) m_ImmuneToStunJumpCount -= 1; + if (bImmuneToStunMove && m_ImmuneToStunMoveCount > 0) m_ImmuneToStunMoveCount -= 1; + if (bImmuneToStunTurn && m_ImmuneToStunTurnCount > 0) m_ImmuneToStunTurnCount -= 1; + if (bImmuneToStunUseItem && m_ImmuneToStunUseItemCount > 0) m_ImmuneToStunUseItemCount -= 1; + } else if (state == eStateChangeType::PUSH) { + if (bImmuneToStunAttack) m_ImmuneToStunAttackCount += 1; + if (bImmuneToStunEquip) m_ImmuneToStunEquipCount += 1; + if (bImmuneToStunInteract) m_ImmuneToStunInteractCount += 1; + if (bImmuneToStunJump) m_ImmuneToStunJumpCount += 1; + if (bImmuneToStunMove) m_ImmuneToStunMoveCount += 1; + if (bImmuneToStunTurn) m_ImmuneToStunTurnCount += 1; + if (bImmuneToStunUseItem) m_ImmuneToStunUseItemCount += 1; + } + + GameMessages::SendSetStunImmunity( + m_Parent->GetObjectID(), state, m_Parent->GetSystemAddress(), originator, + bImmuneToStunAttack, + bImmuneToStunEquip, + bImmuneToStunInteract, + bImmuneToStunJump, + bImmuneToStunMove, + bImmuneToStunTurn, + bImmuneToStunUseItem + ); +} diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index e029d607..ba3e1bf4 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -264,6 +264,30 @@ public: std::vector<float> GetActiveSpeedboosts() { return m_ActivePickupRadiusScales; }; + /** + * Push or Pop a layer of stun immunity to this entity + */ + void SetStunImmunity( + const eStateChangeType state, + const LWOOBJID originator = LWOOBJID_EMPTY, + const bool bImmuneToStunAttack = false, + const bool bImmuneToStunEquip = false, + const bool bImmuneToStunInteract = false, + const bool bImmuneToStunJump = false, + const bool bImmuneToStunMove = false, + const bool bImmuneToStunTurn = false, + const bool bImmuneToStunUseItem = false + ); + + // getters for stun immunities + const bool GetImmuneToStunAttack() { return m_ImmuneToStunAttackCount > 0;}; + const bool GetImmuneToStunEquip() { return m_ImmuneToStunEquipCount > 0;}; + const bool GetImmuneToStunInteract() { return m_ImmuneToStunInteractCount > 0;}; + const bool GetImmuneToStunJump() { return m_ImmuneToStunJumpCount > 0;}; + const bool GetImmuneToStunMove() { return m_ImmuneToStunMoveCount > 0;}; + const bool GetImmuneToStunTurn() { return m_ImmuneToStunTurnCount > 0;}; + const bool GetImmuneToStunUseItem() { return m_ImmuneToStunUseItemCount > 0;}; + private: /** * The entity that owns this component @@ -389,6 +413,17 @@ private: * The active speed boost for this entity */ float m_SpeedBoost; + + /** + * stun immunity counters + */ + int32_t m_ImmuneToStunAttackCount; + int32_t m_ImmuneToStunEquipCount; + int32_t m_ImmuneToStunInteractCount; + int32_t m_ImmuneToStunJumpCount; + int32_t m_ImmuneToStunMoveCount; + int32_t m_ImmuneToStunTurnCount; + int32_t m_ImmuneToStunUseItemCount; }; #endif // CONTROLLABLEPHYSICSCOMPONENT_H diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 1b127c41..3e146335 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -55,8 +55,17 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_LootMatrixID = 0; m_MinCoins = 0; m_MaxCoins = 0; - m_ImmuneStacks = 0; m_DamageReduction = 0; + + m_ImmuneToBasicAttackCount = 0; + m_ImmuneToDamageOverTimeCount = 0; + m_ImmuneToKnockbackCount = 0; + m_ImmuneToInterruptCount = 0; + m_ImmuneToSpeedCount = 0; + m_ImmuneToImaginationGainCount = 0; + m_ImmuneToImaginationLossCount = 0; + m_ImmuneToQuickbuildInterruptCount = 0; + m_ImmuneToPullToPointCount = 0; } DestroyableComponent::~DestroyableComponent() { @@ -106,7 +115,16 @@ void DestroyableComponent::Reinitialize(LOT templateID) { void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags) { if (bIsInitialUpdate) { - outBitStream->Write0(); //Contains info about immunities this object has, but it's left out for now. + outBitStream->Write1(); // always write these on construction + outBitStream->Write(m_ImmuneToBasicAttackCount); + outBitStream->Write(m_ImmuneToDamageOverTimeCount); + outBitStream->Write(m_ImmuneToKnockbackCount); + outBitStream->Write(m_ImmuneToInterruptCount); + outBitStream->Write(m_ImmuneToSpeedCount); + outBitStream->Write(m_ImmuneToImaginationGainCount); + outBitStream->Write(m_ImmuneToImaginationLossCount); + outBitStream->Write(m_ImmuneToQuickbuildInterruptCount); + outBitStream->Write(m_ImmuneToPullToPointCount); } outBitStream->Write(m_DirtyHealth || bIsInitialUpdate); @@ -336,7 +354,7 @@ void DestroyableComponent::SetDamageReduction(int32_t value) { void DestroyableComponent::SetIsImmune(bool value) { m_DirtyHealth = true; - m_ImmuneStacks = value ? 1 : 0; + m_ImmuneToBasicAttackCount = value ? 1 : 0; } void DestroyableComponent::SetIsGMImmune(bool value) { @@ -439,7 +457,7 @@ void DestroyableComponent::SetAttacksToBlock(const uint32_t value) { } bool DestroyableComponent::IsImmune() const { - return m_ImmuneStacks > 0 || m_IsGMImmune; + return m_IsGMImmune || m_ImmuneToBasicAttackCount > 0; } bool DestroyableComponent::IsKnockbackImmune() const { @@ -804,12 +822,53 @@ void DestroyableComponent::SetFaction(int32_t factionID, bool ignoreChecks) { AddFaction(factionID, ignoreChecks); } -void DestroyableComponent::PushImmunity(int32_t stacks) { - m_ImmuneStacks += stacks; -} +void DestroyableComponent::SetStatusImmunity( + const eStateChangeType state, + const bool bImmuneToBasicAttack, + const bool bImmuneToDamageOverTime, + const bool bImmuneToKnockback, + const bool bImmuneToInterrupt, + const bool bImmuneToSpeed, + const bool bImmuneToImaginationGain, + const bool bImmuneToImaginationLoss, + const bool bImmuneToQuickbuildInterrupt, + const bool bImmuneToPullToPoint) { -void DestroyableComponent::PopImmunity(int32_t stacks) { - m_ImmuneStacks -= stacks; + if (state == eStateChangeType::POP) { + if (bImmuneToBasicAttack && m_ImmuneToBasicAttackCount > 0) m_ImmuneToBasicAttackCount -= 1; + if (bImmuneToDamageOverTime && m_ImmuneToDamageOverTimeCount > 0) m_ImmuneToDamageOverTimeCount -= 1; + if (bImmuneToKnockback && m_ImmuneToKnockbackCount > 0) m_ImmuneToKnockbackCount -= 1; + if (bImmuneToInterrupt && m_ImmuneToInterruptCount > 0) m_ImmuneToInterruptCount -= 1; + if (bImmuneToSpeed && m_ImmuneToSpeedCount > 0) m_ImmuneToSpeedCount -= 1; + if (bImmuneToImaginationGain && m_ImmuneToImaginationGainCount > 0) m_ImmuneToImaginationGainCount -= 1; + if (bImmuneToImaginationLoss && m_ImmuneToImaginationLossCount > 0) m_ImmuneToImaginationLossCount -= 1; + if (bImmuneToQuickbuildInterrupt && m_ImmuneToQuickbuildInterruptCount > 0) m_ImmuneToQuickbuildInterruptCount -= 1; + if (bImmuneToPullToPoint && m_ImmuneToPullToPointCount > 0) m_ImmuneToPullToPointCount -= 1; + + } else if (state == eStateChangeType::PUSH){ + if (bImmuneToBasicAttack) m_ImmuneToBasicAttackCount += 1; + if (bImmuneToDamageOverTime) m_ImmuneToDamageOverTimeCount += 1; + if (bImmuneToKnockback) m_ImmuneToKnockbackCount += 1; + if (bImmuneToInterrupt) m_ImmuneToInterruptCount += 1; + if (bImmuneToSpeed) m_ImmuneToSpeedCount += 1; + if (bImmuneToImaginationGain) m_ImmuneToImaginationGainCount += 1; + if (bImmuneToImaginationLoss) m_ImmuneToImaginationLossCount += 1; + if (bImmuneToQuickbuildInterrupt) m_ImmuneToQuickbuildInterruptCount += 1; + if (bImmuneToPullToPoint) m_ImmuneToPullToPointCount += 1; + } + + GameMessages::SendSetStatusImmunity( + m_Parent->GetObjectID(), state, m_Parent->GetSystemAddress(), + bImmuneToBasicAttack, + bImmuneToDamageOverTime, + bImmuneToKnockback, + bImmuneToInterrupt, + bImmuneToSpeed, + bImmuneToImaginationGain, + bImmuneToImaginationLoss, + bImmuneToQuickbuildInterrupt, + bImmuneToPullToPoint + ); } void DestroyableComponent::FixStats() { diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 5bb990a7..2736f47c 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -396,16 +396,31 @@ public: void Smash(LWOOBJID source, eKillType killType = eKillType::VIOLENT, const std::u16string& deathType = u"", uint32_t skillID = 0); /** - * Pushes a layer of immunity to this entity, making it immune for longer - * @param stacks the amount of immunity to add + * Push or Pop a layer of status immunity to this entity */ - void PushImmunity(int32_t stacks = 1); + void SetStatusImmunity( + const eStateChangeType state, + const bool bImmuneToBasicAttack = false, + const bool bImmuneToDamageOverTime = false, + const bool bImmuneToKnockback = false, + const bool bImmuneToInterrupt = false, + const bool bImmuneToSpeed = false, + const bool bImmuneToImaginationGain = false, + const bool bImmuneToImaginationLoss = false, + const bool bImmuneToQuickbuildInterrupt = false, + const bool bImmuneToPullToPoint = false + ); - /** - * Pops layers of immunity, making it immune for less longer - * @param stacks the number of layers of immunity to remove - */ - void PopImmunity(int32_t stacks = 1); + // Getters for status immunities + const bool GetImmuneToBasicAttack() {return m_ImmuneToBasicAttackCount > 0;}; + const bool GetImmuneToDamageOverTime() {return m_ImmuneToDamageOverTimeCount > 0;}; + const bool GetImmuneToKnockback() {return m_ImmuneToKnockbackCount > 0;}; + const bool GetImmuneToInterrupt() {return m_ImmuneToInterruptCount > 0;}; + const bool GetImmuneToSpeed() {return m_ImmuneToSpeedCount > 0;}; + const bool GetImmuneToImaginationGain() {return m_ImmuneToImaginationGainCount > 0;}; + const bool GetImmuneToImaginationLoss() {return m_ImmuneToImaginationLossCount > 0;}; + const bool GetImmuneToQuickbuildInterrupt() {return m_ImmuneToQuickbuildInterruptCount > 0;}; + const bool GetImmuneToPullToPoint() {return m_ImmuneToPullToPointCount > 0;}; /** * Utility to reset all stats to the default stats based on items and completed missions @@ -428,7 +443,7 @@ public: /** * Notify subscribed scripts of Damage actions. - * + * * @param attacker The attacking Entity * @param damage The amount of damage that was done */ @@ -493,11 +508,6 @@ private: */ uint32_t m_AttacksToBlock; - /** - * The layers of immunity this entity has left - */ - int32_t m_ImmuneStacks; - /** * The amount of damage that should be reduced from every attack */ @@ -577,6 +587,19 @@ private: * The list of scripts subscribed to this components actions */ std::map<LWOOBJID, CppScripts::Script*> m_SubscribedScripts; + + /** + * status immunity counters + */ + uint32_t m_ImmuneToBasicAttackCount; + uint32_t m_ImmuneToDamageOverTimeCount; + uint32_t m_ImmuneToKnockbackCount; + uint32_t m_ImmuneToInterruptCount; + uint32_t m_ImmuneToSpeedCount; + uint32_t m_ImmuneToImaginationGainCount; + uint32_t m_ImmuneToImaginationLossCount; + uint32_t m_ImmuneToQuickbuildInterruptCount; + uint32_t m_ImmuneToPullToPointCount; }; #endif // DESTROYABLECOMPONENT_H diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 6247f32d..e5ff2f2a 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -959,7 +959,7 @@ void InventoryComponent::HandlePossession(Item* item) { return; } - GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStunState::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); + GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStateChangeType::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); // Set the mount Item ID so that we know what were handling possessorComponent->SetMountItemID(item->GetId()); diff --git a/dGame/dComponents/PossessorComponent.cpp b/dGame/dComponents/PossessorComponent.cpp index f0cad5ca..69046c3b 100644 --- a/dGame/dComponents/PossessorComponent.cpp +++ b/dGame/dComponents/PossessorComponent.cpp @@ -54,7 +54,7 @@ void PossessorComponent::Mount(Entity* mount) { // GM's to send GameMessages::SendSetJetPackMode(m_Parent, false); GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress()); - GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStunState::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); + GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStateChangeType::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); EntityManager::Instance()->SerializeEntity(m_Parent); EntityManager::Instance()->SerializeEntity(mount); diff --git a/dGame/dComponents/RailActivatorComponent.cpp b/dGame/dComponents/RailActivatorComponent.cpp index 1b94fc4a..25fad26e 100644 --- a/dGame/dComponents/RailActivatorComponent.cpp +++ b/dGame/dComponents/RailActivatorComponent.cpp @@ -95,7 +95,7 @@ void RailActivatorComponent::OnUse(Entity* originator) { void RailActivatorComponent::OnRailMovementReady(Entity* originator) const { // Stun the originator - GameMessages::SendSetStunned(originator->GetObjectID(), PUSH, originator->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(originator->GetObjectID(), eStateChangeType::PUSH, originator->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); @@ -123,7 +123,7 @@ void RailActivatorComponent::OnRailMovementReady(Entity* originator) const { void RailActivatorComponent::OnCancelRailMovement(Entity* originator) { // Remove the stun from the originator - GameMessages::SendSetStunned(originator->GetObjectID(), POP, originator->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(originator->GetObjectID(), eStateChangeType::POP, originator->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 634e6a1e..c6c7d2d1 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2904,7 +2904,7 @@ void GameMessages::HandleCinematicUpdate(RakNet::BitStream* inStream, Entity* en } } -void GameMessages::SendSetStunned(LWOOBJID objectId, eStunState stateChangeType, const SystemAddress& sysAddr, +void GameMessages::SendSetStunned(LWOOBJID objectId, eStateChangeType stateChangeType, const SystemAddress& sysAddr, LWOOBJID originator, bool bCantAttack, bool bCantEquip, bool bCantInteract, bool bCantJump, bool bCantMove, bool bCantTurn, bool bCantUseItem, bool bDontTerminateInteract, bool bIgnoreImmunity, @@ -2952,6 +2952,69 @@ void GameMessages::SendSetStunned(LWOOBJID objectId, eStunState stateChangeType, SEND_PACKET; } +void GameMessages::SendSetStunImmunity(LWOOBJID target, eStateChangeType state, const SystemAddress& sysAddr, + LWOOBJID originator, + bool bImmuneToStunAttack, + bool bImmuneToStunEquip, + bool bImmuneToStunInteract, + bool bImmuneToStunJump, + bool bImmuneToStunMove, + bool bImmuneToStunTurn, + bool bImmuneToStunUseItem) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(target); + bitStream.Write(GAME_MSG::GAME_MSG_SET_STUN_IMMUNITY); + + bitStream.Write(originator != LWOOBJID_EMPTY); + if (originator != LWOOBJID_EMPTY) bitStream.Write(originator); + + bitStream.Write(state); + + bitStream.Write(bImmuneToStunAttack); + bitStream.Write(bImmuneToStunEquip); + bitStream.Write(bImmuneToStunInteract); + bitStream.Write(bImmuneToStunJump); + bitStream.Write(bImmuneToStunMove); + bitStream.Write(bImmuneToStunTurn); + bitStream.Write(bImmuneToStunUseItem); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; + SEND_PACKET; +} + +void GameMessages::SendSetStatusImmunity(LWOOBJID objectId, eStateChangeType state, const SystemAddress& sysAddr, + bool bImmuneToBasicAttack, + bool bImmuneToDamageOverTime, + bool bImmuneToKnockback, + bool bImmuneToInterrupt, + bool bImmuneToSpeed, + bool bImmuneToImaginationGain, + bool bImmuneToImaginationLoss, + bool bImmuneToQuickbuildInterrupt, + bool bImmuneToPullToPoint) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_SET_STATUS_IMMUNITY); + + bitStream.Write(state); + + bitStream.Write(bImmuneToBasicAttack); + bitStream.Write(bImmuneToDamageOverTime); + bitStream.Write(bImmuneToKnockback); + bitStream.Write(bImmuneToInterrupt); + bitStream.Write(bImmuneToSpeed); + bitStream.Write(bImmuneToImaginationGain); + bitStream.Write(bImmuneToImaginationLoss); + bitStream.Write(bImmuneToQuickbuildInterrupt); + bitStream.Write(bImmuneToPullToPoint); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; + SEND_PACKET; +} void GameMessages::SendOrientToAngle(LWOOBJID objectId, bool bRelativeToCurrent, float fAngle, const SystemAddress& sysAddr) { CBITSTREAM; @@ -3991,7 +4054,7 @@ void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* e EntityManager::Instance()->SerializeEntity(entity); // We aren't mounted so remove the stun - GameMessages::SendSetStunned(entity->GetObjectID(), eStunState::POP, UNASSIGNED_SYSTEM_ADDRESS, LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); + GameMessages::SendSetStunned(entity->GetObjectID(), eStateChangeType::POP, UNASSIGNED_SYSTEM_ADDRESS, LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); } } } diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 6575ad85..6fa4e694 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -268,7 +268,7 @@ namespace GameMessages { float leadOut = -1.0f, bool leavePlayerLocked = false); void HandleCinematicUpdate(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); - void SendSetStunned(LWOOBJID objectId, eStunState stateChangeType, const SystemAddress& sysAddr, + void SendSetStunned(LWOOBJID objectId, eStateChangeType stateChangeType, const SystemAddress& sysAddr, LWOOBJID originator = LWOOBJID_EMPTY, bool bCantAttack = false, bool bCantEquip = false, bool bCantInteract = false, bool bCantJump = false, bool bCantMove = false, bool bCantTurn = false, bool bCantUseItem = false, bool bDontTerminateInteract = false, bool bIgnoreImmunity = true, @@ -277,6 +277,35 @@ namespace GameMessages { bool bCantMoveOutChangeWasApplied = false, bool bCantTurnOutChangeWasApplied = false, bool bCantUseItemOutChangeWasApplied = false); + void SendSetStunImmunity( + LWOOBJID target, + eStateChangeType state, + const SystemAddress& sysAddr, + LWOOBJID originator = LWOOBJID_EMPTY, + bool bImmuneToStunAttack = false, + bool bImmuneToStunEquip = false, + bool bImmuneToStunInteract = false, + bool bImmuneToStunJump = false, + bool bImmuneToStunMove = false, + bool bImmuneToStunTurn = false, + bool bImmuneToStunUseItem = false + ); + + void SendSetStatusImmunity( + LWOOBJID objectId, + eStateChangeType state, + const SystemAddress& sysAddr, + bool bImmuneToBasicAttack = false, + bool bImmuneToDamageOverTime = false, + bool bImmuneToKnockback = false, + bool bImmuneToInterrupt = false, + bool bImmuneToSpeed = false, + bool bImmuneToImaginationGain = false, + bool bImmuneToImaginationLoss = false, + bool bImmuneToQuickbuildInterrupt = false, + bool bImmuneToPullToPoint = false + ); + void SendOrientToAngle(LWOOBJID objectId, bool bRelativeToCurrent, float fAngle, const SystemAddress& sysAddr); void SendAddRunSpeedModifier(LWOOBJID objectId, LWOOBJID caster, uint32_t modifier, const SystemAddress& sysAddr); diff --git a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp index d3c59448..ea3ce9b8 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp @@ -131,7 +131,7 @@ void BaseEnemyApe::StunApe(Entity* self, bool stunState) { skillComponent->Interrupt(); } - GameMessages::SendSetStunned(self->GetObjectID(), stunState ? PUSH : POP, UNASSIGNED_SYSTEM_ADDRESS, self->GetObjectID(), + GameMessages::SendSetStunned(self->GetObjectID(), stunState ? eStateChangeType::PUSH : eStateChangeType::POP, UNASSIGNED_SYSTEM_ADDRESS, self->GetObjectID(), true, true, true, true, true, true, true, true, true); diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp index 9b85cf85..da1954d6 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp @@ -147,21 +147,21 @@ void AmSkullkinDrill::OnUse(Entity* self, Entity* user) { } void AmSkullkinDrill::FreezePlayer(Entity* self, Entity* player, bool bFreeze) { - eStunState eChangeType = POP; + auto StateChangeType = eStateChangeType::POP; if (bFreeze) { if (player->GetIsDead()) { return; } - eChangeType = PUSH; + StateChangeType = eStateChangeType::PUSH; } else { if (player->GetIsDead()) { // } } - GameMessages::SendSetStunned(player->GetObjectID(), eChangeType, player->GetSystemAddress(), self->GetObjectID(), + GameMessages::SendSetStunned(player->GetObjectID(), StateChangeType, player->GetSystemAddress(), self->GetObjectID(), true, false, true, false, true, false, true ); } diff --git a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp index 7d67c781..eeabeef6 100644 --- a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp +++ b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp @@ -13,7 +13,7 @@ void GfCaptainsCannon::OnUse(Entity* self, Entity* user) { self->SetVar<bool>(u"bIsInUse", true); self->SetNetworkVar<bool>(u"bIsInUse", true); - GameMessages::SendSetStunned(user->GetObjectID(), PUSH, user->GetSystemAddress(), + GameMessages::SendSetStunned(user->GetObjectID(), eStateChangeType::PUSH, user->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true, true ); @@ -63,7 +63,7 @@ void GfCaptainsCannon::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendPlay2DAmbientSound(player, "{7457d85c-4537-4317-ac9d-2f549219ea87}"); } else if (timerName == "cinematicTimer") { - GameMessages::SendSetStunned(playerId, POP, player->GetSystemAddress(), + GameMessages::SendSetStunned(playerId, eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true, true ); diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index ebde7b20..dac5783c 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -16,7 +16,7 @@ void MastTeleport::OnRebuildComplete(Entity* self, Entity* target) { if (Preconditions::Check(target, 154) && Preconditions::Check(target, 44)) { self->SetVar<LWOOBJID>(u"userID", target->GetObjectID()); - GameMessages::SendSetStunned(target->GetObjectID(), PUSH, target->GetSystemAddress(), + GameMessages::SendSetStunned(target->GetObjectID(), eStateChangeType::PUSH, target->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); @@ -81,7 +81,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendTeleport(playerId, position, NiQuaternion::IDENTITY, player->GetSystemAddress()); - GameMessages::SendSetStunned(playerId, POP, player->GetSystemAddress(), + GameMessages::SendSetStunned(playerId, eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); } diff --git a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp index f30f4fc7..5410047d 100644 --- a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp +++ b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp @@ -36,7 +36,7 @@ void NtAssemblyTubeServer::RunAssemblyTube(Entity* self, Entity* player) { if (player->IsPlayer() && !bPlayerBeingTeleported) { auto teleCinematic = self->GetVar<std::u16string>(u"Cinematic"); - GameMessages::SendSetStunned(playerID, PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(playerID, eStateChangeType::PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); @@ -108,7 +108,7 @@ void NtAssemblyTubeServer::UnlockPlayer(Entity* self, Entity* player) { m_TeleportingPlayerTable[playerID] = false; - GameMessages::SendSetStunned(playerID, POP, player->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(playerID, eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); } diff --git a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp index 06482c82..8d14050b 100644 --- a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp @@ -34,11 +34,11 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { GameMessages::SendPlayAnimation(player, u"rebuild-celebrate"); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SparkStop", 0, 0, player->GetObjectID(), "", player->GetSystemAddress()); - GameMessages::SendSetStunned(player->GetObjectID(), eStunState::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); + GameMessages::SendSetStunned(player->GetObjectID(), eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); self->SetVar(u"bActive", false); }); GameMessages::SendPlayAnimation(user, u"nexus-powerpanel", 6.0f); - GameMessages::SendSetStunned(user->GetObjectID(), eStunState::PUSH, user->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); + GameMessages::SendSetStunned(user->GetObjectID(), eStateChangeType::PUSH, user->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); return; } diff --git a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp index 8003e93f..64af4d34 100644 --- a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp @@ -22,7 +22,7 @@ void NtParadoxTeleServer::OnProximityUpdate(Entity* self, Entity* entering, std: const auto bPlayerBeingTeleported = m_TeleportingPlayerTable[playerID]; if (player->IsPlayer() && !bPlayerBeingTeleported) { - GameMessages::SendSetStunned(playerID, PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(playerID, eStateChangeType::PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); @@ -100,7 +100,7 @@ void NtParadoxTeleServer::UnlockPlayer(Entity* self, Entity* player) { m_TeleportingPlayerTable[playerID] = false; - GameMessages::SendSetStunned(playerID, POP, player->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(playerID, eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); diff --git a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp index d7f4cb99..e6cd2df6 100644 --- a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp +++ b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp @@ -14,7 +14,7 @@ void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { self->SetNetworkVar(u"bIsInUse", true); - GameMessages::SendSetStunned(playerID, PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(playerID, eStateChangeType::PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); @@ -92,7 +92,7 @@ void NtVentureCannonServer::ExitCannonEnded(Entity* self, Entity* player) { } void NtVentureCannonServer::UnlockCannonPlayer(Entity* self, Entity* player) { - GameMessages::SendSetStunned(player->GetObjectID(), POP, player->GetSystemAddress(), LWOOBJID_EMPTY, + GameMessages::SendSetStunned(player->GetObjectID(), eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); diff --git a/dScripts/BaseConsoleTeleportServer.cpp b/dScripts/BaseConsoleTeleportServer.cpp index a8538de5..d0162e9c 100644 --- a/dScripts/BaseConsoleTeleportServer.cpp +++ b/dScripts/BaseConsoleTeleportServer.cpp @@ -15,7 +15,8 @@ void BaseConsoleTeleportServer::BaseOnMessageBoxResponse(Entity* self, Entity* s if (button == 1) { - GameMessages::SendSetStunned(player->GetObjectID(), PUSH, player->GetSystemAddress(), player->GetObjectID(), + GameMessages::SendSetStunned( + player->GetObjectID(), eStateChangeType::PUSH, player->GetSystemAddress(), player->GetObjectID(), true, true, true, true, true, true, true ); @@ -82,11 +83,10 @@ void BaseConsoleTeleportServer::TransferPlayer(Entity* self, Entity* player, int return; } - // Ignoring extra effects for now - - /*GameMessages::SendSetStunned(player->GetObjectID(), POP, player->GetSystemAddress(), player->GetObjectID(), + GameMessages::SendSetStunned( + player->GetObjectID(), eStateChangeType::POP, player->GetSystemAddress(), player->GetObjectID(), true, true, true, true, true, true, true - );*/ + ); GameMessages::SendTerminateInteraction(player->GetObjectID(), FROM_INTERACTION, player->GetObjectID()); diff --git a/dScripts/EquipmentScripts/PersonalFortress.cpp b/dScripts/EquipmentScripts/PersonalFortress.cpp index e7e89e80..f5062f9b 100644 --- a/dScripts/EquipmentScripts/PersonalFortress.cpp +++ b/dScripts/EquipmentScripts/PersonalFortress.cpp @@ -2,49 +2,56 @@ #include "GameMessages.h" #include "SkillComponent.h" #include "DestroyableComponent.h" +#include "ControllablePhysicsComponent.h" #include "EntityManager.h" void PersonalFortress::OnStartup(Entity* self) { auto* owner = self->GetOwner(); self->AddTimer("FireSkill", 1.5); - GameMessages::SendSetStunned(owner->GetObjectID(), PUSH, owner->GetSystemAddress(), LWOOBJID_EMPTY, - true, true, true, true, true, true, true, true, true - ); auto* destroyableComponent = owner->GetComponent<DestroyableComponent>(); + if (destroyableComponent) destroyableComponent->SetStatusImmunity( + eStateChangeType::PUSH, + true, true, true, true, true, false, true, false, false + ); - if (destroyableComponent != nullptr) { - destroyableComponent->PushImmunity(); - } + auto* controllablePhysicsComponent = owner->GetComponent<ControllablePhysicsComponent>(); + if (controllablePhysicsComponent) controllablePhysicsComponent->SetStunImmunity( + eStateChangeType::PUSH, LWOOBJID_EMPTY, + true, true, true, true, true, true + ); + + GameMessages::SendSetStunned(owner->GetObjectID(), eStateChangeType::PUSH, owner->GetSystemAddress(), LWOOBJID_EMPTY, + true, true, true, true, true, true, true, true, true + ); EntityManager::Instance()->SerializeEntity(owner); } void PersonalFortress::OnDie(Entity* self, Entity* killer) { auto* owner = self->GetOwner(); - GameMessages::SendSetStunned(owner->GetObjectID(), POP, owner->GetSystemAddress(), LWOOBJID_EMPTY, + auto* destroyableComponent = owner->GetComponent<DestroyableComponent>(); + if (destroyableComponent) destroyableComponent->SetStatusImmunity( + eStateChangeType::POP, + true, true, true, true, true, false, true, false, false + ); + + auto* controllablePhysicsComponent = owner->GetComponent<ControllablePhysicsComponent>(); + if (controllablePhysicsComponent) controllablePhysicsComponent->SetStunImmunity( + eStateChangeType::POP, LWOOBJID_EMPTY, + true, true, true, true, true, true + ); + + GameMessages::SendSetStunned(owner->GetObjectID(), eStateChangeType::POP, owner->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true, true, true ); - auto* destroyableComponent = owner->GetComponent<DestroyableComponent>(); - - if (destroyableComponent != nullptr) { - destroyableComponent->PopImmunity(); - } - EntityManager::Instance()->SerializeEntity(owner); } void PersonalFortress::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "FireSkill") { - auto* owner = self->GetOwner(); - auto* skillComponent = self->GetComponent<SkillComponent>(); - - if (skillComponent == nullptr) { - return; - } - - skillComponent->CalculateBehavior(650, 13364, LWOOBJID_EMPTY, true, false); + if (skillComponent) skillComponent->CalculateBehavior(650, 13364, LWOOBJID_EMPTY, true, false); } } diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index db914c7f..f9146ec4 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -77,7 +77,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int auto* player = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(PlayerIDVariable)); if (player != nullptr) { Game::logger->Log("SGCannon", "Player is ready"); - /*GameMessages::SendSetStunned(player->GetObjectID(), PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, + /*GameMessages::SendSetStunned(player->GetObjectID(), eStateChangeType::PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true);*/ Game::logger->Log("SGCannon", "Sending ActivityEnter"); diff --git a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp index 97288909..5448a4c2 100644 --- a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp @@ -41,10 +41,19 @@ protected: TEST_F(DestroyableTest, DestroyableComponentSerializeConstructionTest) { destroyableComponent->Serialize(&bitStream, true, flags); // Assert that the full number of bits are present - ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 460); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 748); { // Now read in the full serialized construction BitStream - bool optionStatusImmunityInfo{}; // Values under this option are unused. + bool optionStatusImmunityInfo{}; + uint32_t ImmuneToBasicAttackCount{}; + uint32_t ImmuneToDamageOverTimeCount{}; + uint32_t ImmuneToKnockbackCount{}; + uint32_t ImmuneToInterruptCount{}; + uint32_t ImmuneToSpeedCount{}; + uint32_t ImmuneToImaginationGainCount{}; + uint32_t ImmuneToImaginationLossCount{}; + uint32_t ImmuneToQuickbuildInterruptCount{}; + uint32_t ImmuneToPullToPointCount{}; bool optionStatsInfo{}; uint32_t currentHealth{}; float maxHealth{}; @@ -70,7 +79,15 @@ TEST_F(DestroyableTest, DestroyableComponentSerializeConstructionTest) { bool optionIsOnThreatList{}; bool isThreatened{}; bitStream.Read(optionStatusImmunityInfo); - + bitStream.Read(ImmuneToBasicAttackCount); + bitStream.Read(ImmuneToDamageOverTimeCount); + bitStream.Read(ImmuneToKnockbackCount); + bitStream.Read(ImmuneToInterruptCount); + bitStream.Read(ImmuneToSpeedCount); + bitStream.Read(ImmuneToImaginationGainCount); + bitStream.Read(ImmuneToImaginationLossCount); + bitStream.Read(ImmuneToQuickbuildInterruptCount); + bitStream.Read(ImmuneToPullToPointCount); bitStream.Read(optionStatsInfo); bitStream.Read(currentHealth); bitStream.Read(maxHealth); @@ -101,7 +118,16 @@ TEST_F(DestroyableTest, DestroyableComponentSerializeConstructionTest) { bitStream.Read(optionIsOnThreatList); bitStream.Read(isThreatened); - EXPECT_EQ(optionStatusImmunityInfo, false); + EXPECT_EQ(optionStatusImmunityInfo, true); + EXPECT_EQ(ImmuneToBasicAttackCount, 0); + EXPECT_EQ(ImmuneToDamageOverTimeCount, 0); + EXPECT_EQ(ImmuneToKnockbackCount, 0); + EXPECT_EQ(ImmuneToInterruptCount, 0); + EXPECT_EQ(ImmuneToSpeedCount, 0); + EXPECT_EQ(ImmuneToImaginationGainCount, 0); + EXPECT_EQ(ImmuneToImaginationLossCount, 0); + EXPECT_EQ(ImmuneToQuickbuildInterruptCount, 0); + EXPECT_EQ(ImmuneToPullToPointCount, 0); EXPECT_EQ(optionStatsInfo, true); EXPECT_EQ(currentHealth, 23); @@ -298,3 +324,208 @@ TEST_F(DestroyableTest, DestroyableComponentValiditiyTest) { EXPECT_FALSE(destroyableComponent->IsFriend(enemyEntity)); delete enemyEntity; } + +TEST_F(DestroyableTest, DestroyableComponentImmunityTest) { + // assert to show that they are empty + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + // set them all to true (count 1) and check + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, true, true, true, true, true, true, true, true, true); + ASSERT_TRUE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_TRUE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_TRUE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_TRUE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_TRUE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_TRUE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_TRUE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_TRUE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_TRUE(destroyableComponent->GetImmuneToPullToPoint()); + + // remove them to check that they get removed properly + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true, true, true, true, true, true, true, true, true); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + + // should not crash to remove them again + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true, true, true, true, true, true, true, true, true); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + + // just do one + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, true); + ASSERT_TRUE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + // now stack it to 2 on basic attack + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, true); + ASSERT_TRUE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + // remove one and still shoudl be true + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true); + ASSERT_TRUE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + // go back to 0 + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + // check individual ones now + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, true, false, false, false, false, false, false, false, false); + ASSERT_TRUE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true, false, false, false, false, false, false, false, false); + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, true, false, false, false, false, false, false, false); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_TRUE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, true, false, false, false, false, false, false, false); + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, false, true, false, false, false, false, false, false); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_TRUE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, false, true, false, false, false, false, false, false); + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, false, false, true, false, false, false, false, false); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_TRUE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, false, false, true, false, false, false, false, false); + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, false, false, false, true, false, false, false, false); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_TRUE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, false, false, false, true, false, false, false, false); + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, false, false, false, false, true, false, false, false); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_TRUE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, false, false, false, false, true, false, false, false); + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, false, false, false, false, false, true, false, false); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_TRUE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, false, false, false, false, false, true, false, false); + + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, false, false, false, false, false, false, true, false); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_TRUE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, false, false, false, false, false, false, true, false); + + + destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, false, false, false, false, false, false, false, false, true); + ASSERT_FALSE(destroyableComponent->GetImmuneToBasicAttack()); + ASSERT_FALSE(destroyableComponent->GetImmuneToDamageOverTime()); + ASSERT_FALSE(destroyableComponent->GetImmuneToKnockback()); + ASSERT_FALSE(destroyableComponent->GetImmuneToInterrupt()); + ASSERT_FALSE(destroyableComponent->GetImmuneToSpeed()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationGain()); + ASSERT_FALSE(destroyableComponent->GetImmuneToImaginationLoss()); + ASSERT_FALSE(destroyableComponent->GetImmuneToQuickbuildInterrupt()); + ASSERT_TRUE(destroyableComponent->GetImmuneToPullToPoint()); + destroyableComponent->SetStatusImmunity(eStateChangeType::POP, false, false, false, false, false, false, false, false, true); + +} + From 5374c555f549cc47dbedebf71dcdd9c47a9825f8 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sat, 7 Jan 2023 00:14:51 -0600 Subject: [PATCH 104/166] Implement bubble seriliaztion in controllable physics (#942) * bubble * "Correct" serialization and enum * Enum update * figured out what things do * accurate types and cleanup * add sanity check add getter add slash command for testing * fix default * cleanup slash command * handle game message probably remove funny slash command add all bubble GM's Co-authored-by: Jett <55758076+Jettford@users.noreply.github.com> --- dCommon/dEnums/dMessageIdentifiers.h | 7 ++- dCommon/dEnums/eBubbleType.h | 14 +++++ .../ControllablePhysicsComponent.cpp | 49 ++++++++++++++--- .../ControllablePhysicsComponent.h | 53 +++++++++++++++++-- dGame/dGameMessages/GameMessageHandler.cpp | 9 +++- dGame/dGameMessages/GameMessages.cpp | 40 ++++++++++++++ dGame/dGameMessages/GameMessages.h | 9 ++++ dGame/dUtilities/SlashCommandHandler.cpp | 1 + 8 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 dCommon/dEnums/eBubbleType.h diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index ed4167c8..c1afc497 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -374,6 +374,8 @@ enum GAME_MSG : unsigned short { GAME_MSG_PET_TAMING_TRY_BUILD_RESULT = 668, GAME_MSG_NOTIFY_TAMING_BUILD_SUCCESS = 673, GAME_MSG_NOTIFY_TAMING_MODEL_LOADED_ON_SERVER = 674, + GAME_MSG_ACTIVATE_BUBBLE_BUFF = 678, + GAME_MSG_DEACTIVATE_BUBBLE_BUFF = 679, GAME_MSG_ADD_PET_TO_PLAYER = 681, GAME_MSG_REQUEST_SET_PET_NAME = 683, GAME_MSG_SET_PET_NAME = 684, @@ -386,7 +388,10 @@ enum GAME_MSG : unsigned short { GAME_MSG_QUERY_PROPERTY_DATA = 717, GAME_MSG_PROPERTY_EDITOR_BEGIN = 724, GAME_MSG_PROPERTY_EDITOR_END = 725, - GAME_MSG_START_PATHING = 735, + GAME_MSG_IS_MINIFIG_IN_A_BUBBLE = 729, + GAME_MSG_START_PATHING = 733, + GAME_MSG_ACTIVATE_BUBBLE_BUFF_FROM_SERVER = 734, + GAME_MSG_DEACTIVATE_BUBBLE_BUFF_FROM_SERVER = 735, GAME_MSG_NOTIFY_CLIENT_ZONE_OBJECT = 737, GAME_MSG_UPDATE_REPUTATION = 746, GAME_MSG_PROPERTY_RENTAL_RESPONSE = 750, diff --git a/dCommon/dEnums/eBubbleType.h b/dCommon/dEnums/eBubbleType.h new file mode 100644 index 00000000..4aa6fad1 --- /dev/null +++ b/dCommon/dEnums/eBubbleType.h @@ -0,0 +1,14 @@ +#pragma once + +#ifndef __EBUBBLETYPE__H__ +#define __EBUBBLETYPE__H__ + +#include <cstdint> + +enum class eBubbleType : uint32_t { + DEFAULT = 0, + ENERGY = 1, + SKUNK = 2, +}; + +#endif //!__EBUBBLETYPE__H__ diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index 2920a84f..6a6d69ce 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -31,8 +31,15 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Com m_GravityScale = 1; m_DirtyCheats = false; m_IgnoreMultipliers = false; + + m_DirtyEquippedItemInfo = true; m_PickupRadius = 0.0f; - m_DirtyPickupRadiusScale = true; + + m_DirtyBubble = false; + m_IsInBubble = false; + m_SpecialAnims = false; + m_BubbleType = eBubbleType::DEFAULT; + m_IsTeleporting = false; m_ImmuneToStunAttackCount = 0; @@ -99,14 +106,22 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bo m_DirtyCheats = false; } - outBitStream->Write(m_DirtyPickupRadiusScale); - if (m_DirtyPickupRadiusScale) { + outBitStream->Write(m_DirtyEquippedItemInfo); + if (m_DirtyEquippedItemInfo) { outBitStream->Write(m_PickupRadius); - outBitStream->Write0(); //No clue what this is so im leaving it false. - m_DirtyPickupRadiusScale = false; + outBitStream->Write(m_InJetpackMode); + m_DirtyEquippedItemInfo = false; } - outBitStream->Write0(); + outBitStream->Write(m_DirtyBubble); + if (m_DirtyBubble) { + outBitStream->Write(m_IsInBubble); + if (m_IsInBubble) { + outBitStream->Write(m_BubbleType); + outBitStream->Write(m_SpecialAnims); + } + m_DirtyBubble = false; + } outBitStream->Write(m_DirtyPosition || bIsInitialUpdate); if (m_DirtyPosition || bIsInitialUpdate) { @@ -263,7 +278,7 @@ void ControllablePhysicsComponent::AddPickupRadiusScale(float value) { m_ActivePickupRadiusScales.push_back(value); if (value > m_PickupRadius) { m_PickupRadius = value; - m_DirtyPickupRadiusScale = true; + m_DirtyEquippedItemInfo = true; } } @@ -279,7 +294,7 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) { // Recalculate pickup radius since we removed one by now m_PickupRadius = 0.0f; - m_DirtyPickupRadiusScale = true; + m_DirtyEquippedItemInfo = true; for (uint32_t i = 0; i < m_ActivePickupRadiusScales.size(); i++) { auto candidateRadius = m_ActivePickupRadiusScales[i]; if (m_PickupRadius < candidateRadius) m_PickupRadius = candidateRadius; @@ -314,6 +329,24 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) { EntityManager::Instance()->SerializeEntity(m_Parent); } +void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bool specialAnims){ + if (m_IsInBubble) { + Game::logger->Log("ControllablePhysicsComponent", "Already in bubble"); + return; + } + m_BubbleType = bubbleType; + m_IsInBubble = true; + m_DirtyBubble = true; + m_SpecialAnims = specialAnims; + EntityManager::Instance()->SerializeEntity(m_Parent); +} + +void ControllablePhysicsComponent::DeactivateBubbleBuff(){ + m_DirtyBubble = true; + m_IsInBubble = false; + EntityManager::Instance()->SerializeEntity(m_Parent); +}; + void ControllablePhysicsComponent::SetStunImmunity( const eStateChangeType state, const LWOOBJID originator, diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index ba3e1bf4..a05a11fd 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -9,6 +9,7 @@ #include "Component.h" #include "dpCollisionChecks.h" #include "PhantomPhysicsComponent.h" +#include "eBubbleType.h" class Entity; class dpEntity; @@ -257,14 +258,40 @@ public: */ std::vector<float> GetActivePickupRadiusScales() { return m_ActivePickupRadiusScales; }; - + /** + * Add a Speed boost to the entity + * This will recalculate the speed boost based on what is being added + */ void AddSpeedboost(float value); + /** + * Remove speed boost from entity + * This will recalculate the speed boost based on what is the last one in te vector + */ void RemoveSpeedboost(float value); + /** + * The speed boosts of this component. + * @return All active Speed boosts for this component. + */ std::vector<float> GetActiveSpeedboosts() { return m_ActivePickupRadiusScales; }; /** + * Activates the Bubble Buff + */ + void ActivateBubbleBuff(eBubbleType bubbleType = eBubbleType::DEFAULT, bool specialAnims = true); + + /** + * Deactivates the Bubble Buff + */ + void DeactivateBubbleBuff(); + + /** + * Gets if the Entity is in a bubble + */ + bool GetIsInBubble(){ return m_IsInBubble; }; + + /** * Push or Pop a layer of stun immunity to this entity */ void SetStunImmunity( @@ -387,7 +414,7 @@ private: /** * Whether the pickup scale is dirty. */ - bool m_DirtyPickupRadiusScale; + bool m_DirtyEquippedItemInfo; /** * The list of pickup radius scales for this entity @@ -414,7 +441,27 @@ private: */ float m_SpeedBoost; - /** + /* + * If Bubble info is dirty + */ + bool m_DirtyBubble; + + /* + * If the entity is in a bubble + */ + bool m_IsInBubble; + + /* + * The type of bubble the entity has + */ + eBubbleType m_BubbleType; + + /* + * If the entity should be using the special animations + */ + bool m_SpecialAnims; + + /** * stun immunity counters */ int32_t m_ImmuneToStunAttackCount; diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index c03f58db..a91a1e2a 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -665,9 +665,14 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case GAME_MSG_DISMOUNT_COMPLETE: GameMessages::HandleDismountComplete(inStream, entity, sysAddr); break; - + case GAME_MSG_DEACTIVATE_BUBBLE_BUFF: + GameMessages::HandleDeactivateBubbleBuff(inStream, entity); + break; + case GAME_MSG_ACTIVATE_BUBBLE_BUFF: + GameMessages::HandleActivateBubbleBuff(inStream, entity); + break; default: - //Game::logger->Log("GameMessageHandler", "Unknown game message ID: %X", messageID); + // Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID); break; } } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c6c7d2d1..7e9ea898 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -6084,3 +6084,43 @@ void GameMessages::HandleUpdatePlayerStatistic(RakNet::BitStream* inStream, Enti characterComponent->UpdatePlayerStatistic((StatisticID)updateID, (uint64_t)std::max(updateValue, int64_t(0))); } } + +void GameMessages::HandleDeactivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity) { + auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>(); + if (controllablePhysicsComponent) controllablePhysicsComponent->DeactivateBubbleBuff(); +} + +void GameMessages::HandleActivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity) { + bool specialAnimations; + if (!inStream->Read(specialAnimations)) return; + + std::u16string type = GeneralUtils::ReadWString(inStream); + auto bubbleType = eBubbleType::DEFAULT; + if (type == u"skunk") bubbleType = eBubbleType::SKUNK; + else if (type == u"energy") bubbleType = eBubbleType::ENERGY; + + auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>(); + if (controllablePhysicsComponent) controllablePhysicsComponent->ActivateBubbleBuff(bubbleType, specialAnimations); +} + +void GameMessages::SendActivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_ACTIVATE_BUBBLE_BUFF_FROM_SERVER); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; + SEND_PACKET; +} + +void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_DEACTIVATE_BUBBLE_BUFF_FROM_SERVER); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; + SEND_PACKET; +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 6fa4e694..0675ae76 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -617,6 +617,15 @@ namespace GameMessages { void HandleReportBug(RakNet::BitStream* inStream, Entity* entity); void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId); + + // bubble + void HandleDeactivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity); + + void HandleActivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity); + + void SendActivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); + + void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); }; #endif // GAMEMESSAGES_H diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 9ee4c1e6..e6e29ceb 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -68,6 +68,7 @@ #include "AssetManager.h" #include "BinaryPathFinder.h" #include "dConfig.h" +#include "eBubbleType.h" #include "AMFFormat.h" #include "MovingPlatformComponent.h" #include "dMessageIdentifiers.h" From a28a2e60cfaeef09394e8d46e49f75248d8b4f25 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 6 Jan 2023 22:16:43 -0800 Subject: [PATCH 105/166] Add property Teleport behavior (#846) * Add property Teleport behavior Untested. Will mark pr as ready for review when this has been tested * Fix issues --- dGame/dBehaviors/Behavior.cpp | 5 +- dGame/dBehaviors/CMakeLists.txt | 1 + dGame/dBehaviors/PropertyTeleportBehavior.cpp | 61 +++++++++++++++++++ dGame/dBehaviors/PropertyTeleportBehavior.h | 21 +++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 dGame/dBehaviors/PropertyTeleportBehavior.cpp create mode 100644 dGame/dBehaviors/PropertyTeleportBehavior.h diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 40c37a95..c8c1a1de 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -48,6 +48,7 @@ #include "PlayEffectBehavior.h" #include "DamageAbsorptionBehavior.h" #include "VentureVisionBehavior.h" +#include "PropertyTeleportBehavior.h" #include "BlockBehavior.h" #include "ClearTargetBehavior.h" #include "PullToPointBehavior.h" @@ -263,7 +264,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { case BehaviorTemplates::BEHAVIOR_DAMAGE_REDUCTION: behavior = new DamageReductionBehavior(behaviorId); break; - case BehaviorTemplates::BEHAVIOR_PROPERTY_TELEPORT: break; + case BehaviorTemplates::BEHAVIOR_PROPERTY_TELEPORT: + behavior = new PropertyTeleportBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_PROPERTY_CLEAR_TARGET: behavior = new ClearTargetBehavior(behaviorId); break; diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index e274872d..7b331fe0 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -35,6 +35,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "OverTimeBehavior.cpp" "PlayEffectBehavior.cpp" "ProjectileAttackBehavior.cpp" + "PropertyTeleportBehavior.cpp" "PullToPointBehavior.cpp" "RemoveBuffBehavior.cpp" "RepairBehavior.cpp" diff --git a/dGame/dBehaviors/PropertyTeleportBehavior.cpp b/dGame/dBehaviors/PropertyTeleportBehavior.cpp new file mode 100644 index 00000000..447b085b --- /dev/null +++ b/dGame/dBehaviors/PropertyTeleportBehavior.cpp @@ -0,0 +1,61 @@ +#include "PropertyTeleportBehavior.h" + +#include "BehaviorBranchContext.h" +#include "BehaviorContext.h" +#include "Character.h" +#include "CharacterComponent.h" +#include "ChatPackets.h" +#include "WorldPackets.h" +#include "EntityManager.h" +#include "Game.h" +#include "ZoneInstanceManager.h" +#include "dZoneManager.h" + +void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + auto* caster = EntityManager::Instance()->GetEntity(context->caster); + if (!caster) return; + + auto* character = caster->GetCharacter(); + if (!character) return; + + LWOOBJID objId = caster->GetObjectID(); + + LWOMAPID targetMapId = m_MapId; + LWOCLONEID targetCloneId = character->GetPropertyCloneID(); + + if (dZoneManager::Instance()->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) { + targetMapId = character->GetLastNonInstanceZoneID(); + targetCloneId = 0; + } else { + character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZoneID().GetMapID()); + } + + ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, false, [objId](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { + + auto* entity = EntityManager::Instance()->GetEntity(objId); + if (!entity) return; + + const auto sysAddr = entity->GetSystemAddress(); + + if (zoneClone != 0) ChatPackets::SendSystemMessage(sysAddr, u"Transfering to your property!"); + else ChatPackets::SendSystemMessage(sysAddr, u"Transfering back to previous world!"); + + Game::logger->Log("PropertyTeleportBehavior", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort); + if (entity->GetCharacter()) { + entity->GetCharacter()->SetZoneID(zoneID); + entity->GetCharacter()->SetZoneInstance(zoneInstance); + entity->GetCharacter()->SetZoneClone(zoneClone); + entity->GetComponent<CharacterComponent>()->SetLastRocketConfig(u""); + } + + entity->GetCharacter()->SaveXMLToDatabase(); + + WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift); + return; + }); +} + +void PropertyTeleportBehavior::Load() { + this->m_CancelIfInteracting = GetBoolean("cancel_if_interacting"); // TODO unused + this->m_MapId = LWOMAPID(GetInt("mapID")); +} diff --git a/dGame/dBehaviors/PropertyTeleportBehavior.h b/dGame/dBehaviors/PropertyTeleportBehavior.h new file mode 100644 index 00000000..74eed03b --- /dev/null +++ b/dGame/dBehaviors/PropertyTeleportBehavior.h @@ -0,0 +1,21 @@ +#pragma once +#include "Behavior.h" + +class PropertyTeleportBehavior final : public Behavior +{ +public: + /* + * Inherited + */ + + explicit PropertyTeleportBehavior(const uint32_t behavior_id) : Behavior(behavior_id) { + } + + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + + void Load() override; + +private: + LWOMAPID m_MapId; + bool m_CancelIfInteracting; +}; From a580e3a2f5edd0e2b90b693b036f9e66dad760df Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 6 Jan 2023 22:17:09 -0800 Subject: [PATCH 106/166] Update lookup command (#909) * Update lookup command * Fix bugs Update SlashCommandHandler.cpp --- dGame/dUtilities/SlashCommandHandler.cpp | 10 ++++++++-- docs/Commands.md | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index e6e29ceb..cc1c82a9 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1198,11 +1198,17 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { auto query = CDClientDatabase::CreatePreppedStmt( "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); + // Concatenate all of the arguments into a single query so a multi word query can be used properly. + std::string conditional = args[0]; + args.erase(args.begin()); + for (auto& argument : args) { + conditional += ' ' + argument; + } - const std::string query_text = "%" + args[0] + "%"; + const std::string query_text = "%" + conditional + "%"; query.bind(1, query_text.c_str()); auto tables = query.execQuery(); diff --git a/docs/Commands.md b/docs/Commands.md index 7c4f494f..7dc11ff1 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -78,7 +78,7 @@ These commands are primarily for development and testing. The usage of many of t |inspect|`/inspect <component> (-m <waypoint> \| -a <animation> \| -s \| -p \| -f (faction) \| -t)`|Finds the closest entity with the given component or LDF variable (ignoring players and racing cars), printing its ID, distance from the player, and whether it is sleeping, as well as the the IDs of all components the entity has. See [Detailed `/inspect` Usage](#detailed-inspect-usage) below.|8| |list-spawns|`/list-spawns`|Lists all the character spawn points in the zone. Additionally, this command will display the current scene that plays when the character lands in the next zone, if there is one.|8| |locrow|`/locrow`|Prints the your current position and rotation information to the console.|8| -|lookup|`/lookup <query>`|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query.|8| +|lookup|`/lookup <query>`|Searches through the Objects table in the client SQLite database for items whose display name, name, or description contains the query. Query can be multiple words delimited by spaces.|8| |playanimation|`/playanimation <id>`|Plays animation with given ID. Alias: `/playanim`.|8| |playeffect|`/playeffect <effect id> <effect type> <effect name>`|Plays an effect.|8| |playlvlfx|`/playlvlfx`|Plays the level up animation on your character.|8| From 8920cd106325f2c1d577f5c1089cf66bde14e34c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 7 Jan 2023 01:48:59 -0800 Subject: [PATCH 107/166] Use field names instead of numbers for CDClient tables (#945) --- dDatabase/Tables/CDActivitiesTable.cpp | 39 ++-- dDatabase/Tables/CDActivityRewardsTable.cpp | 15 +- dDatabase/Tables/CDAnimationsTable.cpp | 27 +-- dDatabase/Tables/CDBehaviorParameterTable.cpp | 7 +- dDatabase/Tables/CDBehaviorTemplateTable.cpp | 7 +- dDatabase/Tables/CDBrickIDTableTable.cpp | 5 +- .../Tables/CDComponentsRegistryTable.cpp | 13 +- dDatabase/Tables/CDCurrencyTableTable.cpp | 11 +- .../Tables/CDDestructibleComponentTable.cpp | 29 +-- dDatabase/Tables/CDEmoteTable.cpp | 17 +- dDatabase/Tables/CDEmoteTable.h | 4 +- dDatabase/Tables/CDFeatureGatingTable.cpp | 11 +- .../Tables/CDInventoryComponentTable.cpp | 9 +- dDatabase/Tables/CDItemComponentTable.cpp | 169 +++++++++--------- dDatabase/Tables/CDItemSetSkillsTable.cpp | 7 +- dDatabase/Tables/CDItemSetsTable.cpp | 31 ++-- .../Tables/CDLevelProgressionLookupTable.cpp | 7 +- dDatabase/Tables/CDLootMatrixTable.cpp | 19 +- dDatabase/Tables/CDLootTableTable.cpp | 13 +- dDatabase/Tables/CDMissionEmailTable.cpp | 17 +- .../Tables/CDMissionNPCComponentTable.cpp | 11 +- dDatabase/Tables/CDMissionTasksTable.cpp | 27 +-- dDatabase/Tables/CDMissionsTable.cpp | 105 +++++------ .../Tables/CDMovementAIComponentTable.cpp | 17 +- dDatabase/Tables/CDObjectSkillsTable.cpp | 9 +- dDatabase/Tables/CDObjectsTable.cpp | 55 +++--- dDatabase/Tables/CDPackageComponentTable.cpp | 7 +- dDatabase/Tables/CDPhysicsComponentTable.cpp | 33 ++-- .../CDPropertyEntranceComponentTable.cpp | 11 +- dDatabase/Tables/CDPropertyTemplateTable.cpp | 9 +- .../CDProximityMonitorComponentTable.cpp | 9 +- dDatabase/Tables/CDRailActivatorComponent.cpp | 33 ++-- dDatabase/Tables/CDRarityTableTable.cpp | 9 +- dDatabase/Tables/CDRebuildComponentTable.cpp | 21 +-- dDatabase/Tables/CDRewardsTable.cpp | 13 +- dDatabase/Tables/CDScriptComponentTable.cpp | 7 +- dDatabase/Tables/CDSkillBehaviorTable.cpp | 39 ++-- dDatabase/Tables/CDVendorComponentTable.cpp | 11 +- dDatabase/Tables/CDZoneTableTable.cpp | 55 +++--- 39 files changed, 488 insertions(+), 450 deletions(-) diff --git a/dDatabase/Tables/CDActivitiesTable.cpp b/dDatabase/Tables/CDActivitiesTable.cpp index 835ca3d2..d6fa354e 100644 --- a/dDatabase/Tables/CDActivitiesTable.cpp +++ b/dDatabase/Tables/CDActivitiesTable.cpp @@ -21,25 +21,25 @@ CDActivitiesTable::CDActivitiesTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Activities"); while (!tableData.eof()) { CDActivities entry; - entry.ActivityID = tableData.getIntField(0, -1); - entry.locStatus = tableData.getIntField(1, -1); - entry.instanceMapID = tableData.getIntField(2, -1); - entry.minTeams = tableData.getIntField(3, -1); - entry.maxTeams = tableData.getIntField(4, -1); - entry.minTeamSize = tableData.getIntField(5, -1); - entry.maxTeamSize = tableData.getIntField(6, -1); - entry.waitTime = tableData.getIntField(7, -1); - entry.startDelay = tableData.getIntField(8, -1); - entry.requiresUniqueData = tableData.getIntField(9, -1); - entry.leaderboardType = tableData.getIntField(10, -1); - entry.localize = tableData.getIntField(11, -1); - entry.optionalCostLOT = tableData.getIntField(12, -1); - entry.optionalCostCount = tableData.getIntField(13, -1); - entry.showUIRewards = tableData.getIntField(14, -1); - entry.CommunityActivityFlagID = tableData.getIntField(15, -1); - entry.gate_version = tableData.getStringField(16, ""); - entry.noTeamLootOnDeath = tableData.getIntField(17, -1); - entry.optionalPercentage = tableData.getFloatField(18, -1.0f); + entry.ActivityID = tableData.getIntField("ActivityID", -1); + entry.locStatus = tableData.getIntField("locStatus", -1); + entry.instanceMapID = tableData.getIntField("instanceMapID", -1); + entry.minTeams = tableData.getIntField("minTeams", -1); + entry.maxTeams = tableData.getIntField("maxTeams", -1); + entry.minTeamSize = tableData.getIntField("minTeamSize", -1); + entry.maxTeamSize = tableData.getIntField("maxTeamSize", -1); + entry.waitTime = tableData.getIntField("waitTime", -1); + entry.startDelay = tableData.getIntField("startDelay", -1); + entry.requiresUniqueData = tableData.getIntField("requiresUniqueData", -1); + entry.leaderboardType = tableData.getIntField("leaderboardType", -1); + entry.localize = tableData.getIntField("localize", -1); + entry.optionalCostLOT = tableData.getIntField("optionalCostLOT", -1); + entry.optionalCostCount = tableData.getIntField("optionalCostCount", -1); + entry.showUIRewards = tableData.getIntField("showUIRewards", -1); + entry.CommunityActivityFlagID = tableData.getIntField("CommunityActivityFlagID", -1); + entry.gate_version = tableData.getStringField("gate_version", ""); + entry.noTeamLootOnDeath = tableData.getIntField("noTeamLootOnDeath", -1); + entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f); this->entries.push_back(entry); tableData.nextRow(); @@ -70,3 +70,4 @@ std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActiviti std::vector<CDActivities> CDActivitiesTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDActivityRewardsTable.cpp b/dDatabase/Tables/CDActivityRewardsTable.cpp index f1719204..3922d9fb 100644 --- a/dDatabase/Tables/CDActivityRewardsTable.cpp +++ b/dDatabase/Tables/CDActivityRewardsTable.cpp @@ -21,13 +21,13 @@ CDActivityRewardsTable::CDActivityRewardsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards"); while (!tableData.eof()) { CDActivityRewards entry; - entry.objectTemplate = tableData.getIntField(0, -1); - entry.ActivityRewardIndex = tableData.getIntField(1, -1); - entry.activityRating = tableData.getIntField(2, -1); - entry.LootMatrixIndex = tableData.getIntField(3, -1); - entry.CurrencyIndex = tableData.getIntField(4, -1); - entry.ChallengeRating = tableData.getIntField(5, -1); - entry.description = tableData.getStringField(6, ""); + entry.objectTemplate = tableData.getIntField("objectTemplate", -1); + entry.ActivityRewardIndex = tableData.getIntField("ActivityRewardIndex", -1); + entry.activityRating = tableData.getIntField("activityRating", -1); + entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); + entry.CurrencyIndex = tableData.getIntField("CurrencyIndex", -1); + entry.ChallengeRating = tableData.getIntField("ChallengeRating", -1); + entry.description = tableData.getStringField("description", ""); this->entries.push_back(entry); tableData.nextRow(); @@ -58,3 +58,4 @@ std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool( std::vector<CDActivityRewards> CDActivityRewardsTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDAnimationsTable.cpp b/dDatabase/Tables/CDAnimationsTable.cpp index 399804f8..e21d44c5 100644 --- a/dDatabase/Tables/CDAnimationsTable.cpp +++ b/dDatabase/Tables/CDAnimationsTable.cpp @@ -21,19 +21,19 @@ CDAnimationsTable::CDAnimationsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations"); while (!tableData.eof()) { CDAnimations entry; - entry.animationGroupID = tableData.getIntField(0, -1); - entry.animation_type = tableData.getStringField(1, ""); - entry.animation_name = tableData.getStringField(2, ""); - entry.chance_to_play = tableData.getFloatField(3, -1.0f); - entry.min_loops = tableData.getIntField(4, -1); - entry.max_loops = tableData.getIntField(5, -1); - entry.animation_length = tableData.getFloatField(6, -1.0f); - entry.hideEquip = tableData.getIntField(7, -1) == 1 ? true : false; - entry.ignoreUpperBody = tableData.getIntField(8, -1) == 1 ? true : false; - entry.restartable = tableData.getIntField(9, -1) == 1 ? true : false; - entry.face_animation_name = tableData.getStringField(10, ""); - entry.priority = tableData.getFloatField(11, -1.0f); - entry.blendTime = tableData.getFloatField(12, -1.0f); + entry.animationGroupID = tableData.getIntField("animationGroupID", -1); + entry.animation_type = tableData.getStringField("animation_type", ""); + entry.animation_name = tableData.getStringField("animation_name", ""); + entry.chance_to_play = tableData.getFloatField("chance_to_play", -1.0f); + entry.min_loops = tableData.getIntField("min_loops", -1); + entry.max_loops = tableData.getIntField("max_loops", -1); + entry.animation_length = tableData.getFloatField("animation_length", -1.0f); + entry.hideEquip = tableData.getIntField("hideEquip", -1) == 1 ? true : false; + entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", -1) == 1 ? true : false; + entry.restartable = tableData.getIntField("restartable", -1) == 1 ? true : false; + entry.face_animation_name = tableData.getStringField("face_animation_name", ""); + entry.priority = tableData.getFloatField("priority", -1.0f); + entry.blendTime = tableData.getFloatField("blendTime", -1.0f); this->entries.push_back(entry); tableData.nextRow(); @@ -64,3 +64,4 @@ std::vector<CDAnimations> CDAnimationsTable::Query(std::function<bool(CDAnimatio std::vector<CDAnimations> CDAnimationsTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index d09a71b2..b894688b 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -8,8 +8,8 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { uint64_t hash = 0; while (!tableData.eof()) { CDBehaviorParameter entry; - entry.behaviorID = tableData.getIntField(0, -1); - auto candidateStringToAdd = std::string(tableData.getStringField(1, "")); + entry.behaviorID = tableData.getIntField("behaviorID", -1); + auto candidateStringToAdd = std::string(tableData.getStringField("parameterID", "")); auto parameter = m_ParametersList.find(candidateStringToAdd); if (parameter != m_ParametersList.end()) { entry.parameterID = parameter; @@ -19,7 +19,7 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { } hash = entry.behaviorID; hash = (hash << 31U) | entry.parameterID->second; - entry.value = tableData.getFloatField(2, -1.0f); + entry.value = tableData.getFloatField("value", -1.0f); m_Entries.insert(std::make_pair(hash, entry)); @@ -62,3 +62,4 @@ std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID } return returnInfo; } + diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.cpp b/dDatabase/Tables/CDBehaviorTemplateTable.cpp index 1628756f..4adb9bce 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.cpp +++ b/dDatabase/Tables/CDBehaviorTemplateTable.cpp @@ -21,9 +21,9 @@ CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate"); while (!tableData.eof()) { CDBehaviorTemplate entry; - entry.behaviorID = tableData.getIntField(0, -1); - entry.templateID = tableData.getIntField(1, -1); - entry.effectID = tableData.getIntField(2, -1); + entry.behaviorID = tableData.getIntField("behaviorID", -1); + entry.templateID = tableData.getIntField("templateID", -1); + entry.effectID = tableData.getIntField("effectID", -1); auto candidateToAdd = tableData.getStringField(3, ""); auto parameter = m_EffectHandles.find(candidateToAdd); if (parameter != m_EffectHandles.end()) { @@ -75,3 +75,4 @@ const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behav return entry->second; } } + diff --git a/dDatabase/Tables/CDBrickIDTableTable.cpp b/dDatabase/Tables/CDBrickIDTableTable.cpp index 9dbdf2c0..7cd3e86f 100644 --- a/dDatabase/Tables/CDBrickIDTableTable.cpp +++ b/dDatabase/Tables/CDBrickIDTableTable.cpp @@ -21,8 +21,8 @@ CDBrickIDTableTable::CDBrickIDTableTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BrickIDTable"); while (!tableData.eof()) { CDBrickIDTable entry; - entry.NDObjectID = tableData.getIntField(0, -1); - entry.LEGOBrickID = tableData.getIntField(1, -1); + entry.NDObjectID = tableData.getIntField("NDObjectID", -1); + entry.LEGOBrickID = tableData.getIntField("LEGOBrickID", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -53,3 +53,4 @@ std::vector<CDBrickIDTable> CDBrickIDTableTable::Query(std::function<bool(CDBric std::vector<CDBrickIDTable> CDBrickIDTableTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDComponentsRegistryTable.cpp b/dDatabase/Tables/CDComponentsRegistryTable.cpp index 8e5ae108..987c66ab 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.cpp +++ b/dDatabase/Tables/CDComponentsRegistryTable.cpp @@ -24,9 +24,9 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry"); while (!tableData.eof()) { CDComponentsRegistry entry; - entry.id = tableData.getIntField(0, -1); - entry.component_type = tableData.getIntField(1, -1); - entry.component_id = tableData.getIntField(2, -1); + entry.id = tableData.getIntField("id", -1); + entry.component_type = tableData.getIntField("component_type", -1); + entry.component_id = tableData.getIntField("component_id", -1); this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id); @@ -91,9 +91,9 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen auto tableData = CDClientDatabase::ExecuteQuery(query.str()); while (!tableData.eof()) { CDComponentsRegistry entry; - entry.id = tableData.getIntField(0, -1); - entry.component_type = tableData.getIntField(1, -1); - entry.component_id = tableData.getIntField(2, -1); + entry.id = tableData.getIntField("id", -1); + entry.component_type = tableData.getIntField("component_type", -1); + entry.component_id = tableData.getIntField("component_id", -1); //this->entries.push_back(entry); @@ -126,3 +126,4 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen return defaultValue; #endif } + diff --git a/dDatabase/Tables/CDCurrencyTableTable.cpp b/dDatabase/Tables/CDCurrencyTableTable.cpp index a1923a73..21870f00 100644 --- a/dDatabase/Tables/CDCurrencyTableTable.cpp +++ b/dDatabase/Tables/CDCurrencyTableTable.cpp @@ -21,11 +21,11 @@ CDCurrencyTableTable::CDCurrencyTableTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM CurrencyTable"); while (!tableData.eof()) { CDCurrencyTable entry; - entry.currencyIndex = tableData.getIntField(0, -1); - entry.npcminlevel = tableData.getIntField(1, -1); - entry.minvalue = tableData.getIntField(2, -1); - entry.maxvalue = tableData.getIntField(3, -1); - entry.id = tableData.getIntField(4, -1); + entry.currencyIndex = tableData.getIntField("currencyIndex", -1); + entry.npcminlevel = tableData.getIntField("npcminlevel", -1); + entry.minvalue = tableData.getIntField("minvalue", -1); + entry.maxvalue = tableData.getIntField("maxvalue", -1); + entry.id = tableData.getIntField("id", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -56,3 +56,4 @@ std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCu std::vector<CDCurrencyTable> CDCurrencyTableTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDDestructibleComponentTable.cpp b/dDatabase/Tables/CDDestructibleComponentTable.cpp index d7438fc7..2480fc24 100644 --- a/dDatabase/Tables/CDDestructibleComponentTable.cpp +++ b/dDatabase/Tables/CDDestructibleComponentTable.cpp @@ -21,20 +21,20 @@ CDDestructibleComponentTable::CDDestructibleComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DestructibleComponent"); while (!tableData.eof()) { CDDestructibleComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.faction = tableData.getIntField(1, -1); - entry.factionList = tableData.getStringField(2, ""); - entry.life = tableData.getIntField(3, -1); - entry.imagination = tableData.getIntField(4, -1); - entry.LootMatrixIndex = tableData.getIntField(5, -1); - entry.CurrencyIndex = tableData.getIntField(6, -1); - entry.level = tableData.getIntField(7, -1); - entry.armor = tableData.getFloatField(8, -1.0f); - entry.death_behavior = tableData.getIntField(9, -1); - entry.isnpc = tableData.getIntField(10, -1) == 1 ? true : false; - entry.attack_priority = tableData.getIntField(11, -1); - entry.isSmashable = tableData.getIntField(12, -1) == 1 ? true : false; - entry.difficultyLevel = tableData.getIntField(13, -1); + entry.id = tableData.getIntField("id", -1); + entry.faction = tableData.getIntField("faction", -1); + entry.factionList = tableData.getStringField("factionList", ""); + entry.life = tableData.getIntField("life", -1); + entry.imagination = tableData.getIntField("imagination", -1); + entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); + entry.CurrencyIndex = tableData.getIntField("CurrencyIndex", -1); + entry.level = tableData.getIntField("level", -1); + entry.armor = tableData.getFloatField("armor", -1.0f); + entry.death_behavior = tableData.getIntField("death_behavior", -1); + entry.isnpc = tableData.getIntField("isnpc", -1) == 1 ? true : false; + entry.attack_priority = tableData.getIntField("attack_priority", -1); + entry.isSmashable = tableData.getIntField("isSmashable", -1) == 1 ? true : false; + entry.difficultyLevel = tableData.getIntField("difficultyLevel", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -65,3 +65,4 @@ std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::fu std::vector<CDDestructibleComponent> CDDestructibleComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDEmoteTable.cpp b/dDatabase/Tables/CDEmoteTable.cpp index e3898422..b97e02e8 100644 --- a/dDatabase/Tables/CDEmoteTable.cpp +++ b/dDatabase/Tables/CDEmoteTable.cpp @@ -5,14 +5,14 @@ CDEmoteTableTable::CDEmoteTableTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Emotes"); while (!tableData.eof()) { CDEmoteTable* entry = new CDEmoteTable(); - entry->ID = tableData.getIntField(0, -1); - entry->animationName = tableData.getStringField(1, ""); - entry->iconFilename = tableData.getStringField(2, ""); - entry->channel = tableData.getIntField(3, -1); - entry->locked = tableData.getIntField(5, -1) != 0; - entry->localize = tableData.getIntField(6, -1) != 0; - entry->locState = tableData.getIntField(7, -1); - entry->gateVersion = tableData.getIntField(8, -1); + entry->ID = tableData.getIntField("id", -1); + entry->animationName = tableData.getStringField("animationName", ""); + entry->iconFilename = tableData.getStringField("iconFilename", ""); + entry->channel = tableData.getIntField("channel", -1); + entry->locked = tableData.getIntField("locked", -1) != 0; + entry->localize = tableData.getIntField("localize", -1) != 0; + entry->locState = tableData.getIntField("locStatus", -1); + entry->gateVersion = tableData.getStringField("gate_version", ""); entries.insert(std::make_pair(entry->ID, entry)); tableData.nextRow(); @@ -42,3 +42,4 @@ CDEmoteTable* CDEmoteTableTable::GetEmote(int id) { return nullptr; } + diff --git a/dDatabase/Tables/CDEmoteTable.h b/dDatabase/Tables/CDEmoteTable.h index a22ae23e..1f4fb246 100644 --- a/dDatabase/Tables/CDEmoteTable.h +++ b/dDatabase/Tables/CDEmoteTable.h @@ -19,7 +19,7 @@ struct CDEmoteTable { channel = -1; locked = false; localize = false; - gateVersion = -1; + gateVersion = ""; } int ID; @@ -29,7 +29,7 @@ struct CDEmoteTable { int channel; bool locked; bool localize; - int gateVersion; + std::string gateVersion; }; //! CDEmoteTable table diff --git a/dDatabase/Tables/CDFeatureGatingTable.cpp b/dDatabase/Tables/CDFeatureGatingTable.cpp index dfc65387..0abcdb25 100644 --- a/dDatabase/Tables/CDFeatureGatingTable.cpp +++ b/dDatabase/Tables/CDFeatureGatingTable.cpp @@ -21,11 +21,11 @@ CDFeatureGatingTable::CDFeatureGatingTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM FeatureGating"); while (!tableData.eof()) { CDFeatureGating entry; - entry.featureName = tableData.getStringField(0, ""); - entry.major = tableData.getIntField(1, -1); - entry.current = tableData.getIntField(2, -1); - entry.minor = tableData.getIntField(3, -1); - entry.description = tableData.getStringField(4, ""); + entry.featureName = tableData.getStringField("featureName", ""); + entry.major = tableData.getIntField("major", -1); + entry.current = tableData.getIntField("current", -1); + entry.minor = tableData.getIntField("minor", -1); + entry.description = tableData.getStringField("description", ""); this->entries.push_back(entry); tableData.nextRow(); @@ -66,3 +66,4 @@ bool CDFeatureGatingTable::FeatureUnlocked(const std::string& feature) const { std::vector<CDFeatureGating> CDFeatureGatingTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDInventoryComponentTable.cpp b/dDatabase/Tables/CDInventoryComponentTable.cpp index 65f09c9b..cf956775 100644 --- a/dDatabase/Tables/CDInventoryComponentTable.cpp +++ b/dDatabase/Tables/CDInventoryComponentTable.cpp @@ -21,10 +21,10 @@ CDInventoryComponentTable::CDInventoryComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM InventoryComponent"); while (!tableData.eof()) { CDInventoryComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.itemid = tableData.getIntField(1, -1); - entry.count = tableData.getIntField(2, -1); - entry.equip = tableData.getIntField(3, -1) == 1 ? true : false; + entry.id = tableData.getIntField("id", -1); + entry.itemid = tableData.getIntField("itemid", -1); + entry.count = tableData.getIntField("count", -1); + entry.equip = tableData.getIntField("equip", -1) == 1 ? true : false; this->entries.push_back(entry); tableData.nextRow(); @@ -55,3 +55,4 @@ std::vector<CDInventoryComponent> CDInventoryComponentTable::Query(std::function std::vector<CDInventoryComponent> CDInventoryComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDItemComponentTable.cpp b/dDatabase/Tables/CDItemComponentTable.cpp index 6ff192fd..a3cb4159 100644 --- a/dDatabase/Tables/CDItemComponentTable.cpp +++ b/dDatabase/Tables/CDItemComponentTable.cpp @@ -23,48 +23,48 @@ CDItemComponentTable::CDItemComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemComponent"); while (!tableData.eof()) { CDItemComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.equipLocation = tableData.getStringField(1, ""); - entry.baseValue = tableData.getIntField(2, -1); - entry.isKitPiece = tableData.getIntField(3, -1) == 1 ? true : false; - entry.rarity = tableData.getIntField(4, 0); - entry.itemType = tableData.getIntField(5, -1); - entry.itemInfo = tableData.getInt64Field(6, -1); - entry.inLootTable = tableData.getIntField(7, -1) == 1 ? true : false; - entry.inVendor = tableData.getIntField(8, -1) == 1 ? true : false; - entry.isUnique = tableData.getIntField(9, -1) == 1 ? true : false; - entry.isBOP = tableData.getIntField(10, -1) == 1 ? true : false; - entry.isBOE = tableData.getIntField(11, -1) == 1 ? true : false; - entry.reqFlagID = tableData.getIntField(12, -1); - entry.reqSpecialtyID = tableData.getIntField(13, -1); - entry.reqSpecRank = tableData.getIntField(14, -1); - entry.reqAchievementID = tableData.getIntField(15, -1); - entry.stackSize = tableData.getIntField(16, -1); - entry.color1 = tableData.getIntField(17, -1); - entry.decal = tableData.getIntField(18, -1); - entry.offsetGroupID = tableData.getIntField(19, -1); - entry.buildTypes = tableData.getIntField(20, -1); - entry.reqPrecondition = tableData.getStringField(21, ""); - entry.animationFlag = tableData.getIntField(22, 0); - entry.equipEffects = tableData.getIntField(23, -1); - entry.readyForQA = tableData.getIntField(24, -1) == 1 ? true : false; - entry.itemRating = tableData.getIntField(25, -1); - entry.isTwoHanded = tableData.getIntField(26, -1) == 1 ? true : false; - entry.minNumRequired = tableData.getIntField(27, -1); - entry.delResIndex = tableData.getIntField(28, -1); - entry.currencyLOT = tableData.getIntField(29, -1); - entry.altCurrencyCost = tableData.getIntField(30, -1); - entry.subItems = tableData.getStringField(31, ""); - entry.audioEventUse = tableData.getStringField(32, ""); - entry.noEquipAnimation = tableData.getIntField(33, -1) == 1 ? true : false; - entry.commendationLOT = tableData.getIntField(34, -1); - entry.commendationCost = tableData.getIntField(35, -1); - entry.audioEquipMetaEventSet = tableData.getStringField(36, ""); - entry.currencyCosts = tableData.getStringField(37, ""); - entry.ingredientInfo = tableData.getStringField(38, ""); - entry.locStatus = tableData.getIntField(39, -1); - entry.forgeType = tableData.getIntField(40, -1); - entry.SellMultiplier = tableData.getFloatField(41, -1.0f); + entry.id = tableData.getIntField("id", -1); + entry.equipLocation = tableData.getStringField("equipLocation", ""); + entry.baseValue = tableData.getIntField("baseValue", -1); + entry.isKitPiece = tableData.getIntField("isKitPiece", -1) == 1 ? true : false; + entry.rarity = tableData.getIntField("rarity", 0); + entry.itemType = tableData.getIntField("itemType", -1); + entry.itemInfo = tableData.getInt64Field("itemInfo", -1); + entry.inLootTable = tableData.getIntField("inLootTable", -1) == 1 ? true : false; + entry.inVendor = tableData.getIntField("inVendor", -1) == 1 ? true : false; + entry.isUnique = tableData.getIntField("isUnique", -1) == 1 ? true : false; + entry.isBOP = tableData.getIntField("isBOP", -1) == 1 ? true : false; + entry.isBOE = tableData.getIntField("isBOE", -1) == 1 ? true : false; + entry.reqFlagID = tableData.getIntField("reqFlagID", -1); + entry.reqSpecialtyID = tableData.getIntField("reqSpecialtyID", -1); + entry.reqSpecRank = tableData.getIntField("reqSpecRank", -1); + entry.reqAchievementID = tableData.getIntField("reqAchievementID", -1); + entry.stackSize = tableData.getIntField("stackSize", -1); + entry.color1 = tableData.getIntField("color1", -1); + entry.decal = tableData.getIntField("decal", -1); + entry.offsetGroupID = tableData.getIntField("offsetGroupID", -1); + entry.buildTypes = tableData.getIntField("buildTypes", -1); + entry.reqPrecondition = tableData.getStringField("reqPrecondition", ""); + entry.animationFlag = tableData.getIntField("animationFlag", 0); + entry.equipEffects = tableData.getIntField("equipEffects", -1); + entry.readyForQA = tableData.getIntField("readyForQA", -1) == 1 ? true : false; + entry.itemRating = tableData.getIntField("itemRating", -1); + entry.isTwoHanded = tableData.getIntField("isTwoHanded", -1) == 1 ? true : false; + entry.minNumRequired = tableData.getIntField("minNumRequired", -1); + entry.delResIndex = tableData.getIntField("delResIndex", -1); + entry.currencyLOT = tableData.getIntField("currencyLOT", -1); + entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1); + entry.subItems = tableData.getStringField("subItems", ""); + entry.audioEventUse = tableData.getStringField("audioEventUse", ""); + entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false; + entry.commendationLOT = tableData.getIntField("commendationLOT", -1); + entry.commendationCost = tableData.getIntField("commendationCost", -1); + entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", ""); + entry.currencyCosts = tableData.getStringField("currencyCosts", ""); + entry.ingredientInfo = tableData.getStringField("ingredientInfo", ""); + entry.locStatus = tableData.getIntField("locStatus", -1); + entry.forgeType = tableData.getIntField("forgeType", -1); + entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f); this->entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); @@ -101,48 +101,48 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s while (!tableData.eof()) { CDItemComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.equipLocation = tableData.getStringField(1, ""); - entry.baseValue = tableData.getIntField(2, -1); - entry.isKitPiece = tableData.getIntField(3, -1) == 1 ? true : false; - entry.rarity = tableData.getIntField(4, 0); - entry.itemType = tableData.getIntField(5, -1); - entry.itemInfo = tableData.getInt64Field(6, -1); - entry.inLootTable = tableData.getIntField(7, -1) == 1 ? true : false; - entry.inVendor = tableData.getIntField(8, -1) == 1 ? true : false; - entry.isUnique = tableData.getIntField(9, -1) == 1 ? true : false; - entry.isBOP = tableData.getIntField(10, -1) == 1 ? true : false; - entry.isBOE = tableData.getIntField(11, -1) == 1 ? true : false; - entry.reqFlagID = tableData.getIntField(12, -1); - entry.reqSpecialtyID = tableData.getIntField(13, -1); - entry.reqSpecRank = tableData.getIntField(14, -1); - entry.reqAchievementID = tableData.getIntField(15, -1); - entry.stackSize = tableData.getIntField(16, -1); - entry.color1 = tableData.getIntField(17, -1); - entry.decal = tableData.getIntField(18, -1); - entry.offsetGroupID = tableData.getIntField(19, -1); - entry.buildTypes = tableData.getIntField(20, -1); - entry.reqPrecondition = tableData.getStringField(21, ""); - entry.animationFlag = tableData.getIntField(22, 0); - entry.equipEffects = tableData.getIntField(23, -1); - entry.readyForQA = tableData.getIntField(24, -1) == 1 ? true : false; - entry.itemRating = tableData.getIntField(25, -1); - entry.isTwoHanded = tableData.getIntField(26, -1) == 1 ? true : false; - entry.minNumRequired = tableData.getIntField(27, -1); - entry.delResIndex = tableData.getIntField(28, -1); - entry.currencyLOT = tableData.getIntField(29, -1); - entry.altCurrencyCost = tableData.getIntField(30, -1); - entry.subItems = tableData.getStringField(31, ""); - UNUSED(entry.audioEventUse = tableData.getStringField(32, "")); - entry.noEquipAnimation = tableData.getIntField(33, -1) == 1 ? true : false; - entry.commendationLOT = tableData.getIntField(34, -1); - entry.commendationCost = tableData.getIntField(35, -1); - UNUSED(entry.audioEquipMetaEventSet = tableData.getStringField(36, "")); - entry.currencyCosts = tableData.getStringField(37, ""); - UNUSED(entry.ingredientInfo = tableData.getStringField(38, "")); - entry.locStatus = tableData.getIntField(39, -1); - entry.forgeType = tableData.getIntField(40, -1); - entry.SellMultiplier = tableData.getFloatField(41, -1.0f); + entry.id = tableData.getIntField("id", -1); + entry.equipLocation = tableData.getStringField("equipLocation", ""); + entry.baseValue = tableData.getIntField("baseValue", -1); + entry.isKitPiece = tableData.getIntField("isKitPiece", -1) == 1 ? true : false; + entry.rarity = tableData.getIntField("rarity", 0); + entry.itemType = tableData.getIntField("itemType", -1); + entry.itemInfo = tableData.getInt64Field("itemInfo", -1); + entry.inLootTable = tableData.getIntField("inLootTable", -1) == 1 ? true : false; + entry.inVendor = tableData.getIntField("inVendor", -1) == 1 ? true : false; + entry.isUnique = tableData.getIntField("isUnique", -1) == 1 ? true : false; + entry.isBOP = tableData.getIntField("isBOP", -1) == 1 ? true : false; + entry.isBOE = tableData.getIntField("isBOE", -1) == 1 ? true : false; + entry.reqFlagID = tableData.getIntField("reqFlagID", -1); + entry.reqSpecialtyID = tableData.getIntField("reqSpecialtyID", -1); + entry.reqSpecRank = tableData.getIntField("reqSpecRank", -1); + entry.reqAchievementID = tableData.getIntField("reqAchievementID", -1); + entry.stackSize = tableData.getIntField("stackSize", -1); + entry.color1 = tableData.getIntField("color1", -1); + entry.decal = tableData.getIntField("decal", -1); + entry.offsetGroupID = tableData.getIntField("offsetGroupID", -1); + entry.buildTypes = tableData.getIntField("buildTypes", -1); + entry.reqPrecondition = tableData.getStringField("reqPrecondition", ""); + entry.animationFlag = tableData.getIntField("animationFlag", 0); + entry.equipEffects = tableData.getIntField("equipEffects", -1); + entry.readyForQA = tableData.getIntField("readyForQA", -1) == 1 ? true : false; + entry.itemRating = tableData.getIntField("itemRating", -1); + entry.isTwoHanded = tableData.getIntField("isTwoHanded", -1) == 1 ? true : false; + entry.minNumRequired = tableData.getIntField("minNumRequired", -1); + entry.delResIndex = tableData.getIntField("delResIndex", -1); + entry.currencyLOT = tableData.getIntField("currencyLOT", -1); + entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1); + entry.subItems = tableData.getStringField("subItems", ""); + UNUSED(entry.audioEventUse = tableData.getStringField("audioEventUse", "")); + entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false; + entry.commendationLOT = tableData.getIntField("commendationLOT", -1); + entry.commendationCost = tableData.getIntField("commendationCost", -1); + UNUSED(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "")); + entry.currencyCosts = tableData.getStringField("currencyCosts", ""); + UNUSED(entry.ingredientInfo = tableData.getStringField("ingredientInfo", "")); + entry.locStatus = tableData.getIntField("locStatus", -1); + entry.forgeType = tableData.getIntField("forgeType", -1); + entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f); this->entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); @@ -177,3 +177,4 @@ std::map<LOT, uint32_t> CDItemComponentTable::ParseCraftingCurrencies(const CDIt return currencies; } + diff --git a/dDatabase/Tables/CDItemSetSkillsTable.cpp b/dDatabase/Tables/CDItemSetSkillsTable.cpp index e94cf527..107e25d9 100644 --- a/dDatabase/Tables/CDItemSetSkillsTable.cpp +++ b/dDatabase/Tables/CDItemSetSkillsTable.cpp @@ -21,9 +21,9 @@ CDItemSetSkillsTable::CDItemSetSkillsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSetSkills"); while (!tableData.eof()) { CDItemSetSkills entry; - entry.SkillSetID = tableData.getIntField(0, -1); - entry.SkillID = tableData.getIntField(1, -1); - entry.SkillCastType = tableData.getIntField(2, -1); + entry.SkillSetID = tableData.getIntField("SkillSetID", -1); + entry.SkillID = tableData.getIntField("SkillID", -1); + entry.SkillCastType = tableData.getIntField("SkillCastType", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -65,3 +65,4 @@ std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetBySkillID(unsigned int Ski return toReturn; } + diff --git a/dDatabase/Tables/CDItemSetsTable.cpp b/dDatabase/Tables/CDItemSetsTable.cpp index 606e0cf9..1f9d7409 100644 --- a/dDatabase/Tables/CDItemSetsTable.cpp +++ b/dDatabase/Tables/CDItemSetsTable.cpp @@ -21,21 +21,21 @@ CDItemSetsTable::CDItemSetsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSets"); while (!tableData.eof()) { CDItemSets entry; - entry.setID = tableData.getIntField(0, -1); - entry.locStatus = tableData.getIntField(1, -1); - entry.itemIDs = tableData.getStringField(2, ""); - entry.kitType = tableData.getIntField(3, -1); - entry.kitRank = tableData.getIntField(4, -1); - entry.kitImage = tableData.getIntField(5, -1); - entry.skillSetWith2 = tableData.getIntField(6, -1); - entry.skillSetWith3 = tableData.getIntField(7, -1); - entry.skillSetWith4 = tableData.getIntField(8, -1); - entry.skillSetWith5 = tableData.getIntField(9, -1); - entry.skillSetWith6 = tableData.getIntField(10, -1); - entry.localize = tableData.getIntField(11, -1) == 1 ? true : false; - entry.gate_version = tableData.getStringField(12, ""); - entry.kitID = tableData.getIntField(13, -1); - entry.priority = tableData.getFloatField(14, -1.0f); + entry.setID = tableData.getIntField("setID", -1); + entry.locStatus = tableData.getIntField("locStatus", -1); + entry.itemIDs = tableData.getStringField("itemIDs", ""); + entry.kitType = tableData.getIntField("kitType", -1); + entry.kitRank = tableData.getIntField("kitRank", -1); + entry.kitImage = tableData.getIntField("kitImage", -1); + entry.skillSetWith2 = tableData.getIntField("skillSetWith2", -1); + entry.skillSetWith3 = tableData.getIntField("skillSetWith3", -1); + entry.skillSetWith4 = tableData.getIntField("skillSetWith4", -1); + entry.skillSetWith5 = tableData.getIntField("skillSetWith5", -1); + entry.skillSetWith6 = tableData.getIntField("skillSetWith6", -1); + entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false; + entry.gate_version = tableData.getStringField("gate_version", ""); + entry.kitID = tableData.getIntField("kitID", -1); + entry.priority = tableData.getFloatField("priority", -1.0f); this->entries.push_back(entry); tableData.nextRow(); @@ -66,3 +66,4 @@ std::vector<CDItemSets> CDItemSetsTable::Query(std::function<bool(CDItemSets)> p std::vector<CDItemSets> CDItemSetsTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDLevelProgressionLookupTable.cpp b/dDatabase/Tables/CDLevelProgressionLookupTable.cpp index 121c9f62..b3231308 100644 --- a/dDatabase/Tables/CDLevelProgressionLookupTable.cpp +++ b/dDatabase/Tables/CDLevelProgressionLookupTable.cpp @@ -21,9 +21,9 @@ CDLevelProgressionLookupTable::CDLevelProgressionLookupTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LevelProgressionLookup"); while (!tableData.eof()) { CDLevelProgressionLookup entry; - entry.id = tableData.getIntField(0, -1); - entry.requiredUScore = tableData.getIntField(1, -1); - entry.BehaviorEffect = tableData.getStringField(2, ""); + entry.id = tableData.getIntField("id", -1); + entry.requiredUScore = tableData.getIntField("requiredUScore", -1); + entry.BehaviorEffect = tableData.getStringField("BehaviorEffect", ""); this->entries.push_back(entry); tableData.nextRow(); @@ -54,3 +54,4 @@ std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std:: std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDLootMatrixTable.cpp b/dDatabase/Tables/CDLootMatrixTable.cpp index d47c081b..93a2fda1 100644 --- a/dDatabase/Tables/CDLootMatrixTable.cpp +++ b/dDatabase/Tables/CDLootMatrixTable.cpp @@ -21,15 +21,15 @@ CDLootMatrixTable::CDLootMatrixTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootMatrix"); while (!tableData.eof()) { CDLootMatrix entry; - entry.LootMatrixIndex = tableData.getIntField(0, -1); - entry.LootTableIndex = tableData.getIntField(1, -1); - entry.RarityTableIndex = tableData.getIntField(2, -1); - entry.percent = tableData.getFloatField(3, -1.0f); - entry.minToDrop = tableData.getIntField(4, -1); - entry.maxToDrop = tableData.getIntField(5, -1); - entry.id = tableData.getIntField(6, -1); - entry.flagID = tableData.getIntField(7, -1); - UNUSED(entry.gate_version = tableData.getStringField(8, "")); + entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); + entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1); + entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1); + entry.percent = tableData.getFloatField("percent", -1.0f); + entry.minToDrop = tableData.getIntField("minToDrop", -1); + entry.maxToDrop = tableData.getIntField("maxToDrop", -1); + entry.id = tableData.getIntField("id", -1); + entry.flagID = tableData.getIntField("flagID", -1); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); this->entries.push_back(entry); tableData.nextRow(); @@ -60,3 +60,4 @@ std::vector<CDLootMatrix> CDLootMatrixTable::Query(std::function<bool(CDLootMatr const std::vector<CDLootMatrix>& CDLootMatrixTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDLootTableTable.cpp b/dDatabase/Tables/CDLootTableTable.cpp index da8c824b..91cced47 100644 --- a/dDatabase/Tables/CDLootTableTable.cpp +++ b/dDatabase/Tables/CDLootTableTable.cpp @@ -21,12 +21,12 @@ CDLootTableTable::CDLootTableTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootTable"); while (!tableData.eof()) { CDLootTable entry; - entry.id = tableData.getIntField(0, -1); - entry.itemid = tableData.getIntField(0, -1); - entry.LootTableIndex = tableData.getIntField(1, -1); - entry.id = tableData.getIntField(2, -1); - entry.MissionDrop = tableData.getIntField(3, -1) == 1 ? true : false; - entry.sortPriority = tableData.getIntField(4, -1); + entry.id = tableData.getIntField("id", -1); + entry.itemid = tableData.getIntField("itemid", -1); + entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1); + entry.id = tableData.getIntField("id", -1); + entry.MissionDrop = tableData.getIntField("MissionDrop", -1) == 1 ? true : false; + entry.sortPriority = tableData.getIntField("sortPriority", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -57,3 +57,4 @@ std::vector<CDLootTable> CDLootTableTable::Query(std::function<bool(CDLootTable) const std::vector<CDLootTable>& CDLootTableTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDMissionEmailTable.cpp b/dDatabase/Tables/CDMissionEmailTable.cpp index a8beb95b..4fac7be2 100644 --- a/dDatabase/Tables/CDMissionEmailTable.cpp +++ b/dDatabase/Tables/CDMissionEmailTable.cpp @@ -21,14 +21,14 @@ CDMissionEmailTable::CDMissionEmailTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionEmail"); while (!tableData.eof()) { CDMissionEmail entry; - entry.ID = tableData.getIntField(0, -1); - entry.messageType = tableData.getIntField(1, -1); - entry.notificationGroup = tableData.getIntField(2, -1); - entry.missionID = tableData.getIntField(3, -1); - entry.attachmentLOT = tableData.getIntField(4, 0); - entry.localize = (bool)tableData.getIntField(5, -1); - entry.locStatus = tableData.getIntField(6, -1); - entry.gate_version = tableData.getStringField(7, ""); + entry.ID = tableData.getIntField("ID", -1); + entry.messageType = tableData.getIntField("messageType", -1); + entry.notificationGroup = tableData.getIntField("notificationGroup", -1); + entry.missionID = tableData.getIntField("missionID", -1); + entry.attachmentLOT = tableData.getIntField("attachmentLOT", 0); + entry.localize = (bool)tableData.getIntField("localize", -1); + entry.locStatus = tableData.getIntField("locStatus", -1); + entry.gate_version = tableData.getStringField("gate_version", ""); this->entries.push_back(entry); tableData.nextRow(); @@ -59,3 +59,4 @@ std::vector<CDMissionEmail> CDMissionEmailTable::Query(std::function<bool(CDMiss std::vector<CDMissionEmail> CDMissionEmailTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDMissionNPCComponentTable.cpp b/dDatabase/Tables/CDMissionNPCComponentTable.cpp index e2589890..461cc909 100644 --- a/dDatabase/Tables/CDMissionNPCComponentTable.cpp +++ b/dDatabase/Tables/CDMissionNPCComponentTable.cpp @@ -21,11 +21,11 @@ CDMissionNPCComponentTable::CDMissionNPCComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionNPCComponent"); while (!tableData.eof()) { CDMissionNPCComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.missionID = tableData.getIntField(1, -1); - entry.offersMission = tableData.getIntField(2, -1) == 1 ? true : false; - entry.acceptsMission = tableData.getIntField(3, -1) == 1 ? true : false; - entry.gate_version = tableData.getStringField(4, ""); + entry.id = tableData.getIntField("id", -1); + entry.missionID = tableData.getIntField("missionID", -1); + entry.offersMission = tableData.getIntField("offersMission", -1) == 1 ? true : false; + entry.acceptsMission = tableData.getIntField("acceptsMission", -1) == 1 ? true : false; + entry.gate_version = tableData.getStringField("gate_version", ""); this->entries.push_back(entry); tableData.nextRow(); @@ -56,3 +56,4 @@ std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::Query(std::functi std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDMissionTasksTable.cpp b/dDatabase/Tables/CDMissionTasksTable.cpp index 81de2088..c22da1ef 100644 --- a/dDatabase/Tables/CDMissionTasksTable.cpp +++ b/dDatabase/Tables/CDMissionTasksTable.cpp @@ -21,19 +21,19 @@ CDMissionTasksTable::CDMissionTasksTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionTasks"); while (!tableData.eof()) { CDMissionTasks entry; - entry.id = tableData.getIntField(0, -1); - UNUSED(entry.locStatus = tableData.getIntField(1, -1)); - entry.taskType = tableData.getIntField(2, -1); - entry.target = tableData.getIntField(3, -1); - entry.targetGroup = tableData.getStringField(4, ""); - entry.targetValue = tableData.getIntField(5, -1); - entry.taskParam1 = tableData.getStringField(6, ""); - UNUSED(entry.largeTaskIcon = tableData.getStringField(7, "")); - UNUSED(entry.IconID = tableData.getIntField(8, -1)); - entry.uid = tableData.getIntField(9, -1); - UNUSED(entry.largeTaskIconID = tableData.getIntField(10, -1)); - UNUSED(entry.localize = tableData.getIntField(11, -1) == 1 ? true : false); - UNUSED(entry.gate_version = tableData.getStringField(12, "")); + entry.id = tableData.getIntField("id", -1); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + entry.taskType = tableData.getIntField("taskType", -1); + entry.target = tableData.getIntField("target", -1); + entry.targetGroup = tableData.getStringField("targetGroup", ""); + entry.targetValue = tableData.getIntField("targetValue", -1); + entry.taskParam1 = tableData.getStringField("taskParam1", ""); + UNUSED(entry.largeTaskIcon = tableData.getStringField("largeTaskIcon", "")); + UNUSED(entry.IconID = tableData.getIntField("IconID", -1)); + entry.uid = tableData.getIntField("uid", -1); + UNUSED(entry.largeTaskIconID = tableData.getIntField("largeTaskIconID", -1)); + UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); this->entries.push_back(entry); tableData.nextRow(); @@ -78,3 +78,4 @@ std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missio const std::vector<CDMissionTasks>& CDMissionTasksTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDMissionsTable.cpp b/dDatabase/Tables/CDMissionsTable.cpp index 7e59657d..a87b4327 100644 --- a/dDatabase/Tables/CDMissionsTable.cpp +++ b/dDatabase/Tables/CDMissionsTable.cpp @@ -23,58 +23,58 @@ CDMissionsTable::CDMissionsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Missions"); while (!tableData.eof()) { CDMissions entry; - entry.id = tableData.getIntField(0, -1); - entry.defined_type = tableData.getStringField(1, ""); - entry.defined_subtype = tableData.getStringField(2, ""); - entry.UISortOrder = tableData.getIntField(3, -1); - entry.offer_objectID = tableData.getIntField(4, -1); - entry.target_objectID = tableData.getIntField(5, -1); - entry.reward_currency = tableData.getInt64Field(6, -1); - entry.LegoScore = tableData.getIntField(7, -1); - entry.reward_reputation = tableData.getIntField(8, -1); - entry.isChoiceReward = tableData.getIntField(9, -1) == 1 ? true : false; - entry.reward_item1 = tableData.getIntField(10, 0); - entry.reward_item1_count = tableData.getIntField(11, 0); - entry.reward_item2 = tableData.getIntField(12, 0); - entry.reward_item2_count = tableData.getIntField(13, 0); - entry.reward_item3 = tableData.getIntField(14, 0); - entry.reward_item3_count = tableData.getIntField(15, 0); - entry.reward_item4 = tableData.getIntField(16, 0); - entry.reward_item4_count = tableData.getIntField(17, 0); - entry.reward_emote = tableData.getIntField(18, -1); - entry.reward_emote2 = tableData.getIntField(19, -1); - entry.reward_emote3 = tableData.getIntField(20, -1); - entry.reward_emote4 = tableData.getIntField(21, -1); - entry.reward_maximagination = tableData.getIntField(22, -1); - entry.reward_maxhealth = tableData.getIntField(23, -1); - entry.reward_maxinventory = tableData.getIntField(24, -1); - entry.reward_maxmodel = tableData.getIntField(25, -1); - entry.reward_maxwidget = tableData.getIntField(26, -1); - entry.reward_maxwallet = tableData.getIntField(27, -1); - entry.repeatable = tableData.getIntField(28, -1) == 1 ? true : false; - entry.reward_currency_repeatable = tableData.getIntField(29, -1); - entry.reward_item1_repeatable = tableData.getIntField(30, -1); - entry.reward_item1_repeat_count = tableData.getIntField(31, -1); - entry.reward_item2_repeatable = tableData.getIntField(32, -1); - entry.reward_item2_repeat_count = tableData.getIntField(33, -1); - entry.reward_item3_repeatable = tableData.getIntField(34, -1); - entry.reward_item3_repeat_count = tableData.getIntField(35, -1); - entry.reward_item4_repeatable = tableData.getIntField(36, -1); - entry.reward_item4_repeat_count = tableData.getIntField(37, -1); - entry.time_limit = tableData.getIntField(38, -1); - entry.isMission = tableData.getIntField(39, -1) ? true : false; - entry.missionIconID = tableData.getIntField(40, -1); - entry.prereqMissionID = tableData.getStringField(41, ""); - entry.localize = tableData.getIntField(42, -1) == 1 ? true : false; - entry.inMOTD = tableData.getIntField(43, -1) == 1 ? true : false; - entry.cooldownTime = tableData.getInt64Field(44, -1); - entry.isRandom = tableData.getIntField(45, -1) == 1 ? true : false; - entry.randomPool = tableData.getStringField(46, ""); - entry.UIPrereqID = tableData.getIntField(47, -1); - UNUSED(entry.gate_version = tableData.getStringField(48, "")); - UNUSED(entry.HUDStates = tableData.getStringField(49, "")); - UNUSED(entry.locStatus = tableData.getIntField(50, -1)); - entry.reward_bankinventory = tableData.getIntField(51, -1); + entry.id = tableData.getIntField("id", -1); + entry.defined_type = tableData.getStringField("defined_type", ""); + entry.defined_subtype = tableData.getStringField("defined_subtype", ""); + entry.UISortOrder = tableData.getIntField("UISortOrder", -1); + entry.offer_objectID = tableData.getIntField("offer_objectID", -1); + entry.target_objectID = tableData.getIntField("target_objectID", -1); + entry.reward_currency = tableData.getInt64Field("reward_currency", -1); + entry.LegoScore = tableData.getIntField("LegoScore", -1); + entry.reward_reputation = tableData.getIntField("reward_reputation", -1); + entry.isChoiceReward = tableData.getIntField("isChoiceReward", -1) == 1 ? true : false; + entry.reward_item1 = tableData.getIntField("reward_item1", 0); + entry.reward_item1_count = tableData.getIntField("reward_item1_count", 0); + entry.reward_item2 = tableData.getIntField("reward_item2", 0); + entry.reward_item2_count = tableData.getIntField("reward_item2_count", 0); + entry.reward_item3 = tableData.getIntField("reward_item3", 0); + entry.reward_item3_count = tableData.getIntField("reward_item3_count", 0); + entry.reward_item4 = tableData.getIntField("reward_item4", 0); + entry.reward_item4_count = tableData.getIntField("reward_item4_count", 0); + entry.reward_emote = tableData.getIntField("reward_emote", -1); + entry.reward_emote2 = tableData.getIntField("reward_emote2", -1); + entry.reward_emote3 = tableData.getIntField("reward_emote3", -1); + entry.reward_emote4 = tableData.getIntField("reward_emote4", -1); + entry.reward_maximagination = tableData.getIntField("reward_maximagination", -1); + entry.reward_maxhealth = tableData.getIntField("reward_maxhealth", -1); + entry.reward_maxinventory = tableData.getIntField("reward_maxinventory", -1); + entry.reward_maxmodel = tableData.getIntField("reward_maxmodel", -1); + entry.reward_maxwidget = tableData.getIntField("reward_maxwidget", -1); + entry.reward_maxwallet = tableData.getIntField("reward_maxwallet", -1); + entry.repeatable = tableData.getIntField("repeatable", -1) == 1 ? true : false; + entry.reward_currency_repeatable = tableData.getIntField("reward_currency_repeatable", -1); + entry.reward_item1_repeatable = tableData.getIntField("reward_item1_repeatable", -1); + entry.reward_item1_repeat_count = tableData.getIntField("reward_item1_repeat_count", -1); + entry.reward_item2_repeatable = tableData.getIntField("reward_item2_repeatable", -1); + entry.reward_item2_repeat_count = tableData.getIntField("reward_item2_repeat_count", -1); + entry.reward_item3_repeatable = tableData.getIntField("reward_item3_repeatable", -1); + entry.reward_item3_repeat_count = tableData.getIntField("reward_item3_repeat_count", -1); + entry.reward_item4_repeatable = tableData.getIntField("reward_item4_repeatable", -1); + entry.reward_item4_repeat_count = tableData.getIntField("reward_item4_repeat_count", -1); + entry.time_limit = tableData.getIntField("time_limit", -1); + entry.isMission = tableData.getIntField("isMission", -1) ? true : false; + entry.missionIconID = tableData.getIntField("missionIconID", -1); + entry.prereqMissionID = tableData.getStringField("prereqMissionID", ""); + entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false; + entry.inMOTD = tableData.getIntField("inMOTD", -1) == 1 ? true : false; + entry.cooldownTime = tableData.getInt64Field("cooldownTime", -1); + entry.isRandom = tableData.getIntField("isRandom", -1) == 1 ? true : false; + entry.randomPool = tableData.getStringField("randomPool", ""); + entry.UIPrereqID = tableData.getIntField("UIPrereqID", -1); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.HUDStates = tableData.getStringField("HUDStates", "")); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -131,3 +131,4 @@ const CDMissions& CDMissionsTable::GetByMissionID(uint32_t missionID, bool& foun return Default; } + diff --git a/dDatabase/Tables/CDMovementAIComponentTable.cpp b/dDatabase/Tables/CDMovementAIComponentTable.cpp index a98be8ba..333ec202 100644 --- a/dDatabase/Tables/CDMovementAIComponentTable.cpp +++ b/dDatabase/Tables/CDMovementAIComponentTable.cpp @@ -21,14 +21,14 @@ CDMovementAIComponentTable::CDMovementAIComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovementAIComponent"); while (!tableData.eof()) { CDMovementAIComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.MovementType = tableData.getStringField(1, ""); - entry.WanderChance = tableData.getFloatField(2, -1.0f); - entry.WanderDelayMin = tableData.getFloatField(3, -1.0f); - entry.WanderDelayMax = tableData.getFloatField(4, -1.0f); - entry.WanderSpeed = tableData.getFloatField(5, -1.0f); - entry.WanderRadius = tableData.getFloatField(6, -1.0f); - entry.attachedPath = tableData.getStringField(7, ""); + entry.id = tableData.getIntField("id", -1); + entry.MovementType = tableData.getStringField("MovementType", ""); + entry.WanderChance = tableData.getFloatField("WanderChance", -1.0f); + entry.WanderDelayMin = tableData.getFloatField("WanderDelayMin", -1.0f); + entry.WanderDelayMax = tableData.getFloatField("WanderDelayMax", -1.0f); + entry.WanderSpeed = tableData.getFloatField("WanderSpeed", -1.0f); + entry.WanderRadius = tableData.getFloatField("WanderRadius", -1.0f); + entry.attachedPath = tableData.getStringField("attachedPath", ""); this->entries.push_back(entry); tableData.nextRow(); @@ -59,3 +59,4 @@ std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::functi std::vector<CDMovementAIComponent> CDMovementAIComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDObjectSkillsTable.cpp b/dDatabase/Tables/CDObjectSkillsTable.cpp index 1a5c4790..dc797529 100644 --- a/dDatabase/Tables/CDObjectSkillsTable.cpp +++ b/dDatabase/Tables/CDObjectSkillsTable.cpp @@ -21,10 +21,10 @@ CDObjectSkillsTable::CDObjectSkillsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ObjectSkills"); while (!tableData.eof()) { CDObjectSkills entry; - entry.objectTemplate = tableData.getIntField(0, -1); - entry.skillID = tableData.getIntField(1, -1); - entry.castOnType = tableData.getIntField(2, -1); - entry.AICombatWeight = tableData.getIntField(3, -1); + entry.objectTemplate = tableData.getIntField("objectTemplate", -1); + entry.skillID = tableData.getIntField("skillID", -1); + entry.castOnType = tableData.getIntField("castOnType", -1); + entry.AICombatWeight = tableData.getIntField("AICombatWeight", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -55,3 +55,4 @@ std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObje std::vector<CDObjectSkills> CDObjectSkillsTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDObjectsTable.cpp b/dDatabase/Tables/CDObjectsTable.cpp index 03979af2..5133becc 100644 --- a/dDatabase/Tables/CDObjectsTable.cpp +++ b/dDatabase/Tables/CDObjectsTable.cpp @@ -18,20 +18,20 @@ CDObjectsTable::CDObjectsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Objects"); while (!tableData.eof()) { CDObjects entry; - entry.id = tableData.getIntField(0, -1); - entry.name = tableData.getStringField(1, ""); - entry.placeable = tableData.getIntField(2, -1); - entry.type = tableData.getStringField(3, ""); - entry.description = tableData.getStringField(4, ""); - entry.localize = tableData.getIntField(5, -1); - entry.npcTemplateID = tableData.getIntField(6, -1); - entry.displayName = tableData.getStringField(7, ""); - entry.interactionDistance = tableData.getFloatField(8, -1.0f); - entry.nametag = tableData.getIntField(9, -1); - entry._internalNotes = tableData.getStringField(10, ""); - entry.locStatus = tableData.getIntField(11, -1); - entry.gate_version = tableData.getStringField(12, ""); - entry.HQ_valid = tableData.getIntField(13, -1); + entry.id = tableData.getIntField("id", -1); + entry.name = tableData.getStringField("name", ""); + entry.placeable = tableData.getIntField("placeable", -1); + entry.type = tableData.getStringField("type", ""); + entry.description = tableData.getStringField("description", ""); + entry.localize = tableData.getIntField("localize", -1); + entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1); + entry.displayName = tableData.getStringField("displayName", ""); + entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f); + entry.nametag = tableData.getIntField("nametag", -1); + entry._internalNotes = tableData.getStringField("_internalNotes", ""); + entry.locStatus = tableData.getIntField("locStatus", -1); + entry.gate_version = tableData.getStringField("gate_version", ""); + entry.HQ_valid = tableData.getIntField("HQ_valid", -1); this->entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); @@ -71,20 +71,20 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) { // Now get the data while (!tableData.eof()) { CDObjects entry; - entry.id = tableData.getIntField(0, -1); - entry.name = tableData.getStringField(1, ""); - UNUSED(entry.placeable = tableData.getIntField(2, -1)); - entry.type = tableData.getStringField(3, ""); + entry.id = tableData.getIntField("id", -1); + entry.name = tableData.getStringField("name", ""); + UNUSED(entry.placeable = tableData.getIntField("placeable", -1)); + entry.type = tableData.getStringField("type", ""); UNUSED(ntry.description = tableData.getStringField(4, "")); - UNUSED(entry.localize = tableData.getIntField(5, -1)); - UNUSED(entry.npcTemplateID = tableData.getIntField(6, -1)); - UNUSED(entry.displayName = tableData.getStringField(7, "")); - entry.interactionDistance = tableData.getFloatField(8, -1.0f); - UNUSED(entry.nametag = tableData.getIntField(9, -1)); - UNUSED(entry._internalNotes = tableData.getStringField(10, "")); - UNUSED(entry.locStatus = tableData.getIntField(11, -1)); - UNUSED(entry.gate_version = tableData.getStringField(12, "")); - UNUSED(entry.HQ_valid = tableData.getIntField(13, -1)); + UNUSED(entry.localize = tableData.getIntField("localize", -1)); + UNUSED(entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1)); + UNUSED(entry.displayName = tableData.getStringField("displayName", "")); + entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f); + UNUSED(entry.nametag = tableData.getIntField("nametag", -1)); + UNUSED(entry._internalNotes = tableData.getStringField("_internalNotes", "")); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.HQ_valid = tableData.getIntField("HQ_valid", -1)); this->entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); @@ -100,3 +100,4 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) { return m_default; } + diff --git a/dDatabase/Tables/CDPackageComponentTable.cpp b/dDatabase/Tables/CDPackageComponentTable.cpp index 83673c6f..eabe68da 100644 --- a/dDatabase/Tables/CDPackageComponentTable.cpp +++ b/dDatabase/Tables/CDPackageComponentTable.cpp @@ -21,9 +21,9 @@ CDPackageComponentTable::CDPackageComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PackageComponent"); while (!tableData.eof()) { CDPackageComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.LootMatrixIndex = tableData.getIntField(1, -1); - entry.packageType = tableData.getIntField(2, -1); + entry.id = tableData.getIntField("id", -1); + entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); + entry.packageType = tableData.getIntField("packageType", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -54,3 +54,4 @@ std::vector<CDPackageComponent> CDPackageComponentTable::Query(std::function<boo std::vector<CDPackageComponent> CDPackageComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDPhysicsComponentTable.cpp b/dDatabase/Tables/CDPhysicsComponentTable.cpp index 8cb7a3b0..f85d83c4 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.cpp +++ b/dDatabase/Tables/CDPhysicsComponentTable.cpp @@ -4,22 +4,22 @@ CDPhysicsComponentTable::CDPhysicsComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent"); while (!tableData.eof()) { CDPhysicsComponent* entry = new CDPhysicsComponent(); - entry->id = tableData.getIntField(0, -1); - entry->bStatic = tableData.getIntField(1, -1) != 0; - entry->physicsAsset = tableData.getStringField(2, ""); - UNUSED(entry->jump = tableData.getIntField(3, -1) != 0); - UNUSED(entry->doublejump = tableData.getIntField(4, -1) != 0); - entry->speed = tableData.getFloatField(5, -1); - UNUSED(entry->rotSpeed = tableData.getFloatField(6, -1)); - entry->playerHeight = tableData.getFloatField(7); - entry->playerRadius = tableData.getFloatField(8); - entry->pcShapeType = tableData.getIntField(9); - entry->collisionGroup = tableData.getIntField(10); - UNUSED(entry->airSpeed = tableData.getFloatField(11)); - UNUSED(entry->boundaryAsset = tableData.getStringField(12)); - UNUSED(entry->jumpAirSpeed = tableData.getFloatField(13)); - UNUSED(entry->friction = tableData.getFloatField(14)); - UNUSED(entry->gravityVolumeAsset = tableData.getStringField(15)); + entry->id = tableData.getIntField("id", -1); + entry->bStatic = tableData.getIntField("static", -1) != 0; + entry->physicsAsset = tableData.getStringField("physics_asset", ""); + UNUSED(entry->jump = tableData.getIntField("jump", -1) != 0); + UNUSED(entry->doublejump = tableData.getIntField("doublejump", -1) != 0); + entry->speed = tableData.getFloatField("speed", -1); + UNUSED(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1)); + entry->playerHeight = tableData.getFloatField("playerHeight"); + entry->playerRadius = tableData.getFloatField("playerRadius"); + entry->pcShapeType = tableData.getIntField("pcShapeType"); + entry->collisionGroup = tableData.getIntField("collisionGroup"); + UNUSED(entry->airSpeed = tableData.getFloatField("airSpeed")); + UNUSED(entry->boundaryAsset = tableData.getStringField("boundaryAsset")); + UNUSED(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed")); + UNUSED(entry->friction = tableData.getFloatField("friction")); + UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset")); m_entries.insert(std::make_pair(entry->id, entry)); tableData.nextRow(); @@ -47,3 +47,4 @@ CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) { return nullptr; } + diff --git a/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp b/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp index 01a2ae37..127ebc9d 100644 --- a/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp +++ b/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp @@ -18,11 +18,11 @@ CDPropertyEntranceComponentTable::CDPropertyEntranceComponentTable() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PropertyEntranceComponent;"); while (!tableData.eof()) { auto entry = CDPropertyEntranceComponent{ - static_cast<uint32_t>(tableData.getIntField(0, -1)), - static_cast<uint32_t>(tableData.getIntField(1, -1)), - tableData.getStringField(2, ""), - static_cast<bool>(tableData.getIntField(3, false)), - tableData.getStringField(4, "") + static_cast<uint32_t>(tableData.getIntField("id", -1)), + static_cast<uint32_t>(tableData.getIntField("mapID", -1)), + tableData.getStringField("propertyName", ""), + static_cast<bool>(tableData.getIntField("isOnProperty", false)), + tableData.getStringField("groupType", "") }; this->entries.push_back(entry); @@ -46,3 +46,4 @@ CDPropertyEntranceComponent CDPropertyEntranceComponentTable::GetByID(uint32_t i return defaultEntry; } + diff --git a/dDatabase/Tables/CDPropertyTemplateTable.cpp b/dDatabase/Tables/CDPropertyTemplateTable.cpp index 7dd118eb..bf56da7b 100644 --- a/dDatabase/Tables/CDPropertyTemplateTable.cpp +++ b/dDatabase/Tables/CDPropertyTemplateTable.cpp @@ -17,10 +17,10 @@ CDPropertyTemplateTable::CDPropertyTemplateTable() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PropertyTemplate;"); while (!tableData.eof()) { auto entry = CDPropertyTemplate{ - static_cast<uint32_t>(tableData.getIntField(0, -1)), - static_cast<uint32_t>(tableData.getIntField(1, -1)), - static_cast<uint32_t>(tableData.getIntField(2, -1)), - tableData.getStringField(3, "") + static_cast<uint32_t>(tableData.getIntField("id", -1)), + static_cast<uint32_t>(tableData.getIntField("mapID", -1)), + static_cast<uint32_t>(tableData.getIntField("vendorMapID", -1)), + tableData.getStringField("spawnName", "") }; this->entries.push_back(entry); @@ -44,3 +44,4 @@ CDPropertyTemplate CDPropertyTemplateTable::GetByMapID(uint32_t mapID) { return defaultEntry; } + diff --git a/dDatabase/Tables/CDProximityMonitorComponentTable.cpp b/dDatabase/Tables/CDProximityMonitorComponentTable.cpp index 092f3ca1..98cde098 100644 --- a/dDatabase/Tables/CDProximityMonitorComponentTable.cpp +++ b/dDatabase/Tables/CDProximityMonitorComponentTable.cpp @@ -21,10 +21,10 @@ CDProximityMonitorComponentTable::CDProximityMonitorComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ProximityMonitorComponent"); while (!tableData.eof()) { CDProximityMonitorComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.Proximities = tableData.getStringField(1, ""); - entry.LoadOnClient = tableData.getIntField(2, -1); - entry.LoadOnServer = tableData.getIntField(3, -1); + entry.id = tableData.getIntField("id", -1); + entry.Proximities = tableData.getStringField("Proximities", ""); + entry.LoadOnClient = tableData.getIntField("LoadOnClient", -1); + entry.LoadOnServer = tableData.getIntField("LoadOnServer", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -55,3 +55,4 @@ std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::Query std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDRailActivatorComponent.cpp b/dDatabase/Tables/CDRailActivatorComponent.cpp index 4c141256..4d1b5e7e 100644 --- a/dDatabase/Tables/CDRailActivatorComponent.cpp +++ b/dDatabase/Tables/CDRailActivatorComponent.cpp @@ -6,35 +6,35 @@ CDRailActivatorComponentTable::CDRailActivatorComponentTable() { while (!tableData.eof()) { CDRailActivatorComponent entry; - entry.id = tableData.getIntField(0); + entry.id = tableData.getIntField("id", 0); - entry.startAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField(1, "")); - entry.loopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField(2, "")); - entry.stopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField(3, "")); - entry.startSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField(4, "")); - entry.loopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField(5, "")); - entry.stopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField(6, "")); + entry.startAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField("startAnim", "")); + entry.loopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField("loopAnim", "")); + entry.stopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField("stopAnim", "")); + entry.startSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField("startSound", "")); + entry.loopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField("loopSound", "")); + entry.stopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField("stopSound", "")); - std::string loopEffectString(tableData.getStringField(7, "")); + std::string loopEffectString(tableData.getStringField("effectIDs", "")); entry.loopEffectID = EffectPairFromString(loopEffectString); - entry.preconditions = tableData.getStringField(8, "-1"); + entry.preconditions = tableData.getStringField("preconditions", "-1"); - entry.playerCollision = tableData.getIntField(9, 0); + entry.playerCollision = tableData.getIntField("playerCollision", 0); - entry.cameraLocked = tableData.getIntField(10, 0); + entry.cameraLocked = tableData.getIntField("cameraLocked", 0); - std::string startEffectString(tableData.getStringField(11, "")); + std::string startEffectString(tableData.getStringField("StartEffectID", "")); entry.startEffectID = EffectPairFromString(startEffectString); - std::string stopEffectString(tableData.getStringField(12, "")); + std::string stopEffectString(tableData.getStringField("StopEffectID", "")); entry.stopEffectID = EffectPairFromString(stopEffectString); - entry.damageImmune = tableData.getIntField(13, 0); + entry.damageImmune = tableData.getIntField("DamageImmune", 0); - entry.noAggro = tableData.getIntField(14, 0); + entry.noAggro = tableData.getIntField("NoAggro", 0); - entry.showNameBillboard = tableData.getIntField(15, 0); + entry.showNameBillboard = tableData.getIntField("ShowNameBillboard", 0); m_Entries.push_back(entry); tableData.nextRow(); @@ -70,3 +70,4 @@ std::pair<uint32_t, std::u16string> CDRailActivatorComponentTable::EffectPairFro return {}; } + diff --git a/dDatabase/Tables/CDRarityTableTable.cpp b/dDatabase/Tables/CDRarityTableTable.cpp index 67878cd2..cfa8d01c 100644 --- a/dDatabase/Tables/CDRarityTableTable.cpp +++ b/dDatabase/Tables/CDRarityTableTable.cpp @@ -21,10 +21,10 @@ CDRarityTableTable::CDRarityTableTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RarityTable"); while (!tableData.eof()) { CDRarityTable entry; - entry.id = tableData.getIntField(0, -1); - entry.randmax = tableData.getFloatField(1, -1); - entry.rarity = tableData.getIntField(2, -1); - entry.RarityTableIndex = tableData.getIntField(3, -1); + entry.id = tableData.getIntField("id", -1); + entry.randmax = tableData.getFloatField("randmax", -1); + entry.rarity = tableData.getIntField("rarity", -1); + entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -55,3 +55,4 @@ std::vector<CDRarityTable> CDRarityTableTable::Query(std::function<bool(CDRarity const std::vector<CDRarityTable>& CDRarityTableTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDRebuildComponentTable.cpp b/dDatabase/Tables/CDRebuildComponentTable.cpp index c4299b98..111592d4 100644 --- a/dDatabase/Tables/CDRebuildComponentTable.cpp +++ b/dDatabase/Tables/CDRebuildComponentTable.cpp @@ -21,16 +21,16 @@ CDRebuildComponentTable::CDRebuildComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RebuildComponent"); while (!tableData.eof()) { CDRebuildComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.reset_time = tableData.getFloatField(1, -1.0f); - entry.complete_time = tableData.getFloatField(2, -1.0f); - entry.take_imagination = tableData.getIntField(3, -1); - entry.interruptible = tableData.getIntField(4, -1) == 1 ? true : false; - entry.self_activator = tableData.getIntField(5, -1) == 1 ? true : false; - entry.custom_modules = tableData.getStringField(6, ""); - entry.activityID = tableData.getIntField(7, -1); - entry.post_imagination_cost = tableData.getIntField(8, -1); - entry.time_before_smash = tableData.getFloatField(9, -1.0f); + entry.id = tableData.getIntField("id", -1); + entry.reset_time = tableData.getFloatField("reset_time", -1.0f); + entry.complete_time = tableData.getFloatField("complete_time", -1.0f); + entry.take_imagination = tableData.getIntField("take_imagination", -1); + entry.interruptible = tableData.getIntField("interruptible", -1) == 1 ? true : false; + entry.self_activator = tableData.getIntField("self_activator", -1) == 1 ? true : false; + entry.custom_modules = tableData.getStringField("custom_modules", ""); + entry.activityID = tableData.getIntField("activityID", -1); + entry.post_imagination_cost = tableData.getIntField("post_imagination_cost", -1); + entry.time_before_smash = tableData.getFloatField("time_before_smash", -1.0f); this->entries.push_back(entry); tableData.nextRow(); @@ -61,3 +61,4 @@ std::vector<CDRebuildComponent> CDRebuildComponentTable::Query(std::function<boo std::vector<CDRebuildComponent> CDRebuildComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDRewardsTable.cpp b/dDatabase/Tables/CDRewardsTable.cpp index 99d56f26..a53e02b5 100644 --- a/dDatabase/Tables/CDRewardsTable.cpp +++ b/dDatabase/Tables/CDRewardsTable.cpp @@ -4,12 +4,12 @@ CDRewardsTable::CDRewardsTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Rewards"); while (!tableData.eof()) { CDRewards* entry = new CDRewards(); - entry->id = tableData.getIntField(0, -1); - entry->levelID = tableData.getIntField(1, -1); - entry->missionID = tableData.getIntField(2, -1); - entry->rewardType = tableData.getIntField(3, -1); - entry->value = tableData.getIntField(4, -1); - entry->count = tableData.getIntField(5, -1); + entry->id = tableData.getIntField("id", -1); + entry->levelID = tableData.getIntField("LevelID", -1); + entry->missionID = tableData.getIntField("MissionID", -1); + entry->rewardType = tableData.getIntField("RewardType", -1); + entry->value = tableData.getIntField("value", -1); + entry->count = tableData.getIntField("count", -1); m_entries.insert(std::make_pair(entry->id, entry)); tableData.nextRow(); @@ -38,3 +38,4 @@ std::vector<CDRewards*> CDRewardsTable::GetByLevelID(uint32_t levelID) { return result; } + diff --git a/dDatabase/Tables/CDScriptComponentTable.cpp b/dDatabase/Tables/CDScriptComponentTable.cpp index b34f96f1..d91dcee9 100644 --- a/dDatabase/Tables/CDScriptComponentTable.cpp +++ b/dDatabase/Tables/CDScriptComponentTable.cpp @@ -18,9 +18,9 @@ CDScriptComponentTable::CDScriptComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ScriptComponent"); while (!tableData.eof()) { CDScriptComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.script_name = tableData.getStringField(1, ""); - entry.client_script_name = tableData.getStringField(2, ""); + entry.id = tableData.getIntField("id", -1); + entry.script_name = tableData.getStringField("script_name", ""); + entry.client_script_name = tableData.getStringField("client_script_name", ""); this->entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); @@ -45,3 +45,4 @@ const CDScriptComponent& CDScriptComponentTable::GetByID(unsigned int id) { return m_ToReturnWhenNoneFound; } + diff --git a/dDatabase/Tables/CDSkillBehaviorTable.cpp b/dDatabase/Tables/CDSkillBehaviorTable.cpp index e3986578..b6b601a1 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.cpp +++ b/dDatabase/Tables/CDSkillBehaviorTable.cpp @@ -23,25 +23,25 @@ CDSkillBehaviorTable::CDSkillBehaviorTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM SkillBehavior"); while (!tableData.eof()) { CDSkillBehavior entry; - entry.skillID = tableData.getIntField(0, -1); - UNUSED(entry.locStatus = tableData.getIntField(1, -1)); - entry.behaviorID = tableData.getIntField(2, -1); - entry.imaginationcost = tableData.getIntField(3, -1); - entry.cooldowngroup = tableData.getIntField(4, -1); - entry.cooldown = tableData.getFloatField(5, -1.0f); - UNUSED(entry.isNpcEditor = tableData.getIntField(6, -1) == 1 ? true : false); - UNUSED(entry.skillIcon = tableData.getIntField(7, -1)); - UNUSED(entry.oomSkillID = tableData.getStringField(8, "")); - UNUSED(entry.oomBehaviorEffectID = tableData.getIntField(9, -1)); - UNUSED(entry.castTypeDesc = tableData.getIntField(10, -1)); - UNUSED(entry.imBonusUI = tableData.getIntField(11, -1)); - UNUSED(entry.lifeBonusUI = tableData.getIntField(12, -1)); - UNUSED(entry.armorBonusUI = tableData.getIntField(13, -1)); - UNUSED(entry.damageUI = tableData.getIntField(14, -1)); - UNUSED(entry.hideIcon = tableData.getIntField(15, -1) == 1 ? true : false); - UNUSED(entry.localize = tableData.getIntField(16, -1) == 1 ? true : false); - UNUSED(entry.gate_version = tableData.getStringField(17, "")); - UNUSED(entry.cancelType = tableData.getIntField(18, -1)); + entry.skillID = tableData.getIntField("skillID", -1); + UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); + entry.behaviorID = tableData.getIntField("behaviorID", -1); + entry.imaginationcost = tableData.getIntField("imaginationcost", -1); + entry.cooldowngroup = tableData.getIntField("cooldowngroup", -1); + entry.cooldown = tableData.getFloatField("cooldown", -1.0f); + UNUSED(entry.isNpcEditor = tableData.getIntField("isNpcEditor", -1) == 1 ? true : false); + UNUSED(entry.skillIcon = tableData.getIntField("skillIcon", -1)); + UNUSED(entry.oomSkillID = tableData.getStringField("oomSkillID", "")); + UNUSED(entry.oomBehaviorEffectID = tableData.getIntField("oomBehaviorEffectID", -1)); + UNUSED(entry.castTypeDesc = tableData.getIntField("castTypeDesc", -1)); + UNUSED(entry.imBonusUI = tableData.getIntField("imBonusUI", -1)); + UNUSED(entry.lifeBonusUI = tableData.getIntField("lifeBonusUI", -1)); + UNUSED(entry.armorBonusUI = tableData.getIntField("armorBonusUI", -1)); + UNUSED(entry.damageUI = tableData.getIntField("damageUI", -1)); + UNUSED(entry.hideIcon = tableData.getIntField("hideIcon", -1) == 1 ? true : false); + UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.cancelType = tableData.getIntField("cancelType", -1)); this->entries.insert(std::make_pair(entry.skillID, entry)); //this->entries.push_back(entry); @@ -82,3 +82,4 @@ const CDSkillBehavior& CDSkillBehaviorTable::GetSkillByID(unsigned int skillID) return m_empty; } + diff --git a/dDatabase/Tables/CDVendorComponentTable.cpp b/dDatabase/Tables/CDVendorComponentTable.cpp index f1dd96db..86d87d4b 100644 --- a/dDatabase/Tables/CDVendorComponentTable.cpp +++ b/dDatabase/Tables/CDVendorComponentTable.cpp @@ -21,11 +21,11 @@ CDVendorComponentTable::CDVendorComponentTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM VendorComponent"); while (!tableData.eof()) { CDVendorComponent entry; - entry.id = tableData.getIntField(0, -1); - entry.buyScalar = tableData.getFloatField(1, -1.0f); - entry.sellScalar = tableData.getFloatField(2, -1.0f); - entry.refreshTimeSeconds = tableData.getFloatField(3, -1.0f); - entry.LootMatrixIndex = tableData.getIntField(4, -1); + entry.id = tableData.getIntField("id", -1); + entry.buyScalar = tableData.getFloatField("buyScalar", -1.0f); + entry.sellScalar = tableData.getFloatField("sellScalar", -1.0f); + entry.refreshTimeSeconds = tableData.getFloatField("refreshTimeSeconds", -1.0f); + entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); this->entries.push_back(entry); tableData.nextRow(); @@ -56,3 +56,4 @@ std::vector<CDVendorComponent> CDVendorComponentTable::Query(std::function<bool( std::vector<CDVendorComponent> CDVendorComponentTable::GetEntries(void) const { return this->entries; } + diff --git a/dDatabase/Tables/CDZoneTableTable.cpp b/dDatabase/Tables/CDZoneTableTable.cpp index e172f79a..04f7d102 100644 --- a/dDatabase/Tables/CDZoneTableTable.cpp +++ b/dDatabase/Tables/CDZoneTableTable.cpp @@ -18,33 +18,33 @@ CDZoneTableTable::CDZoneTableTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ZoneTable"); while (!tableData.eof()) { CDZoneTable entry; - entry.zoneID = tableData.getIntField(0, -1); - entry.locStatus = tableData.getIntField(1, -1); - entry.zoneName = tableData.getStringField(2, ""); - entry.scriptID = tableData.getIntField(3, -1); - entry.ghostdistance_min = tableData.getFloatField(4, -1.0f); - entry.ghostdistance = tableData.getFloatField(5, -1.0f); - entry.population_soft_cap = tableData.getIntField(6, -1); - entry.population_hard_cap = tableData.getIntField(7, -1); - UNUSED(entry.DisplayDescription = tableData.getStringField(8, "")); - UNUSED(entry.mapFolder = tableData.getStringField(9, "")); - entry.smashableMinDistance = tableData.getFloatField(10, -1.0f); - entry.smashableMaxDistance = tableData.getFloatField(11, -1.0f); - UNUSED(entry.mixerProgram = tableData.getStringField(12, "")); - UNUSED(entry.clientPhysicsFramerate = tableData.getStringField(13, "")); - UNUSED(entry.serverPhysicsFramerate = tableData.getStringField(14, "")); - entry.zoneControlTemplate = tableData.getIntField(15, -1); - entry.widthInChunks = tableData.getIntField(16, -1); - entry.heightInChunks = tableData.getIntField(17, -1); - entry.petsAllowed = tableData.getIntField(18, -1) == 1 ? true : false; - entry.localize = tableData.getIntField(19, -1) == 1 ? true : false; - entry.fZoneWeight = tableData.getFloatField(20, -1.0f); - UNUSED(entry.thumbnail = tableData.getStringField(21, "")); - entry.PlayerLoseCoinsOnDeath = tableData.getIntField(22, -1) == 1 ? true : false; - UNUSED(entry.disableSaveLoc = tableData.getIntField(23, -1) == 1 ? true : false); - entry.teamRadius = tableData.getFloatField(24, -1.0f); - UNUSED(entry.gate_version = tableData.getStringField(25, "")); - UNUSED(entry.mountsAllowed = tableData.getIntField(26, -1) == 1 ? true : false); + entry.zoneID = tableData.getIntField("zoneID", -1); + entry.locStatus = tableData.getIntField("locStatus", -1); + entry.zoneName = tableData.getStringField("zoneName", ""); + entry.scriptID = tableData.getIntField("scriptID", -1); + entry.ghostdistance_min = tableData.getFloatField("ghostdistance_min", -1.0f); + entry.ghostdistance = tableData.getFloatField("ghostdistance", -1.0f); + entry.population_soft_cap = tableData.getIntField("population_soft_cap", -1); + entry.population_hard_cap = tableData.getIntField("population_hard_cap", -1); + UNUSED(entry.DisplayDescription = tableData.getStringField("DisplayDescription", "")); + UNUSED(entry.mapFolder = tableData.getStringField("mapFolder", "")); + entry.smashableMinDistance = tableData.getFloatField("smashableMinDistance", -1.0f); + entry.smashableMaxDistance = tableData.getFloatField("smashableMaxDistance", -1.0f); + UNUSED(entry.mixerProgram = tableData.getStringField("mixerProgram", "")); + UNUSED(entry.clientPhysicsFramerate = tableData.getStringField("clientPhysicsFramerate", "")); + UNUSED(entry.serverPhysicsFramerate = tableData.getStringField("serverPhysicsFramerate", "")); + entry.zoneControlTemplate = tableData.getIntField("zoneControlTemplate", -1); + entry.widthInChunks = tableData.getIntField("widthInChunks", -1); + entry.heightInChunks = tableData.getIntField("heightInChunks", -1); + entry.petsAllowed = tableData.getIntField("petsAllowed", -1) == 1 ? true : false; + entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false; + entry.fZoneWeight = tableData.getFloatField("fZoneWeight", -1.0f); + UNUSED(entry.thumbnail = tableData.getStringField("thumbnail", "")); + entry.PlayerLoseCoinsOnDeath = tableData.getIntField("PlayerLoseCoinsOnDeath", -1) == 1 ? true : false; + UNUSED(entry.disableSaveLoc = tableData.getIntField("disableSaveLoc", -1) == 1 ? true : false); + entry.teamRadius = tableData.getFloatField("teamRadius", -1.0f); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + UNUSED(entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false); this->m_Entries.insert(std::make_pair(entry.zoneID, entry)); tableData.nextRow(); @@ -71,3 +71,4 @@ const CDZoneTable* CDZoneTableTable::Query(unsigned int zoneID) { return nullptr; } + From e67f310632196310dbe15e8a9a35b307225e25d8 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 8 Jan 2023 01:01:53 -0800 Subject: [PATCH 108/166] Fix missing template override for AMFFormats (#946) --- dGame/dGameMessages/GameMessages.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 7e9ea898..9aafd0fc 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -77,6 +77,7 @@ #include "AMFDeserialize.h" #include "eBlueprintSaveResponseType.h" #include "eAninmationFlags.h" +#include "AMFFormat_BitStream.h" void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) { CBITSTREAM; From ce39e3ad6b7822d49480f9535e4a509183fc50c0 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Wed, 11 Jan 2023 01:10:14 -0600 Subject: [PATCH 109/166] Add ldf controlls to vanity npc tools make vanity npc use more forgiving --- dGame/dUtilities/VanityUtilities.cpp | 127 ++++++++++++++------------- dGame/dUtilities/VanityUtilities.h | 1 + 2 files changed, 69 insertions(+), 59 deletions(-) diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 74fd0f67..7fabfbce 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -65,17 +65,21 @@ void VanityUtilities::SpawnVanity() { npcIndex = GeneralUtils::GenerateRandomNumber<uint32_t>(0, npcList.size() - 1); } - const auto& npc = npcList[npcIndex]; + auto& npc = npcList[npcIndex]; taken.push_back(npcIndex); // Spawn the NPC - std::vector<LDFBaseData*> data = { new LDFData<std::vector<std::u16string>>( - u"syncLDF", { u"custom_script_client" }), - new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") }; + Game::logger->Log("VanityUtilities", "ldf size is %i", npc.ldf.size()); + if (npc.ldf.empty()) { + npc.ldf = { + new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }), + new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") + }; + } // Spawn the NPC - auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, data); + auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf); npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases); @@ -86,11 +90,11 @@ void VanityUtilities::SpawnVanity() { } // Loop through all NPCs - for (const auto& pair : m_NPCs) { - if (pair.m_Locations.find(Game::server->GetZoneID()) == pair.m_Locations.end()) + for (auto& npc : m_NPCs) { + if (npc.m_Locations.find(Game::server->GetZoneID()) == npc.m_Locations.end()) continue; - const std::vector<VanityNPCLocation>& locations = pair.m_Locations.at(Game::server->GetZoneID()); + const std::vector<VanityNPCLocation>& locations = npc.m_Locations.at(Game::server->GetZoneID()); // Pick a random location const auto& location = locations[GeneralUtils::GenerateRandomNumber<int>( @@ -101,27 +105,30 @@ void VanityUtilities::SpawnVanity() { continue; } - std::vector<LDFBaseData*> data = { new LDFData<std::vector<std::u16string>>( - u"syncLDF", { u"custom_script_client" }), - new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") }; + if (npc.ldf.empty()) { + npc.ldf = { + new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }), + new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") + }; + } // Spawn the NPC - auto* npc = SpawnNPC(pair.m_LOT, pair.m_Name, location.m_Position, location.m_Rotation, pair.m_Equipment, data); + auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf); - npc->SetVar<std::vector<std::string>>(u"chats", pair.m_Phrases); + npcEntity->SetVar<std::vector<std::string>>(u"chats", npc.m_Phrases); - auto* scriptComponent = npc->GetComponent<ScriptComponent>(); + auto* scriptComponent = npcEntity->GetComponent<ScriptComponent>(); if (scriptComponent != nullptr) { - scriptComponent->SetScript(pair.m_Script); + scriptComponent->SetScript(npc.m_Script); scriptComponent->SetSerialized(false); - for (const auto& pair : pair.m_Flags) { - npc->SetVar<bool>(GeneralUtils::ASCIIToUTF16(pair.first), pair.second); + for (const auto& npc : npc.m_Flags) { + npcEntity->SetVar<bool>(GeneralUtils::ASCIIToUTF16(npc.first), npc.second); } } - SetupNPCTalk(npc); + SetupNPCTalk(npcEntity); } if (zoneID == 1200) { @@ -266,10 +273,7 @@ void VanityUtilities::ParseXML(const std::string& file) { // Get the NPC name auto* name = npc->Attribute("name"); - if (name == nullptr) { - Game::logger->Log("VanityUtilities", "Failed to parse NPC name"); - continue; - } + if (!name) name = ""; // Get the NPC lot auto* lot = npc->Attribute("lot"); @@ -281,71 +285,76 @@ void VanityUtilities::ParseXML(const std::string& file) { // Get the equipment auto* equipment = npc->FirstChildElement("equipment"); - - if (equipment == nullptr) { - Game::logger->Log("VanityUtilities", "Failed to parse NPC equipment"); - continue; - } - - auto* text = equipment->GetText(); - std::vector<LOT> inventory; - if (text != nullptr) { - std::string equipmentString(text); + if (equipment) { + auto* text = equipment->GetText(); - std::vector<std::string> splitEquipment = GeneralUtils::SplitString(equipmentString, ','); + if (text != nullptr) { + std::string equipmentString(text); - for (auto& item : splitEquipment) { - inventory.push_back(std::stoi(item)); + std::vector<std::string> splitEquipment = GeneralUtils::SplitString(equipmentString, ','); + + for (auto& item : splitEquipment) { + inventory.push_back(std::stoi(item)); + } } } + // Get the phrases auto* phrases = npc->FirstChildElement("phrases"); - if (phrases == nullptr) { - Game::logger->Log("VanityUtilities", "Failed to parse NPC phrases"); - continue; - } + std::vector<std::string> phraseList = {}; - std::vector<std::string> phraseList; - - for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr; - phrase = phrase->NextSiblingElement("phrase")) { - // Get the phrase - auto* text = phrase->GetText(); - - if (text == nullptr) { - Game::logger->Log("VanityUtilities", "Failed to parse NPC phrase"); - continue; + if (phrases) { + for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr; + phrase = phrase->NextSiblingElement("phrase")) { + // Get the phrase + auto* text = phrase->GetText(); + if (text == nullptr) { + Game::logger->Log("VanityUtilities", "Failed to parse NPC phrase"); + continue; + } + phraseList.push_back(text); } - - phraseList.push_back(text); } // Get the script auto* scriptElement = npc->FirstChildElement("script"); - std::string scriptName; + std::string scriptName = ""; if (scriptElement != nullptr) { auto* scriptNameAttribute = scriptElement->Attribute("name"); - - if (scriptNameAttribute == nullptr) { - Game::logger->Log("VanityUtilities", "Failed to parse NPC script name"); - continue; - } - - scriptName = scriptNameAttribute; + if (scriptNameAttribute) scriptName = scriptNameAttribute; } + auto* ldfElement = npc->FirstChildElement("ldf"); + std::vector<std::u16string> keys = {}; + + std::vector<LDFBaseData*> ldf = {}; + if(ldfElement) { + for (auto* entry = ldfElement->FirstChildElement("entry"); entry != nullptr; + entry = entry->NextSiblingElement("entry")) { + // Get the ldf data + auto* data = entry->Attribute("data"); + if (!data) continue; + + LDFBaseData* ldfData = LDFBaseData::DataFromString(data); + keys.push_back(ldfData->GetKey()); + ldf.push_back(ldfData); + } + } + if (!keys.empty()) ldf.push_back(new LDFData<std::vector<std::u16string>>(u"syncLDF", keys)); + VanityNPC npcData; npcData.m_Name = name; npcData.m_LOT = std::stoi(lot); npcData.m_Equipment = inventory; npcData.m_Phrases = phraseList; npcData.m_Script = scriptName; + npcData.ldf = ldf; // Get flags auto* flags = npc->FirstChildElement("flags"); diff --git a/dGame/dUtilities/VanityUtilities.h b/dGame/dUtilities/VanityUtilities.h index 2f1886ed..0cca0aba 100644 --- a/dGame/dUtilities/VanityUtilities.h +++ b/dGame/dUtilities/VanityUtilities.h @@ -20,6 +20,7 @@ struct VanityNPC std::string m_Script; std::map<std::string, bool> m_Flags; std::map<uint32_t, std::vector<VanityNPCLocation>> m_Locations; + std::vector<LDFBaseData*> ldf; }; struct VanityParty From e7bc4ef77345ff29cb3a56a2e30bf72fddc690aa Mon Sep 17 00:00:00 2001 From: "Gie \"Max\" Vanommeslaeghe" <gievanom@hotmail.com> Date: Wed, 11 Jan 2023 20:08:54 +0100 Subject: [PATCH 110/166] add hardcore mode --- dGame/dComponents/DestroyableComponent.cpp | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 3e146335..e08de3e6 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -2,6 +2,7 @@ #include <BitStream.h> #include "dLogger.h" #include "Game.h" +#include "dConfig.h" #include "AMFFormat.h" #include "AMFFormat_BitStream.h" @@ -666,6 +667,75 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 return; } Smash(source, eKillType::VIOLENT, u"", skillID); + + //check if hardcore mode is enabled + if (Game::config->GetValue("hardcore_mode") == "1") { + //check if this is a player: + if (m_Parent->GetLOT() == 1) { + //get hardcore_lose_uscore_on_death_percent from dconfig: + auto hardcore_lose_uscore_on_death_percent = std::stoi(Game::config->GetValue("hardcore_lose_uscore_on_death_percent")); + + //remove hardcore_lose_uscore_on_death_percent from the player's uscore: + auto* character = m_Parent->GetComponent<CharacterComponent>(); + auto uscore = character->GetUScore(); + + auto uscore_to_lose = uscore * hardcore_lose_uscore_on_death_percent / 100; + character->SetUScore(uscore - uscore_to_lose); + + //get hardcore_dropinventory on death from dconfig: + auto hardcore_dropinventory_on_death = (bool)std::stoi(Game::config->GetValue("hardcore_dropinventory_on_death")); + + if (hardcore_dropinventory_on_death == false) return; + + //drop all items from inventory: + auto* inventory = m_Parent->GetComponent<InventoryComponent>(); + + //get the items inventory: + auto items = inventory->GetInventory(eInventoryType::ITEMS); + for (auto item : items->GetItems()) { + //check if this is an equipped item: + if (item.second->IsEquipped()) { + //unequip the item: + inventory->UnEquipItem(item.second); + } + + //drop the item: + GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount()); + + //remove from inventory: + inventory->RemoveItem(item.second->GetLot(), item.second->GetCount()); + } + + //get character: + auto* chars = m_Parent->GetCharacter(); + if (chars) { + auto coins = chars->GetCoins(); + + //lose all coins: + chars->SetCoins(0, eLootSourceType::LOOT_SOURCE_NONE); + + //drop all coins: + GameMessages::SendDropClientLoot(m_Parent, source, 0, coins, m_Parent->GetPosition(), 0); + } + } else { + //award the player some u-score: + auto* player = EntityManager::Instance()->GetEntity(source); + if (player && player->GetLOT() == 1) { + auto* playerStats = player->GetComponent<CharacterComponent>(); + if (playerStats) { + //get the maximum health from this enemy: + auto maxHealth = GetMaxHealth(); + + //get the u-score to award from dconfig: + auto hardcore_uscore_enemies_multiplier = std::stoi(Game::config->GetValue("hardcore_uscore_enemies_multiplier")); + int uscore = maxHealth * hardcore_uscore_enemies_multiplier; + + playerStats->SetUScore(playerStats->GetUScore() + uscore); + GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_NONE); + } + } + } + } } void DestroyableComponent::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd) { From bfa4fbd5a9d66f50e75b680d9e3652744186ba11 Mon Sep 17 00:00:00 2001 From: "Gie \"Max\" Vanommeslaeghe" <gievanom@hotmail.com> Date: Wed, 11 Jan 2023 20:11:06 +0100 Subject: [PATCH 111/166] add hardcore_mode to settings --- resources/worldconfig.ini | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index 0c24c447..abedfb4b 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -46,3 +46,15 @@ max_number_of_best_friends=5 # Disables loot drops disable_drops=0 + +# Hardcore mode settings +hardcore_enabled=0 + +# Drop your entire inventory on death + coins (drops on the ground, so can be retrieved) +hardcore_dropinventory=1 + +# Enemies drop their max hp * this value. 0 will effectively disable it. +hardcore_uscore_enemies_multiplier=2 + +# Percentage of u-score to lose on player death +hardcore_lose_uscore_on_death_percent=10 From 5557a98129490287d547e880898272aea90ae5c2 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Wed, 11 Jan 2023 14:10:48 -0600 Subject: [PATCH 112/166] fix hardmode example config options (#952) --- resources/worldconfig.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index abedfb4b..64b4fb40 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -48,10 +48,10 @@ max_number_of_best_friends=5 disable_drops=0 # Hardcore mode settings -hardcore_enabled=0 +hardcore_mode=0 # Drop your entire inventory on death + coins (drops on the ground, so can be retrieved) -hardcore_dropinventory=1 +hardcore_dropinventory_on_death=1 # Enemies drop their max hp * this value. 0 will effectively disable it. hardcore_uscore_enemies_multiplier=2 From 7aacfc1bf039212ddf60fd54eb2a7ebf52037084 Mon Sep 17 00:00:00 2001 From: wincent <wincent.holm@gmail.com> Date: Wed, 11 Jan 2023 21:50:21 +0100 Subject: [PATCH 113/166] Fixed crashes related to hardcore mode --- dGame/dComponents/DestroyableComponent.cpp | 42 ++++++++++++---------- dGame/dUtilities/SlashCommandHandler.cpp | 13 +++++-- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index e08de3e6..0e8ce56e 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -666,46 +666,46 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 return; } - Smash(source, eKillType::VIOLENT, u"", skillID); //check if hardcore mode is enabled if (Game::config->GetValue("hardcore_mode") == "1") { //check if this is a player: if (m_Parent->GetLOT() == 1) { //get hardcore_lose_uscore_on_death_percent from dconfig: - auto hardcore_lose_uscore_on_death_percent = std::stoi(Game::config->GetValue("hardcore_lose_uscore_on_death_percent")); + auto hardcoreLoseUscoreOnDeathPercent = std::stoi(Game::config->GetValue("hardcore_lose_uscore_on_death_percent")); //remove hardcore_lose_uscore_on_death_percent from the player's uscore: auto* character = m_Parent->GetComponent<CharacterComponent>(); auto uscore = character->GetUScore(); - auto uscore_to_lose = uscore * hardcore_lose_uscore_on_death_percent / 100; - character->SetUScore(uscore - uscore_to_lose); + auto uscoreToLose = uscore * hardcoreLoseUscoreOnDeathPercent / 100; + character->SetUScore(uscore - uscoreToLose); - //get hardcore_dropinventory on death from dconfig: - auto hardcore_dropinventory_on_death = (bool)std::stoi(Game::config->GetValue("hardcore_dropinventory_on_death")); + GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::LOOT_SOURCE_MISSION); - if (hardcore_dropinventory_on_death == false) return; + // Reload the player + EntityManager::Instance()->DestructEntity(m_Parent); + EntityManager::Instance()->ConstructEntity(m_Parent); + + auto hardcoreDropinventoryOnDeath = (bool)std::stoi(Game::config->GetValue("hardcore_dropinventory_on_death")); + + if (hardcoreDropinventoryOnDeath == false) return; //drop all items from inventory: auto* inventory = m_Parent->GetComponent<InventoryComponent>(); //get the items inventory: auto items = inventory->GetInventory(eInventoryType::ITEMS); - for (auto item : items->GetItems()) { - //check if this is an equipped item: - if (item.second->IsEquipped()) { - //unequip the item: - inventory->UnEquipItem(item.second); - } - + auto itemMap = items->GetItems(); + for (const auto& item : itemMap) { //drop the item: GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount()); - //remove from inventory: - inventory->RemoveItem(item.second->GetLot(), item.second->GetCount()); + item.second->SetCount(0, false, false); } + EntityManager::Instance()->SerializeEntity(m_Parent); + //get character: auto* chars = m_Parent->GetCharacter(); if (chars) { @@ -727,15 +727,19 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 auto maxHealth = GetMaxHealth(); //get the u-score to award from dconfig: - auto hardcore_uscore_enemies_multiplier = std::stoi(Game::config->GetValue("hardcore_uscore_enemies_multiplier")); - int uscore = maxHealth * hardcore_uscore_enemies_multiplier; + auto hardcoreUscoreEnemiesMultiplier = std::stoi(Game::config->GetValue("hardcore_uscore_enemies_multiplier")); + int uscore = maxHealth * hardcoreUscoreEnemiesMultiplier; playerStats->SetUScore(playerStats->GetUScore() + uscore); - GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_NONE); + GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_MISSION); + + EntityManager::Instance()->SerializeEntity(m_Parent); } } } } + + Smash(source, eKillType::VIOLENT, u"", skillID); } void DestroyableComponent::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd) { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index cc1c82a9..70637990 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1312,7 +1312,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if ((chatCommand == "giveuscore") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { int32_t uscore; if (!GeneralUtils::TryParse(args[0], uscore)) { @@ -1323,7 +1323,16 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit CharacterComponent* character = entity->GetComponent<CharacterComponent>(); if (character) character->SetUScore(character->GetUScore() + uscore); // LOOT_SOURCE_MODERATION should work but it doesn't. Relog to see uscore changes - GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_MODERATION); + + eLootSourceType lootType = eLootSourceType::LOOT_SOURCE_MODERATION; + + int32_t type; + if (args.size() >= 2 && GeneralUtils::TryParse(args[1], type)) + { + lootType = (eLootSourceType) type; + } + + GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType); } if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { From 7bca43ffc1fb2576fb2b517747d8cc7455d9fc88 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 11 Jan 2023 22:36:03 -0800 Subject: [PATCH 114/166] Fix tests (#953) --- tests/dGameTests/GameDependencies.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 81875ab6..353b53b8 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -6,6 +6,7 @@ #include "dServer.h" #include "EntityInfo.h" #include "EntityManager.h" +#include "dConfig.h" #include <gtest/gtest.h> class dZoneManager; @@ -30,6 +31,7 @@ protected: info.lot = 999; Game::logger = new dLogger("./testing.log", true, true); Game::server = new dServerMock(); + Game::config = new dConfig("worldconfig.ini"); } void TearDownDependencies() { @@ -39,6 +41,7 @@ protected: Game::logger->Flush(); delete Game::logger; } + if (Game::config) delete Game::config; } EntityInfo info; From 872270704c44408cbc466526c5e891a839b6c722 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Thu, 12 Jan 2023 13:16:24 -0600 Subject: [PATCH 115/166] Hardmode cleanups (#954) * load values once so that it doesn't check every time don't return, just skip don't realod char * address feedback * don't drop the only item you can't get again * address most feedback * move settings for HC mode * fix comment * claenup whitespace --- dGame/EntityManager.cpp | 11 ++ dGame/EntityManager.h | 11 ++ dGame/dComponents/DestroyableComponent.cpp | 145 +++++++++++---------- dGame/dComponents/DestroyableComponent.h | 3 + 4 files changed, 100 insertions(+), 70 deletions(-) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 99ead79d..67553b41 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -18,6 +18,7 @@ #include "Game.h" #include "dLogger.h" #include "MessageIdentifiers.h" +#include "dConfig.h" EntityManager* EntityManager::m_Address = nullptr; @@ -58,6 +59,16 @@ void EntityManager::Initialize() { m_GhostingExcludedZones.end(), dZoneManager::Instance()->GetZoneID().GetMapID() ) == m_GhostingExcludedZones.end(); + + // grab hardcore mode settings and load them with sane defaults + auto hcmode = Game::config->GetValue("hardcore_mode"); + m_HardcoreMode = hcmode.empty() ? false : (hcmode == "1"); + auto hcUscorePercent = Game::config->GetValue("hardcore_lose_uscore_on_death_percent"); + m_HardcoreLoseUscoreOnDeathPercent = hcUscorePercent.empty() ? 10 : std::stoi(hcUscorePercent); + auto hcUscoreMult = Game::config->GetValue("hardcore_uscore_enemies_multiplier"); + m_HardcoreUscoreEnemiesMultiplier = hcUscoreMult.empty() ? 2 : std::stoi(hcUscoreMult); + auto hcDropInv = Game::config->GetValue("hardcore_dropinventory_on_death"); + m_HardcoreDropinventoryOnDeath = hcDropInv.empty() ? false : (hcDropInv == "1"); } EntityManager::~EntityManager() { diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 36bc5962..8a930de3 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -78,6 +78,11 @@ public: static bool IsExcludedFromGhosting(LOT lot); + const bool GetHardcoreMode() { return m_HardcoreMode; }; + const uint32_t GetHardcoreLoseUscoreOnDeathPercent() { return m_HardcoreLoseUscoreOnDeathPercent; }; + const bool GetHardcoreDropinventoryOnDeath() { return m_HardcoreDropinventoryOnDeath; }; + const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; }; + private: static EntityManager* m_Address; //For singleton method static std::vector<LWOMAPID> m_GhostingExcludedZones; @@ -102,6 +107,12 @@ private: // Map of spawnname to entity object ID std::unordered_map<std::string, LWOOBJID> m_SpawnPoints; + + // hardcore mode vars + bool m_HardcoreMode; + uint32_t m_HardcoreLoseUscoreOnDeathPercent; + bool m_HardcoreDropinventoryOnDeath; + uint32_t m_HardcoreUscoreEnemiesMultiplier; }; #endif // ENTITYMANAGER_H diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 0e8ce56e..1455ce58 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -668,77 +668,10 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 } //check if hardcore mode is enabled - if (Game::config->GetValue("hardcore_mode") == "1") { - //check if this is a player: - if (m_Parent->GetLOT() == 1) { - //get hardcore_lose_uscore_on_death_percent from dconfig: - auto hardcoreLoseUscoreOnDeathPercent = std::stoi(Game::config->GetValue("hardcore_lose_uscore_on_death_percent")); - - //remove hardcore_lose_uscore_on_death_percent from the player's uscore: - auto* character = m_Parent->GetComponent<CharacterComponent>(); - auto uscore = character->GetUScore(); - - auto uscoreToLose = uscore * hardcoreLoseUscoreOnDeathPercent / 100; - character->SetUScore(uscore - uscoreToLose); - - GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::LOOT_SOURCE_MISSION); - - // Reload the player - EntityManager::Instance()->DestructEntity(m_Parent); - EntityManager::Instance()->ConstructEntity(m_Parent); - - auto hardcoreDropinventoryOnDeath = (bool)std::stoi(Game::config->GetValue("hardcore_dropinventory_on_death")); - - if (hardcoreDropinventoryOnDeath == false) return; - - //drop all items from inventory: - auto* inventory = m_Parent->GetComponent<InventoryComponent>(); - - //get the items inventory: - auto items = inventory->GetInventory(eInventoryType::ITEMS); - auto itemMap = items->GetItems(); - for (const auto& item : itemMap) { - //drop the item: - GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount()); - - item.second->SetCount(0, false, false); - } - - EntityManager::Instance()->SerializeEntity(m_Parent); - - //get character: - auto* chars = m_Parent->GetCharacter(); - if (chars) { - auto coins = chars->GetCoins(); - - //lose all coins: - chars->SetCoins(0, eLootSourceType::LOOT_SOURCE_NONE); - - //drop all coins: - GameMessages::SendDropClientLoot(m_Parent, source, 0, coins, m_Parent->GetPosition(), 0); - } - } else { - //award the player some u-score: - auto* player = EntityManager::Instance()->GetEntity(source); - if (player && player->GetLOT() == 1) { - auto* playerStats = player->GetComponent<CharacterComponent>(); - if (playerStats) { - //get the maximum health from this enemy: - auto maxHealth = GetMaxHealth(); - - //get the u-score to award from dconfig: - auto hardcoreUscoreEnemiesMultiplier = std::stoi(Game::config->GetValue("hardcore_uscore_enemies_multiplier")); - int uscore = maxHealth * hardcoreUscoreEnemiesMultiplier; - - playerStats->SetUScore(playerStats->GetUScore() + uscore); - GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_MISSION); - - EntityManager::Instance()->SerializeEntity(m_Parent); - } - } - } + if (EntityManager::Instance()->GetHardcoreMode()) { + DoHardcoreModeDrops(source); } - + Smash(source, eKillType::VIOLENT, u"", skillID); } @@ -1045,3 +978,75 @@ void DestroyableComponent::FixStats() { void DestroyableComponent::AddOnHitCallback(const std::function<void(Entity*)>& callback) { m_OnHitCallbacks.push_back(callback); } + +void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ + //check if this is a player: + if (m_Parent->IsPlayer()) { + //remove hardcore_lose_uscore_on_death_percent from the player's uscore: + auto* character = m_Parent->GetComponent<CharacterComponent>(); + auto uscore = character->GetUScore(); + + auto uscoreToLose = uscore * (EntityManager::Instance()->GetHardcoreLoseUscoreOnDeathPercent() / 100); + character->SetUScore(uscore - uscoreToLose); + + GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::LOOT_SOURCE_MISSION); + + if (EntityManager::Instance()->GetHardcoreDropinventoryOnDeath()) { + //drop all items from inventory: + auto* inventory = m_Parent->GetComponent<InventoryComponent>(); + if (inventory) { + //get the items inventory: + auto items = inventory->GetInventory(eInventoryType::ITEMS); + if (items){ + auto itemMap = items->GetItems(); + if (!itemMap.empty()){ + for (const auto& item : itemMap) { + //drop the item: + if (!item.second) continue; + // don't drop the thinkng cap + if (item.second->GetLot() == 6086) continue; + GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount()); + item.second->SetCount(0, false, false); + } + EntityManager::Instance()->SerializeEntity(m_Parent); + } + } + } + } + + //get character: + auto* chars = m_Parent->GetCharacter(); + if (chars) { + auto coins = chars->GetCoins(); + + //lose all coins: + chars->SetCoins(0, eLootSourceType::LOOT_SOURCE_NONE); + + //drop all coins: + GameMessages::SendDropClientLoot(m_Parent, source, LOT_NULL, coins, m_Parent->GetPosition()); + } + + // Reload the player since we can't normally reduce uscore from the server and we want the UI to update + // do this last so we don't get killed.... again + EntityManager::Instance()->DestructEntity(m_Parent); + EntityManager::Instance()->ConstructEntity(m_Parent); + return; + } + + //award the player some u-score: + auto* player = EntityManager::Instance()->GetEntity(source); + if (player && player->IsPlayer()) { + auto* playerStats = player->GetComponent<CharacterComponent>(); + if (playerStats) { + //get the maximum health from this enemy: + auto maxHealth = GetMaxHealth(); + + int uscore = maxHealth * EntityManager::Instance()->GetHardcoreUscoreEnemiesMultiplier(); + + playerStats->SetUScore(playerStats->GetUScore() + uscore); + GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::LOOT_SOURCE_MISSION); + + EntityManager::Instance()->SerializeEntity(m_Parent); + } + } +} diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 2736f47c..854144d9 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -452,6 +452,9 @@ public: void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd); void Unsubscribe(LWOOBJID scriptObjId); + // handle hardcode mode drops + void DoHardcoreModeDrops(const LWOOBJID source); + private: /** * Whether or not the health should be serialized From fbaf1cbb256c42b31b70947e71c17a37ff2bc8ab Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 17 Jan 2023 04:06:09 -0800 Subject: [PATCH 116/166] Dont preemptively delete objects (#958) Let finalizeShutdown take care of it --- dMasterServer/MasterServer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 82645797..77571e22 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -248,8 +248,6 @@ int main(int argc, char** argv) { std::cout << "Account created successfully!\n"; - Database::Destroy("MasterServer"); - delete Game::logger; return EXIT_SUCCESS; } From 7418e02365683baa8a0b7e6442ade907cb9dfb43 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 17 Jan 2023 04:07:34 -0800 Subject: [PATCH 117/166] Update AmTeapotServer.cpp (#949) --- dScripts/02_server/Map/AM/AmTeapotServer.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dScripts/02_server/Map/AM/AmTeapotServer.cpp b/dScripts/02_server/Map/AM/AmTeapotServer.cpp index 32abafd6..1f47cb1a 100644 --- a/dScripts/02_server/Map/AM/AmTeapotServer.cpp +++ b/dScripts/02_server/Map/AM/AmTeapotServer.cpp @@ -1,14 +1,21 @@ #include "AmTeapotServer.h" #include "InventoryComponent.h" #include "GameMessages.h" - +#include "Item.h" void AmTeapotServer::OnUse(Entity* self, Entity* user) { auto* inventoryComponent = user->GetComponent<InventoryComponent>(); if (!inventoryComponent) return; - if (inventoryComponent->GetLotCount(BLUE_FLOWER_LEAVES) >= 10) { - inventoryComponent->RemoveItem(BLUE_FLOWER_LEAVES, 10); + auto* blueFlowerItem = inventoryComponent->FindItemByLot(BLUE_FLOWER_LEAVES, eInventoryType::ITEMS); + if (!blueFlowerItem) { + blueFlowerItem = inventoryComponent->FindItemByLot(BLUE_FLOWER_LEAVES, eInventoryType::VAULT_ITEMS); + if (!blueFlowerItem) return; + } + + // The client allows you to use the teapot only if you have a stack of 10 leaves in some inventory somewhere. + if (blueFlowerItem->GetCount() >= 10) { + blueFlowerItem->SetCount(blueFlowerItem->GetCount() - 10); inventoryComponent->AddItem(WU_S_IMAGINATION_TEA, 1); } GameMessages::SendTerminateInteraction(user->GetObjectID(), FROM_INTERACTION, self->GetObjectID()); From 14085d09bd8b682da8c6d493cb5ba96daafa1c20 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 17 Jan 2023 11:26:50 -0800 Subject: [PATCH 118/166] Add note for compiling with multiple jobs (#948) * Fix overread in projectile behavior * Fix stuns * Correctly read in bitStream * Fix projectile behavior * Address movement type issues * Update shutdown time to be accurate * Fix small issues * Fix missing template * Add note for compile jobs --- README.md | 4 ++++ build.sh | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 27de7d6d..df782a32 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,10 @@ You can either run `build.sh` when in the root folder of the repository: Or manually run the commands used in [build.sh](build.sh). +If you would like to build the server faster, append `-j<number>` where number is the number of simultaneous compile jobs to run at once. It is recommended that you have this number always be 1 less than your core count to prevent slowdowns. The command would look like this if you would build with 4 jobs at once: +```bash +./build.sh -j4 +``` ### Notes Depending on your operating system, you may need to adjust some pre-processor defines in [CMakeVariables.txt](./CMakeVariables.txt) before building: * If you are on MacOS, ensure OPENSSL_ROOT_DIR is pointing to the openssl root directory. diff --git a/build.sh b/build.sh index a736a4ee..b8d33492 100755 --- a/build.sh +++ b/build.sh @@ -9,5 +9,5 @@ cd build cmake .. # To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8' -cmake --build . --config Release +cmake --build . --config Release $1 From 6fd80e3117304ea28d437ade85fdca4bc95b7217 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 20 Jan 2023 01:50:46 -0600 Subject: [PATCH 119/166] Don't enable HC on minigame worlds (#959) * Fix max's ouchi * use smarter logic * fix whitespace * clone --- dGame/EntityManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 67553b41..22c31291 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -69,6 +69,10 @@ void EntityManager::Initialize() { m_HardcoreUscoreEnemiesMultiplier = hcUscoreMult.empty() ? 2 : std::stoi(hcUscoreMult); auto hcDropInv = Game::config->GetValue("hardcore_dropinventory_on_death"); m_HardcoreDropinventoryOnDeath = hcDropInv.empty() ? false : (hcDropInv == "1"); + + // If cloneID is not zero, then hardcore mode is disabled + // aka minigames and props + if (dZoneManager::Instance()->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false; } EntityManager::~EntityManager() { From c8cd51ef63472fa8cafd7492a085ef7d134275b2 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 20 Jan 2023 00:07:25 -0800 Subject: [PATCH 120/166] Fix warning for overrides (#961) --- dCommon/AMFFormat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dCommon/AMFFormat.h b/dCommon/AMFFormat.h index 2b423abd..6e479ef6 100644 --- a/dCommon/AMFFormat.h +++ b/dCommon/AMFFormat.h @@ -257,7 +257,7 @@ private: /*! \return The AMF value type */ - AMFValueType GetValueType() { return ValueType; } + AMFValueType GetValueType() override { return ValueType; } public: static const AMFValueType ValueType = AMFArray; @@ -362,7 +362,7 @@ private: /*! \return The AMF value type */ - AMFValueType GetValueType() { return ValueType; } + AMFValueType GetValueType() override { return ValueType; } ~AMFObjectValue() override; public: From cff94b6c225ab3d92408b63e4541d2cea5a419a1 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 21 Jan 2023 07:37:09 -0800 Subject: [PATCH 121/166] Fix hash collisions in achievements (#962) --- dGame/dComponents/AchievementCacheKey.h | 43 +++++++++++++++++++++++++ dGame/dComponents/MissionComponent.cpp | 19 ++++++----- dGame/dComponents/MissionComponent.h | 14 ++++---- 3 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 dGame/dComponents/AchievementCacheKey.h diff --git a/dGame/dComponents/AchievementCacheKey.h b/dGame/dComponents/AchievementCacheKey.h new file mode 100644 index 00000000..d8892197 --- /dev/null +++ b/dGame/dComponents/AchievementCacheKey.h @@ -0,0 +1,43 @@ +#ifndef __ACHIEVEMENTCACHEKEY__H__ +#define __ACHIEVEMENTCACHEKEY__H__ + +class AchievementCacheKey { +public: + AchievementCacheKey() { + targets = ""; + value = 0; + type = MissionTaskType::MISSION_TASK_TYPE_UNKNOWN; + }; + + bool operator==(const AchievementCacheKey& point) const { + return this->targets == point.targets && this->value == point.value && this->type == point.type; + }; + void SetTargets(const std::string value) { this->targets = value; }; + void SetValue(uint32_t value) { this->value = value; }; + void SetType(MissionTaskType value) { this->type = value; }; + + std::string GetTargets() const { return this->targets; }; + uint32_t GetValue() const { return this->value; }; + MissionTaskType GetType() const { return this->type; }; +private: + std::string targets; + uint32_t value; + MissionTaskType type; + +}; + +// Specialization of hash for the above class +namespace std { + template<> + struct hash<AchievementCacheKey> { + size_t operator()(const AchievementCacheKey& key) const { + size_t hash = 0; + GeneralUtils::hash_combine(hash, key.GetType()); + GeneralUtils::hash_combine(hash, key.GetValue()); + GeneralUtils::hash_combine(hash, key.GetTargets()); + return hash; + }; + }; +}; + +#endif //!__ACHIEVEMENTCACHEKEY__H__ diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index 96f213e5..2ef6c2f6 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -17,10 +17,11 @@ #include "dZoneManager.h" #include "Mail.h" #include "MissionPrerequisites.h" +#include "AchievementCacheKey.h" // MARK: Mission Component -std::unordered_map<size_t, std::vector<uint32_t>> MissionComponent::m_AchievementCache = {}; +std::unordered_map<AchievementCacheKey, std::vector<uint32_t>> MissionComponent::m_AchievementCache = {}; //! Initializer MissionComponent::MissionComponent(Entity* parent) : Component(parent) { @@ -391,12 +392,12 @@ bool MissionComponent::LookForAchievements(MissionTaskType type, int32_t value, const std::vector<uint32_t>& MissionComponent::QueryAchievements(MissionTaskType type, int32_t value, const std::string targets) { // Create a hash which represent this query for achievements - size_t hash = 0; - GeneralUtils::hash_combine(hash, type); - GeneralUtils::hash_combine(hash, value); - GeneralUtils::hash_combine(hash, targets); + AchievementCacheKey toFind; + toFind.SetType(type); + toFind.SetValue(value); + toFind.SetTargets(targets); - const std::unordered_map<size_t, std::vector<uint32_t>>::iterator& iter = m_AchievementCache.find(hash); + const auto& iter = m_AchievementCache.find(toFind); // Check if this query is cached if (iter != m_AchievementCache.end()) { @@ -447,11 +448,9 @@ const std::vector<uint32_t>& MissionComponent::QueryAchievements(MissionTaskType } } } - // Insert into cache - m_AchievementCache.insert_or_assign(hash, result); - - return m_AchievementCache.find(hash)->second; + m_AchievementCache.insert_or_assign(toFind, result); + return m_AchievementCache.find(toFind)->second; } bool MissionComponent::RequiresItem(const LOT lot) { diff --git a/dGame/dComponents/MissionComponent.h b/dGame/dComponents/MissionComponent.h index 58185a68..a3e39a88 100644 --- a/dGame/dComponents/MissionComponent.h +++ b/dGame/dComponents/MissionComponent.h @@ -17,11 +17,13 @@ #include "CDMissionsTable.h" #include "Component.h" - /** - * The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for - * progression of each of the mission task types (see MissionTaskType). - */ -class MissionComponent : public Component +class AchievementCacheKey; + +/** + * The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for + * progression of each of the mission task types (see MissionTaskType). + */ +class MissionComponent: public Component { public: static const uint32_t ComponentType = COMPONENT_TYPE_MISSION; @@ -192,7 +194,7 @@ private: * As achievements can be hard to query, we here store a list of all the mission IDs that can be unlocked for a * combination of tasks and values, so that they can be easily re-queried later */ - static std::unordered_map<size_t, std::vector<uint32_t>> m_AchievementCache; + static std::unordered_map<AchievementCacheKey, std::vector<uint32_t>> m_AchievementCache; /** * Order of missions in the UI. This value is incremented by 1 From faf42d2f8cf432df2993b031f079b0b8c6d7dbe7 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Sun, 22 Jan 2023 17:38:47 -0600 Subject: [PATCH 122/166] cleanup enums to make them more consistent --- dChatServer/ChatPacketHandler.cpp | 56 +++---- dChatServer/ChatPacketHandler.h | 4 +- dCommon/dEnums/ItemSetPassiveAbilityID.h | 105 ------------- dCommon/dEnums/MissionLockState.h | 13 -- dCommon/dEnums/MissionState.h | 56 ------- dCommon/dEnums/MissionTaskType.h | 31 ---- dCommon/dEnums/PermissionMap.h | 42 ------ dCommon/dEnums/RacingTaskParam.h | 20 --- ...esponseCode.h => eAddFriendResponseCode.h} | 6 +- ...esponseType.h => eAddFriendResponseType.h} | 8 +- dCommon/dEnums/eBubbleType.h | 4 +- dCommon/dEnums/eHelpType.h | 41 +++++ dCommon/dEnums/eItemSetPassiveAbilityID.h | 58 +++++++ dCommon/dEnums/eItemType.h | 50 +++--- dCommon/dEnums/eMissionLockState.h | 12 ++ dCommon/dEnums/eMissionState.h | 56 +++++++ dCommon/dEnums/eMissionTaskType.h | 43 ++++++ dCommon/dEnums/ePackageType.h | 13 ++ dCommon/dEnums/ePermissionMap.h | 46 ++++++ dCommon/dEnums/eRacingTaskParam.h | 25 +++ dGame/Character.cpp | 16 +- dGame/Character.h | 9 +- dGame/Entity.cpp | 5 +- dGame/TradingManager.cpp | 5 +- dGame/dComponents/AchievementCacheKey.h | 10 +- dGame/dComponents/DestroyableComponent.cpp | 15 +- dGame/dComponents/InventoryComponent.cpp | 27 ++-- dGame/dComponents/InventoryComponent.h | 10 +- dGame/dComponents/MissionComponent.cpp | 19 +-- dGame/dComponents/MissionComponent.h | 18 +-- dGame/dComponents/MissionOfferComponent.cpp | 9 +- dGame/dComponents/PetComponent.cpp | 4 +- .../PropertyManagementComponent.cpp | 3 +- dGame/dComponents/RacingControlComponent.cpp | 19 +-- dGame/dComponents/RebuildComponent.cpp | 6 +- .../dComponents/ScriptedActivityComponent.cpp | 3 +- dGame/dGameMessages/GameMessageHandler.cpp | 3 +- dGame/dGameMessages/GameMessages.cpp | 55 +++---- dGame/dInventory/Inventory.cpp | 51 ++++--- dGame/dInventory/Item.cpp | 6 +- dGame/dInventory/ItemSet.cpp | 3 +- dGame/dInventory/ItemSetPassiveAbility.cpp | 142 +++++++++--------- dGame/dMission/Mission.cpp | 70 +++++---- dGame/dMission/Mission.h | 15 +- dGame/dMission/MissionPrerequisites.cpp | 4 +- dGame/dMission/MissionTask.cpp | 51 ++++--- dGame/dMission/MissionTask.h | 4 +- dGame/dUtilities/Loot.cpp | 10 +- dGame/dUtilities/Mail.cpp | 5 +- dGame/dUtilities/Preconditions.cpp | 10 +- dGame/dUtilities/SlashCommandHandler.cpp | 3 +- dNet/ClientPackets.cpp | 2 +- .../02_server/Equipment/BootyDigServer.cpp | 7 +- .../Equipment/MaestromExtracticatorServer.cpp | 3 +- .../02_server/Map/AG/NpcAgCourseStarter.cpp | 4 +- dScripts/02_server/Map/AG/NpcCowboyServer.cpp | 14 +- dScripts/02_server/Map/AG/NpcCowboyServer.h | 2 +- .../02_server/Map/AG/NpcEpsilonServer.cpp | 2 +- dScripts/02_server/Map/AG/NpcEpsilonServer.h | 2 +- .../02_server/Map/AG/NpcNjAssistantServer.cpp | 9 +- .../02_server/Map/AG/NpcNjAssistantServer.h | 2 +- dScripts/02_server/Map/AG/NpcPirateServer.cpp | 8 +- dScripts/02_server/Map/AG/NpcPirateServer.h | 2 +- dScripts/02_server/Map/AG/NpcWispServer.cpp | 10 +- dScripts/02_server/Map/AG/NpcWispServer.h | 2 +- .../02_server/Map/AG/RemoveRentalGear.cpp | 6 +- dScripts/02_server/Map/AG/RemoveRentalGear.h | 2 +- .../02_server/Map/AM/AmDropshipComputer.cpp | 3 +- dScripts/02_server/Map/FV/FvFong.cpp | 6 +- dScripts/02_server/Map/FV/FvFong.h | 2 +- .../02_server/Map/FV/ImgBrickConsoleQB.cpp | 5 +- dScripts/02_server/Map/GF/GfTikiTorch.cpp | 3 +- .../02_server/Map/General/ExplodingAsset.cpp | 5 +- .../02_server/Map/General/GrowingFlower.cpp | 12 +- .../General/ImaginationBackpackHealServer.cpp | 6 +- .../02_server/Map/General/PetDigServer.cpp | 7 +- .../02_server/Map/General/PropertyDevice.cpp | 3 +- .../Map/General/TouchMissionUpdateServer.cpp | 3 +- .../02_server/Map/NT/NtAssemblyTubeServer.cpp | 4 +- dScripts/02_server/Map/NT/NtDukeServer.cpp | 7 +- dScripts/02_server/Map/NT/NtDukeServer.h | 2 +- .../02_server/Map/NT/NtParadoxPanelServer.cpp | 3 +- .../02_server/Map/NT/NtParadoxTeleServer.cpp | 3 +- .../Map/NT/NtSentinelWalkwayServer.cpp | 3 +- dScripts/02_server/Map/NT/NtVandaServer.cpp | 6 +- dScripts/02_server/Map/NT/NtVandaServer.h | 2 +- .../Map/NT/NtVentureSpeedPadServer.cpp | 3 +- .../02_server/Map/PR/SpawnGryphonServer.cpp | 3 +- .../Map/Property/AG_Small/ZoneAgProperty.cpp | 11 +- .../02_server/Map/SS/SsModularBuildServer.cpp | 3 +- .../02_server/Map/VE/VeBricksampleServer.cpp | 3 +- dScripts/02_server/Map/VE/VeEpsilonServer.cpp | 6 +- dScripts/02_server/Map/VE/VeEpsilonServer.h | 2 +- dScripts/02_server/Map/njhub/NjColeNPC.cpp | 5 +- dScripts/02_server/Map/njhub/NjColeNPC.h | 2 +- .../02_server/Map/njhub/NjJayMissionItems.cpp | 2 +- .../02_server/Map/njhub/NjJayMissionItems.h | 2 +- .../Map/njhub/NjNPCMissionSpinjitzuServer.cpp | 7 +- .../Map/njhub/NjNPCMissionSpinjitzuServer.h | 2 +- dScripts/02_server/Map/njhub/NjWuNPC.cpp | 11 +- dScripts/02_server/Map/njhub/NjWuNPC.h | 2 +- dScripts/BasePropertyServer.cpp | 6 +- dScripts/BaseSurvivalServer.cpp | 11 +- dScripts/BaseWavesServer.cpp | 23 +-- dScripts/CppScripts.h | 8 +- dScripts/Darkitect.cpp | 3 +- dScripts/NPCAddRemoveItem.cpp | 8 +- dScripts/NPCAddRemoveItem.h | 2 +- dScripts/NtFactionSpyServer.cpp | 3 +- dScripts/ai/AG/ActSharkPlayerDeathTrigger.cpp | 4 +- dScripts/ai/FV/FvFreeGfNinjas.cpp | 7 +- dScripts/ai/FV/FvFreeGfNinjas.h | 2 +- dScripts/ai/GENERAL/LegoDieRoll.cpp | 3 +- dScripts/ai/GF/GfJailkeepMission.cpp | 9 +- dScripts/ai/GF/GfJailkeepMission.h | 2 +- dScripts/ai/GF/PetDigBuild.cpp | 3 +- dScripts/ai/GF/PirateRep.cpp | 6 +- dScripts/ai/GF/PirateRep.h | 2 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 9 +- dScripts/ai/NP/NpcNpSpacemanBob.cpp | 5 +- dScripts/ai/NP/NpcNpSpacemanBob.h | 2 +- dScripts/ai/NS/NsConcertInstrument.cpp | 6 +- dScripts/ai/NS/NsJohnnyMissionServer.cpp | 5 +- dScripts/ai/NS/NsJohnnyMissionServer.h | 2 +- dScripts/ai/NS/NsModularBuild.cpp | 3 +- dScripts/ai/PROPERTY/AG/AgPropGuard.cpp | 11 +- dScripts/ai/PROPERTY/AG/AgPropGuard.h | 2 +- dScripts/ai/PROPERTY/AgPropguards.cpp | 8 +- dScripts/ai/PROPERTY/AgPropguards.h | 2 +- .../OBJECTS/FvRaceSmashEggImagineServer.cpp | 7 +- .../RACING/OBJECTS/RaceImagineCrateServer.cpp | 5 +- .../ai/RACING/OBJECTS/RaceImaginePowerup.cpp | 5 +- .../ai/RACING/OBJECTS/RaceSmashServer.cpp | 7 +- 133 files changed, 898 insertions(+), 808 deletions(-) delete mode 100644 dCommon/dEnums/ItemSetPassiveAbilityID.h delete mode 100644 dCommon/dEnums/MissionLockState.h delete mode 100644 dCommon/dEnums/MissionState.h delete mode 100644 dCommon/dEnums/MissionTaskType.h delete mode 100644 dCommon/dEnums/PermissionMap.h delete mode 100644 dCommon/dEnums/RacingTaskParam.h rename dCommon/dEnums/{AddFriendResponseCode.h => eAddFriendResponseCode.h} (50%) rename dCommon/dEnums/{AddFriendResponseType.h => eAddFriendResponseType.h} (59%) create mode 100644 dCommon/dEnums/eHelpType.h create mode 100644 dCommon/dEnums/eItemSetPassiveAbilityID.h create mode 100644 dCommon/dEnums/eMissionLockState.h create mode 100644 dCommon/dEnums/eMissionState.h create mode 100644 dCommon/dEnums/eMissionTaskType.h create mode 100644 dCommon/dEnums/ePackageType.h create mode 100644 dCommon/dEnums/ePermissionMap.h create mode 100644 dCommon/dEnums/eRacingTaskParam.h diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index 119083ee..592c3870 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -8,8 +8,8 @@ #include "dServer.h" #include "GeneralUtils.h" #include "dLogger.h" -#include "AddFriendResponseCode.h" -#include "AddFriendResponseType.h" +#include "eAddFriendResponseCode.h" +#include "eAddFriendResponseType.h" #include "RakString.h" #include "dConfig.h" @@ -115,7 +115,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { auto requestor = playerContainer.GetPlayerData(requestorPlayerID); if (requestor->playerName == playerName) { - SendFriendResponse(requestor, requestor, AddFriendResponseType::MYTHRAN); + SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN); return; }; std::unique_ptr<PlayerData> requestee(playerContainer.GetPlayerData(playerName)); @@ -153,7 +153,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { requestee.reset(new PlayerData()); requestee->playerName = playerName; - SendFriendResponse(requestor, requestee.get(), result->next() ? AddFriendResponseType::NOTONLINE : AddFriendResponseType::INVALIDCHARACTER); + SendFriendResponse(requestor, requestee.get(), result->next() ? eAddFriendResponseType::NOTONLINE : eAddFriendResponseType::INVALIDCHARACTER); return; } @@ -197,10 +197,10 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { if (oldBestFriendStatus != bestFriendStatus) { if (requestee->countOfBestFriends >= maxNumberOfBestFriends || requestor->countOfBestFriends >= maxNumberOfBestFriends) { if (requestee->countOfBestFriends >= maxNumberOfBestFriends) { - SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::THEIRFRIENDLISTFULL, false); + SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::THEIRFRIENDLISTFULL, false); } if (requestor->countOfBestFriends >= maxNumberOfBestFriends) { - SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::YOURFRIENDSLISTFULL, false); + SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::YOURFRIENDSLISTFULL, false); } } else { // Then update the database with this new info. @@ -215,8 +215,8 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { if (bestFriendStatus == 3U) { requestee->countOfBestFriends += 1; requestor->countOfBestFriends += 1; - if (requestee->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestee.get(), requestor, AddFriendResponseType::ACCEPTED, false, true); - if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::ACCEPTED, false, true); + if (requestee->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestee.get(), requestor, eAddFriendResponseType::ACCEPTED, false, true); + if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::ACCEPTED, false, true); for (auto& friendData : requestor->friends) { if (friendData.friendID == requestee->playerID) { friendData.isBestFriend = true; @@ -230,7 +230,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { } } } else { - if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), AddFriendResponseType::WAITINGAPPROVAL, true, true); + if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::WAITINGAPPROVAL, true, true); } } else { // Do not send this if we are requesting to be a best friend. @@ -247,7 +247,7 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { inStream.Read(playerID); inStream.Read(playerID); - AddFriendResponseCode clientResponseCode = static_cast<AddFriendResponseCode>(packet->data[0x14]); + eAddFriendResponseCode clientResponseCode = static_cast<eAddFriendResponseCode>(packet->data[0x14]); std::string friendName = PacketUtils::ReadString(0x15, packet, true); //Now to try and find both of these: @@ -255,29 +255,29 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { auto requestee = playerContainer.GetPlayerData(friendName); if (!requestor || !requestee) return; - AddFriendResponseType serverResponseCode{}; + eAddFriendResponseType serverResponseCode{}; uint8_t isAlreadyBestFriends = 0U; // We need to convert this response code to one we can actually send back to the client. switch (clientResponseCode) { - case AddFriendResponseCode::ACCEPTED: - serverResponseCode = AddFriendResponseType::ACCEPTED; + case eAddFriendResponseCode::ACCEPTED: + serverResponseCode = eAddFriendResponseType::ACCEPTED; break; - case AddFriendResponseCode::BUSY: - serverResponseCode = AddFriendResponseType::BUSY; + case eAddFriendResponseCode::BUSY: + serverResponseCode = eAddFriendResponseType::BUSY; break; - case AddFriendResponseCode::CANCELLED: - serverResponseCode = AddFriendResponseType::CANCELLED; + case eAddFriendResponseCode::CANCELLED: + serverResponseCode = eAddFriendResponseType::CANCELLED; break; - case AddFriendResponseCode::REJECTED: - serverResponseCode = AddFriendResponseType::DECLINED; + case eAddFriendResponseCode::REJECTED: + serverResponseCode = eAddFriendResponseType::DECLINED; break; } // Now that we have handled the base cases, we need to check the other cases. - if (serverResponseCode == AddFriendResponseType::ACCEPTED) { + if (serverResponseCode == eAddFriendResponseType::ACCEPTED) { for (auto friendData : requestor->friends) { if (friendData.friendID == requestee->playerID) { - serverResponseCode = AddFriendResponseType::ALREADYFRIEND; + serverResponseCode = eAddFriendResponseType::ALREADYFRIEND; if (friendData.isBestFriend) { isAlreadyBestFriends = 1U; } @@ -286,7 +286,7 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { } // This message is NOT sent for best friends and is handled differently for those requests. - if (serverResponseCode == AddFriendResponseType::ACCEPTED) { + if (serverResponseCode == eAddFriendResponseType::ACCEPTED) { // Add the each player to the others friend list. FriendData requestorData; requestorData.zoneID = requestor->zoneID; @@ -313,8 +313,8 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { statement->execute(); } - if (serverResponseCode != AddFriendResponseType::DECLINED) SendFriendResponse(requestor, requestee, serverResponseCode, isAlreadyBestFriends); - if (serverResponseCode != AddFriendResponseType::ALREADYFRIEND) SendFriendResponse(requestee, requestor, serverResponseCode, isAlreadyBestFriends); + if (serverResponseCode != eAddFriendResponseType::DECLINED) SendFriendResponse(requestor, requestee, serverResponseCode, isAlreadyBestFriends); + if (serverResponseCode != eAddFriendResponseType::ALREADYFRIEND) SendFriendResponse(requestee, requestor, serverResponseCode, isAlreadyBestFriends); } void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { @@ -922,7 +922,7 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send //Make sure people aren't requesting people that they're already friends with: for (auto fr : receiver->friends) { if (fr.friendID == sender->playerID) { - SendFriendResponse(sender, receiver, AddFriendResponseType::ALREADYFRIEND, fr.isBestFriend); + SendFriendResponse(sender, receiver, eAddFriendResponseType::ALREADYFRIEND, fr.isBestFriend); return; //we have this player as a friend, yeet this function so it doesn't send another request. } } @@ -940,7 +940,7 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send SEND_PACKET; } -void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sender, AddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) { +void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) { if (!receiver || !sender) return; CBITSTREAM; @@ -951,11 +951,11 @@ void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sen PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_ADD_FRIEND_RESPONSE); bitStream.Write(responseCode); // For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver. - bitStream.Write<uint8_t>(responseCode != AddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS); + bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS); // Then write the player name PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); // Then if this is an acceptance code, write the following extra info. - if (responseCode == AddFriendResponseType::ACCEPTED) { + if (responseCode == eAddFriendResponseType::ACCEPTED) { bitStream.Write(sender->playerID); bitStream.Write(sender->zoneID); bitStream.Write(isBestFriendRequest); //isBFF diff --git a/dChatServer/ChatPacketHandler.h b/dChatServer/ChatPacketHandler.h index fffd1ca4..f2d83502 100644 --- a/dChatServer/ChatPacketHandler.h +++ b/dChatServer/ChatPacketHandler.h @@ -4,7 +4,7 @@ #include "BitStream.h" struct PlayerData; -enum class AddFriendResponseType : uint8_t; +enum class eAddFriendResponseType : uint8_t; namespace ChatPacketHandler { void HandleFriendlistRequest(Packet* packet); @@ -35,6 +35,6 @@ namespace ChatPacketHandler { void SendFriendUpdate(PlayerData* friendData, PlayerData* playerData, uint8_t notifyType, uint8_t isBestFriend); void SendFriendRequest(PlayerData* receiver, PlayerData* sender); - void SendFriendResponse(PlayerData* receiver, PlayerData* sender, AddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U); + void SendFriendResponse(PlayerData* receiver, PlayerData* sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready = 0U, uint8_t isBestFriendRequest = 0U); void SendRemoveFriend(PlayerData* receiver, std::string& personToRemove, bool isSuccessful); }; diff --git a/dCommon/dEnums/ItemSetPassiveAbilityID.h b/dCommon/dEnums/ItemSetPassiveAbilityID.h deleted file mode 100644 index 92caea19..00000000 --- a/dCommon/dEnums/ItemSetPassiveAbilityID.h +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -/** -2 Engineer (Rank 1) Item Set -3 Engineer (Rank 2) Item Set -4 Engineer (Rank 3) Item Set -7 Knight (Rank 1) Item Set -8 Knight (Rank 2) Item Set -9 Knight (Rank 3) Item Set -10 Space Ranger (Rank 1) Item Set -11 Space Ranger (Rank 2) Item Set -12 Space Ranger (Rank 3) Item Set -13 Samurai (Rank 1) Item Set -14 Samurai (Rank 2) Item Set -15 Samurai (Rank 3) Item Set -16 Sorcerer (Rank 1) Item Set -17 Sorcerer (Rank 2) Item Set -18 Sorcerer (Rank 3) Item Set -19 Space Marauder (Rank 1) Item Set -20 Space Marauder (Rank 2) Item Set -21 Space Marauder (Rank 3) Item Set -22 Shinobi (Rank 1) Item Set -23 Shinobi (Rank 2) Item Set -24 Shinobi (Rank 3) Item Set -25 Inventor (Rank 1) Item Set -26 Inventor (Rank 2) Item Set -27 Inventor (Rank 3) Item Set -28 Summoner (Rank 1) Item Set -29 Summoner (Rank 2) Item Set -30 Summoner (Rank 3) Item Set -31 Adventurer (Rank 1) Item Set -32 Adventurer (Rank 2) Item Set -33 Adventurer (Rank 3) Item Set -34 Daredevil (Rank 1) Item Set -35 Daredevil (Rank 2) Item Set -36 Daredevil (Rank 3) Item Set -37 Buccaneer (Rank 1) Item Set -38 Buccaneer (Rank 2) Item Set -39 Buccaneer (Rank 3) Item Set -40 Bone Suit Item Set -41 Imagination Spinjitzu Item Set -42 Bat Lord Item Set -43 Mosaic Jester Item Set -44 Explorien Bot Item Set -45 [Unnamed] Item Set -46 [Unnamed] Item Set -47 [Unnamed] Item Set -48 Earth Spinjitzu Item Set -49 [Unnamed] Item Set -50 Fire Spinjitzu Item Set -51 Ice Spinjitzu Item Set -52 Lightning Spinjitzu Item Set - */ -enum class ItemSetPassiveAbilityID -{ - EngineerRank1 = 2, - EngineerRank2 = 3, - EngineerRank3 = 4, - KnightRank1 = 7, - KnightRank2 = 8, - KnightRank3 = 9, - SpaceRangerRank1 = 10, - SpaceRangerRank2 = 11, - SpaceRangerRank3 = 12, - SamuraiRank1 = 13, - SamuraiRank2 = 14, - SamuraiRank3 = 15, - SorcererRank1 = 16, - SorcererRank2 = 17, - SorcererRank3 = 18, - SpaceMarauderRank1 = 19, - SpaceMarauderRank2 = 20, - SpaceMarauderRank3 = 21, - ShinobiRank1 = 22, - ShinobiRank2 = 23, - ShinobiRank3 = 24, - InventorRank1 = 25, - InventorRank2 = 26, - InventorRank3 = 27, - SummonerRank1 = 28, - SummonerRank2 = 29, - SummonerRank3 = 30, - AdventurerRank1 = 31, - AdventurerRank2 = 32, - AdventurerRank3 = 33, - DaredevilRank1 = 34, - DaredevilRank2 = 35, - DaredevilRank3 = 36, - BuccaneerRank1 = 37, - BuccaneerRank2 = 38, - BuccaneerRank3 = 39, - BoneSuit = 40, - ImaginationSpinjitzu = 41, - BatLord = 42, - MosaicJester = 43, - ExplorienBot = 44, - Unnamed1 = 45, - Unnamed2 = 46, - Unnamed3 = 47, - EarthSpinjitzu = 48, - Unnamed4 = 49, - FireSpinjitzu = 50, - IceSpinjitzu = 51, - LightningSpinjitzu = 52 -}; diff --git a/dCommon/dEnums/MissionLockState.h b/dCommon/dEnums/MissionLockState.h deleted file mode 100644 index 9fd2252a..00000000 --- a/dCommon/dEnums/MissionLockState.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#ifndef MISSIONLOCKSTATE_H -#define MISSIONLOCKSTATE_H - -enum class MissionLockState : int -{ - MISSION_LOCK_LOCKED, - MISSION_LOCK_NEW, - MISSION_LOCK_UNLOCKED, -}; - -#endif diff --git a/dCommon/dEnums/MissionState.h b/dCommon/dEnums/MissionState.h deleted file mode 100644 index f040d33a..00000000 --- a/dCommon/dEnums/MissionState.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#ifndef __MISSIONSTATE__H__ -#define __MISSIONSTATE__H__ - -/** - * Represents the possible states a mission can be in - */ -enum class MissionState : int32_t { - /** - * The mission state is unknown - */ - MISSION_STATE_UNKNOWN = -1, - - /** - * The mission is yielding rewards - */ - MISSION_STATE_REWARDING = 0, - - /** - * The mission can be accepted - */ - MISSION_STATE_AVAILABLE = 1, - - /** - * The mission has been accepted but not yet completed - */ - MISSION_STATE_ACTIVE = 2, - - /** - * All the tasks for the mission have been completed and the entity can turn the mission in to complete it - */ - MISSION_STATE_READY_TO_COMPLETE = 4, //!< The mission is ready to complete - - /** - * The mission has been completed - */ - MISSION_STATE_COMPLETE = 8, - - /** - * The mission is available again and has been completed before. Used for daily missions. - */ - MISSION_STATE_COMPLETE_AVAILABLE = 9, - - /** - * The mission is active and has been completed before. Used for daily missions. - */ - MISSION_STATE_COMPLETE_ACTIVE = 10, - - /** - * The mission has been completed before and has now been completed again. Used for daily missions. - */ - MISSION_STATE_COMPLETE_READY_TO_COMPLETE = 12 -}; - -#endif //!__MISSIONSTATE__H__ diff --git a/dCommon/dEnums/MissionTaskType.h b/dCommon/dEnums/MissionTaskType.h deleted file mode 100644 index 6c9b2668..00000000 --- a/dCommon/dEnums/MissionTaskType.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#ifndef MISSIONTASKTYPE_H -#define MISSIONTASKTYPE_H - -//! An enum for mission task types -enum class MissionTaskType : int { - MISSION_TASK_TYPE_UNKNOWN = -1, //!< The task type is unknown - MISSION_TASK_TYPE_SMASH = 0, //!< A task for smashing something - MISSION_TASK_TYPE_SCRIPT = 1, //!< A task handled by a server LUA script - MISSION_TASK_TYPE_ACTIVITY = 2, //!< A task for completing a quickbuild - MISSION_TASK_TYPE_ENVIRONMENT = 3, //!< A task for something in the environment - MISSION_TASK_TYPE_MISSION_INTERACTION = 4, //!< A task for interacting with a mission - MISSION_TASK_TYPE_EMOTE = 5, //!< A task for playing an emote - MISSION_TASK_TYPE_FOOD = 9, //!< A task for eating food - MISSION_TASK_TYPE_SKILL = 10, //!< A task for performing a skill - MISSION_TASK_TYPE_ITEM_COLLECTION = 11, //!< A task for collecting an item - MISSION_TASK_TYPE_LOCATION = 12, //!< A task for finding a location - MISSION_TASK_TYPE_MINIGAME = 14, //!< A task for doing something in a minigame - MISSION_TASK_TYPE_NON_MISSION_INTERACTION = 15, //!< A task for interacting with a non-mission - MISSION_TASK_TYPE_MISSION_COMPLETE = 16, //!< A task for completing a mission - MISSION_TASK_TYPE_EARN_REPUTATION = 17, //!< A task for earning reputation - MISSION_TASK_TYPE_POWERUP = 21, //!< A task for collecting a powerup - MISSION_TASK_TYPE_PET_TAMING = 22, //!< A task for taming a pet - MISSION_TASK_TYPE_RACING = 23, //!< A task for racing - MISSION_TASK_TYPE_PLAYER_FLAG = 24, //!< A task for setting a player flag - MISSION_TASK_TYPE_PLACE_MODEL = 25, //!< A task for picking up a model - MISSION_TASK_TYPE_VISIT_PROPERTY = 30 //!< A task for visiting a property -}; - -#endif diff --git a/dCommon/dEnums/PermissionMap.h b/dCommon/dEnums/PermissionMap.h deleted file mode 100644 index 8c271f17..00000000 --- a/dCommon/dEnums/PermissionMap.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include <cstdint> - -/** - * Bitmap of permissions and restrictions for characters. - */ -enum class PermissionMap : uint64_t -{ - /** - * Reserved for future use, bit 0-3. - */ - - /** - * The character has restricted trade acccess, bit 4. - */ - RestrictedTradeAccess = 0x1 << 4, - - /** - * The character has restricted mail access, bit 5. - */ - RestrictedMailAccess = 0x1 << 5, - - /** - * The character has restricted chat access, bit 6. - */ - RestrictedChatAccess = 0x1 << 6, - - // - // Combined permissions - // - - /** - * The character is marked as 'old', restricted from trade and mail. - */ - Old = RestrictedTradeAccess | RestrictedMailAccess, - - /** - * The character is soft banned, restricted from trade, mail, and chat. - */ - SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess, -}; diff --git a/dCommon/dEnums/RacingTaskParam.h b/dCommon/dEnums/RacingTaskParam.h deleted file mode 100644 index 5958cb5a..00000000 --- a/dCommon/dEnums/RacingTaskParam.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <cstdint> - -enum class RacingTaskParam : int32_t { - RACING_TASK_PARAM_FINISH_WITH_PLACEMENT = 1, //<! A task param for finishing with a specific placement. - RACING_TASK_PARAM_LAP_TIME = 2, //<! A task param for finishing with a specific lap time. - RACING_TASK_PARAM_TOTAL_TRACK_TIME = 3, //<! A task param for finishing with a specific track time. - RACING_TASK_PARAM_COMPLETE_ANY_RACING_TASK = 4, //<! A task param for completing a racing task. - RACING_TASK_PARAM_COMPLETE_TRACK_TASKS = 5, //<! A task param for completing a task for a specific track. - RACING_TASK_PARAM_MODULAR_BUILDING = 6, //<! A task param for modular building with racing builds. - RACING_TASK_PARAM_SAFE_DRIVER = 10, //<! A task param for completing a race without smashing. - RACING_TASK_PARAM_SMASHABLES = 11, //<! A task param for smashing entities during a race. - RACING_TASK_PARAM_COLLECT_IMAGINATION = 12, //<! A task param for collecting imagination during a race. - RACING_TASK_PARAM_COMPETED_IN_RACE = 13, //<! A task param for competing in a race. - RACING_TASK_PARAM_WIN_RACE_IN_WORLD = 14, //<! A task param for winning a race in a specific world. - RACING_TASK_PARAM_FIRST_PLACE_MULTIPLE_TRACKS = 15, //<! A task param for finishing in first place on multiple tracks. - RACING_TASK_PARAM_LAST_PLACE_FINISH = 16, //<! A task param for finishing in last place. - RACING_TASK_PARAM_SMASH_SPECIFIC_SMASHABLE = 17 //<! A task param for smashing dragon eggs during a race. -}; diff --git a/dCommon/dEnums/AddFriendResponseCode.h b/dCommon/dEnums/eAddFriendResponseCode.h similarity index 50% rename from dCommon/dEnums/AddFriendResponseCode.h rename to dCommon/dEnums/eAddFriendResponseCode.h index bb2faff7..56304c82 100644 --- a/dCommon/dEnums/AddFriendResponseCode.h +++ b/dCommon/dEnums/eAddFriendResponseCode.h @@ -1,11 +1,11 @@ #pragma once -#ifndef __ADDFRIENDRESPONSECODE__H__ -#define __ADDFRIENDRESPONSECODE__H__ +#ifndef __EADDFRIENDRESPONSECODE__H__ +#define __EADDFRIENDRESPONSECODE__H__ #include <cstdint> -enum class AddFriendResponseCode : uint8_t { +enum class eAddFriendResponseCode : uint8_t { ACCEPTED = 0, REJECTED, BUSY, diff --git a/dCommon/dEnums/AddFriendResponseType.h b/dCommon/dEnums/eAddFriendResponseType.h similarity index 59% rename from dCommon/dEnums/AddFriendResponseType.h rename to dCommon/dEnums/eAddFriendResponseType.h index 305796e8..5568aafb 100644 --- a/dCommon/dEnums/AddFriendResponseType.h +++ b/dCommon/dEnums/eAddFriendResponseType.h @@ -1,11 +1,11 @@ #pragma once -#ifndef __ADDFRIENDRESPONSETYPE__H__ -#define __ADDFRIENDRESPONSETYPE__H__ +#ifndef __EADDFRIENDRESPONSETYPE__H__ +#define __EADDFRIENDRESPONSETYPE__H__ #include <cstdint> -enum class AddFriendResponseType : uint8_t { +enum class eAddFriendResponseType : uint8_t { ACCEPTED = 0, ALREADYFRIEND, INVALIDCHARACTER, @@ -21,4 +21,4 @@ enum class AddFriendResponseType : uint8_t { FRIENDISFREETRIAL }; -#endif //!__ADDFRIENDRESPONSETYPE__H__ +#endif //!__EADDFRIENDRESPONSETYPE__H__ diff --git a/dCommon/dEnums/eBubbleType.h b/dCommon/dEnums/eBubbleType.h index 4aa6fad1..9ceef4b5 100644 --- a/dCommon/dEnums/eBubbleType.h +++ b/dCommon/dEnums/eBubbleType.h @@ -7,8 +7,8 @@ enum class eBubbleType : uint32_t { DEFAULT = 0, - ENERGY = 1, - SKUNK = 2, + ENERGY, + SKUNK }; #endif //!__EBUBBLETYPE__H__ diff --git a/dCommon/dEnums/eHelpType.h b/dCommon/dEnums/eHelpType.h new file mode 100644 index 00000000..d1838cc6 --- /dev/null +++ b/dCommon/dEnums/eHelpType.h @@ -0,0 +1,41 @@ + +#ifndef __EHELPTYPE__H__ +#define __EHELPTYPE__H__ + +#include <cstdint> + +enum class eHelpType : int32_t { + NONE = 0, + UNLOCK_MINIMAP = 2, + TOGGLETOOLTIP_OUTOFTIME_REBUILD = 3, + TOGGLETOOLTIP_LEAVELOSE_REBUILD = 4, + TOGGLECONTROLSTUTORIAL_WALKING = 6, + DISPLAYTUTORIAL_PASSPORT_1ST_SMASH = 7, + TOOLTIP_1ST_IMAGINATION_PICKUP = 8, + UNKNOWN9 = 9, + PETTAMINGMINIGAME_TUTORIAL_01 = 15, + PR_BOUNCER_TUTORIAL_03 = 16, + PR_TOOLTIP_1ST_PET_JUMPED_ON_SWITCH = 17, + PR_DIG_TUTORIAL_01 = 18, + PR_DIG_TUTORIAL_03 = 19, + PR_BOUNCER_TUTORIAL_01 = 20, + PR_NO_IMAGINATION_HIBERNATE = 21, + UNKNOWN22 = 22, + TOGGLECONTROLSTUTORIAL_JUMPING = 26, + TOGGLECONTROLSTUTORIAL_DOUBLEJUMPING = 27, + TOGGLECONTROLSTUTORIAL_CAMERA = 28, + TOGGLECONTROLSTUTORIAL_SMASH = 30, + UNKNOWN38 = 38, + UI_MOD_BUILD_PUT_ON_HAT = 40, + UI_MOD_BUILD_EQUIP_FIRST_MODULE = 41, + UNKNOWN42 = 42, + UNKNOWN43 = 43, + UI_MOD_BUILD_GO_LAUNCH_ROCKET = 44, + UI_MOD_BUILD_TALK_TO_SKYLANE = 45, + UNKNOWN53 = 53, + PET_DESPAWN_BY_OWNER_HIBERNATE = 69, + PET_DESPAWN_TAMING_NEW_PET = 70, + UI_INVENTORY_FULL_CANNOT_PICKUP_ITEM = 86 +}; + +#endif //!__EHELPTYPE__H__ diff --git a/dCommon/dEnums/eItemSetPassiveAbilityID.h b/dCommon/dEnums/eItemSetPassiveAbilityID.h new file mode 100644 index 00000000..8641d0f2 --- /dev/null +++ b/dCommon/dEnums/eItemSetPassiveAbilityID.h @@ -0,0 +1,58 @@ +#pragma once + +#ifndef __EITEMSETPASSIVEABILITYID__H__ +#define __EITEMSETPASSIVEABILITYID__H__ + +enum class eItemSetPassiveAbilityID { + EngineerRank1 = 2, + EngineerRank2 = 3, + EngineerRank3 = 4, + KnightRank1 = 7, + KnightRank2 = 8, + KnightRank3 = 9, + SpaceRangerRank1 = 10, + SpaceRangerRank2 = 11, + SpaceRangerRank3 = 12, + SamuraiRank1 = 13, + SamuraiRank2 = 14, + SamuraiRank3 = 15, + SorcererRank1 = 16, + SorcererRank2 = 17, + SorcererRank3 = 18, + SpaceMarauderRank1 = 19, + SpaceMarauderRank2 = 20, + SpaceMarauderRank3 = 21, + ShinobiRank1 = 22, + ShinobiRank2 = 23, + ShinobiRank3 = 24, + InventorRank1 = 25, + InventorRank2 = 26, + InventorRank3 = 27, + SummonerRank1 = 28, + SummonerRank2 = 29, + SummonerRank3 = 30, + AdventurerRank1 = 31, + AdventurerRank2 = 32, + AdventurerRank3 = 33, + DaredevilRank1 = 34, + DaredevilRank2 = 35, + DaredevilRank3 = 36, + BuccaneerRank1 = 37, + BuccaneerRank2 = 38, + BuccaneerRank3 = 39, + BoneSuit = 40, + ImaginationSpinjitzu = 41, + BatLord = 42, + MosaicJester = 43, + ExplorienBot = 44, + Unnamed1 = 45, + Unnamed2 = 46, + Unnamed3 = 47, + EarthSpinjitzu = 48, + Unnamed4 = 49, + FireSpinjitzu = 50, + IceSpinjitzu = 51, + LightningSpinjitzu = 52 +}; + +#endif //!__EITEMSETPASSIVEABILITYID__H__ diff --git a/dCommon/dEnums/eItemType.h b/dCommon/dEnums/eItemType.h index e68ce695..69eb18e9 100644 --- a/dCommon/dEnums/eItemType.h +++ b/dCommon/dEnums/eItemType.h @@ -6,31 +6,31 @@ #include <cstdint> enum class eItemType : int32_t { - ITEM_TYPE_UNKNOWN = -1, //!< An unknown item type - ITEM_TYPE_BRICK = 1, //!< A brick - ITEM_TYPE_HAT = 2, //!< A hat / head item - ITEM_TYPE_HAIR = 3, //!< A hair item - ITEM_TYPE_NECK = 4, //!< A neck item - ITEM_TYPE_LEFT_HAND = 5, //!< A left handed item - ITEM_TYPE_RIGHT_HAND = 6, //!< A right handed item - ITEM_TYPE_LEGS = 7, //!< A pants item - ITEM_TYPE_LEFT_TRINKET = 8, //!< A left handled trinket item - ITEM_TYPE_RIGHT_TRINKET = 9, //!< A right handed trinket item - ITEM_TYPE_BEHAVIOR = 10, //!< A behavior - ITEM_TYPE_PROPERTY = 11, //!< A property - ITEM_TYPE_MODEL = 12, //!< A model - ITEM_TYPE_COLLECTIBLE = 13, //!< A collectible item - ITEM_TYPE_CONSUMABLE = 14, //!< A consumable item - ITEM_TYPE_CHEST = 15, //!< A chest item - ITEM_TYPE_EGG = 16, //!< An egg - ITEM_TYPE_PET_FOOD = 17, //!< A pet food item - ITEM_TYPE_QUEST_OBJECT = 18, //!< A quest item - ITEM_TYPE_PET_INVENTORY_ITEM = 19, //!< A pet inventory item - ITEM_TYPE_PACKAGE = 20, //!< A package - ITEM_TYPE_LOOT_MODEL = 21, //!< A loot model - ITEM_TYPE_VEHICLE = 22, //!< A vehicle - ITEM_TYPE_CURRENCY = 23, //!< Currency - ITEM_TYPE_MOUNT = 24 //!< A Mount + UNKNOWN = -1, + BRICK, + HAT, + HAIR, + NECK, + LEFT_HAND, + RIGHT_HAND, + LEGS, + LEFT_TRINKET, + RIGHT_TRINKET, + BEHAVIOR, + PROPERTY, + MODEL, + COLLECTIBLE, + CONSUMABLE, + CHEST, + EGG, + PET_FOOD, + QUEST_OBJECT, + PET_INVENTORY_ITEM, + PACKAGE, + LOOT_MODEL, + VEHICLE, + LUP_MODEL, + MOUNT }; #endif //!__EITEMTYPE__H__ diff --git a/dCommon/dEnums/eMissionLockState.h b/dCommon/dEnums/eMissionLockState.h new file mode 100644 index 00000000..52752767 --- /dev/null +++ b/dCommon/dEnums/eMissionLockState.h @@ -0,0 +1,12 @@ +#pragma once + +#ifndef __EMISSIONLOCKSTATE__H__ +#define __EMISSIONLOCKSTATE__H__ + +enum class eMissionLockState : int { + LOCKED, + NEW, + UNLOCKED, +}; + +#endif //!__EMISSIONLOCKSTATE__H__ diff --git a/dCommon/dEnums/eMissionState.h b/dCommon/dEnums/eMissionState.h new file mode 100644 index 00000000..e080f455 --- /dev/null +++ b/dCommon/dEnums/eMissionState.h @@ -0,0 +1,56 @@ +#pragma once + +#ifndef __MISSIONSTATE__H__ +#define __MISSIONSTATE__H__ + +/** + * Represents the possible states a mission can be in + */ +enum class eMissionState : int { + /** + * The mission state is unknown + */ + UNKNOWN = -1, + + /** + * The mission is yielding rewards + */ + REWARDING = 0, + + /** + * The mission can be accepted + */ + AVAILABLE = 1, + + /** + * The mission has been accepted but not yet completed + */ + ACTIVE = 2, + + /** + * All the tasks for the mission have been completed and the entity can turn the mission in to complete it + */ + READY_TO_COMPLETE = 4, //!< The mission is ready to complete + + /** + * The mission has been completed + */ + COMPLETE = 8, + + /** + * The mission is available again and has been completed before. Used for daily missions. + */ + COMPLETE_AVAILABLE = 9, + + /** + * The mission is active and has been completed before. Used for daily missions. + */ + COMPLETE_ACTIVE = 10, + + /** + * The mission has been completed before and has now been completed again. Used for daily missions. + */ + COMPLETE_READY_TO_COMPLETE = 12 +}; + +#endif //!__MISSIONSTATE__H__ diff --git a/dCommon/dEnums/eMissionTaskType.h b/dCommon/dEnums/eMissionTaskType.h new file mode 100644 index 00000000..2636f88c --- /dev/null +++ b/dCommon/dEnums/eMissionTaskType.h @@ -0,0 +1,43 @@ +#pragma once + +#ifndef __EMISSIONTASKTYPE__H__ +#define __EMISSIONTASKTYPE__H__ + +enum class eMissionTaskType : int { + UNKNOWN = -1, + SMASH, + SCRIPT, + ACTIVITY, + COLLECTION, + TALK_TO_NPC, + EMOTE, + SHASH_CHAIN, + BUY, + SELL, + USE_ITEM, + USE_SKILL, + GATHER, + EXPLORE, + DELIVERY, + PERFORM_ACTIVITY, + INTERACT, + META, + EARN_REPUTATION, + VOTING, + SHOWCASE_DELIVERY, + REVIECE_CAST, + POWERUP, + PET_TAMING, + RACING, + PLAYER_FLAG, + PLACE_MODEL, + REMOVE_MODEL, + ADD_BEHAVIOR, + REMOVE_BEHAVIOR, + CLAIM_PROPERTY, + VISIT_PROPERTY, + TIME_PLAYED, + DONATION +}; + +#endif //!__EMISSIONTASKTYPE__H__ diff --git a/dCommon/dEnums/ePackageType.h b/dCommon/dEnums/ePackageType.h new file mode 100644 index 00000000..2c1c9977 --- /dev/null +++ b/dCommon/dEnums/ePackageType.h @@ -0,0 +1,13 @@ +#ifndef __EPACKAGETYPE__H__ +#define __EPACKAGETYPE__H__ + +enum class ePackageType { + INVALID = -1, + ITEM, + BRICKS, + MODELS, + CAR_MODELS +}; + + +#endif //!__EPACKAGETYPE__H__ diff --git a/dCommon/dEnums/ePermissionMap.h b/dCommon/dEnums/ePermissionMap.h new file mode 100644 index 00000000..d15c9fd3 --- /dev/null +++ b/dCommon/dEnums/ePermissionMap.h @@ -0,0 +1,46 @@ +#pragma once + +#include <cstdint> + +#ifndef __EPERMISSIONMAP__H__ +#define __EPERMISSIONMAP__H__ + +/** + * Bitmap of permissions and restrictions for characters. + */ +enum class ePermissionMap : uint64_t { + /** + * Reserved for future use, bit 0-3. + */ + + /** + * The character has restricted trade acccess, bit 4. + */ + RestrictedTradeAccess = 0x1 << 4, + + /** + * The character has restricted mail access, bit 5. + */ + RestrictedMailAccess = 0x1 << 5, + + /** + * The character has restricted chat access, bit 6. + */ + RestrictedChatAccess = 0x1 << 6, + + // + // Combined permissions + // + + /** + * The character is marked as 'old', restricted from trade and mail. + */ + Old = RestrictedTradeAccess | RestrictedMailAccess, + + /** + * The character is soft banned, restricted from trade, mail, and chat. + */ + SoftBanned = RestrictedTradeAccess | RestrictedMailAccess | RestrictedChatAccess, +}; + +#endif //!__EPERMISSIONMAP__H__ diff --git a/dCommon/dEnums/eRacingTaskParam.h b/dCommon/dEnums/eRacingTaskParam.h new file mode 100644 index 00000000..df50e382 --- /dev/null +++ b/dCommon/dEnums/eRacingTaskParam.h @@ -0,0 +1,25 @@ +#pragma once + +#ifndef __ERACINGTASKPARAM__H__ +#define __ERACINGTASKPARAM__H__ + +#include <cstdint> + +enum class eRacingTaskParam : int32_t { + FINISH_WITH_PLACEMENT = 1, + LAP_TIME, + TOTAL_TRACK_TIME, + COMPLETE_ANY_RACING_TASK, + COMPLETE_TRACK_TASKS, + MODULAR_BUILDING, + SAFE_DRIVER = 10, + SMASHABLES, + COLLECT_IMAGINATION, + COMPETED_IN_RACE, + WIN_RACE_IN_WORLD, + FIRST_PLACE_MULTIPLE_TRACKS, + LAST_PLACE_FINISH, + SMASH_SPECIFIC_SMASHABLE +}; + +#endif //!__ERACINGTASKPARAM__H__ diff --git a/dGame/Character.cpp b/dGame/Character.cpp index 67a0bf1b..572a3e9e 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -16,6 +16,8 @@ #include "ChatPackets.h" #include "Inventory.h" #include "InventoryComponent.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" Character::Character(uint32_t id, User* parentUser) { //First load the name, etc: @@ -34,7 +36,7 @@ Character::Character(uint32_t id, User* parentUser) { m_UnapprovedName = res->getString(2).c_str(); m_NameRejected = res->getBoolean(3); m_PropertyCloneID = res->getUInt(4); - m_PermissionMap = static_cast<PermissionMap>(res->getUInt64(5)); + m_PermissionMap = static_cast<ePermissionMap>(res->getUInt64(5)); } delete res; @@ -93,7 +95,7 @@ void Character::UpdateFromDatabase() { m_UnapprovedName = res->getString(2).c_str(); m_NameRejected = res->getBoolean(3); m_PropertyCloneID = res->getUInt(4); - m_PermissionMap = static_cast<PermissionMap>(res->getUInt64(5)); + m_PermissionMap = static_cast<ePermissionMap>(res->getUInt64(5)); } delete res; @@ -423,7 +425,7 @@ void Character::SetPlayerFlag(const uint32_t flagId, const bool value) { auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_PLAYER_FLAG, flagId); + missionComponent->Progress(eMissionTaskType::PLAYER_FLAG, flagId); } } } @@ -535,7 +537,7 @@ void Character::OnZoneLoad() { if (missionComponent != nullptr) { // Fix the monument race flag - if (missionComponent->GetMissionState(319) >= MissionState::MISSION_STATE_READY_TO_COMPLETE) { + if (missionComponent->GetMissionState(319) >= eMissionState::READY_TO_COMPLETE) { SetPlayerFlag(33, true); } } @@ -550,7 +552,7 @@ void Character::OnZoneLoad() { /** * Restrict old character to 1 million coins */ - if (HasPermission(PermissionMap::Old)) { + if (HasPermission(ePermissionMap::Old)) { if (GetCoins() > 1000000) { SetCoins(1000000, eLootSourceType::LOOT_SOURCE_NONE); } @@ -568,11 +570,11 @@ void Character::OnZoneLoad() { } } -PermissionMap Character::GetPermissionMap() const { +ePermissionMap Character::GetPermissionMap() const { return m_PermissionMap; } -bool Character::HasPermission(PermissionMap permission) const { +bool Character::HasPermission(ePermissionMap permission) const { return (static_cast<uint64_t>(m_PermissionMap) & static_cast<uint64_t>(permission)) != 0; } diff --git a/dGame/Character.h b/dGame/Character.h index 07bde36c..abded1b3 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -9,11 +9,12 @@ #include "NiPoint3.h" #include "NiQuaternion.h" -#include "PermissionMap.h" +#include "ePermissionMap.h" class User; struct Packet; class Entity; +enum class ePermissionMap : uint64_t; /** * Meta information about a character, like their name and style @@ -385,14 +386,14 @@ public: * Gets the permissions of the character, determining what actions a character may do * @return the permissions for this character */ - PermissionMap GetPermissionMap() const; + ePermissionMap GetPermissionMap() const; /** * Check if this character has a certain permission * @param permission the ID of the permission to check for * @return whether the character has the specified permission */ - bool HasPermission(PermissionMap permission) const; + bool HasPermission(ePermissionMap permission) const; /** * Gets all the emotes this character has unlocked so far @@ -481,7 +482,7 @@ private: /** * Bitmap of permission attributes this character has. */ - PermissionMap m_PermissionMap; + ePermissionMap m_PermissionMap; /** * The default name of this character diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index c0f71324..eefa5107 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -22,6 +22,7 @@ #include "EntityTimer.h" #include "EntityCallbackTimer.h" #include "Loot.h" +#include "eMissionTaskType.h" //Component includes: #include "Component.h" @@ -1318,7 +1319,7 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) { auto* missionComponent = other->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_LOCATION, 0, 0, GeneralUtils::UTF16ToWTF8(poi)); + missionComponent->Progress(eMissionTaskType::EXPLORE, 0, 0, GeneralUtils::UTF16ToWTF8(poi)); } } @@ -1614,7 +1615,7 @@ void Entity::PickupItem(const LWOOBJID& objectID) { auto* missionComponent = GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_POWERUP, skill.skillID); + missionComponent->Progress(eMissionTaskType::POWERUP, skill.skillID); } } } else { diff --git a/dGame/TradingManager.cpp b/dGame/TradingManager.cpp index ed55f217..e1eac422 100644 --- a/dGame/TradingManager.cpp +++ b/dGame/TradingManager.cpp @@ -9,6 +9,7 @@ #include "Character.h" #include "CharacterComponent.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" TradingManager* TradingManager::m_Address = nullptr; @@ -161,14 +162,14 @@ void Trade::Complete() { for (const auto& tradeItem : m_ItemsA) { auto* itemToRemove = inventoryA->FindItemById(tradeItem.itemId); if (itemToRemove) itemToRemove->SetCount(itemToRemove->GetCount() - tradeItem.itemCount); - missionsA->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); + missionsA->Progress(eMissionTaskType::GATHER, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); inventoryB->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE); } for (const auto& tradeItem : m_ItemsB) { auto* itemToRemove = inventoryB->FindItemById(tradeItem.itemId); if (itemToRemove) itemToRemove->SetCount(itemToRemove->GetCount() - tradeItem.itemCount); - missionsB->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); + missionsB->Progress(eMissionTaskType::GATHER, tradeItem.itemLot, LWOOBJID_EMPTY, "", -tradeItem.itemCount); inventoryA->AddItem(tradeItem.itemLot, tradeItem.itemCount, eLootSourceType::LOOT_SOURCE_TRADE); } diff --git a/dGame/dComponents/AchievementCacheKey.h b/dGame/dComponents/AchievementCacheKey.h index d8892197..398e0231 100644 --- a/dGame/dComponents/AchievementCacheKey.h +++ b/dGame/dComponents/AchievementCacheKey.h @@ -1,3 +1,5 @@ +#include "eMissionTaskType.h" + #ifndef __ACHIEVEMENTCACHEKEY__H__ #define __ACHIEVEMENTCACHEKEY__H__ @@ -6,7 +8,7 @@ public: AchievementCacheKey() { targets = ""; value = 0; - type = MissionTaskType::MISSION_TASK_TYPE_UNKNOWN; + type = eMissionTaskType::UNKNOWN; }; bool operator==(const AchievementCacheKey& point) const { @@ -14,15 +16,15 @@ public: }; void SetTargets(const std::string value) { this->targets = value; }; void SetValue(uint32_t value) { this->value = value; }; - void SetType(MissionTaskType value) { this->type = value; }; + void SetType(eMissionTaskType value) { this->type = value; }; std::string GetTargets() const { return this->targets; }; uint32_t GetValue() const { return this->value; }; - MissionTaskType GetType() const { return this->type; }; + eMissionTaskType GetType() const { return this->type; }; private: std::string targets; uint32_t value; - MissionTaskType type; + eMissionTaskType type; }; diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 1455ce58..4763c863 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -32,6 +32,7 @@ #include "InventoryComponent.h" #include "dZoneManager.h" #include "WorldConfig.h" +#include "eMissionTaskType.h" DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_iArmor = 0; @@ -467,9 +468,9 @@ bool DestroyableComponent::IsKnockbackImmune() const { if (characterComponent != nullptr && inventoryComponent != nullptr && characterComponent->GetCurrentActivity() == eGameActivities::ACTIVITY_QUICKBUILDING) { const auto hasPassive = inventoryComponent->HasAnyPassive({ - ItemSetPassiveAbilityID::EngineerRank2, ItemSetPassiveAbilityID::EngineerRank3, - ItemSetPassiveAbilityID::SummonerRank2, ItemSetPassiveAbilityID::SummonerRank3, - ItemSetPassiveAbilityID::InventorRank2, ItemSetPassiveAbilityID::InventorRank3, + eItemSetPassiveAbilityID::EngineerRank2, eItemSetPassiveAbilityID::EngineerRank3, + eItemSetPassiveAbilityID::SummonerRank2, eItemSetPassiveAbilityID::SummonerRank3, + eItemSetPassiveAbilityID::InventorRank2, eItemSetPassiveAbilityID::InventorRank3, }, 5); if (hasPassive) { @@ -736,12 +737,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType if (memberMissions == nullptr) continue; - memberMissions->Progress(MissionTaskType::MISSION_TASK_TYPE_SMASH, m_Parent->GetLOT()); - memberMissions->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, m_Parent->GetLOT(), skillID); + memberMissions->Progress(eMissionTaskType::SMASH, m_Parent->GetLOT()); + memberMissions->Progress(eMissionTaskType::USE_SKILL, m_Parent->GetLOT(), skillID); } } else { - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_SMASH, m_Parent->GetLOT()); - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, m_Parent->GetLOT(), skillID); + missions->Progress(eMissionTaskType::SMASH, m_Parent->GetLOT()); + missions->Progress(eMissionTaskType::USE_SKILL, m_Parent->GetLOT(), skillID); } } } diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index e5ff2f2a..8925554e 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -28,6 +28,7 @@ #include "eItemType.h" #include "eUnequippableActiveType.h" #include "CppScripts.h" +#include "eMissionTaskType.h" InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) { this->m_Dirty = true; @@ -196,7 +197,7 @@ void InventoryComponent::AddItem( auto* item = new Item(lot, inventory, slot, count, config, parent, showFlyingLoot, isModMoveAndEquip, subKey, bound, lootSourceType); if (missions != nullptr && !IsTransferInventory(inventoryType)) { - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, lot, LWOOBJID_EMPTY, "", count, IsTransferInventory(inventorySourceType)); + missions->Progress(eMissionTaskType::GATHER, lot, LWOOBJID_EMPTY, "", count, IsTransferInventory(inventorySourceType)); } return; @@ -284,7 +285,7 @@ void InventoryComponent::AddItem( } if (missions != nullptr && !IsTransferInventory(inventoryType)) { - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, lot, LWOOBJID_EMPTY, "", count - outOfSpace, IsTransferInventory(inventorySourceType)); + missions->Progress(eMissionTaskType::GATHER, lot, LWOOBJID_EMPTY, "", count - outOfSpace, IsTransferInventory(inventorySourceType)); } } @@ -373,7 +374,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in if (missionComponent != nullptr) { if (IsTransferInventory(inventory)) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, lot, LWOOBJID_EMPTY, "", -static_cast<int32_t>(count)); + missionComponent->Progress(eMissionTaskType::GATHER, lot, LWOOBJID_EMPTY, "", -static_cast<int32_t>(count)); } } } @@ -841,9 +842,9 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { const auto type = static_cast<eItemType>(item->GetInfo().itemType); - if (!building && (item->GetLot() == 6086 || type == eItemType::ITEM_TYPE_LOOT_MODEL || type == eItemType::ITEM_TYPE_VEHICLE)) return; + if (!building && (item->GetLot() == 6086 || type == eItemType::LOOT_MODEL || type == eItemType::VEHICLE)) return; - if (type != eItemType::ITEM_TYPE_LOOT_MODEL && type != eItemType::ITEM_TYPE_MODEL) { + if (type != eItemType::LOOT_MODEL && type != eItemType::MODEL) { if (!item->GetBound() && !item->GetPreconditionExpression()->Check(m_Parent)) { return; } @@ -1202,14 +1203,14 @@ void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger, En } } -bool InventoryComponent::HasAnyPassive(const std::vector<ItemSetPassiveAbilityID>& passiveIDs, int32_t equipmentRequirement) const { +bool InventoryComponent::HasAnyPassive(const std::vector<eItemSetPassiveAbilityID>& passiveIDs, int32_t equipmentRequirement) const { for (auto* set : m_Itemsets) { if (set->GetEquippedCount() < equipmentRequirement) { continue; } // Check if the set has any of the passive abilities - if (std::find(passiveIDs.begin(), passiveIDs.end(), static_cast<ItemSetPassiveAbilityID>(set->GetID())) != passiveIDs.end()) { + if (std::find(passiveIDs.begin(), passiveIDs.end(), static_cast<eItemSetPassiveAbilityID>(set->GetID())) != passiveIDs.end()) { return true; } } @@ -1285,15 +1286,15 @@ void InventoryComponent::RemoveDatabasePet(LWOOBJID id) { BehaviorSlot InventoryComponent::FindBehaviorSlot(const eItemType type) { switch (type) { - case eItemType::ITEM_TYPE_HAT: + case eItemType::HAT: return BehaviorSlot::Head; - case eItemType::ITEM_TYPE_NECK: + case eItemType::NECK: return BehaviorSlot::Neck; - case eItemType::ITEM_TYPE_LEFT_HAND: + case eItemType::LEFT_HAND: return BehaviorSlot::Offhand; - case eItemType::ITEM_TYPE_RIGHT_HAND: + case eItemType::RIGHT_HAND: return BehaviorSlot::Primary; - case eItemType::ITEM_TYPE_CONSUMABLE: + case eItemType::CONSUMABLE: return BehaviorSlot::Consumable; default: return BehaviorSlot::Invalid; @@ -1343,7 +1344,7 @@ std::vector<uint32_t> InventoryComponent::FindBuffs(Item* item, bool castOnEquip } if (missions != nullptr && castOnEquip) { - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, result.skillID); + missions->Progress(eMissionTaskType::USE_SKILL, result.skillID); } // If item is not a proxy, add its buff to the added buffs. diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index f63a8d70..b660de15 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -17,7 +17,7 @@ #include "DatabasePet.h" #include "Component.h" #include "ItemSetPassiveAbility.h" -#include "ItemSetPassiveAbilityID.h" +#include "eItemSetPassiveAbilityID.h" #include "PossessorComponent.h" #include "eInventoryType.h" @@ -291,7 +291,7 @@ public: * @param equipmentRequirement the number of equipment required to be allowed to have the ability * @return if the entity has any of the passed passive abilities equipped */ - bool HasAnyPassive(const std::vector<ItemSetPassiveAbilityID>& passiveIDs, int32_t equipmentRequirement) const; + bool HasAnyPassive(const std::vector<eItemSetPassiveAbilityID>& passiveIDs, int32_t equipmentRequirement) const; /** * Despawns the currently active pet, if any @@ -354,14 +354,14 @@ public: /** * Call this when you equip an item. This calls OnFactionTriggerItemEquipped for any scripts found on the items. - * + * * @param equippedItem The item script to lookup and call equip on */ void EquipScripts(Item* equippedItem); - + /** * Call this when you unequip an item. This calls OnFactionTriggerItemUnequipped for any scripts found on the items. - * + * * @param unequippedItem The item script to lookup and call unequip on */ void UnequipScripts(Item* unequippedItem); diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index 2ef6c2f6..cbae7f9f 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -18,6 +18,7 @@ #include "Mail.h" #include "MissionPrerequisites.h" #include "AchievementCacheKey.h" +#include "eMissionState.h" // MARK: Mission Component @@ -53,11 +54,11 @@ Mission* MissionComponent::GetMission(const uint32_t missionId) const { } -MissionState MissionComponent::GetMissionState(const uint32_t missionId) const { +eMissionState MissionComponent::GetMissionState(const uint32_t missionId) const { auto* mission = GetMission(missionId); if (mission == nullptr) { - return CanAccept(missionId) ? MissionState::MISSION_STATE_AVAILABLE : MissionState::MISSION_STATE_UNKNOWN; + return CanAccept(missionId) ? eMissionState::AVAILABLE : eMissionState::UNKNOWN; } return mission->GetMissionState(); @@ -143,7 +144,7 @@ void MissionComponent::RemoveMission(uint32_t missionId) { m_Missions.erase(missionId); } -void MissionComponent::Progress(MissionTaskType type, int32_t value, LWOOBJID associate, const std::string& targets, int32_t count, bool ignoreAchievements) { +void MissionComponent::Progress(eMissionTaskType type, int32_t value, LWOOBJID associate, const std::string& targets, int32_t count, bool ignoreAchievements) { for (const auto& pair : m_Missions) { auto* mission = pair.second; @@ -215,7 +216,7 @@ void MissionComponent::ForceProgressTaskType(const uint32_t missionId, const uin } for (auto* element : mission->GetTasks()) { - if (element->GetType() != static_cast<MissionTaskType>(taskType)) continue; + if (element->GetType() != static_cast<eMissionTaskType>(taskType)) continue; element->AddProgress(value); } @@ -253,7 +254,7 @@ void MissionComponent::ForceProgressValue(uint32_t missionId, uint32_t taskType, } for (auto* element : mission->GetTasks()) { - if (element->GetType() != static_cast<MissionTaskType>(taskType) || !element->InAllTargets(value)) continue; + if (element->GetType() != static_cast<eMissionTaskType>(taskType) || !element->InAllTargets(value)) continue; element->AddProgress(1); } @@ -281,7 +282,7 @@ bool MissionComponent::GetMissionInfo(uint32_t missionId, CDMissions& result) { #define MISSION_NEW_METHOD -bool MissionComponent::LookForAchievements(MissionTaskType type, int32_t value, bool progress, LWOOBJID associate, const std::string& targets, int32_t count) { +bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, bool progress, LWOOBJID associate, const std::string& targets, int32_t count) { #ifdef MISSION_NEW_METHOD // Query for achievments, using the cache const auto& result = QueryAchievements(type, value, targets); @@ -390,7 +391,7 @@ bool MissionComponent::LookForAchievements(MissionTaskType type, int32_t value, #endif } -const std::vector<uint32_t>& MissionComponent::QueryAchievements(MissionTaskType type, int32_t value, const std::string targets) { +const std::vector<uint32_t>& MissionComponent::QueryAchievements(eMissionTaskType type, int32_t value, const std::string targets) { // Create a hash which represent this query for achievements AchievementCacheKey toFind; toFind.SetType(type); @@ -484,7 +485,7 @@ bool MissionComponent::RequiresItem(const LOT lot) { } for (auto* task : mission->GetTasks()) { - if (task->IsComplete() || task->GetType() != MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION) { + if (task->IsComplete() || task->GetType() != eMissionTaskType::GATHER) { continue; } @@ -496,7 +497,7 @@ bool MissionComponent::RequiresItem(const LOT lot) { } } - const auto required = LookForAchievements(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, lot, false); + const auto required = LookForAchievements(eMissionTaskType::GATHER, lot, false); return required; } diff --git a/dGame/dComponents/MissionComponent.h b/dGame/dComponents/MissionComponent.h index a3e39a88..231b3321 100644 --- a/dGame/dComponents/MissionComponent.h +++ b/dGame/dComponents/MissionComponent.h @@ -19,11 +19,11 @@ class AchievementCacheKey; -/** - * The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for - * progression of each of the mission task types (see MissionTaskType). - */ -class MissionComponent: public Component + /** + * The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for + * progression of each of the mission task types (see eMissionTaskType). + */ +class MissionComponent : public Component { public: static const uint32_t ComponentType = COMPONENT_TYPE_MISSION; @@ -52,7 +52,7 @@ public: * @param missionId the ID of the mission to get the mission state for * @return the mission state of the mission specified by the ID */ - MissionState GetMissionState(uint32_t missionId) const; + eMissionState GetMissionState(uint32_t missionId) const; /** * Checks if the entity has all the requirements for accepting the mission specified by the ID. @@ -93,7 +93,7 @@ public: * @param count the number to progress by, for example the number of items * @param ignoreAchievements do not progress achievements */ - void Progress(MissionTaskType type, int32_t value, LWOOBJID associate = 0, const std::string& targets = "", int32_t count = 1, bool ignoreAchievements = false); + void Progress(eMissionTaskType type, int32_t value, LWOOBJID associate = 0, const std::string& targets = "", int32_t count = 1, bool ignoreAchievements = false); /** * Forces progression for a mission and task, ignoring checks @@ -140,7 +140,7 @@ public: * @param count the number of values to progress by (differs by task type) * @return true if a achievement was accepted, false otherwise */ - bool LookForAchievements(MissionTaskType type, int32_t value, bool progress = true, LWOOBJID associate = LWOOBJID_EMPTY, const std::string& targets = "", int32_t count = 1); + bool LookForAchievements(eMissionTaskType type, int32_t value, bool progress = true, LWOOBJID associate = LWOOBJID_EMPTY, const std::string& targets = "", int32_t count = 1); /** * Checks if there's a mission active that requires the collection of the specified LOT @@ -188,7 +188,7 @@ private: * @param targets optional targets to progress with * @return list of mission IDs (achievements) that can be progressed for the given parameters */ - static const std::vector<uint32_t>& QueryAchievements(MissionTaskType type, int32_t value, const std::string targets); + static const std::vector<uint32_t>& QueryAchievements(eMissionTaskType type, int32_t value, const std::string targets); /** * As achievements can be hard to query, we here store a list of all the mission IDs that can be unlocked for a diff --git a/dGame/dComponents/MissionOfferComponent.cpp b/dGame/dComponents/MissionOfferComponent.cpp index 2f2ed0f0..f8446868 100644 --- a/dGame/dComponents/MissionOfferComponent.cpp +++ b/dGame/dComponents/MissionOfferComponent.cpp @@ -14,6 +14,7 @@ #include "dLogger.h" #include "Game.h" #include "MissionPrerequisites.h" +#include "eMissionState.h" OfferedMission::OfferedMission(const uint32_t missionId, const bool offersMission, const bool acceptsMission) { this->missionId = missionId; @@ -170,10 +171,10 @@ void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifi for (const auto sample : randomMissionPool) { const auto state = missionComponent->GetMissionState(sample); - if (state == MissionState::MISSION_STATE_ACTIVE || - state == MissionState::MISSION_STATE_COMPLETE_ACTIVE || - state == MissionState::MISSION_STATE_READY_TO_COMPLETE || - state == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE || + if (state == eMissionState::ACTIVE || + state == eMissionState::COMPLETE_ACTIVE || + state == eMissionState::READY_TO_COMPLETE || + state == eMissionState::COMPLETE_READY_TO_COMPLETE || sample == specifiedMissionId) { mission = missionComponent->GetMission(sample); diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 771a9cc1..5549f952 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -21,6 +21,8 @@ #include "dChatFilter.h" #include "Database.h" #include "EntityInfo.h" +#include "eMissionTaskType.h" + std::unordered_map<LOT, PetComponent::PetPuzzleData> PetComponent::buildCache{}; std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::currentActivities{}; @@ -602,7 +604,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { auto* missionComponent = tamer->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_PET_TAMING, m_Parent->GetLOT()); + missionComponent->Progress(eMissionTaskType::PET_TAMING, m_Parent->GetLOT()); } SetStatus(1); diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 8d23c17e..ce2c8e5e 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -18,6 +18,7 @@ #include "RocketLaunchpadControlComponent.h" #include "PropertyEntranceComponent.h" #include "InventoryComponent.h" +#include "eMissionTaskType.h" #include <vector> #include "CppScripts.h" @@ -404,7 +405,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N }); // Progress place model missions auto missionComponent = entity->GetComponent<MissionComponent>(); - if (missionComponent != nullptr) missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_PLACE_MODEL, 0); + if (missionComponent != nullptr) missionComponent->Progress(eMissionTaskType::PLACE_MODEL, 0); } void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int deleteReason) { diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index f64dbc15..4b27ac0f 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -15,13 +15,14 @@ #include "Player.h" #include "PossessableComponent.h" #include "PossessorComponent.h" -#include "RacingTaskParam.h" +#include "eRacingTaskParam.h" #include "Spawner.h" #include "VehiclePhysicsComponent.h" #include "dServer.h" #include "dZoneManager.h" #include "dConfig.h" #include "Loot.h" +#include "eMissionTaskType.h" #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 @@ -395,18 +396,18 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, if (missionComponent == nullptr) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, 0, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COMPETED_IN_RACE); // Progress task for competing in a race - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, data->smashedTimes, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SAFE_DRIVER); // Finish a race without being smashed. + missionComponent->Progress(eMissionTaskType::RACING, 0, (LWOOBJID)eRacingTaskParam::COMPETED_IN_RACE); // Progress task for competing in a race + missionComponent->Progress(eMissionTaskType::RACING, data->smashedTimes, (LWOOBJID)eRacingTaskParam::SAFE_DRIVER); // Finish a race without being smashed. // If solo racing is enabled OR if there are 3 players in the race, progress placement tasks. if (m_SoloRacing || m_LoadedPlayers > 2) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, data->finished, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_FINISH_WITH_PLACEMENT); // Finish in 1st place on a race + missionComponent->Progress(eMissionTaskType::RACING, data->finished, (LWOOBJID)eRacingTaskParam::FINISH_WITH_PLACEMENT); // Finish in 1st place on a race if (data->finished == 1) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks. - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_WIN_RACE_IN_WORLD); // Finished first place in specific world. + missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks. + missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::WIN_RACE_IN_WORLD); // Finished first place in specific world. } if (data->finished == m_LoadedPlayers) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_LAST_PLACE_FINISH); // Finished first place in specific world. + missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world. } } } else if (id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") { @@ -828,7 +829,7 @@ void RacingControlComponent::Update(float deltaTime) { if (missionComponent != nullptr) { // Progress lap time tasks - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, (lapTime) * 1000, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_LAP_TIME); + missionComponent->Progress(eMissionTaskType::RACING, (lapTime) * 1000, (LWOOBJID)eRacingTaskParam::LAP_TIME); if (player.lap == 3) { m_Finished++; @@ -844,7 +845,7 @@ void RacingControlComponent::Update(float deltaTime) { raceTime, raceTime * 1000); // Entire race time - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, (raceTime) * 1000, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_TOTAL_TRACK_TIME); + missionComponent->Progress(eMissionTaskType::RACING, (raceTime) * 1000, (LWOOBJID)eRacingTaskParam::TOTAL_TRACK_TIME); auto* characterComponent = playerEntity->GetComponent<CharacterComponent>(); if (characterComponent != nullptr) { diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 83ae818e..bf7bd3e5 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -7,7 +7,7 @@ #include "dLogger.h" #include "CharacterComponent.h" #include "MissionComponent.h" -#include "MissionTaskType.h" +#include "eMissionTaskType.h" #include "dServer.h" #include "PacketUtils.h" @@ -473,12 +473,12 @@ void RebuildComponent::CompleteRebuild(Entity* user) { auto* member = EntityManager::Instance()->GetEntity(memberId); if (member) { auto* missionComponent = member->GetComponent<MissionComponent>(); - if (missionComponent) missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ACTIVITY, m_ActivityId); + if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId); } } } else{ auto* missionComponent = builder->GetComponent<MissionComponent>(); - if (missionComponent) missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ACTIVITY, m_ActivityId); + if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId); } LootGenerator::Instance().DropActivityLoot(builder, m_Parent, m_ActivityId, 1); } diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index a03dddbe..067446e7 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -20,6 +20,7 @@ #include "DestroyableComponent.h" #include "dMessageIdentifiers.h" #include "Loot.h" +#include "eMissionTaskType.h" ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { m_ActivityID = activityID; @@ -552,7 +553,7 @@ void ActivityInstance::StartZone() { void ActivityInstance::RewardParticipant(Entity* participant) { auto* missionComponent = participant->GetComponent<MissionComponent>(); if (missionComponent) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ACTIVITY, m_ActivityInfo.ActivityID); + missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityInfo.ActivityID); } // First, get the activity data diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index a91a1e2a..16942ecc 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -31,6 +31,7 @@ #include "StartSkill.h" #include "EchoStartSkill.h" #include "EchoSyncSkill.h" +#include "eMissionTaskType.h" using namespace std; @@ -281,7 +282,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System MissionComponent* comp = entity->GetComponent<MissionComponent>(); if (comp) { - comp->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, startSkill.skillID); + comp->Progress(eMissionTaskType::USE_SKILL, startSkill.skillID); } CDSkillBehaviorTable* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 9aafd0fc..58d72d3c 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -31,7 +31,9 @@ #include "LeaderboardManager.h" #include "AMFFormat.h" #include "Loot.h" -#include "RacingTaskParam.h" +#include "eRacingTaskParam.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" #include <sstream> #include <future> @@ -3264,7 +3266,7 @@ void GameMessages::HandleClientTradeRequest(RakNet::BitStream* inStream, Entity* // Check if the player has restricted trade access auto* character = entity->GetCharacter(); - if (character->HasPermission(PermissionMap::RestrictedTradeAccess)) { + if (character->HasPermission(ePermissionMap::RestrictedTradeAccess)) { // Send a message to the player ChatPackets::SendSystemMessage( sysAddr, @@ -3284,7 +3286,7 @@ void GameMessages::HandleClientTradeRequest(RakNet::BitStream* inStream, Entity* if (invitee != nullptr && invitee->IsPlayer()) { character = invitee->GetCharacter(); - if (character->HasPermission(PermissionMap::RestrictedTradeAccess)) { + if (character->HasPermission(ePermissionMap::RestrictedTradeAccess)) { // Send a message to the player ChatPackets::SendSystemMessage( sysAddr, @@ -4707,25 +4709,10 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti LOT tokenId = -1; - if (missionComponent->GetMissionState(545) == MissionState::MISSION_STATE_COMPLETE) // "Join Assembly!" - { - tokenId = 8318; // "Assembly Token" - } - - if (missionComponent->GetMissionState(556) == MissionState::MISSION_STATE_COMPLETE) // "Join Venture League!" - { - tokenId = 8321; // "Venture League Token" - } - - if (missionComponent->GetMissionState(567) == MissionState::MISSION_STATE_COMPLETE) // "Join The Sentinels!" - { - tokenId = 8319; // "Sentinels Token" - } - - if (missionComponent->GetMissionState(578) == MissionState::MISSION_STATE_COMPLETE) // "Join Paradox!" - { - tokenId = 8320; // "Paradox Token" - } + if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) tokenId = 8318; // "Assembly Token" + if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) tokenId = 8321; // "Venture League Token" + if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) tokenId = 8319; // "Sentinels Token" + if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) tokenId = 8320; // "Paradox Token" const uint32_t altCurrencyCost = itemComp.commendationCost * count; @@ -5031,8 +5018,8 @@ void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, if (missionComponent == nullptr) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MISSION_INTERACTION, interactedObject->GetLOT(), interactedObject->GetObjectID()); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_NON_MISSION_INTERACTION, interactedObject->GetLOT(), interactedObject->GetObjectID()); + missionComponent->Progress(eMissionTaskType::TALK_TO_NPC, interactedObject->GetLOT(), interactedObject->GetObjectID()); + missionComponent->Progress(eMissionTaskType::INTERACT, interactedObject->GetLOT(), interactedObject->GetObjectID()); } void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) { @@ -5059,7 +5046,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (targetEntity != nullptr) { targetEntity->OnEmoteReceived(emoteID, entity); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_EMOTE, emoteID, targetID); + missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, targetID); } } else { Game::logger->LogDebug("GameMessages", "Target ID is empty, using backup"); @@ -5071,7 +5058,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (Vector3::DistanceSquared(scripted->GetPosition(), referencePoint) > 5.0f * 5.0f) continue; scripted->OnEmoteReceived(emoteID, entity); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_EMOTE, emoteID, scripted->GetObjectID()); + missionComponent->Progress(eMissionTaskType::EMOTE, emoteID, scripted->GetObjectID()); } } @@ -5163,7 +5150,7 @@ void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* e void GameMessages::HandleMissionDialogOK(RakNet::BitStream* inStream, Entity* entity) { bool bIsComplete{}; - MissionState iMissionState{}; + eMissionState iMissionState{}; int missionID{}; LWOOBJID responder{}; Entity* player = nullptr; @@ -5185,9 +5172,9 @@ void GameMessages::HandleMissionDialogOK(RakNet::BitStream* inStream, Entity* en return; } - if (iMissionState == MissionState::MISSION_STATE_AVAILABLE || iMissionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE) { + if (iMissionState == eMissionState::AVAILABLE || iMissionState == eMissionState::COMPLETE_AVAILABLE) { missionComponent->AcceptMission(missionID); - } else if (iMissionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || iMissionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) { + } else if (iMissionState == eMissionState::READY_TO_COMPLETE || iMissionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { missionComponent->CompleteMission(missionID); } } @@ -5219,7 +5206,7 @@ void GameMessages::HandleHasBeenCollected(RakNet::BitStream* inStream, Entity* e MissionComponent* missionComponent = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); if (missionComponent) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ENVIRONMENT, entity->GetLOT(), entity->GetObjectID()); + missionComponent->Progress(eMissionTaskType::COLLECTION, entity->GetLOT(), entity->GetObjectID()); } } @@ -5438,7 +5425,7 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, En auto* missionComponent = entity->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, item->GetLot(), LWOOBJID_EMPTY, "", -iStackCount); + missionComponent->Progress(eMissionTaskType::GATHER, item->GetLot(), LWOOBJID_EMPTY, "", -iStackCount); } } } @@ -5593,8 +5580,8 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* if (entity->GetLOT() != 9980 || Game::server->GetZoneID() != 1200) { if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, entity->GetLOT(), entity->GetObjectID()); - if (count >= 7 && everyPieceSwapped) missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, LWOOBJID_EMPTY, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_MODULAR_BUILDING); + missionComponent->Progress(eMissionTaskType::SCRIPT, entity->GetLOT(), entity->GetObjectID()); + if (count >= 7 && everyPieceSwapped) missionComponent->Progress(eMissionTaskType::RACING, LWOOBJID_EMPTY, (LWOOBJID)eRacingTaskParam::MODULAR_BUILDING); } } } @@ -5826,7 +5813,7 @@ void GameMessages::HandleClientItemConsumed(RakNet::BitStream* inStream, Entity* auto* missions = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); if (missions != nullptr) { - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_FOOD, itemLot); + missions->Progress(eMissionTaskType::USE_ITEM, itemLot); } } diff --git a/dGame/dInventory/Inventory.cpp b/dGame/dInventory/Inventory.cpp index 990b08f3..69a643ae 100644 --- a/dGame/dInventory/Inventory.cpp +++ b/dGame/dInventory/Inventory.cpp @@ -231,41 +231,42 @@ eInventoryType Inventory::FindInventoryTypeForLot(const LOT lot) { const auto itemType = static_cast<eItemType>(itemComponent.itemType); switch (itemType) { - case eItemType::ITEM_TYPE_BRICK: + case eItemType::BRICK: return BRICKS; - case eItemType::ITEM_TYPE_BEHAVIOR: + case eItemType::BEHAVIOR: return BEHAVIORS; - case eItemType::ITEM_TYPE_PROPERTY: + case eItemType::PROPERTY: return PROPERTY_DEEDS; - case eItemType::ITEM_TYPE_MODEL: - case eItemType::ITEM_TYPE_VEHICLE: - case eItemType::ITEM_TYPE_LOOT_MODEL: - case eItemType::ITEM_TYPE_MOUNT: + case eItemType::MODEL: + case eItemType::VEHICLE: + case eItemType::LOOT_MODEL: + case eItemType::LUP_MODEL: + case eItemType::MOUNT: return MODELS; - case eItemType::ITEM_TYPE_HAT: - case eItemType::ITEM_TYPE_HAIR: - case eItemType::ITEM_TYPE_NECK: - case eItemType::ITEM_TYPE_LEFT_HAND: - case eItemType::ITEM_TYPE_RIGHT_HAND: - case eItemType::ITEM_TYPE_LEGS: - case eItemType::ITEM_TYPE_LEFT_TRINKET: - case eItemType::ITEM_TYPE_RIGHT_TRINKET: - case eItemType::ITEM_TYPE_COLLECTIBLE: - case eItemType::ITEM_TYPE_CONSUMABLE: - case eItemType::ITEM_TYPE_CHEST: - case eItemType::ITEM_TYPE_EGG: - case eItemType::ITEM_TYPE_PET_FOOD: - case eItemType::ITEM_TYPE_PET_INVENTORY_ITEM: - case eItemType::ITEM_TYPE_PACKAGE: - case eItemType::ITEM_TYPE_CURRENCY: + case eItemType::HAT: + case eItemType::HAIR: + case eItemType::NECK: + case eItemType::LEFT_HAND: + case eItemType::RIGHT_HAND: + case eItemType::LEGS: + case eItemType::LEFT_TRINKET: + case eItemType::RIGHT_TRINKET: + case eItemType::COLLECTIBLE: + case eItemType::CONSUMABLE: + case eItemType::CHEST: + case eItemType::EGG: + case eItemType::PET_FOOD: + case eItemType::PET_INVENTORY_ITEM: + case eItemType::PACKAGE: + return ITEMS; - case eItemType::ITEM_TYPE_QUEST_OBJECT: - case eItemType::ITEM_TYPE_UNKNOWN: + case eItemType::QUEST_OBJECT: + case eItemType::UNKNOWN: default: return QUEST; } diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index d6721bdd..2a054ae8 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -76,7 +76,7 @@ Item::Item( const auto type = static_cast<eItemType>(info->itemType); - if (type == eItemType::ITEM_TYPE_MOUNT) { + if (type == eItemType::MOUNT) { id = GeneralUtils::SetBit(id, OBJECT_BIT_CLIENT); } @@ -283,10 +283,10 @@ void Item::UseNonEquip(Item* item) { } const auto type = static_cast<eItemType>(info->itemType); - if (type == eItemType::ITEM_TYPE_MOUNT) { + if (type == eItemType::MOUNT) { playerInventoryComponent->HandlePossession(this); // TODO Check if mounts are allowed to be spawned - } else if (type == eItemType::ITEM_TYPE_PET_INVENTORY_ITEM && subKey != LWOOBJID_EMPTY) { + } else if (type == eItemType::PET_INVENTORY_ITEM && subKey != LWOOBJID_EMPTY) { const auto& databasePet = playerInventoryComponent->GetDatabasePet(subKey); if (databasePet.lot != LOT_NULL) { playerInventoryComponent->SpawnPet(this); diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index 1c67f6d6..e246f9f7 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -6,6 +6,7 @@ #include "CDClientDatabase.h" #include "Game.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" #include <algorithm> ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) { @@ -130,7 +131,7 @@ void ItemSet::OnEquip(const LOT lot) { const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, skill); + missionComponent->Progress(eMissionTaskType::USE_SKILL, skill); skillComponent->HandleUnmanaged(behaviorId, m_InventoryComponent->GetParent()->GetObjectID()); } diff --git a/dGame/dInventory/ItemSetPassiveAbility.cpp b/dGame/dInventory/ItemSetPassiveAbility.cpp index 83db4405..bf7c19cb 100644 --- a/dGame/dInventory/ItemSetPassiveAbility.cpp +++ b/dGame/dInventory/ItemSetPassiveAbility.cpp @@ -3,7 +3,7 @@ #include "DestroyableComponent.h" #include "SkillComponent.h" #include "ItemSet.h" -#include "ItemSetPassiveAbilityID.h" +#include "eItemSetPassiveAbilityID.h" ItemSetPassiveAbility::ItemSetPassiveAbility(PassiveAbilityTrigger trigger, Entity* parent, ItemSet* itemSet) { m_Trigger = trigger; @@ -46,31 +46,31 @@ void ItemSetPassiveAbility::Activate(Entity* target) { EntityManager::Instance()->SerializeEntity(m_Parent); - const auto id = static_cast<ItemSetPassiveAbilityID>(m_ItemSet->GetID()); + const auto id = static_cast<eItemSetPassiveAbilityID>(m_ItemSet->GetID()); const auto parentID = m_Parent->GetObjectID(); const auto equippedCount = m_ItemSet->GetEquippedCount(); switch (id) { // Assembly - case ItemSetPassiveAbilityID::InventorRank1: - case ItemSetPassiveAbilityID::SummonerRank1: - case ItemSetPassiveAbilityID::EngineerRank1: { + case eItemSetPassiveAbilityID::InventorRank1: + case eItemSetPassiveAbilityID::SummonerRank1: + case eItemSetPassiveAbilityID::EngineerRank1: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(394, 4401, parentID); break; } - case ItemSetPassiveAbilityID::InventorRank2: - case ItemSetPassiveAbilityID::SummonerRank2: - case ItemSetPassiveAbilityID::EngineerRank2: { + case eItemSetPassiveAbilityID::InventorRank2: + case eItemSetPassiveAbilityID::SummonerRank2: + case eItemSetPassiveAbilityID::EngineerRank2: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(581, 9433, parentID); break; } - case ItemSetPassiveAbilityID::InventorRank3: - case ItemSetPassiveAbilityID::SummonerRank3: - case ItemSetPassiveAbilityID::EngineerRank3: { + case eItemSetPassiveAbilityID::InventorRank3: + case eItemSetPassiveAbilityID::SummonerRank3: + case eItemSetPassiveAbilityID::EngineerRank3: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(582, 9435, parentID); @@ -78,57 +78,57 @@ void ItemSetPassiveAbility::Activate(Entity* target) { } // Sentinel - case ItemSetPassiveAbilityID::KnightRank1: { + case eItemSetPassiveAbilityID::KnightRank1: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(559, 8884, parentID); break; } - case ItemSetPassiveAbilityID::KnightRank2: { + case eItemSetPassiveAbilityID::KnightRank2: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(560, 8885, parentID); break; } - case ItemSetPassiveAbilityID::KnightRank3: { + case eItemSetPassiveAbilityID::KnightRank3: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(561, 8890, parentID); break; } - case ItemSetPassiveAbilityID::SpaceRangerRank1: { + case eItemSetPassiveAbilityID::SpaceRangerRank1: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(1101, 24612, parentID); break; } - case ItemSetPassiveAbilityID::SpaceRangerRank2: { + case eItemSetPassiveAbilityID::SpaceRangerRank2: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(1102, 24617, parentID); break; } - case ItemSetPassiveAbilityID::SpaceRangerRank3: { + case eItemSetPassiveAbilityID::SpaceRangerRank3: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(1103, 24622, parentID); break; } - case ItemSetPassiveAbilityID::SamuraiRank1: { + case eItemSetPassiveAbilityID::SamuraiRank1: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(562, 8899, parentID); break; } - case ItemSetPassiveAbilityID::SamuraiRank2: { + case eItemSetPassiveAbilityID::SamuraiRank2: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(563, 8904, parentID); break; } - case ItemSetPassiveAbilityID::SamuraiRank3: { + case eItemSetPassiveAbilityID::SamuraiRank3: { if (equippedCount < 4) return; m_Cooldown = 11.0f; skillComponent->CalculateBehavior(564, 8909, parentID); @@ -143,47 +143,47 @@ void ItemSetPassiveAbility::Activate(Entity* target) { std::vector<ItemSetPassiveAbility> ItemSetPassiveAbility::FindAbilities(uint32_t itemSetID, Entity* parent, ItemSet* itemSet) { std::vector<ItemSetPassiveAbility> abilities; - switch (static_cast<ItemSetPassiveAbilityID>(itemSetID)) { + switch (static_cast<eItemSetPassiveAbilityID>(itemSetID)) { // Assembly - case ItemSetPassiveAbilityID::SummonerRank1: - case ItemSetPassiveAbilityID::SummonerRank2: - case ItemSetPassiveAbilityID::SummonerRank3: - case ItemSetPassiveAbilityID::InventorRank1: - case ItemSetPassiveAbilityID::InventorRank2: - case ItemSetPassiveAbilityID::InventorRank3: - case ItemSetPassiveAbilityID::EngineerRank1: - case ItemSetPassiveAbilityID::EngineerRank2: - case ItemSetPassiveAbilityID::EngineerRank3: { + case eItemSetPassiveAbilityID::SummonerRank1: + case eItemSetPassiveAbilityID::SummonerRank2: + case eItemSetPassiveAbilityID::SummonerRank3: + case eItemSetPassiveAbilityID::InventorRank1: + case eItemSetPassiveAbilityID::InventorRank2: + case eItemSetPassiveAbilityID::InventorRank3: + case eItemSetPassiveAbilityID::EngineerRank1: + case eItemSetPassiveAbilityID::EngineerRank2: + case eItemSetPassiveAbilityID::EngineerRank3: { abilities.emplace_back(PassiveAbilityTrigger::AssemblyImagination, parent, itemSet); break; } // Sentinel - case ItemSetPassiveAbilityID::KnightRank1: - case ItemSetPassiveAbilityID::KnightRank2: - case ItemSetPassiveAbilityID::KnightRank3: - case ItemSetPassiveAbilityID::SpaceRangerRank1: - case ItemSetPassiveAbilityID::SpaceRangerRank2: - case ItemSetPassiveAbilityID::SpaceRangerRank3: - case ItemSetPassiveAbilityID::SamuraiRank1: - case ItemSetPassiveAbilityID::SamuraiRank2: - case ItemSetPassiveAbilityID::SamuraiRank3: { + case eItemSetPassiveAbilityID::KnightRank1: + case eItemSetPassiveAbilityID::KnightRank2: + case eItemSetPassiveAbilityID::KnightRank3: + case eItemSetPassiveAbilityID::SpaceRangerRank1: + case eItemSetPassiveAbilityID::SpaceRangerRank2: + case eItemSetPassiveAbilityID::SpaceRangerRank3: + case eItemSetPassiveAbilityID::SamuraiRank1: + case eItemSetPassiveAbilityID::SamuraiRank2: + case eItemSetPassiveAbilityID::SamuraiRank3: { abilities.emplace_back(PassiveAbilityTrigger::SentinelArmor, parent, itemSet); abilities.emplace_back(PassiveAbilityTrigger::EnemySmashed, parent, itemSet); break; } // Paradox - case ItemSetPassiveAbilityID::BatLord: - case ItemSetPassiveAbilityID::SpaceMarauderRank1: - case ItemSetPassiveAbilityID::SpaceMarauderRank2: - case ItemSetPassiveAbilityID::SpaceMarauderRank3: - case ItemSetPassiveAbilityID::SorcererRank1: - case ItemSetPassiveAbilityID::SorcererRank2: - case ItemSetPassiveAbilityID::SorcererRank3: - case ItemSetPassiveAbilityID::ShinobiRank1: - case ItemSetPassiveAbilityID::ShinobiRank2: - case ItemSetPassiveAbilityID::ShinobiRank3: { + case eItemSetPassiveAbilityID::BatLord: + case eItemSetPassiveAbilityID::SpaceMarauderRank1: + case eItemSetPassiveAbilityID::SpaceMarauderRank2: + case eItemSetPassiveAbilityID::SpaceMarauderRank3: + case eItemSetPassiveAbilityID::SorcererRank1: + case eItemSetPassiveAbilityID::SorcererRank2: + case eItemSetPassiveAbilityID::SorcererRank3: + case eItemSetPassiveAbilityID::ShinobiRank1: + case eItemSetPassiveAbilityID::ShinobiRank2: + case eItemSetPassiveAbilityID::ShinobiRank3: { abilities.emplace_back(PassiveAbilityTrigger::EnemySmashed, parent, itemSet); break; @@ -205,110 +205,110 @@ void ItemSetPassiveAbility::OnEnemySmshed(Entity* target) { EntityManager::Instance()->SerializeEntity(m_Parent); - const auto id = static_cast<ItemSetPassiveAbilityID>(m_ItemSet->GetID()); + const auto id = static_cast<eItemSetPassiveAbilityID>(m_ItemSet->GetID()); const auto parentID = m_Parent->GetObjectID(); const auto equippedCount = m_ItemSet->GetEquippedCount(); switch (id) { // Bat Lord - case ItemSetPassiveAbilityID::BatLord: { + case eItemSetPassiveAbilityID::BatLord: { if (equippedCount < 5) return; destroyableComponent->Heal(3); break; } // Sentinel - case ItemSetPassiveAbilityID::KnightRank1: { + case eItemSetPassiveAbilityID::KnightRank1: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::KnightRank2: { + case eItemSetPassiveAbilityID::KnightRank2: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::KnightRank3: { + case eItemSetPassiveAbilityID::KnightRank3: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::SpaceRangerRank1: { + case eItemSetPassiveAbilityID::SpaceRangerRank1: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::SpaceRangerRank2: { + case eItemSetPassiveAbilityID::SpaceRangerRank2: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::SpaceRangerRank3: { + case eItemSetPassiveAbilityID::SpaceRangerRank3: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::SamuraiRank1: { + case eItemSetPassiveAbilityID::SamuraiRank1: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::SamuraiRank2: { + case eItemSetPassiveAbilityID::SamuraiRank2: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } - case ItemSetPassiveAbilityID::SamuraiRank3: { + case eItemSetPassiveAbilityID::SamuraiRank3: { if (equippedCount < 5) return; destroyableComponent->Repair(1); break; } // Paradox - case ItemSetPassiveAbilityID::SpaceMarauderRank1: { + case eItemSetPassiveAbilityID::SpaceMarauderRank1: { if (equippedCount < 4) return; destroyableComponent->Imagine(1); break; } - case ItemSetPassiveAbilityID::SpaceMarauderRank2: { + case eItemSetPassiveAbilityID::SpaceMarauderRank2: { if (equippedCount < 4) return; destroyableComponent->Imagine(2); break; } - case ItemSetPassiveAbilityID::SpaceMarauderRank3: { + case eItemSetPassiveAbilityID::SpaceMarauderRank3: { if (equippedCount < 4) return; destroyableComponent->Imagine(3); break; } - case ItemSetPassiveAbilityID::ShinobiRank1: { + case eItemSetPassiveAbilityID::ShinobiRank1: { if (equippedCount < 4) return; destroyableComponent->Imagine(1); break; } - case ItemSetPassiveAbilityID::ShinobiRank2: { + case eItemSetPassiveAbilityID::ShinobiRank2: { if (equippedCount < 4) return; destroyableComponent->Imagine(2); break; } - case ItemSetPassiveAbilityID::ShinobiRank3: { - if (equippedCount < 4 || !target) return; - skillComponent->CalculateBehavior(695, 11399, target->GetObjectID()); + case eItemSetPassiveAbilityID::ShinobiRank3: { + if (equippedCount < 4) return; + destroyableComponent->Imagine(3); break; } - case ItemSetPassiveAbilityID::SorcererRank1: { + case eItemSetPassiveAbilityID::SorcererRank1: { if (equippedCount < 4) return; destroyableComponent->Imagine(1); break; } - case ItemSetPassiveAbilityID::SorcererRank2: { + case eItemSetPassiveAbilityID::SorcererRank2: { if (equippedCount < 4) return; destroyableComponent->Imagine(2); break; } - case ItemSetPassiveAbilityID::SorcererRank3: { + case eItemSetPassiveAbilityID::SorcererRank3: { if (equippedCount < 4) return; destroyableComponent->Imagine(3); break; diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index df1b16d7..0e1acdac 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -12,7 +12,7 @@ #include "GameMessages.h" #include "Mail.h" #include "MissionComponent.h" -#include "RacingTaskParam.h" +#include "eRacingTaskParam.h" #include "dLogger.h" #include "dServer.h" #include "dZoneManager.h" @@ -20,6 +20,10 @@ #include "User.h" #include "Database.h" #include "WorldConfig.h" +#include "eMissionState.h" +#include "eMissionTaskType.h" +#include "eMissionLockState.h" + Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_MissionComponent = missionComponent; @@ -32,7 +36,7 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_Reward = 0; - m_State = MissionState::MISSION_STATE_UNKNOWN; + m_State = eMissionState::UNKNOWN; auto* missionsTable = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); @@ -60,7 +64,7 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { void Mission::LoadFromXml(tinyxml2::XMLElement* element) { // Start custom XML if (element->Attribute("state") != nullptr) { - m_State = static_cast<MissionState>(std::stoul(element->Attribute("state"))); + m_State = static_cast<eMissionState>(std::stoul(element->Attribute("state"))); } // End custom XML @@ -85,8 +89,8 @@ void Mission::LoadFromXml(tinyxml2::XMLElement* element) { const auto type = m_Tasks[index]->GetType(); - if (type == MissionTaskType::MISSION_TASK_TYPE_ENVIRONMENT || - type == MissionTaskType::MISSION_TASK_TYPE_VISIT_PROPERTY) { + if (type == eMissionTaskType::COLLECTION || + type == eMissionTaskType::VISIT_PROPERTY) { std::vector<uint32_t> uniques; const auto value = std::stoul(task->Attribute("v")); @@ -100,7 +104,7 @@ void Mission::LoadFromXml(tinyxml2::XMLElement* element) { uniques.push_back(unique); - if (m_MissionComponent != nullptr && type == MissionTaskType::MISSION_TASK_TYPE_ENVIRONMENT) { + if (m_MissionComponent != nullptr && type == eMissionTaskType::COLLECTION) { m_MissionComponent->AddCollectible(unique); } @@ -144,8 +148,8 @@ void Mission::UpdateXml(tinyxml2::XMLElement* element) { } for (auto* task : m_Tasks) { - if (task->GetType() == MissionTaskType::MISSION_TASK_TYPE_ENVIRONMENT || - task->GetType() == MissionTaskType::MISSION_TASK_TYPE_VISIT_PROPERTY) { + if (task->GetType() == eMissionTaskType::COLLECTION || + task->GetType() == eMissionTaskType::VISIT_PROPERTY) { auto* child = element->GetDocument()->NewElement("sv"); @@ -229,7 +233,7 @@ std::vector<MissionTask*> Mission::GetTasks() const { return m_Tasks; } -MissionState Mission::GetMissionState() const { +eMissionState Mission::GetMissionState() const { return m_State; } @@ -246,47 +250,47 @@ bool Mission::IsRepeatable() const { } bool Mission::IsComplete() const { - return m_State == MissionState::MISSION_STATE_COMPLETE; + return m_State == eMissionState::COMPLETE; } bool Mission::IsActive() const { - return m_State == MissionState::MISSION_STATE_ACTIVE || m_State == MissionState::MISSION_STATE_COMPLETE_AVAILABLE; + return m_State == eMissionState::ACTIVE || m_State == eMissionState::COMPLETE_AVAILABLE; } void Mission::MakeActive() { - SetMissionState(m_Completions == 0 ? MissionState::MISSION_STATE_ACTIVE : MissionState::MISSION_STATE_COMPLETE_ACTIVE); + SetMissionState(m_Completions == 0 ? eMissionState::ACTIVE : eMissionState::COMPLETE_ACTIVE); } bool Mission::IsReadyToComplete() const { - return m_State == MissionState::MISSION_STATE_READY_TO_COMPLETE || m_State == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE; + return m_State == eMissionState::READY_TO_COMPLETE || m_State == eMissionState::COMPLETE_READY_TO_COMPLETE; } void Mission::MakeReadyToComplete() { - SetMissionState(m_Completions == 0 ? MissionState::MISSION_STATE_READY_TO_COMPLETE : MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE); + SetMissionState(m_Completions == 0 ? eMissionState::READY_TO_COMPLETE : eMissionState::COMPLETE_READY_TO_COMPLETE); } bool Mission::IsAvalible() const { - return m_State == MissionState::MISSION_STATE_AVAILABLE || m_State == MissionState::MISSION_STATE_COMPLETE_AVAILABLE; + return m_State == eMissionState::AVAILABLE || m_State == eMissionState::COMPLETE_AVAILABLE; } bool Mission::IsFetchMission() const { - return m_Tasks.size() == 1 && m_Tasks[0]->GetType() == MissionTaskType::MISSION_TASK_TYPE_MISSION_INTERACTION; + return m_Tasks.size() == 1 && m_Tasks[0]->GetType() == eMissionTaskType::TALK_TO_NPC; } void Mission::MakeAvalible() { - SetMissionState(m_Completions == 0 ? MissionState::MISSION_STATE_AVAILABLE : MissionState::MISSION_STATE_COMPLETE_AVAILABLE); + SetMissionState(m_Completions == 0 ? eMissionState::AVAILABLE : eMissionState::COMPLETE_AVAILABLE); } void Mission::Accept() { - SetMissionTypeState(MissionLockState::MISSION_LOCK_NEW, info->defined_type, info->defined_subtype); + SetMissionTypeState(eMissionLockState::NEW, info->defined_type, info->defined_subtype); - SetMissionState(m_Completions > 0 ? MissionState::MISSION_STATE_COMPLETE_ACTIVE : MissionState::MISSION_STATE_ACTIVE); + SetMissionState(m_Completions > 0 ? eMissionState::COMPLETE_ACTIVE : eMissionState::ACTIVE); Catchup(); } void Mission::Complete(const bool yieldRewards) { - if (m_State != MissionState::MISSION_STATE_ACTIVE && m_State != MissionState::MISSION_STATE_COMPLETE_ACTIVE) { + if (m_State != eMissionState::ACTIVE && m_State != eMissionState::COMPLETE_ACTIVE) { // If we are accepting a mission here there is no point to giving it a unique ID since we just complete it immediately. Accept(); } @@ -295,13 +299,13 @@ void Mission::Complete(const bool yieldRewards) { task->Complete(); } - SetMissionState(MissionState::MISSION_STATE_REWARDING, true); + SetMissionState(eMissionState::REWARDING, true); if (yieldRewards) { YieldRewards(); } - SetMissionState(MissionState::MISSION_STATE_COMPLETE); + SetMissionState(eMissionState::COMPLETE); m_Completions++; @@ -320,11 +324,11 @@ void Mission::Complete(const bool yieldRewards) { auto* missionComponent = entity->GetComponent<MissionComponent>(); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MISSION_COMPLETE, info->id); + missionComponent->Progress(eMissionTaskType::META, info->id); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, info->id, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COMPLETE_ANY_RACING_TASK); + missionComponent->Progress(eMissionTaskType::RACING, info->id, (LWOOBJID)eRacingTaskParam::COMPLETE_ANY_RACING_TASK); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, info->id, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COMPLETE_TRACK_TASKS); + missionComponent->Progress(eMissionTaskType::RACING, info->id, (LWOOBJID)eRacingTaskParam::COMPLETE_TRACK_TASKS); auto* missionEmailTable = CDClientManager::Instance()->GetTable<CDMissionEmailTable>("MissionEmail"); @@ -371,7 +375,7 @@ void Mission::Catchup() { for (auto* task : m_Tasks) { const auto type = task->GetType(); - if (type == MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION) { + if (type == eMissionTaskType::GATHER) { for (auto target : task->GetAllTargets()) { const auto count = inventory->GetLotCountNonTransfer(target); @@ -381,7 +385,7 @@ void Mission::Catchup() { } } - if (type == MissionTaskType::MISSION_TASK_TYPE_PLAYER_FLAG) { + if (type == eMissionTaskType::PLAYER_FLAG) { for (auto target : task->GetAllTargets()) { const auto flag = GetUser()->GetLastUsedChar()->GetPlayerFlag(target); @@ -416,7 +420,7 @@ void Mission::YieldRewards() { // Remove mission items for (auto* task : m_Tasks) { - if (task->GetType() != MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION) { + if (task->GetType() != eMissionTaskType::GATHER) { continue; } @@ -429,7 +433,7 @@ void Mission::YieldRewards() { inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue, eInventoryType::ITEMS); inventoryComponent->RemoveItem(target, task->GetClientInfo().targetValue, eInventoryType::QUEST); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, target, LWOOBJID_EMPTY, "", -task->GetClientInfo().targetValue); + missionComponent->Progress(eMissionTaskType::GATHER, target, LWOOBJID_EMPTY, "", -task->GetClientInfo().targetValue); } } } @@ -525,7 +529,7 @@ void Mission::YieldRewards() { } if (info->reward_reputation > 0) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_EARN_REPUTATION, 0, 0L, "", info->reward_reputation); + missionComponent->Progress(eMissionTaskType::EARN_REPUTATION, 0, 0L, "", info->reward_reputation); auto character = entity->GetComponent<CharacterComponent>(); if (character) { character->SetReputation(character->GetReputation() + info->reward_reputation); @@ -560,7 +564,7 @@ void Mission::YieldRewards() { } } -void Mission::Progress(MissionTaskType type, int32_t value, LWOOBJID associate, const std::string& targets, int32_t count) { +void Mission::Progress(eMissionTaskType type, int32_t value, LWOOBJID associate, const std::string& targets, int32_t count) { const auto isRemoval = count < 0; if (isRemoval && (IsComplete() || IsAchievement())) { @@ -584,7 +588,7 @@ void Mission::Progress(MissionTaskType type, int32_t value, LWOOBJID associate, } } -void Mission::SetMissionState(const MissionState state, const bool sendingRewards) { +void Mission::SetMissionState(const eMissionState state, const bool sendingRewards) { this->m_State = state; auto* entity = GetAssociate(); @@ -596,7 +600,7 @@ void Mission::SetMissionState(const MissionState state, const bool sendingReward GameMessages::SendNotifyMission(entity, entity->GetParentUser()->GetSystemAddress(), info->id, static_cast<int>(state), sendingRewards); } -void Mission::SetMissionTypeState(MissionLockState state, const std::string& type, const std::string& subType) { +void Mission::SetMissionTypeState(eMissionLockState state, const std::string& type, const std::string& subType) { // TODO } diff --git a/dGame/dMission/Mission.h b/dGame/dMission/Mission.h index f9902a06..b04c3548 100644 --- a/dGame/dMission/Mission.h +++ b/dGame/dMission/Mission.h @@ -10,13 +10,12 @@ #include "MissionTask.h" #include "dCommonVars.h" #include "Entity.h" -#include "MissionState.h" -#include "MissionLockState.h" namespace tinyxml2 { class XMLElement; }; - +enum class eMissionState : int; +enum class eMissionLockState : int; class MissionComponent; /** @@ -53,7 +52,7 @@ public: * Returns the current state of this mission * @return the current state of this mission */ - MissionState GetMissionState() const; + eMissionState GetMissionState() const; /** * Returns the database information that represents to this mission. @@ -102,12 +101,12 @@ public: * @param state the mission state to set * @param sendingRewards a flag indicating to the client that rewards wil lfollow */ - void SetMissionState(MissionState state, bool sendingRewards = false); + void SetMissionState(eMissionState state, bool sendingRewards = false); /** * Currently unimplemented */ - void SetMissionTypeState(MissionLockState state, const std::string& type, const std::string& subType); + void SetMissionTypeState(eMissionLockState state, const std::string& type, const std::string& subType); /** * Returns whether this mission is an achievement @@ -208,7 +207,7 @@ public: * @param targets optional multiple targets that need to be met for progression * @param count optional count to progress with */ - void Progress(MissionTaskType type, int32_t value, LWOOBJID associate = 0, const std::string& targets = "", int32_t count = 1); + void Progress(eMissionTaskType type, int32_t value, LWOOBJID associate = 0, const std::string& targets = "", int32_t count = 1); /** * Returns if the mission ID that's given belongs to an existing mission @@ -251,7 +250,7 @@ private: /** * The current state this mission is in */ - MissionState m_State; + eMissionState m_State; /** * The number of times the entity has completed this mission diff --git a/dGame/dMission/MissionPrerequisites.cpp b/dGame/dMission/MissionPrerequisites.cpp index 46fa73a6..6b55151c 100644 --- a/dGame/dMission/MissionPrerequisites.cpp +++ b/dGame/dMission/MissionPrerequisites.cpp @@ -106,8 +106,8 @@ bool PrerequisiteExpression::Execute(const std::unordered_map<uint32_t, Mission* if (this->sub != 0) { // Special case for one Wisp Lee repeatable mission. a = mission->GetClientInfo().id == 1883 ? - mission->GetMissionState() == static_cast<MissionState>(this->sub) : - mission->GetMissionState() >= static_cast<MissionState>(this->sub); + mission->GetMissionState() == static_cast<eMissionState>(this->sub) : + mission->GetMissionState() >= static_cast<eMissionState>(this->sub); } else if (mission->IsComplete()) { a = true; } diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index d52e6e95..e339d232 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -13,6 +13,7 @@ #include "dZoneManager.h" #include "InventoryComponent.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" MissionTask::MissionTask(Mission* mission, CDMissionTasks* info, uint32_t mask) { this->info = info; @@ -42,8 +43,8 @@ MissionTask::MissionTask(Mission* mission, CDMissionTasks* info, uint32_t mask) } -MissionTaskType MissionTask::GetType() const { - return static_cast<MissionTaskType>(info->taskType); +eMissionTaskType MissionTask::GetType() const { + return static_cast<eMissionTaskType>(info->taskType); } @@ -187,7 +188,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& const auto type = GetType(); if (count < 0) { - if (mission->IsMission() && type == MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION && InAllTargets(value)) { + if (mission->IsMission() && type == eMissionTaskType::GATHER && InAllTargets(value)) { if (parameters.size() > 0 && (parameters[0] & 1) != 0) { return; } @@ -218,10 +219,10 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& std::vector<LDFBaseData*> settings; switch (type) { - case MissionTaskType::MISSION_TASK_TYPE_UNKNOWN: + case eMissionTaskType::UNKNOWN: break; - case MissionTaskType::MISSION_TASK_TYPE_ACTIVITY: + case eMissionTaskType::ACTIVITY: { if (InAllTargets(value)) { AddProgress(count); @@ -256,8 +257,8 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_FOOD: - case MissionTaskType::MISSION_TASK_TYPE_MISSION_INTERACTION: + case eMissionTaskType::USE_ITEM: + case eMissionTaskType::TALK_TO_NPC: { if (GetTarget() != value) break; @@ -266,7 +267,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_EMOTE: + case eMissionTaskType::EMOTE: { if (!InParameters(value)) break; @@ -287,7 +288,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_SKILL: + case eMissionTaskType::USE_SKILL: { // This is a complicated check because for some missions we need to check for the associate being in the parameters instead of the value being in the parameters. if (associate == LWOOBJID_EMPTY && GetAllTargets().size() == 1 && GetAllTargets()[0] == -1) { @@ -298,7 +299,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_MINIGAME: + case eMissionTaskType::PERFORM_ACTIVITY: { auto* minigameManager = EntityManager::Instance()->GetEntity(associate); if (minigameManager == nullptr) @@ -327,7 +328,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_VISIT_PROPERTY: + case eMissionTaskType::VISIT_PROPERTY: { if (!InAllTargets(value)) break; @@ -340,7 +341,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_ENVIRONMENT: + case eMissionTaskType::COLLECTION: { if (!InAllTargets(value)) break; @@ -375,7 +376,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_LOCATION: + case eMissionTaskType::EXPLORE: { if (info->targetGroup != targets) break; @@ -384,9 +385,9 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_RACING: + case eMissionTaskType::RACING: { - // The meaning of associate can be found in RacingTaskParam.h + // The meaning of associate can be found in eRacingTaskParam.h if (parameters.empty()) break; if (!InAllTargets(dZoneManager::Instance()->GetZone()->GetWorldID()) && !(parameters[0] == 4 || parameters[0] == 5) && !InAllTargets(value)) break; @@ -426,15 +427,15 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_PET_TAMING: - case MissionTaskType::MISSION_TASK_TYPE_SCRIPT: - case MissionTaskType::MISSION_TASK_TYPE_NON_MISSION_INTERACTION: - case MissionTaskType::MISSION_TASK_TYPE_MISSION_COMPLETE: - case MissionTaskType::MISSION_TASK_TYPE_POWERUP: - case MissionTaskType::MISSION_TASK_TYPE_SMASH: - case MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION: - case MissionTaskType::MISSION_TASK_TYPE_PLAYER_FLAG: - case MissionTaskType::MISSION_TASK_TYPE_EARN_REPUTATION: + case eMissionTaskType::PET_TAMING: + case eMissionTaskType::SCRIPT: + case eMissionTaskType::INTERACT: + case eMissionTaskType::META: + case eMissionTaskType::POWERUP: + case eMissionTaskType::SMASH: + case eMissionTaskType::GATHER: + case eMissionTaskType::PLAYER_FLAG: + case eMissionTaskType::EARN_REPUTATION: { if (!InAllTargets(value)) break; @@ -442,7 +443,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - case MissionTaskType::MISSION_TASK_TYPE_PLACE_MODEL: + case eMissionTaskType::PLACE_MODEL: { AddProgress(count); break; diff --git a/dGame/dMission/MissionTask.h b/dGame/dMission/MissionTask.h index ea4b8a05..f867b632 100644 --- a/dGame/dMission/MissionTask.h +++ b/dGame/dMission/MissionTask.h @@ -4,9 +4,9 @@ #define MISSIONTASK_H #include "CDMissionTasksTable.h" -#include "MissionTaskType.h" #include "dCommonVars.h" +enum class eMissionTaskType : int; class Mission; /** @@ -57,7 +57,7 @@ public: * Returns the type of this task * @return the type of this task */ - MissionTaskType GetType() const; + eMissionTaskType GetType() const; /** * Returns the value that should be progressed to, to complete the mission (the target value) diff --git a/dGame/dUtilities/Loot.cpp b/dGame/dUtilities/Loot.cpp index 784d873f..44e35a91 100644 --- a/dGame/dUtilities/Loot.cpp +++ b/dGame/dUtilities/Loot.cpp @@ -13,6 +13,8 @@ #include "GeneralUtils.h" #include "InventoryComponent.h" #include "MissionComponent.h" +#include "eMissionState.h" + LootGenerator::LootGenerator() { CDLootTableTable* lootTableTable = CDClientManager::Instance()->GetTable<CDLootTableTable>("LootTable"); @@ -186,13 +188,13 @@ std::unordered_map<LOT, int32_t> LootGenerator::RollLootMatrix(Entity* player, u // convert faction token proxy if (drop.itemID == 13763) { - if (missionComponent->GetMissionState(545) == MissionState::MISSION_STATE_COMPLETE) + if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) drop.itemID = 8318; // "Assembly Token" - else if (missionComponent->GetMissionState(556) == MissionState::MISSION_STATE_COMPLETE) + else if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) drop.itemID = 8321; // "Venture League Token" - else if (missionComponent->GetMissionState(567) == MissionState::MISSION_STATE_COMPLETE) + else if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) drop.itemID = 8319; // "Sentinels Token" - else if (missionComponent->GetMissionState(578) == MissionState::MISSION_STATE_COMPLETE) + else if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) drop.itemID = 8320; // "Paradox Token" } diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index a4ac63e1..48f21a5d 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -24,6 +24,7 @@ #include "Character.h" #include "dZoneManager.h" #include "WorldConfig.h" +#include "eMissionTaskType.h" void Mail::SendMail(const Entity* recipient, const std::string& subject, const std::string& body, const LOT attachment, const uint16_t attachmentCount) { @@ -165,7 +166,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd if (!character) return; - if (character->HasPermission(PermissionMap::RestrictedMailAccess)) { + if (character->HasPermission(ePermissionMap::RestrictedMailAccess)) { // Send a message to the player ChatPackets::SendSystemMessage( sysAddr, @@ -268,7 +269,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd auto* missionCompoent = entity->GetComponent<MissionComponent>(); if (missionCompoent != nullptr) { - missionCompoent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, itemLOT, LWOOBJID_EMPTY, "", -attachmentCount); + missionCompoent->Progress(eMissionTaskType::GATHER, itemLOT, LWOOBJID_EMPTY, "", -attachmentCount); } } diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index c23ac53b..8602586c 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -12,7 +12,7 @@ #include "LevelProgressionComponent.h" #include "DestroyableComponent.h" #include "GameMessages.h" - +#include "eMissionState.h" std::map<uint32_t, Precondition*> Preconditions::cache = {}; @@ -142,19 +142,19 @@ bool Precondition::CheckValue(Entity* player, const uint32_t value, bool evaluat case PreconditionType::HasAchievement: mission = missionComponent->GetMission(value); - return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_COMPLETE; + return mission == nullptr || mission->GetMissionState() >= eMissionState::COMPLETE; case PreconditionType::MissionAvailable: mission = missionComponent->GetMission(value); - return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_AVAILABLE; + return mission == nullptr || mission->GetMissionState() >= eMissionState::AVAILABLE; case PreconditionType::OnMission: mission = missionComponent->GetMission(value); - return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_ACTIVE; + return mission == nullptr || mission->GetMissionState() >= eMissionState::ACTIVE; case PreconditionType::MissionComplete: mission = missionComponent->GetMission(value); - return mission == nullptr ? false : mission->GetMissionState() >= MissionState::MISSION_STATE_COMPLETE; + return mission == nullptr ? false : mission->GetMissionState() >= eMissionState::COMPLETE; case PreconditionType::PetDeployed: return false; // TODO case PreconditionType::HasFlag: diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 70637990..1bd3f6f3 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -72,6 +72,7 @@ #include "AMFFormat.h" #include "MovingPlatformComponent.h" #include "dMessageIdentifiers.h" +#include "eMissionState.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; @@ -685,7 +686,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - mission->SetMissionState(MissionState::MISSION_STATE_ACTIVE); + mission->SetMissionState(eMissionState::ACTIVE); return; } diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 61267971..9e8153cc 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -268,7 +268,7 @@ void ClientPackets::HandleChatModerationRequest(const SystemAddress& sysAddr, Pa // Check if the player has restricted chat access auto* character = entity->GetCharacter(); - if (character->HasPermission(PermissionMap::RestrictedChatAccess)) { + if (character->HasPermission(ePermissionMap::RestrictedChatAccess)) { // Send a message to the player ChatPackets::SendSystemMessage( sysAddr, diff --git a/dScripts/02_server/Equipment/BootyDigServer.cpp b/dScripts/02_server/Equipment/BootyDigServer.cpp index 73d96b1f..375bc4e5 100644 --- a/dScripts/02_server/Equipment/BootyDigServer.cpp +++ b/dScripts/02_server/Equipment/BootyDigServer.cpp @@ -2,7 +2,8 @@ #include "EntityManager.h" #include "RenderComponent.h" #include "MissionComponent.h" -#include "MissionTaskType.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" #include "Loot.h" void BootyDigServer::OnStartup(Entity* self) { @@ -37,8 +38,8 @@ BootyDigServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { auto* mission = missionComponent->GetMission(1881); - if (mission != nullptr && (mission->GetMissionState() == MissionState::MISSION_STATE_ACTIVE || mission->GetMissionState() == MissionState::MISSION_STATE_COMPLETE_ACTIVE)) { - mission->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + if (mission != nullptr && (mission->GetMissionState() == eMissionState::ACTIVE || mission->GetMissionState() == eMissionState::COMPLETE_ACTIVE)) { + mission->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); auto* renderComponent = self->GetComponent<RenderComponent>(); if (renderComponent != nullptr) diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp index caaba28f..c01d2362 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp @@ -3,6 +3,7 @@ #include "GeneralUtils.h" #include "EntityManager.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" void MaestromExtracticatorServer::OnStartup(Entity* self) { //self:SetNetworkVar("current_anim", failAnim) @@ -24,7 +25,7 @@ void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* se auto missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent == nullptr) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SMASH, 14718); + missionComponent->Progress(eMissionTaskType::SMASH, 14718); CollectSample(self, sender->GetObjectID()); sender->ScheduleKillAfterUpdate(); } diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index 503d966a..d2cc647e 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -3,6 +3,8 @@ #include "ScriptedActivityComponent.h" #include "GameMessages.h" #include "LeaderboardManager.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" #include "MissionComponent.h" #include <ctime> @@ -89,7 +91,7 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std auto* missionComponent = sender->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { missionComponent->ForceProgressTaskType(1884, 1, 1, false); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MINIGAME, -finish, self->GetObjectID(), + missionComponent->Progress(eMissionTaskType::PERFORM_ACTIVITY, -finish, self->GetObjectID(), "performact_time"); } diff --git a/dScripts/02_server/Map/AG/NpcCowboyServer.cpp b/dScripts/02_server/Map/AG/NpcCowboyServer.cpp index c4940e4d..c5a0e8f9 100644 --- a/dScripts/02_server/Map/AG/NpcCowboyServer.cpp +++ b/dScripts/02_server/Map/AG/NpcCowboyServer.cpp @@ -1,8 +1,8 @@ #include "NpcCowboyServer.h" -#include "MissionState.h" +#include "eMissionState.h" #include "InventoryComponent.h" -void NpcCowboyServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NpcCowboyServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionID != 1880) { return; } @@ -13,14 +13,14 @@ void NpcCowboyServer::OnMissionDialogueOK(Entity* self, Entity* target, int miss return; } - if (missionState == MissionState::MISSION_STATE_COMPLETE_ACTIVE || - missionState == MissionState::MISSION_STATE_ACTIVE || - missionState == MissionState::MISSION_STATE_AVAILABLE || - missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE) { + if (missionState == eMissionState::COMPLETE_ACTIVE || + missionState == eMissionState::ACTIVE || + missionState == eMissionState::AVAILABLE || + missionState == eMissionState::COMPLETE_AVAILABLE) { if (inventoryComponent->GetLotCount(14378) == 0) { inventoryComponent->AddItem(14378, 1, eLootSourceType::LOOT_SOURCE_NONE); } - } else if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) { + } else if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { inventoryComponent->RemoveItem(14378, 1); } } diff --git a/dScripts/02_server/Map/AG/NpcCowboyServer.h b/dScripts/02_server/Map/AG/NpcCowboyServer.h index e600d798..4493315c 100644 --- a/dScripts/02_server/Map/AG/NpcCowboyServer.h +++ b/dScripts/02_server/Map/AG/NpcCowboyServer.h @@ -3,5 +3,5 @@ class NpcCowboyServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; }; diff --git a/dScripts/02_server/Map/AG/NpcEpsilonServer.cpp b/dScripts/02_server/Map/AG/NpcEpsilonServer.cpp index f6b8f5c4..a928e9d9 100644 --- a/dScripts/02_server/Map/AG/NpcEpsilonServer.cpp +++ b/dScripts/02_server/Map/AG/NpcEpsilonServer.cpp @@ -1,7 +1,7 @@ #include "NpcEpsilonServer.h" #include "GameMessages.h" -void NpcEpsilonServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NpcEpsilonServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { //If we are completing the Nexus Force join mission, play the celebration for it: if (missionID == 1851) { diff --git a/dScripts/02_server/Map/AG/NpcEpsilonServer.h b/dScripts/02_server/Map/AG/NpcEpsilonServer.h index 798da33e..4de76bcd 100644 --- a/dScripts/02_server/Map/AG/NpcEpsilonServer.h +++ b/dScripts/02_server/Map/AG/NpcEpsilonServer.h @@ -2,6 +2,6 @@ #include "CppScripts.h" class NpcEpsilonServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState); + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState); }; diff --git a/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp b/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp index a53d8ba3..183765d7 100644 --- a/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp +++ b/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp @@ -3,24 +3,25 @@ #include "InventoryComponent.h" #include "MissionComponent.h" #include "Item.h" +#include "eMissionState.h" -void NpcNjAssistantServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NpcNjAssistantServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionID != mailMission) return; - if (missionState == MissionState::MISSION_STATE_COMPLETE || missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE) { + if (missionState == eMissionState::COMPLETE || missionState == eMissionState::READY_TO_COMPLETE) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"switch", 0, 0, LWOOBJID_EMPTY, "", target->GetSystemAddress()); auto* inv = static_cast<InventoryComponent*>(target->GetComponent(COMPONENT_TYPE_INVENTORY)); // If we are ready to complete our missions, we take the kit from you: - if (inv && missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE) { + if (inv && missionState == eMissionState::READY_TO_COMPLETE) { auto* id = inv->FindItemByLot(14397); //the kit's lot if (id != nullptr) { inv->RemoveItem(id->GetLot(), id->GetCount()); } } - } else if (missionState == MissionState::MISSION_STATE_AVAILABLE) { + } else if (missionState == eMissionState::AVAILABLE) { auto* missionComponent = static_cast<MissionComponent*>(target->GetComponent(COMPONENT_TYPE_MISSION)); missionComponent->CompleteMission(mailAchievement, true); } diff --git a/dScripts/02_server/Map/AG/NpcNjAssistantServer.h b/dScripts/02_server/Map/AG/NpcNjAssistantServer.h index 7ba847d0..1f932752 100644 --- a/dScripts/02_server/Map/AG/NpcNjAssistantServer.h +++ b/dScripts/02_server/Map/AG/NpcNjAssistantServer.h @@ -2,7 +2,7 @@ #include "CppScripts.h" class NpcNjAssistantServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState); + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState); private: int mailMission = 1728; //mission to get the item out of your mailbox diff --git a/dScripts/02_server/Map/AG/NpcPirateServer.cpp b/dScripts/02_server/Map/AG/NpcPirateServer.cpp index 154fe2bc..6e7e696c 100644 --- a/dScripts/02_server/Map/AG/NpcPirateServer.cpp +++ b/dScripts/02_server/Map/AG/NpcPirateServer.cpp @@ -1,17 +1,17 @@ #include "NpcPirateServer.h" -#include "MissionState.h" +#include "eMissionState.h" #include "InventoryComponent.h" -void NpcPirateServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NpcPirateServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { auto* inventory = target->GetComponent<InventoryComponent>(); if (inventory != nullptr && missionID == 1881) { auto* luckyShovel = inventory->FindItemByLot(14591); // Add or remove the lucky shovel based on whether the mission was completed or started - if ((missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE) + if ((missionState == eMissionState::AVAILABLE || missionState == eMissionState::COMPLETE_AVAILABLE) && luckyShovel == nullptr) { inventory->AddItem(14591, 1, eLootSourceType::LOOT_SOURCE_NONE); - } else if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) { + } else if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { inventory->RemoveItem(14591, 1); } } diff --git a/dScripts/02_server/Map/AG/NpcPirateServer.h b/dScripts/02_server/Map/AG/NpcPirateServer.h index dcb399c5..118aec89 100644 --- a/dScripts/02_server/Map/AG/NpcPirateServer.h +++ b/dScripts/02_server/Map/AG/NpcPirateServer.h @@ -2,5 +2,5 @@ #include "CppScripts.h" class NpcPirateServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; }; diff --git a/dScripts/02_server/Map/AG/NpcWispServer.cpp b/dScripts/02_server/Map/AG/NpcWispServer.cpp index d6eab34c..99345973 100644 --- a/dScripts/02_server/Map/AG/NpcWispServer.cpp +++ b/dScripts/02_server/Map/AG/NpcWispServer.cpp @@ -3,9 +3,9 @@ #include "EntityManager.h" #include "Entity.h" #include "GameMessages.h" -#include "MissionState.h" +#include "eMissionState.h" -void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionID != 1849 && missionID != 1883) return; @@ -17,16 +17,16 @@ void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missio auto* maelstromVacuum = inventory->FindItemByLot(maelstromVacuumLot); // For the daily we add the maelstrom vacuum if the player doesn't have it yet - if (missionID == 1883 && (missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE) + if (missionID == 1883 && (missionState == eMissionState::AVAILABLE || missionState == eMissionState::COMPLETE_AVAILABLE) && maelstromVacuum == nullptr) { inventory->AddItem(maelstromVacuumLot, 1, eLootSourceType::LOOT_SOURCE_NONE); - } else if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) { + } else if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { inventory->RemoveItem(maelstromVacuumLot, 1); } // Next up hide or show the samples based on the mission state auto visible = 1; - if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) { + if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { visible = 0; } diff --git a/dScripts/02_server/Map/AG/NpcWispServer.h b/dScripts/02_server/Map/AG/NpcWispServer.h index 86c9c33d..6eaa09e9 100644 --- a/dScripts/02_server/Map/AG/NpcWispServer.h +++ b/dScripts/02_server/Map/AG/NpcWispServer.h @@ -2,5 +2,5 @@ #include "CppScripts.h" class NpcWispServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState); + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState); }; diff --git a/dScripts/02_server/Map/AG/RemoveRentalGear.cpp b/dScripts/02_server/Map/AG/RemoveRentalGear.cpp index fbb00c79..6e7bd4de 100644 --- a/dScripts/02_server/Map/AG/RemoveRentalGear.cpp +++ b/dScripts/02_server/Map/AG/RemoveRentalGear.cpp @@ -1,7 +1,7 @@ #include "RemoveRentalGear.h" #include "InventoryComponent.h" #include "Item.h" -#include "MissionState.h" +#include "eMissionState.h" #include "Character.h" /* @@ -17,10 +17,10 @@ -------------------------------------------------------------- */ -void RemoveRentalGear::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void RemoveRentalGear::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionID != defaultMission && missionID != 313) return; - if (missionState == MissionState::MISSION_STATE_COMPLETE || missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE) { + if (missionState == eMissionState::COMPLETE || missionState == eMissionState::READY_TO_COMPLETE) { auto inv = static_cast<InventoryComponent*>(target->GetComponent(COMPONENT_TYPE_INVENTORY)); if (!inv) return; diff --git a/dScripts/02_server/Map/AG/RemoveRentalGear.h b/dScripts/02_server/Map/AG/RemoveRentalGear.h index 49ca0860..cc33b5f6 100644 --- a/dScripts/02_server/Map/AG/RemoveRentalGear.h +++ b/dScripts/02_server/Map/AG/RemoveRentalGear.h @@ -2,7 +2,7 @@ #include "CppScripts.h" class RemoveRentalGear : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState); + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState); private: int defaultMission = 768; //mission to remove gearSets on completion diff --git a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp index 909beaaf..15ca7267 100644 --- a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp +++ b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp @@ -3,6 +3,7 @@ #include "RebuildComponent.h" #include "InventoryComponent.h" #include "dZoneManager.h" +#include "eMissionState.h" void AmDropshipComputer::OnStartup(Entity* self) { self->AddTimer("reset", 45.0f); @@ -22,7 +23,7 @@ void AmDropshipComputer::OnUse(Entity* self, Entity* user) { return; } - if (inventoryComponent->GetLotCount(m_NexusTalonDataCard) != 0 || missionComponent->GetMission(979)->GetMissionState() == MissionState::MISSION_STATE_COMPLETE) { + if (inventoryComponent->GetLotCount(m_NexusTalonDataCard) != 0 || missionComponent->GetMission(979)->GetMissionState() == eMissionState::COMPLETE) { return; } diff --git a/dScripts/02_server/Map/FV/FvFong.cpp b/dScripts/02_server/Map/FV/FvFong.cpp index 7f63e5e5..13c637e7 100644 --- a/dScripts/02_server/Map/FV/FvFong.cpp +++ b/dScripts/02_server/Map/FV/FvFong.cpp @@ -1,9 +1,9 @@ #include "FvFong.h" #include "Darkitect.h" -#include "MissionState.h" +#include "eMissionState.h" -void FvFong::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { - if (missionID == 734 && missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE) { +void FvFong::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { + if (missionID == 734 && missionState == eMissionState::READY_TO_COMPLETE) { Darkitect Baron; Baron.Reveal(self, target); } diff --git a/dScripts/02_server/Map/FV/FvFong.h b/dScripts/02_server/Map/FV/FvFong.h index 074e6d8c..c0b6d48b 100644 --- a/dScripts/02_server/Map/FV/FvFong.h +++ b/dScripts/02_server/Map/FV/FvFong.h @@ -4,5 +4,5 @@ class FvFong : public CppScripts::Script { public: - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; }; diff --git a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp index 4a12324f..9c7b858f 100644 --- a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp +++ b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp @@ -4,6 +4,7 @@ #include "EntityManager.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eMissionState.h" #include "InventoryComponent.h" int32_t ImgBrickConsoleQB::ResetBricks = 30; @@ -71,13 +72,13 @@ void ImgBrickConsoleQB::OnUse(Entity* self, Entity* user) { auto* inventoryComponent = player->GetComponent<InventoryComponent>(); if (missionComponent != nullptr && inventoryComponent != nullptr) { - if (missionComponent->GetMissionState(1302) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(1302) == eMissionState::ACTIVE) { inventoryComponent->RemoveItem(13074, 1); missionComponent->ForceProgressTaskType(1302, 1, 1); } - if (missionComponent->GetMissionState(1926) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(1926) == eMissionState::ACTIVE) { inventoryComponent->RemoveItem(14472, 1); missionComponent->ForceProgressTaskType(1926, 1, 1); diff --git a/dScripts/02_server/Map/GF/GfTikiTorch.cpp b/dScripts/02_server/Map/GF/GfTikiTorch.cpp index 3a06b054..db7ee6b5 100644 --- a/dScripts/02_server/Map/GF/GfTikiTorch.cpp +++ b/dScripts/02_server/Map/GF/GfTikiTorch.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "RenderComponent.h" +#include "eMissionTaskType.h" void GfTikiTorch::OnStartup(Entity* self) { LightTorch(self); @@ -65,7 +66,7 @@ void GfTikiTorch::OnSkillEventFired(Entity* self, Entity* caster, const std::str auto* casterMissionComponent = caster->GetComponent<MissionComponent>(); if (casterMissionComponent != nullptr) { for (const auto missionID : m_missions) { - casterMissionComponent->ForceProgressTaskType(missionID, static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), 1); + casterMissionComponent->ForceProgressTaskType(missionID, static_cast<uint32_t>(eMissionTaskType::SCRIPT), 1); } } diff --git a/dScripts/02_server/Map/General/ExplodingAsset.cpp b/dScripts/02_server/Map/General/ExplodingAsset.cpp index 46ff1522..16340ee6 100644 --- a/dScripts/02_server/Map/General/ExplodingAsset.cpp +++ b/dScripts/02_server/Map/General/ExplodingAsset.cpp @@ -3,6 +3,7 @@ #include "GameMessages.h" #include "MissionComponent.h" #include "SkillComponent.h" +#include "eMissionTaskType.h" //TODO: this has to be updated so that you only get killed if you're in a certain radius. //And so that all entities in a certain radius are killed, not just the attacker. @@ -51,14 +52,14 @@ void ExplodingAsset::OnHit(Entity* self, Entity* attacker) { if (missionComponent != nullptr) { if (missionID != 0) { missionComponent->ForceProgressValue(missionID, - static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), + static_cast<uint32_t>(eMissionTaskType::SCRIPT), self->GetLOT(), false); } if (!achievementIDs.empty()) { for (const auto& achievementID : GeneralUtils::SplitString(achievementIDs, u'_')) { missionComponent->ForceProgressValue(std::stoi(GeneralUtils::UTF16ToWTF8(achievementID)), - static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), + static_cast<uint32_t>(eMissionTaskType::SCRIPT), self->GetLOT()); } } diff --git a/dScripts/02_server/Map/General/GrowingFlower.cpp b/dScripts/02_server/Map/General/GrowingFlower.cpp index 61bfbc30..ad88528f 100644 --- a/dScripts/02_server/Map/General/GrowingFlower.cpp +++ b/dScripts/02_server/Map/General/GrowingFlower.cpp @@ -1,5 +1,7 @@ #include "GrowingFlower.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" #include "Loot.h" void GrowingFlower::OnSkillEventFired(Entity* self, Entity* target, const std::string& message) { @@ -16,13 +18,13 @@ void GrowingFlower::OnSkillEventFired(Entity* self, Entity* target, const std::s auto* missionComponent = target->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { for (const auto mission : achievementIDs) - missionComponent->ForceProgressTaskType(mission, static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), 1); + missionComponent->ForceProgressTaskType(mission, static_cast<uint32_t>(eMissionTaskType::SCRIPT), 1); - if (mission1 && missionComponent->GetMissionState(mission1) == MissionState::MISSION_STATE_ACTIVE) - missionComponent->ForceProgressTaskType(mission1, static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), 1); + if (mission1 && missionComponent->GetMissionState(mission1) == eMissionState::ACTIVE) + missionComponent->ForceProgressTaskType(mission1, static_cast<uint32_t>(eMissionTaskType::SCRIPT), 1); - if (mission2 && missionComponent->GetMissionState(mission2) == MissionState::MISSION_STATE_ACTIVE) - missionComponent->ForceProgressTaskType(mission2, static_cast<uint32_t>(MissionTaskType::MISSION_TASK_TYPE_SCRIPT), 1); + if (mission2 && missionComponent->GetMissionState(mission2) == eMissionState::ACTIVE) + missionComponent->ForceProgressTaskType(mission2, static_cast<uint32_t>(eMissionTaskType::SCRIPT), 1); } } } diff --git a/dScripts/02_server/Map/General/ImaginationBackpackHealServer.cpp b/dScripts/02_server/Map/General/ImaginationBackpackHealServer.cpp index 1e0d35cf..8b3da9fa 100644 --- a/dScripts/02_server/Map/General/ImaginationBackpackHealServer.cpp +++ b/dScripts/02_server/Map/General/ImaginationBackpackHealServer.cpp @@ -1,6 +1,8 @@ #include "ImaginationBackpackHealServer.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" void ImaginationBackpackHealServer::OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) { if (message == "CastImaginationBackpack") { @@ -11,8 +13,8 @@ void ImaginationBackpackHealServer::OnSkillEventFired(Entity* self, Entity* cast return; auto* missionComponent = caster->GetComponent<MissionComponent>(); - if (missionComponent != nullptr && missionComponent->GetMissionState(healMission) == MissionState::MISSION_STATE_ACTIVE) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + if (missionComponent != nullptr && missionComponent->GetMissionState(healMission) == eMissionState::ACTIVE) { + missionComponent->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ClearMaelstrom", 0, 0, caster->GetObjectID(), "", caster->GetSystemAddress()); } diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index 0d62ff04..81d70faf 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -5,6 +5,7 @@ #include "Character.h" #include "PetComponent.h" #include "User.h" +#include "eMissionState.h" std::vector<LWOOBJID> PetDigServer::treasures{}; @@ -163,13 +164,13 @@ void PetDigServer::ProgressPetDigMissions(const Entity* owner, const Entity* che if (missionComponent != nullptr) { // Can You Dig It progress const auto digMissionState = missionComponent->GetMissionState(843); - if (digMissionState == MissionState::MISSION_STATE_ACTIVE) { + if (digMissionState == eMissionState::ACTIVE) { missionComponent->ForceProgress(843, 1216, 1); } // Pet Excavator progress const auto excavatorMissionState = missionComponent->GetMissionState(505); - if (excavatorMissionState == MissionState::MISSION_STATE_ACTIVE) { + if (excavatorMissionState == eMissionState::ACTIVE) { if (chest->HasVar(u"PetDig")) { int32_t playerFlag = 1260 + chest->GetVarAs<int32_t>(u"PetDig"); Character* player = owner->GetCharacter(); @@ -193,7 +194,7 @@ void PetDigServer::SpawnPet(Entity* self, const Entity* owner, const DigInfo dig // Some treasures require a mission to be active if (digInfo.requiredMission >= 0) { auto* missionComponent = owner->GetComponent<MissionComponent>(); - if (missionComponent != nullptr && missionComponent->GetMissionState(digInfo.requiredMission) < MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent != nullptr && missionComponent->GetMissionState(digInfo.requiredMission) < eMissionState::ACTIVE) { return; } } diff --git a/dScripts/02_server/Map/General/PropertyDevice.cpp b/dScripts/02_server/Map/General/PropertyDevice.cpp index 64771de1..0ad9f5c9 100644 --- a/dScripts/02_server/Map/General/PropertyDevice.cpp +++ b/dScripts/02_server/Map/General/PropertyDevice.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "EntityManager.h" #include "MissionComponent.h" +#include "eMissionState.h" void PropertyDevice::OnStartup(Entity* self) { auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); @@ -17,7 +18,7 @@ void PropertyDevice::OnRebuildComplete(Entity* self, Entity* target) { auto* missionComponent = target->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - if (missionComponent->GetMissionState(m_PropertyMissionID) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(m_PropertyMissionID) == eMissionState::ACTIVE) { GameMessages::SendPlayFXEffect(self->GetObjectID(), 641, u"create", "callhome"); missionComponent->ForceProgress(m_PropertyMissionID, 1793, self->GetLOT()); } diff --git a/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp b/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp index f732305e..00c1b900 100644 --- a/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp +++ b/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp @@ -3,6 +3,7 @@ #include "Entity.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eMissionState.h" void TouchMissionUpdateServer::OnStartup(Entity* self) { self->SetProximityRadius(20, "touchCheck"); // Those does not have a collider for some reason? @@ -29,7 +30,7 @@ void TouchMissionUpdateServer::OnCollisionPhantom(Entity* self, Entity* target) const auto state = mission->GetMissionState(); - if (state >= MissionState::MISSION_STATE_COMPLETE || mission->GetCompletions() > 1) { + if (state >= eMissionState::COMPLETE || mission->GetCompletions() > 1) { return; } diff --git a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp index 5410047d..b4d75296 100644 --- a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp +++ b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp @@ -2,6 +2,8 @@ #include "GameMessages.h" #include "EntityManager.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" void NtAssemblyTubeServer::OnStartup(Entity* self) { self->SetProximityRadius(5, "teleport"); @@ -22,7 +24,7 @@ void NtAssemblyTubeServer::OnProximityUpdate(Entity* self, Entity* entering, std auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + missionComponent->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } } diff --git a/dScripts/02_server/Map/NT/NtDukeServer.cpp b/dScripts/02_server/Map/NT/NtDukeServer.cpp index 327d3290..d48d50c7 100644 --- a/dScripts/02_server/Map/NT/NtDukeServer.cpp +++ b/dScripts/02_server/Map/NT/NtDukeServer.cpp @@ -1,6 +1,7 @@ #include "NtDukeServer.h" #include "InventoryComponent.h" #include "MissionComponent.h" +#include "eMissionState.h" void NtDukeServer::SetVariables(Entity* self) { self->SetVar<float_t>(m_SpyProximityVariable, 35.0f); @@ -19,7 +20,7 @@ void NtDukeServer::SetVariables(Entity* self) { self->SetVar<std::vector<LWOOBJID>>(m_SpyCinematicObjectsVariable, { self->GetObjectID() }); } -void NtDukeServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NtDukeServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { // Handles adding and removing the sword for the Crux Prime Sword mission auto* missionComponent = target->GetComponent<MissionComponent>(); @@ -29,9 +30,9 @@ void NtDukeServer::OnMissionDialogueOK(Entity* self, Entity* target, int mission auto state = missionComponent->GetMissionState(m_SwordMissionID); auto lotCount = inventoryComponent->GetLotCount(m_SwordLot); - if ((state == MissionState::MISSION_STATE_AVAILABLE || state == MissionState::MISSION_STATE_ACTIVE) && lotCount < 1) { + if ((state == eMissionState::AVAILABLE || state == eMissionState::ACTIVE) && lotCount < 1) { inventoryComponent->AddItem(m_SwordLot, 1, eLootSourceType::LOOT_SOURCE_NONE); - } else if (state == MissionState::MISSION_STATE_READY_TO_COMPLETE) { + } else if (state == eMissionState::READY_TO_COMPLETE) { inventoryComponent->RemoveItem(m_SwordLot, lotCount); } } diff --git a/dScripts/02_server/Map/NT/NtDukeServer.h b/dScripts/02_server/Map/NT/NtDukeServer.h index 0878e86c..2103ba8d 100644 --- a/dScripts/02_server/Map/NT/NtDukeServer.h +++ b/dScripts/02_server/Map/NT/NtDukeServer.h @@ -3,7 +3,7 @@ class NtDukeServer : public NtFactionSpyServer { void SetVariables(Entity* self) override; - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; const uint32_t m_SwordMissionID = 1448; const LOT m_SwordLot = 13777; }; diff --git a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp index 8d14050b..0cb0bec4 100644 --- a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp @@ -3,6 +3,7 @@ #include "MissionComponent.h" #include "EntityManager.h" #include "Character.h" +#include "eMissionState.h" void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"bActive", 1, 0, user->GetObjectID(), "", user->GetSystemAddress()); @@ -16,7 +17,7 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { const auto playerID = user->GetObjectID(); for (const auto mission : tPlayerOnMissions) { - if (missionComponent->GetMissionState(mission) != MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(mission) != eMissionState::ACTIVE) { continue; } diff --git a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp index 64af4d34..8b4f19fe 100644 --- a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "EntityManager.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" void NtParadoxTeleServer::OnStartup(Entity* self) { self->SetProximityRadius(5, "teleport"); @@ -44,7 +45,7 @@ void NtParadoxTeleServer::OnProximityUpdate(Entity* self, Entity* entering, std: auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + missionComponent->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } } diff --git a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp index 7b943172..66bfe46f 100644 --- a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp +++ b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp @@ -2,6 +2,7 @@ #include "PhantomPhysicsComponent.h" #include "EntityManager.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" void NtSentinelWalkwayServer::OnStartup(Entity* self) { auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); @@ -38,6 +39,6 @@ void NtSentinelWalkwayServer::OnProximityUpdate(Entity* self, Entity* entering, auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + missionComponent->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } } diff --git a/dScripts/02_server/Map/NT/NtVandaServer.cpp b/dScripts/02_server/Map/NT/NtVandaServer.cpp index e5653005..7750d566 100644 --- a/dScripts/02_server/Map/NT/NtVandaServer.cpp +++ b/dScripts/02_server/Map/NT/NtVandaServer.cpp @@ -1,11 +1,11 @@ #include "NtVandaServer.h" #include "InventoryComponent.h" -#include "MissionState.h" +#include "eMissionState.h" -void NtVandaServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NtVandaServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { // Removes the alien parts after completing the mission - if (missionID == m_AlienPartMissionID && missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE) { + if (missionID == m_AlienPartMissionID && missionState == eMissionState::READY_TO_COMPLETE) { auto* inventoryComponent = target->GetComponent<InventoryComponent>(); for (const auto& alienPartLot : m_AlienPartLots) { inventoryComponent->RemoveItem(alienPartLot, 1); diff --git a/dScripts/02_server/Map/NT/NtVandaServer.h b/dScripts/02_server/Map/NT/NtVandaServer.h index 69e868f5..58162cd9 100644 --- a/dScripts/02_server/Map/NT/NtVandaServer.h +++ b/dScripts/02_server/Map/NT/NtVandaServer.h @@ -2,7 +2,7 @@ #include "CppScripts.h" class NtVandaServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; const uint32_t m_AlienPartMissionID = 1183; const std::vector<LOT> m_AlienPartLots = { 12479, 12480, 12481 }; }; diff --git a/dScripts/02_server/Map/NT/NtVentureSpeedPadServer.cpp b/dScripts/02_server/Map/NT/NtVentureSpeedPadServer.cpp index 0995d1df..07d33555 100644 --- a/dScripts/02_server/Map/NT/NtVentureSpeedPadServer.cpp +++ b/dScripts/02_server/Map/NT/NtVentureSpeedPadServer.cpp @@ -1,6 +1,7 @@ #include "NtVentureSpeedPadServer.h" #include "SkillComponent.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" void NtVentureSpeedPadServer::OnStartup(Entity* self) { self->SetProximityRadius(3, "speedboost"); @@ -17,7 +18,7 @@ void NtVentureSpeedPadServer::OnProximityUpdate(Entity* self, Entity* entering, auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + missionComponent->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } auto* skillComponent = player->GetComponent<SkillComponent>(); diff --git a/dScripts/02_server/Map/PR/SpawnGryphonServer.cpp b/dScripts/02_server/Map/PR/SpawnGryphonServer.cpp index 22e5ff59..2b7e3904 100644 --- a/dScripts/02_server/Map/PR/SpawnGryphonServer.cpp +++ b/dScripts/02_server/Map/PR/SpawnGryphonServer.cpp @@ -2,6 +2,7 @@ #include "InventoryComponent.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eMissionState.h" void SpawnGryphonServer::SetVariables(Entity* self) { self->SetVar<LOT>(u"petLOT", 12433); @@ -17,7 +18,7 @@ void SpawnGryphonServer::OnUse(Entity* self, Entity* user) { // Little extra for handling the case of the egg being placed the first time if (missionComponent != nullptr && inventoryComponent != nullptr - && missionComponent->GetMissionState(1391) == MissionState::MISSION_STATE_ACTIVE) { + && missionComponent->GetMissionState(1391) == eMissionState::ACTIVE) { inventoryComponent->RemoveItem(12483, inventoryComponent->GetLotCount(12483)); GameMessages::SendTerminateInteraction(user->GetObjectID(), FROM_INTERACTION, self->GetObjectID()); return; diff --git a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp index db2bb78a..b6172df1 100644 --- a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp @@ -6,6 +6,7 @@ #include "dZoneManager.h" #include "RenderComponent.h" #include "MissionComponent.h" +#include "eMissionState.h" void ZoneAgProperty::SetGameVariables(Entity* self) { self->SetVar<std::string>(GuardGroup, "Guard"); @@ -80,7 +81,7 @@ void ZoneAgProperty::PropGuardCheck(Entity* self, Entity* player) { const auto state = missionComponent->GetMissionState(self->GetVar<uint32_t>(guardMissionFlag)); const auto firstState = missionComponent->GetMissionState(self->GetVar<uint32_t>(guardFirstMissionFlag)); - if (firstState < MissionState::MISSION_STATE_COMPLETE || (state != MissionState::MISSION_STATE_COMPLETE && state != MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE)) + if (firstState < eMissionState::COMPLETE || (state != eMissionState::COMPLETE && state != eMissionState::COMPLETE_READY_TO_COMPLETE)) ActivateSpawner(self->GetVar<std::string>(PropertyMGSpawner)); } @@ -304,13 +305,13 @@ void ZoneAgProperty::OnZonePropertyModelPlaced(Entity* self, Entity* player) { if (!character->GetPlayerFlag(101)) { BaseZonePropertyModelPlaced(self, player); character->SetPlayerFlag(101, true); - if (missionComponent->GetMissionState(871) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(871) == eMissionState::ACTIVE) { self->SetNetworkVar<std::u16string>(u"Tooltip", u"AnotherModel"); } } else if (!character->GetPlayerFlag(102)) { character->SetPlayerFlag(102, true); - if (missionComponent->GetMissionState(871) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(871) == eMissionState::ACTIVE) { self->SetNetworkVar<std::u16string>(u"Tooltip", u"TwoMoreModels"); } @@ -331,7 +332,7 @@ void ZoneAgProperty::OnZonePropertyModelPickedUp(Entity* self, Entity* player) { if (!character->GetPlayerFlag(109)) { character->SetPlayerFlag(109, true); - if (missionComponent->GetMissionState(891) == MissionState::MISSION_STATE_ACTIVE && !character->GetPlayerFlag(110)) { + if (missionComponent->GetMissionState(891) == eMissionState::ACTIVE && !character->GetPlayerFlag(110)) { self->SetNetworkVar<std::u16string>(u"Tooltip", u"Rotate"); } } @@ -353,7 +354,7 @@ void ZoneAgProperty::OnZonePropertyModelRotated(Entity* self, Entity* player) { if (!character->GetPlayerFlag(110)) { character->SetPlayerFlag(110, true); - if (missionComponent->GetMissionState(891) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(891) == eMissionState::ACTIVE) { self->SetNetworkVar<std::u16string>(u"Tooltip", u"PlaceModel"); self->SetVar<std::string>(u"tutorial", "place_model"); } diff --git a/dScripts/02_server/Map/SS/SsModularBuildServer.cpp b/dScripts/02_server/Map/SS/SsModularBuildServer.cpp index d5b6da50..82c802cc 100644 --- a/dScripts/02_server/Map/SS/SsModularBuildServer.cpp +++ b/dScripts/02_server/Map/SS/SsModularBuildServer.cpp @@ -1,5 +1,6 @@ #include "SsModularBuildServer.h" #include "MissionComponent.h" +#include "eMissionState.h" void SsModularBuildServer::OnModularBuildExit(Entity* self, Entity* player, bool bCompleted, std::vector<LOT> modules) { int missionNum = 1732; @@ -8,7 +9,7 @@ void SsModularBuildServer::OnModularBuildExit(Entity* self, Entity* player, bool MissionComponent* mission = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); Mission* rocketMission = mission->GetMission(missionNum); - if (rocketMission->GetMissionState() == MissionState::MISSION_STATE_ACTIVE) { + if (rocketMission->GetMissionState() == eMissionState::ACTIVE) { mission->ForceProgress(missionNum, 2478, 1); } } diff --git a/dScripts/02_server/Map/VE/VeBricksampleServer.cpp b/dScripts/02_server/Map/VE/VeBricksampleServer.cpp index 5166d0c3..36306d07 100644 --- a/dScripts/02_server/Map/VE/VeBricksampleServer.cpp +++ b/dScripts/02_server/Map/VE/VeBricksampleServer.cpp @@ -3,10 +3,11 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "GameMessages.h" +#include "eMissionState.h" void VeBricksampleServer::OnUse(Entity* self, Entity* user) { auto* missionComponent = user->GetComponent<MissionComponent>(); - if (missionComponent != nullptr && missionComponent->GetMissionState(1183) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent != nullptr && missionComponent->GetMissionState(1183) == eMissionState::ACTIVE) { const auto loot = self->GetVar<int32_t>(m_LootVariable); auto* inventoryComponent = user->GetComponent<InventoryComponent>(); diff --git a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp index 4a2f1bbf..c69f9cc2 100644 --- a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp +++ b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp @@ -2,17 +2,17 @@ #include "Character.h" #include "EntityManager.h" #include "GameMessages.h" -#include "MissionState.h" +#include "eMissionState.h" #include "Entity.h" -void VeEpsilonServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void VeEpsilonServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { auto* character = target->GetCharacter(); if (character == nullptr) return; // Resets the player flags that track which consoles they've used if ((missionID == m_ConsoleMissionID || missionID == m_ConsoleRepeatMissionID) - && (missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE)) { + && (missionState == eMissionState::AVAILABLE || missionState == eMissionState::COMPLETE_AVAILABLE)) { for (auto i = 0; i < 10; i++) { character->SetPlayerFlag(m_ConsoleBaseFlag + i, false); diff --git a/dScripts/02_server/Map/VE/VeEpsilonServer.h b/dScripts/02_server/Map/VE/VeEpsilonServer.h index d1236e96..971cd93e 100644 --- a/dScripts/02_server/Map/VE/VeEpsilonServer.h +++ b/dScripts/02_server/Map/VE/VeEpsilonServer.h @@ -2,7 +2,7 @@ #include "CppScripts.h" class VeEpsilonServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; const uint32_t m_ConsoleMissionID = 1220; const uint32_t m_ConsoleRepeatMissionID = 1225; const uint32_t m_ConsoleBaseFlag = 1010; diff --git a/dScripts/02_server/Map/njhub/NjColeNPC.cpp b/dScripts/02_server/Map/njhub/NjColeNPC.cpp index f151db40..672fdd95 100644 --- a/dScripts/02_server/Map/njhub/NjColeNPC.cpp +++ b/dScripts/02_server/Map/njhub/NjColeNPC.cpp @@ -1,6 +1,7 @@ #include "NjColeNPC.h" #include "MissionComponent.h" #include "InventoryComponent.h" +#include "eMissionState.h" void NjColeNPC::OnEmoteReceived(Entity* self, int32_t emote, Entity* target) { if (emote != 393) { @@ -26,10 +27,10 @@ void NjColeNPC::OnEmoteReceived(Entity* self, int32_t emote, Entity* target) { missionComponent->ForceProgressTaskType(1818, 1, 1); } -void NjColeNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NjColeNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(self, target, missionID, missionState); - if (missionID == 1818 && missionState >= MissionState::MISSION_STATE_READY_TO_COMPLETE) { + if (missionID == 1818 && missionState >= eMissionState::READY_TO_COMPLETE) { auto* missionComponent = target->GetComponent<MissionComponent>(); auto* inventoryComponent = target->GetComponent<InventoryComponent>(); diff --git a/dScripts/02_server/Map/njhub/NjColeNPC.h b/dScripts/02_server/Map/njhub/NjColeNPC.h index cf8e67e1..a2536e32 100644 --- a/dScripts/02_server/Map/njhub/NjColeNPC.h +++ b/dScripts/02_server/Map/njhub/NjColeNPC.h @@ -3,5 +3,5 @@ class NjColeNPC : public NjNPCMissionSpinjitzuServer { void OnEmoteReceived(Entity* self, int32_t emote, Entity* target) override; - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; }; diff --git a/dScripts/02_server/Map/njhub/NjJayMissionItems.cpp b/dScripts/02_server/Map/njhub/NjJayMissionItems.cpp index cc871b86..46131446 100644 --- a/dScripts/02_server/Map/njhub/NjJayMissionItems.cpp +++ b/dScripts/02_server/Map/njhub/NjJayMissionItems.cpp @@ -1,6 +1,6 @@ #include "NjJayMissionItems.h" -void NjJayMissionItems::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NjJayMissionItems::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(self, target, missionID, missionState); NPCAddRemoveItem::OnMissionDialogueOK(self, target, missionID, missionState); } diff --git a/dScripts/02_server/Map/njhub/NjJayMissionItems.h b/dScripts/02_server/Map/njhub/NjJayMissionItems.h index c49f49ea..bdaee3ea 100644 --- a/dScripts/02_server/Map/njhub/NjJayMissionItems.h +++ b/dScripts/02_server/Map/njhub/NjJayMissionItems.h @@ -5,6 +5,6 @@ #include <map> class NjJayMissionItems : public NjNPCMissionSpinjitzuServer, NPCAddRemoveItem { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; std::map<uint32_t, std::vector<ItemSetting>> GetSettings() override; }; diff --git a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp index 69838dc8..30bba804 100644 --- a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp +++ b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp @@ -1,13 +1,12 @@ #include "NjNPCMissionSpinjitzuServer.h" #include "Character.h" #include "EntityManager.h" -#include "MissionState.h" +#include "eMissionState.h" -void NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, - MissionState missionState) { +void NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { const auto& element = self->GetVar<std::u16string>(ElementVariable); - if (missionID == ElementMissions.at(element) && missionState >= MissionState::MISSION_STATE_READY_TO_COMPLETE) { + if (missionID == ElementMissions.at(element) && missionState >= eMissionState::READY_TO_COMPLETE) { const auto targetID = target->GetObjectID(); diff --git a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.h b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.h index 8f25a86a..3c705925 100644 --- a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.h +++ b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.h @@ -18,7 +18,7 @@ static std::map<std::u16string, uint32_t> ElementMissions = { class NjNPCMissionSpinjitzuServer : public CppScripts::Script { public: - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; private: const std::u16string ElementVariable = u"element"; }; diff --git a/dScripts/02_server/Map/njhub/NjWuNPC.cpp b/dScripts/02_server/Map/njhub/NjWuNPC.cpp index 855e4433..9efc623b 100644 --- a/dScripts/02_server/Map/njhub/NjWuNPC.cpp +++ b/dScripts/02_server/Map/njhub/NjWuNPC.cpp @@ -3,8 +3,9 @@ #include "Character.h" #include "EntityManager.h" #include "GameMessages.h" +#include "eMissionState.h" -void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { // The Dragon statue daily mission if (missionID == m_MainDragonMissionID) { @@ -14,8 +15,8 @@ void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, M return; switch (missionState) { - case MissionState::MISSION_STATE_AVAILABLE: - case MissionState::MISSION_STATE_COMPLETE_AVAILABLE: + case eMissionState::AVAILABLE: + case eMissionState::COMPLETE_AVAILABLE: { // Reset the sub missions for (const auto& subMissionID : m_SubDragonMissionIDs) { @@ -33,8 +34,8 @@ void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, M return; } - case MissionState::MISSION_STATE_READY_TO_COMPLETE: - case MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE: + case eMissionState::READY_TO_COMPLETE: + case eMissionState::COMPLETE_READY_TO_COMPLETE: { character->SetPlayerFlag(NJ_WU_SHOW_DAILY_CHEST, true); diff --git a/dScripts/02_server/Map/njhub/NjWuNPC.h b/dScripts/02_server/Map/njhub/NjWuNPC.h index d0cd750b..f8c52303 100644 --- a/dScripts/02_server/Map/njhub/NjWuNPC.h +++ b/dScripts/02_server/Map/njhub/NjWuNPC.h @@ -2,7 +2,7 @@ #include "AmTemplateSkillVolume.h" class NjWuNPC : public AmTemplateSkillVolume { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; const uint32_t m_MainDragonMissionID = 2040; const std::vector<uint32_t> m_SubDragonMissionIDs = { 2064, 2065, 2066, 2067 }; diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index a182c9c1..7552eeca 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -8,6 +8,8 @@ #include "RenderComponent.h" #include "PropertyManagementComponent.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" void BasePropertyServer::SetGameVariables(Entity* self) { self->SetVar<std::string>(ClaimMarkerGroup, ""); @@ -97,7 +99,7 @@ void BasePropertyServer::BasePlayerLoaded(Entity* self, Entity* player) { if (missionComponent != nullptr) { missionComponent->Progress( - MissionTaskType::MISSION_TASK_TYPE_VISIT_PROPERTY, + eMissionTaskType::VISIT_PROPERTY, mapID.GetMapID(), mapID.GetCloneID() ); @@ -150,7 +152,7 @@ void BasePropertyServer::PropGuardCheck(Entity* self, Entity* player) { auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr - && missionComponent->GetMissionState(self->GetVar<uint32_t>(guardMissionFlag)) != MissionState::MISSION_STATE_COMPLETE) { + && missionComponent->GetMissionState(self->GetVar<uint32_t>(guardMissionFlag)) != eMissionState::COMPLETE) { ActivateSpawner(self->GetVar<std::string>(PropertyMGSpawner)); } } diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index 270b6741..3d72628d 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -4,7 +4,8 @@ #include "EntityManager.h" #include "dZoneManager.h" #include "Player.h" -#include "MissionTaskType.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" #include "MissionComponent.h" #include "Character.h" @@ -361,16 +362,16 @@ void BaseSurvivalServer::GameOver(Entity* self) { // Update all mission progression auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MINIGAME, time, self->GetObjectID(), + missionComponent->Progress(eMissionTaskType::PERFORM_ACTIVITY, time, self->GetObjectID(), self->GetVar<std::string>(MissionTypeVariable)); for (const auto& survivalMission : missionsToUpdate) { auto* mission = missionComponent->GetMission(survivalMission.first); if (mission != nullptr && (uint32_t)time >= survivalMission.second - && (mission->GetMissionState() == MissionState::MISSION_STATE_ACTIVE - || mission->GetMissionState() == MissionState::MISSION_STATE_COMPLETE_ACTIVE)) { + && (mission->GetMissionState() == eMissionState::ACTIVE + || mission->GetMissionState() == eMissionState::COMPLETE_ACTIVE)) { - mission->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + mission->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } } } diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 8c32f984..ad40a77d 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -4,7 +4,8 @@ #include "EntityManager.h" #include "dZoneManager.h" #include "Player.h" -#include "MissionTaskType.h" +#include "eMissionTaskType.h" +#include "eMissionState.h" #include "MissionComponent.h" #include "Character.h" @@ -373,7 +374,7 @@ void BaseWavesServer::GameOver(Entity* self, bool won) { // Update all mission progression auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MINIGAME, time, self->GetObjectID(), self->GetVar<std::string>(MissionTypeVariable)); + missionComponent->Progress(eMissionTaskType::PERFORM_ACTIVITY, time, self->GetObjectID(), self->GetVar<std::string>(MissionTypeVariable)); } StopActivity(self, playerID, wave, time, score); @@ -510,15 +511,15 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 // Get the mission state auto missionState = missionComponent->GetMissionState(missionID); // For some reason these achievements are not accepted by default, so we accept them here if they arent already. - if (missionState != MissionState::MISSION_STATE_COMPLETE && missionState != MissionState::MISSION_STATE_UNKNOWN) { + if (missionState != eMissionState::COMPLETE && missionState != eMissionState::UNKNOWN) { missionComponent->AcceptMission(missionID); missionState = missionComponent->GetMissionState(missionID); } - if (missionState != MissionState::MISSION_STATE_COMPLETE) { + if (missionState != eMissionState::COMPLETE) { auto mission = missionComponent->GetMission(missionID); if (mission != nullptr) { - mission->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + mission->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } } } @@ -528,15 +529,15 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 // Get the mission state auto missionState = missionComponent->GetMissionState(missionID); // For some reason these achievements are not accepted by default, so we accept them here if they arent already. - if (missionState != MissionState::MISSION_STATE_COMPLETE && missionState != MissionState::MISSION_STATE_UNKNOWN) { + if (missionState != eMissionState::COMPLETE && missionState != eMissionState::UNKNOWN) { missionComponent->AcceptMission(missionID); missionState = missionComponent->GetMissionState(missionID); } - if (missionState != MissionState::MISSION_STATE_COMPLETE) { + if (missionState != eMissionState::COMPLETE) { auto mission = missionComponent->GetMission(missionID); if (mission != nullptr) { - mission->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + mission->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } } } @@ -564,14 +565,14 @@ void BaseWavesServer::UpdateMissionForAllPlayers(Entity* self, uint32_t missionI // Get the mission state auto missionState = missionComponent->GetMissionState(missionID); // For some reason these achievements are not accepted by default, so we accept them here if they arent already. - if (missionState != MissionState::MISSION_STATE_COMPLETE && missionState != MissionState::MISSION_STATE_UNKNOWN) { + if (missionState != eMissionState::COMPLETE && missionState != eMissionState::UNKNOWN) { missionComponent->AcceptMission(missionID); missionState = missionComponent->GetMissionState(missionID); } - if (missionState != MissionState::MISSION_STATE_COMPLETE) { + if (missionState != eMissionState::COMPLETE) { auto mission = missionComponent->GetMission(missionID); if (mission != nullptr) { - mission->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + mission->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } } } diff --git a/dScripts/CppScripts.h b/dScripts/CppScripts.h index eb9b7a04..21ff8427 100644 --- a/dScripts/CppScripts.h +++ b/dScripts/CppScripts.h @@ -7,7 +7,7 @@ class User; class Entity; class NiPoint3; -enum class MissionState : int32_t; +enum class eMissionState : int32_t; namespace CppScripts { /** @@ -49,7 +49,7 @@ namespace CppScripts { * * Equivalent to 'function onMissionDialogueOK(self, msg)' */ - virtual void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) {}; + virtual void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) {}; /** * Invoked when the client or the server invoked an event server-side. @@ -327,7 +327,7 @@ namespace CppScripts { /** * Used by items to tell their owner that they were equipped. - * + * * @param itemOwner The owner of the item * @param itemObjId The items Object ID */ @@ -335,7 +335,7 @@ namespace CppScripts { /** * Used by items to tell their owner that they were unequipped. - * + * * @param itemOwner The owner of the item * @param itemObjId The items Object ID */ diff --git a/dScripts/Darkitect.cpp b/dScripts/Darkitect.cpp index 323d0247..b4364332 100644 --- a/dScripts/Darkitect.cpp +++ b/dScripts/Darkitect.cpp @@ -4,6 +4,7 @@ #include "EntityManager.h" #include "GameMessages.h" #include "Character.h" +#include "eMissionState.h" void Darkitect::Reveal(Entity* self, Entity* player) { const auto playerID = player->GetObjectID(); @@ -24,7 +25,7 @@ void Darkitect::Reveal(Entity* self, Entity* player) { destroyableComponent->SetHealth(1); destroyableComponent->SetImagination(0); - if (missionComponent->GetMissionState(1295) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(1295) == eMissionState::ACTIVE) { character->SetPlayerFlag(1911, true); } diff --git a/dScripts/NPCAddRemoveItem.cpp b/dScripts/NPCAddRemoveItem.cpp index 1985a02b..f1ef8c0d 100644 --- a/dScripts/NPCAddRemoveItem.cpp +++ b/dScripts/NPCAddRemoveItem.cpp @@ -1,8 +1,8 @@ #include "NPCAddRemoveItem.h" #include "InventoryComponent.h" -#include "MissionState.h" +#include "eMissionState.h" -void NPCAddRemoveItem::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void NPCAddRemoveItem::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { auto* inventory = target->GetComponent<InventoryComponent>(); if (inventory == nullptr) return; @@ -11,9 +11,9 @@ void NPCAddRemoveItem::OnMissionDialogueOK(Entity* self, Entity* target, int mis if (missionSetting.first == missionID) { for (const auto& itemSetting : missionSetting.second) { for (const auto& lot : itemSetting.items) { - if (itemSetting.add && (missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_COMPLETE_AVAILABLE)) { + if (itemSetting.add && (missionState == eMissionState::AVAILABLE || missionState == eMissionState::COMPLETE_AVAILABLE)) { inventory->AddItem(lot, 1, eLootSourceType::LOOT_SOURCE_NONE); - } else if (itemSetting.remove && (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE || missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE)) { + } else if (itemSetting.remove && (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE)) { inventory->RemoveItem(lot, 1); } } diff --git a/dScripts/NPCAddRemoveItem.h b/dScripts/NPCAddRemoveItem.h index a266f817..73a7f2c9 100644 --- a/dScripts/NPCAddRemoveItem.h +++ b/dScripts/NPCAddRemoveItem.h @@ -12,7 +12,7 @@ struct ItemSetting { */ class NPCAddRemoveItem : public CppScripts::Script { protected: - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; virtual std::map<uint32_t, std::vector<ItemSetting>> GetSettings(); private: void OnStartup(Entity* self) override; diff --git a/dScripts/NtFactionSpyServer.cpp b/dScripts/NtFactionSpyServer.cpp index ac068a32..684e6a0e 100644 --- a/dScripts/NtFactionSpyServer.cpp +++ b/dScripts/NtFactionSpyServer.cpp @@ -4,6 +4,7 @@ #include "InventoryComponent.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eMissionState.h" void NtFactionSpyServer::OnStartup(Entity* self) { SetVariables(self); @@ -54,7 +55,7 @@ bool NtFactionSpyServer::IsSpy(Entity* self, Entity* possibleSpy) { auto* character = possibleSpy->GetCharacter(); // A player is a spy if they have the spy mission, have the spy equipment equipped and don't have the spy flag set yet - return missionComponent != nullptr && missionComponent->GetMissionState(spyData.missionID) == MissionState::MISSION_STATE_ACTIVE + return missionComponent != nullptr && missionComponent->GetMissionState(spyData.missionID) == eMissionState::ACTIVE && inventoryComponent != nullptr && inventoryComponent->IsEquipped(spyData.itemID) && character != nullptr && !character->GetPlayerFlag(spyData.flagID); } diff --git a/dScripts/ai/AG/ActSharkPlayerDeathTrigger.cpp b/dScripts/ai/AG/ActSharkPlayerDeathTrigger.cpp index 420fc4d7..49fb6b87 100644 --- a/dScripts/ai/AG/ActSharkPlayerDeathTrigger.cpp +++ b/dScripts/ai/AG/ActSharkPlayerDeathTrigger.cpp @@ -1,6 +1,6 @@ #include "ActSharkPlayerDeathTrigger.h" #include "MissionComponent.h" -#include "MissionTaskType.h" +#include "eMissionTaskType.h" #include "Entity.h" void ActSharkPlayerDeathTrigger::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, @@ -9,7 +9,7 @@ void ActSharkPlayerDeathTrigger::OnFireEventServerSide(Entity* self, Entity* sen auto missionComponent = sender->GetComponent<MissionComponent>(); if (!missionComponent) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, 8419); + missionComponent->Progress(eMissionTaskType::SCRIPT, 8419); if (sender->GetIsDead() || !sender->GetPlayerReadyForUpdates()) return; //Don't kill already dead players or players not ready diff --git a/dScripts/ai/FV/FvFreeGfNinjas.cpp b/dScripts/ai/FV/FvFreeGfNinjas.cpp index 1751b6a7..d690a6f7 100644 --- a/dScripts/ai/FV/FvFreeGfNinjas.cpp +++ b/dScripts/ai/FV/FvFreeGfNinjas.cpp @@ -1,9 +1,10 @@ #include "FvFreeGfNinjas.h" #include "Character.h" #include "MissionComponent.h" +#include "eMissionState.h" -void FvFreeGfNinjas::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { - if (missionID == 705 && missionState == MissionState::MISSION_STATE_AVAILABLE) { +void FvFreeGfNinjas::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { + if (missionID == 705 && missionState == eMissionState::AVAILABLE) { auto* missionComponent = target->GetComponent<MissionComponent>(); if (missionComponent == nullptr) return; @@ -29,7 +30,7 @@ void FvFreeGfNinjas::OnUse(Entity* self, Entity* user) { if (missionComponent == nullptr) return; - if (missionComponent->GetMissionState(705) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(705) == eMissionState::ACTIVE) { auto* character = user->GetCharacter(); if (character != nullptr) character->SetPlayerFlag(68, true); diff --git a/dScripts/ai/FV/FvFreeGfNinjas.h b/dScripts/ai/FV/FvFreeGfNinjas.h index c7e4876e..01b0b6bd 100644 --- a/dScripts/ai/FV/FvFreeGfNinjas.h +++ b/dScripts/ai/FV/FvFreeGfNinjas.h @@ -3,6 +3,6 @@ class FvFreeGfNinjas : public CppScripts::Script { public: - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; void OnUse(Entity* self, Entity* user) override; }; diff --git a/dScripts/ai/GENERAL/LegoDieRoll.cpp b/dScripts/ai/GENERAL/LegoDieRoll.cpp index e86550f9..89819271 100644 --- a/dScripts/ai/GENERAL/LegoDieRoll.cpp +++ b/dScripts/ai/GENERAL/LegoDieRoll.cpp @@ -2,6 +2,7 @@ #include "Entity.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eMissionState.h" void LegoDieRoll::OnStartup(Entity* self) { self->AddTimer("DoneRolling", 10.0f); @@ -39,7 +40,7 @@ void LegoDieRoll::OnTimerDone(Entity* self, std::string timerName) { if (missionComponent != nullptr) { const auto rollMissionState = missionComponent->GetMissionState(756); - if (rollMissionState == MissionState::MISSION_STATE_ACTIVE) { + if (rollMissionState == eMissionState::ACTIVE) { missionComponent->ForceProgress(756, 1103, 1); } } diff --git a/dScripts/ai/GF/GfJailkeepMission.cpp b/dScripts/ai/GF/GfJailkeepMission.cpp index eaa8c73d..b8d4cd30 100644 --- a/dScripts/ai/GF/GfJailkeepMission.cpp +++ b/dScripts/ai/GF/GfJailkeepMission.cpp @@ -1,18 +1,19 @@ #include "GfJailkeepMission.h" #include "MissionComponent.h" #include "Character.h" +#include "eMissionState.h" -void GfJailkeepMission::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void GfJailkeepMission::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { auto* missionComponent = target->GetComponent<MissionComponent>(); if (missionComponent == nullptr) return; - if (missionID == 385 && missionState == MissionState::MISSION_STATE_AVAILABLE) { + if (missionID == 385 && missionState == eMissionState::AVAILABLE) { missionComponent->AcceptMission(386, true); missionComponent->AcceptMission(387, true); missionComponent->AcceptMission(388, true); missionComponent->AcceptMission(390, true); - } else if (missionID == 385 && missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) { + } else if (missionID == 385 && missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { auto* character = target->GetCharacter(); if (character != nullptr && character->GetPlayerFlag(68)) { missionComponent->AcceptMission(701); @@ -28,7 +29,7 @@ void GfJailkeepMission::OnUse(Entity* self, Entity* user) { if (missionComponent == nullptr) return; - if (missionComponent->GetMissionState(385) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent->GetMissionState(385) == eMissionState::ACTIVE) { missionComponent->AcceptMission(386, true); missionComponent->AcceptMission(387, true); missionComponent->AcceptMission(388, true); diff --git a/dScripts/ai/GF/GfJailkeepMission.h b/dScripts/ai/GF/GfJailkeepMission.h index a120d29b..651a6e1b 100644 --- a/dScripts/ai/GF/GfJailkeepMission.h +++ b/dScripts/ai/GF/GfJailkeepMission.h @@ -5,5 +5,5 @@ class GfJailkeepMission final : public CppScripts::Script { public: void OnUse(Entity* self, Entity* user) override; - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; }; diff --git a/dScripts/ai/GF/PetDigBuild.cpp b/dScripts/ai/GF/PetDigBuild.cpp index 32e5b2e3..2c3da9fc 100644 --- a/dScripts/ai/GF/PetDigBuild.cpp +++ b/dScripts/ai/GF/PetDigBuild.cpp @@ -2,6 +2,7 @@ #include "EntityManager.h" #include "EntityInfo.h" #include "MissionComponent.h" +#include "eMissionState.h" void PetDigBuild::OnRebuildComplete(Entity* self, Entity* target) { auto flagNumber = self->GetVar<std::u16string>(u"flagNum"); @@ -22,7 +23,7 @@ void PetDigBuild::OnRebuildComplete(Entity* self, Entity* target) { info.settings.push_back(new LDFData<std::u16string>(u"groupID", u"Flag" + flagNumber)); } else { auto* missionComponent = target->GetComponent<MissionComponent>(); - if (missionComponent != nullptr && missionComponent->GetMissionState(746) == MissionState::MISSION_STATE_ACTIVE) { + if (missionComponent != nullptr && missionComponent->GetMissionState(746) == eMissionState::ACTIVE) { info.lot = 9307; // Special Captain Jack treasure that drops a mission item } else { info.lot = 3495; // Normal AG treasure diff --git a/dScripts/ai/GF/PirateRep.cpp b/dScripts/ai/GF/PirateRep.cpp index 81d69672..ccfa7af6 100644 --- a/dScripts/ai/GF/PirateRep.cpp +++ b/dScripts/ai/GF/PirateRep.cpp @@ -1,10 +1,10 @@ #include "PirateRep.h" #include "Character.h" -#include "MissionState.h" +#include "eMissionState.h" #include "Entity.h" -void PirateRep::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { - if (missionID == m_PirateRepMissionID && missionState >= MissionState::MISSION_STATE_READY_TO_COMPLETE) { +void PirateRep::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { + if (missionID == m_PirateRepMissionID && missionState >= eMissionState::READY_TO_COMPLETE) { auto* character = target->GetCharacter(); if (character) { character->SetPlayerFlag(ePlayerFlags::GF_PIRATE_REP, true); diff --git a/dScripts/ai/GF/PirateRep.h b/dScripts/ai/GF/PirateRep.h index 8fc82c5e..754971be 100644 --- a/dScripts/ai/GF/PirateRep.h +++ b/dScripts/ai/GF/PirateRep.h @@ -3,7 +3,7 @@ class PirateRep : public CppScripts::Script { public: - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; private: const int m_PirateRepMissionID = 301; }; diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index f9146ec4..2948ae3d 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -13,6 +13,7 @@ #include "MissionComponent.h" #include "Loot.h" #include "InventoryComponent.h" +#include "eMissionTaskType.h" void SGCannon::OnStartup(Entity* self) { Game::logger->Log("SGCannon", "OnStartup"); @@ -554,9 +555,9 @@ void SGCannon::StopGame(Entity* self, bool cancel) { auto* missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MINIGAME, self->GetVar<uint32_t>(TotalScoreVariable), self->GetObjectID(), "performact_score"); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_MINIGAME, self->GetVar<uint32_t>(MaxStreakVariable), self->GetObjectID(), "performact_streak"); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_ACTIVITY, m_CannonLot, 0, "", self->GetVar<uint32_t>(TotalScoreVariable)); + missionComponent->Progress(eMissionTaskType::PERFORM_ACTIVITY, self->GetVar<uint32_t>(TotalScoreVariable), self->GetObjectID(), "performact_score"); + missionComponent->Progress(eMissionTaskType::PERFORM_ACTIVITY, self->GetVar<uint32_t>(MaxStreakVariable), self->GetObjectID(), "performact_streak"); + missionComponent->Progress(eMissionTaskType::ACTIVITY, m_CannonLot, 0, "", self->GetVar<uint32_t>(TotalScoreVariable)); } LootGenerator::Instance().GiveActivityLoot(player, self, GetGameID(self), self->GetVar<uint32_t>(TotalScoreVariable)); @@ -666,7 +667,7 @@ void SGCannon::RegisterHit(Entity* self, Entity* target, const std::string& time auto missionComponent = player->GetComponent<MissionComponent>(); if (missionComponent == nullptr) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SMASH, spawnInfo.lot, self->GetObjectID()); + missionComponent->Progress(eMissionTaskType::SMASH, spawnInfo.lot, self->GetObjectID()); } void SGCannon::UpdateStreak(Entity* self) { diff --git a/dScripts/ai/NP/NpcNpSpacemanBob.cpp b/dScripts/ai/NP/NpcNpSpacemanBob.cpp index 5157e488..d242d08f 100644 --- a/dScripts/ai/NP/NpcNpSpacemanBob.cpp +++ b/dScripts/ai/NP/NpcNpSpacemanBob.cpp @@ -1,9 +1,10 @@ #include "NpcNpSpacemanBob.h" #include "DestroyableComponent.h" #include "MissionComponent.h" +#include "eMissionState.h" -void NpcNpSpacemanBob::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { - if (missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE && missionID == 173) { +void NpcNpSpacemanBob::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { + if (missionState == eMissionState::READY_TO_COMPLETE && missionID == 173) { DestroyableComponent* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE)); destroyable->SetImagination(6); MissionComponent* mission = static_cast<MissionComponent*>(target->GetComponent(COMPONENT_TYPE_MISSION)); diff --git a/dScripts/ai/NP/NpcNpSpacemanBob.h b/dScripts/ai/NP/NpcNpSpacemanBob.h index 08cc850d..84c59deb 100644 --- a/dScripts/ai/NP/NpcNpSpacemanBob.h +++ b/dScripts/ai/NP/NpcNpSpacemanBob.h @@ -4,6 +4,6 @@ class NpcNpSpacemanBob : public CppScripts::Script { public: - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState); + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState); }; diff --git a/dScripts/ai/NS/NsConcertInstrument.cpp b/dScripts/ai/NS/NsConcertInstrument.cpp index bba3986d..c7478a05 100644 --- a/dScripts/ai/NS/NsConcertInstrument.cpp +++ b/dScripts/ai/NS/NsConcertInstrument.cpp @@ -7,6 +7,8 @@ #include "SoundTriggerComponent.h" #include "InventoryComponent.h" #include "MissionComponent.h" +#include "eMissionState.h" +#include "eMissionTaskType.h" // Constants are at the bottom @@ -146,8 +148,8 @@ void NsConcertInstrument::StopPlayingInstrument(Entity* self, Entity* player) { // Player might be null if they left if (player != nullptr) { auto* missions = player->GetComponent<MissionComponent>(); - if (missions != nullptr && missions->GetMissionState(176) == MissionState::MISSION_STATE_ACTIVE) { - missions->Progress(MissionTaskType::MISSION_TASK_TYPE_SCRIPT, self->GetLOT()); + if (missions != nullptr && missions->GetMissionState(176) == eMissionState::ACTIVE) { + missions->Progress(eMissionTaskType::SCRIPT, self->GetLOT()); } GameMessages::SendEndCinematic(player->GetObjectID(), cinematics.at(instrumentLot), UNASSIGNED_SYSTEM_ADDRESS, 1.0f); diff --git a/dScripts/ai/NS/NsJohnnyMissionServer.cpp b/dScripts/ai/NS/NsJohnnyMissionServer.cpp index 2d9ae93c..107d3c44 100644 --- a/dScripts/ai/NS/NsJohnnyMissionServer.cpp +++ b/dScripts/ai/NS/NsJohnnyMissionServer.cpp @@ -1,8 +1,9 @@ #include "NsJohnnyMissionServer.h" #include "MissionComponent.h" +#include "eMissionState.h" -void NsJohnnyMissionServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { - if (missionID == 773 && missionState <= MissionState::MISSION_STATE_ACTIVE) { +void NsJohnnyMissionServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { + if (missionID == 773 && missionState <= eMissionState::ACTIVE) { auto* missionComponent = target->GetComponent<MissionComponent>(); if (missionComponent != nullptr) { missionComponent->AcceptMission(774); diff --git a/dScripts/ai/NS/NsJohnnyMissionServer.h b/dScripts/ai/NS/NsJohnnyMissionServer.h index 8de39afa..c37ea06c 100644 --- a/dScripts/ai/NS/NsJohnnyMissionServer.h +++ b/dScripts/ai/NS/NsJohnnyMissionServer.h @@ -2,5 +2,5 @@ #include "CppScripts.h" class NsJohnnyMissionServer : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; }; diff --git a/dScripts/ai/NS/NsModularBuild.cpp b/dScripts/ai/NS/NsModularBuild.cpp index 065d061e..2e00aa19 100644 --- a/dScripts/ai/NS/NsModularBuild.cpp +++ b/dScripts/ai/NS/NsModularBuild.cpp @@ -1,11 +1,12 @@ #include "NsModularBuild.h" #include "MissionComponent.h" +#include "eMissionState.h" void NsModularBuild::OnModularBuildExit(Entity* self, Entity* player, bool bCompleted, std::vector<LOT> modules) { if (bCompleted) { MissionComponent* mission = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); - if (mission->GetMissionState(m_MissionNum) == MissionState::MISSION_STATE_ACTIVE) { + if (mission->GetMissionState(m_MissionNum) == eMissionState::ACTIVE) { for (LOT mod : modules) { if (mod == 9516 || mod == 9517 || mod == 9518) { mission->ForceProgress(m_MissionNum, 1178, 1); diff --git a/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp b/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp index 51f76a27..853da92d 100644 --- a/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp +++ b/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp @@ -5,18 +5,19 @@ #include "InventoryComponent.h" #include "MissionComponent.h" #include "Item.h" +#include "eMissionState.h" -void AgPropGuard::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void AgPropGuard::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { auto* character = target->GetCharacter(); auto* missionComponent = target->GetComponent<MissionComponent>(); auto* inventoryComponent = target->GetComponent<InventoryComponent>(); const auto state = missionComponent->GetMissionState(320); - if (missionID == 768 && missionState == MissionState::MISSION_STATE_AVAILABLE) { + if (missionID == 768 && missionState == eMissionState::AVAILABLE) { if (!character->GetPlayerFlag(71)) { // TODO: Cinematic "MissionCam" } - } else if (missionID == 768 && missionState >= MissionState::MISSION_STATE_READY_TO_COMPLETE) { + } else if (missionID == 768 && missionState >= eMissionState::READY_TO_COMPLETE) { //remove the inventory items for (int item : gearSets) { auto* id = inventoryComponent->FindItemByLot(item); @@ -27,8 +28,8 @@ void AgPropGuard::OnMissionDialogueOK(Entity* self, Entity* target, int missionI } } } else if ( - (missionID == 320 && state == MissionState::MISSION_STATE_AVAILABLE) /*|| - (state == MissionState::MISSION_STATE_COMPLETE && missionID == 891 && missionState == MissionState::MISSION_STATE_READY_TO_COMPLETE)*/ + (missionID == 320 && state == eMissionState::AVAILABLE) /*|| + (state == eMissionState::COMPLETE && missionID == 891 && missionState == eMissionState::READY_TO_COMPLETE)*/ ) { //GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), u"GuardChat", target->GetObjectID(), 0, target->GetObjectID(), "", target->GetSystemAddress()); diff --git a/dScripts/ai/PROPERTY/AG/AgPropGuard.h b/dScripts/ai/PROPERTY/AG/AgPropGuard.h index f68573dd..2b41f006 100644 --- a/dScripts/ai/PROPERTY/AG/AgPropGuard.h +++ b/dScripts/ai/PROPERTY/AG/AgPropGuard.h @@ -4,7 +4,7 @@ class AgPropGuard final : public CppScripts::Script { public: - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; private: std::vector<int> gearSets = { 14359,14321,14353,14315 }; diff --git a/dScripts/ai/PROPERTY/AgPropguards.cpp b/dScripts/ai/PROPERTY/AgPropguards.cpp index 2bcfcf94..9fc6010a 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.cpp +++ b/dScripts/ai/PROPERTY/AgPropguards.cpp @@ -3,9 +3,9 @@ #include "GameMessages.h" #include "EntityManager.h" #include "dZoneManager.h" -#include "MissionState.h" +#include "eMissionState.h" -void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) { +void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { auto* character = target->GetCharacter(); if (character == nullptr) return; @@ -14,11 +14,11 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission if (flag == 0) return; - if ((missionState == MissionState::MISSION_STATE_AVAILABLE || missionState == MissionState::MISSION_STATE_ACTIVE) + if ((missionState == eMissionState::AVAILABLE || missionState == eMissionState::ACTIVE) && !character->GetPlayerFlag(flag)) { // If the player just started the mission, play a cinematic highlighting the target GameMessages::SendPlayCinematic(target->GetObjectID(), u"MissionCam", target->GetSystemAddress()); - } else if (missionState == MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE) { + } else if (missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { // Makes the guard disappear once the mission has been completed const auto zoneControlID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); GameMessages::SendNotifyClientObject(zoneControlID, u"GuardChat", 0, 0, self->GetObjectID(), diff --git a/dScripts/ai/PROPERTY/AgPropguards.h b/dScripts/ai/PROPERTY/AgPropguards.h index 511b7b6a..25701f86 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.h +++ b/dScripts/ai/PROPERTY/AgPropguards.h @@ -2,7 +2,7 @@ #include "CppScripts.h" class AgPropguards : public CppScripts::Script { - void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override; + void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; private: static uint32_t GetFlagForMission(uint32_t missionID); }; diff --git a/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp b/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp index 32dbf619..f69a3eb6 100644 --- a/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp @@ -3,8 +3,9 @@ #include "DestroyableComponent.h" #include "EntityManager.h" #include "PossessableComponent.h" -#include "RacingTaskParam.h" +#include "eRacingTaskParam.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" void FvRaceSmashEggImagineServer::OnDie(Entity* self, Entity* killer) { if (killer != nullptr) { @@ -29,8 +30,8 @@ void FvRaceSmashEggImagineServer::OnDie(Entity* self, Entity* killer) { } if (missionComponent == nullptr) return; // Dragon eggs have their own smash server so we handle mission progression for them here. - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, 0, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASHABLES); - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, self->GetLOT(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASH_SPECIFIC_SMASHABLE); + missionComponent->Progress(eMissionTaskType::RACING, 0, (LWOOBJID)eRacingTaskParam::SMASHABLES); + missionComponent->Progress(eMissionTaskType::RACING, self->GetLOT(), (LWOOBJID)eRacingTaskParam::SMASH_SPECIFIC_SMASHABLE); } } diff --git a/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp b/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp index a35007b4..6a29f9a8 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp @@ -3,9 +3,10 @@ #include "EntityManager.h" #include "PossessableComponent.h" #include "RaceImagineCrateServer.h" -#include "RacingTaskParam.h" +#include "eRacingTaskParam.h" #include "MissionComponent.h" #include "SkillComponent.h" +#include "eMissionTaskType.h" void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) { if (self->GetVar<bool>(u"bIsDead")) { @@ -49,7 +50,7 @@ void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) { // Progress racing smashable missions if (missionComponent == nullptr) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, 0, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASHABLES); + missionComponent->Progress(eMissionTaskType::RACING, 0, (LWOOBJID)eRacingTaskParam::SMASHABLES); } } } diff --git a/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp b/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp index 9bdd0813..92a50873 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp @@ -2,8 +2,9 @@ #include "EntityManager.h" #include "PossessorComponent.h" #include "RaceImaginePowerup.h" -#include "RacingTaskParam.h" +#include "eRacingTaskParam.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" void RaceImaginePowerup::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { @@ -31,6 +32,6 @@ void RaceImaginePowerup::OnFireEventServerSide(Entity* self, Entity* sender, std auto* missionComponent = sender->GetComponent<MissionComponent>(); if (missionComponent == nullptr) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, self->GetLOT(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_COLLECT_IMAGINATION); + missionComponent->Progress(eMissionTaskType::RACING, self->GetLOT(), (LWOOBJID)eRacingTaskParam::COLLECT_IMAGINATION); } } diff --git a/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp b/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp index d0dc3d78..295f38ee 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp @@ -2,8 +2,9 @@ #include "EntityManager.h" #include "PossessableComponent.h" #include "RaceSmashServer.h" -#include "RacingTaskParam.h" +#include "eRacingTaskParam.h" #include "MissionComponent.h" +#include "eMissionTaskType.h" void RaceSmashServer::OnDie(Entity* self, Entity* killer) { // Crate is smashed by the car @@ -22,9 +23,9 @@ void RaceSmashServer::OnDie(Entity* self, Entity* killer) { // Progress racing smashable missions if (missionComponent == nullptr) return; - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, 0, (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASHABLES); + missionComponent->Progress(eMissionTaskType::RACING, 0, (LWOOBJID)eRacingTaskParam::SMASHABLES); // Progress missions that ask us to smash a specific smashable. - missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_RACING, self->GetLOT(), (LWOOBJID)RacingTaskParam::RACING_TASK_PARAM_SMASH_SPECIFIC_SMASHABLE); + missionComponent->Progress(eMissionTaskType::RACING, self->GetLOT(), (LWOOBJID)eRacingTaskParam::SMASH_SPECIFIC_SMASHABLE); } } } From bff14fd391307f69187bb4478f14bf7de94516bf Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Sun, 22 Jan 2023 17:39:38 -0600 Subject: [PATCH 123/166] add blame ignore --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 37567a02..14e48fbe 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -6,3 +6,6 @@ # convert to unix line endings 72477e01e2711e0f61cdb192ee266e5e21b8846f + +# enum cleanup +faf42d2f8cf432df2993b031f079b0b8c6d7dbe7 From 90d184ba93537597411eb5849eb918caf5becc0e Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Tue, 24 Jan 2023 22:36:30 +0000 Subject: [PATCH 124/166] Remove Clang Tidy configurations. (#969) --- .clang-format | 37 ------------------------------------- .clang-tidy | 17 ----------------- 2 files changed, 54 deletions(-) delete mode 100644 .clang-format delete mode 100644 .clang-tidy diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 5af12d3a..00000000 --- a/.clang-format +++ /dev/null @@ -1,37 +0,0 @@ ---- -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false - BeforeLambdaBody: false - BeforeWhile: false -BreakBeforeBraces: Attach -ColumnLimit: 0 -IndentWidth: 4 -IndentCaseLabels: true -IncludeBlocks: Regroup -IncludeCategories: - - Regex: '<[[:alnum:].]+\.h>' - Priority: 1 - - Regex: '<[[:alnum:].]+>' - Priority: 2 - - Regex: '.*/.*' - Priority: 3 - - Regex: '.*' - Priority: 4 -DerivePointerAlignment: false -PointerAlignment: Left -... diff --git a/.clang-tidy b/.clang-tidy deleted file mode 100644 index ea50801d..00000000 --- a/.clang-tidy +++ /dev/null @@ -1,17 +0,0 @@ -Checks: '-*,readability-*,performance-*,modernize-*,-modernize-use-trailing-return-type,bugprone-*' -WarningsAsErrors: true -HeaderFilterRegex: '' -FormatStyle: none -CheckOptions: - - key: readability-identifier-naming.ClassCase - value: CamelCase - - key: readability-identifier-naming.ClassMethodCase - value: CamelCase - - key: readability-identifier-naming.ClassMemberPrefix - value: m_ - - key: readability-identifier-naming.ClassMemberCase - value: CamelCase - - key: readability-identifier-naming.ClassConstantCase - value: UPPER_CASE - - key: readability-identifier-naming.FunctionCase - value: CamelCase \ No newline at end of file From cdffd5ff30772c2223c05a92ee04b31aa4867b37 Mon Sep 17 00:00:00 2001 From: "Gie \"Max\" Vanommeslaeghe" <gievanom@hotmail.com> Date: Wed, 25 Jan 2023 00:09:32 +0100 Subject: [PATCH 125/166] Fix: 968 bug using lookup command with no parameters crashes instance (#970) * Update SlashCommandHandler.cpp * Update SlashCommandHandler.cpp --- dGame/dUtilities/SlashCommandHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 1bd3f6f3..d8be44c6 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1199,7 +1199,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { auto query = CDClientDatabase::CreatePreppedStmt( "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); // Concatenate all of the arguments into a single query so a multi word query can be used properly. From 6aa69de4fd4cb29144c71687024873571960938a Mon Sep 17 00:00:00 2001 From: Jett <55758076+Jettford@users.noreply.github.com> Date: Thu, 26 Jan 2023 00:21:12 +0000 Subject: [PATCH 126/166] Resolution of accidental shifting of eItemType enum (#976) --- dCommon/dEnums/eItemType.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dCommon/dEnums/eItemType.h b/dCommon/dEnums/eItemType.h index 69eb18e9..41c7765b 100644 --- a/dCommon/dEnums/eItemType.h +++ b/dCommon/dEnums/eItemType.h @@ -7,7 +7,7 @@ enum class eItemType : int32_t { UNKNOWN = -1, - BRICK, + BRICK = 1, HAT, HAIR, NECK, From d17f51183ea2f063e60505694a09f7ae8d47d8f1 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 26 Jan 2023 18:41:40 -0800 Subject: [PATCH 127/166] Allow landing animation in Return to the Venture Explorer (#977) --- dGame/dComponents/CharacterComponent.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index ecd5e7b2..98540bd0 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -43,7 +43,6 @@ bool CharacterComponent::LandingAnimDisabled(int zoneID) { switch (zoneID) { case 0: case 556: - case 1001: case 1101: case 1202: case 1203: From 91c0c1fcfb682ff68ded75d71b5b211e4e630b75 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 10 Feb 2023 02:29:53 -0600 Subject: [PATCH 128/166] Split out LUTriggers into it's own component (#986) * Split out LUTriggers into it's own component * some cleanup * fix debug log * use emplace and tryParse * slight refactor to make the work on startup rather than at runtime Also TODO's for getting targets via all the possible methods * address feedback --- dCommon/dEnums/dCommonVars.h | 1 + dCommon/dEnums/eTriggerCommandType.h | 119 +++++++++++++++ dCommon/dEnums/eTriggerEventType.h | 53 +++++++ dGame/Entity.cpp | 137 +++-------------- dGame/Entity.h | 11 +- dGame/EntityManager.cpp | 3 +- dGame/dComponents/CMakeLists.txt | 1 + dGame/dComponents/SwitchComponent.cpp | 5 +- dGame/dComponents/TriggerComponent.cpp | 187 +++++++++++++++++++++++ dGame/dComponents/TriggerComponent.h | 34 +++++ dGame/dUtilities/SlashCommandHandler.cpp | 9 +- dZoneManager/LUTriggers.h | 7 +- dZoneManager/Zone.cpp | 7 +- 13 files changed, 437 insertions(+), 137 deletions(-) create mode 100644 dCommon/dEnums/eTriggerCommandType.h create mode 100644 dCommon/dEnums/eTriggerEventType.h create mode 100644 dGame/dComponents/TriggerComponent.cpp create mode 100644 dGame/dComponents/TriggerComponent.h diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 9bf824e0..c90fd8e6 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -414,6 +414,7 @@ enum eReplicaComponentType : int32_t { COMPONENT_TYPE_MODULE_ASSEMBLY = 61, //!< The ModuleAssembly Component COMPONENT_TYPE_PROPERTY_VENDOR = 65, //!< The PropertyVendor Component COMPONENT_TYPE_ROCKET_LAUNCH = 67, //!< The RocketLaunch Component + COMPONENT_TYPE_TRIGGER = 69, COMPONENT_TYPE_RACING_CONTROL = 71, //!< The RacingControl Component COMPONENT_TYPE_MISSION_OFFER = 73, //!< The MissionOffer Component COMPONENT_TYPE_EXHIBIT = 75, //!< The Exhibit Component diff --git a/dCommon/dEnums/eTriggerCommandType.h b/dCommon/dEnums/eTriggerCommandType.h new file mode 100644 index 00000000..fadfafb8 --- /dev/null +++ b/dCommon/dEnums/eTriggerCommandType.h @@ -0,0 +1,119 @@ +#ifndef __ETRIGGERCOMMANDTYPE__H__ +#define __ETRIGGERCOMMANDTYPE__H__ + +// For info about Trigger Command see: +// https://docs.lu-dev.net/en/latest/file-structures/lutriggers.html?highlight=trigger#possible-values-commands + +enum class eTriggerCommandType { + INVALID, + ZONE_PLAYER, + FIRE_EVENT, + DESTROY_OBJ, + TOGGLE_TRIGGER, + RESET_REBUILD, + SET_PATH, + SET_PICK_TYPE, + MOVE_OBJECT, + ROTATE_OBJECT, + PUSH_OBJECT, + REPEL_OBJECT, + SET_TIMER, + CANCEL_TIMER, + PLAY_CINEMATIC, + TOGGLE_BBB, + UPDATE_MISSION, + SET_BOUNCER_STATE, + BOUNCE_ALL_ON_BOUNCER, + TURN_AROUND_ON_PATH, + GO_FORWARD_ON_PATH, + GO_BACKWARD_ON_PATH, + STOP_PATHING, + START_PATHING, + LOCK_OR_UNLOCK_CONTROLS, + PLAY_EFFECT, + STOP_EFFECT, + ACTIVATE_MUSIC_CUE, + DEACTIVATE_MUSIC_CUE, + FLASH_MUSIC_CUE, + SET_MUSIC_PARAMETER, + PLAY_2D_AMBIENT_SOUND, + STOP_2D_AMBIENT_SOUND, + PLAY_3D_AMBIENT_SOUND, + STOP_3D_AMBIENT_SOUND, + ACTIVATE_MIXER_PROGRAM, + DEACTIVATE_MIXER_PROGRAM, + CAST_SKILL, + DISPLAY_ZONE_SUMMARY, + SET_PHYSICS_VOLUME_EFFECT, + SET_PHYSICS_VOLUME_STATUS, + SET_MODEL_TO_BUILD, + SPAWN_MODEL_BRICKS, + ACTIVATE_SPAWNER_NETWORK, + DEACTIVATE_SPAWNER_NETWORK, + RESET_SPAWNER_NETWORK, + DESTROY_SPAWNER_NETWORK_OBJECTS, + GO_TO_WAYPOINT, + ACTIVATE_PHYSICS +}; + + +class TriggerCommandType { +public: + static eTriggerCommandType StringToTriggerCommandType(std::string commandString) { + const std::map<std::string, eTriggerCommandType> TriggerCommandMap = { + { "zonePlayer", eTriggerCommandType::ZONE_PLAYER}, + { "fireEvent", eTriggerCommandType::FIRE_EVENT}, + { "destroyObj", eTriggerCommandType::DESTROY_OBJ}, + { "toggleTrigger", eTriggerCommandType::TOGGLE_TRIGGER}, + { "resetRebuild", eTriggerCommandType::RESET_REBUILD}, + { "setPath", eTriggerCommandType::SET_PATH}, + { "setPickType", eTriggerCommandType::SET_PICK_TYPE}, + { "moveObject", eTriggerCommandType::MOVE_OBJECT}, + { "rotateObject", eTriggerCommandType::ROTATE_OBJECT}, + { "pushObject", eTriggerCommandType::PUSH_OBJECT}, + { "repelObject", eTriggerCommandType::REPEL_OBJECT}, + { "setTimer", eTriggerCommandType::SET_TIMER}, + { "cancelTimer", eTriggerCommandType::CANCEL_TIMER}, + { "playCinematic", eTriggerCommandType::PLAY_CINEMATIC}, + { "toggleBBB", eTriggerCommandType::TOGGLE_BBB}, + { "updateMission", eTriggerCommandType::UPDATE_MISSION}, + { "setBouncerState", eTriggerCommandType::SET_BOUNCER_STATE}, + { "bounceAllOnBouncer", eTriggerCommandType::BOUNCE_ALL_ON_BOUNCER}, + { "turnAroundOnPath", eTriggerCommandType::TURN_AROUND_ON_PATH}, + { "goForwardOnPath", eTriggerCommandType::GO_FORWARD_ON_PATH}, + { "goBackwardOnPath", eTriggerCommandType::GO_BACKWARD_ON_PATH}, + { "stopPathing", eTriggerCommandType::STOP_PATHING}, + { "startPathing", eTriggerCommandType::START_PATHING}, + { "LockOrUnlockControls", eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS}, + { "PlayEffect", eTriggerCommandType::PLAY_EFFECT}, + { "StopEffect", eTriggerCommandType::STOP_EFFECT}, + { "activateMusicCue", eTriggerCommandType::ACTIVATE_MUSIC_CUE}, + { "deactivateMusicCue", eTriggerCommandType::DEACTIVATE_MUSIC_CUE}, + { "flashMusicCue", eTriggerCommandType::FLASH_MUSIC_CUE}, + { "setMusicParameter", eTriggerCommandType::SET_MUSIC_PARAMETER}, + { "play2DAmbientSound", eTriggerCommandType::PLAY_2D_AMBIENT_SOUND}, + { "stop2DAmbientSound", eTriggerCommandType::STOP_2D_AMBIENT_SOUND}, + { "play3DAmbientSound", eTriggerCommandType::PLAY_3D_AMBIENT_SOUND}, + { "stop3DAmbientSound", eTriggerCommandType::STOP_3D_AMBIENT_SOUND}, + { "activateMixerProgram", eTriggerCommandType::ACTIVATE_MIXER_PROGRAM}, + { "deactivateMixerProgram", eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM}, + { "CastSkill", eTriggerCommandType::CAST_SKILL}, + { "displayZoneSummary", eTriggerCommandType::DISPLAY_ZONE_SUMMARY}, + { "SetPhysicsVolumeEffect", eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT}, + { "SetPhysicsVolumeStatus", eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS}, + { "setModelToBuild", eTriggerCommandType::SET_MODEL_TO_BUILD}, + { "spawnModelBricks", eTriggerCommandType::SPAWN_MODEL_BRICKS}, + { "ActivateSpawnerNetwork", eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK}, + { "DeactivateSpawnerNetwork", eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK}, + { "ResetSpawnerNetwork", eTriggerCommandType::RESET_SPAWNER_NETWORK}, + { "DestroySpawnerNetworkObjects", eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS}, + { "Go_To_Waypoint", eTriggerCommandType::GO_TO_WAYPOINT}, + { "ActivatePhysics", eTriggerCommandType::ACTIVATE_PHYSICS} + }; + + auto intermed = TriggerCommandMap.find(commandString); + return (intermed != TriggerCommandMap.end()) ? intermed->second : eTriggerCommandType::INVALID; + }; +}; + +#endif //!__ETRIGGERCOMMANDTYPE__H__ diff --git a/dCommon/dEnums/eTriggerEventType.h b/dCommon/dEnums/eTriggerEventType.h new file mode 100644 index 00000000..1705ce22 --- /dev/null +++ b/dCommon/dEnums/eTriggerEventType.h @@ -0,0 +1,53 @@ +#ifndef __ETRIGGEREVENTTYPE__H__ +#define __ETRIGGEREVENTTYPE__H__ + +enum class eTriggerEventType { + INVALID, + DESTROY, + CUSTOM_EVENT, + ENTER, + EXIT, + CREATE, + HIT, + TIMER_DONE, + REBUILD_COMPLETE, + ACTIVATED, + DEACTIVATED, + ARRIVED, + ARRIVED_AT_END_OF_PATH, + ZONE_SUMMARY_DISMISSED, + ARRIVED_AT_DESIRED_WAYPOINT, + PET_ON_SWITCH, + PET_OFF_SWITCH, + INTERACT +}; + +class TriggerEventType { +public: + static eTriggerEventType StringToTriggerEventType(std::string commandString) { + const std::map<std::string, eTriggerEventType> TriggerEventMap = { + {"OnDestroy", eTriggerEventType::DESTROY}, + {"OnCustomEvent", eTriggerEventType::CUSTOM_EVENT}, + {"OnEnter", eTriggerEventType::ENTER}, + {"OnExit", eTriggerEventType::EXIT}, + {"OnCreate", eTriggerEventType::CREATE}, + {"OnHit", eTriggerEventType::HIT}, + {"OnTimerDone", eTriggerEventType::TIMER_DONE}, + {"OnRebuildComplete", eTriggerEventType::REBUILD_COMPLETE}, + {"OnActivated", eTriggerEventType::ACTIVATED}, + {"OnDeactivated", eTriggerEventType::DEACTIVATED}, + {"OnArrived", eTriggerEventType::ARRIVED}, + {"OnArrivedAtEndOfPath", eTriggerEventType::ARRIVED_AT_END_OF_PATH}, + {"OnZoneSummaryDismissed", eTriggerEventType::ZONE_SUMMARY_DISMISSED}, + {"OnArrivedAtDesiredWaypoint", eTriggerEventType::ARRIVED_AT_DESIRED_WAYPOINT}, + {"OnPetOnSwitch", eTriggerEventType::PET_ON_SWITCH}, + {"OnPetOffSwitch", eTriggerEventType::PET_OFF_SWITCH}, + {"OnInteract", eTriggerEventType::INTERACT}, + }; + + auto intermed = TriggerEventMap.find(commandString); + return (intermed != TriggerEventMap.end()) ? intermed->second : eTriggerEventType::INVALID; + }; +}; + +#endif //!__ETRIGGEREVENTTYPE__H__ diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index eefa5107..94693385 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -23,6 +23,7 @@ #include "EntityCallbackTimer.h" #include "Loot.h" #include "eMissionTaskType.h" +#include "eTriggerEventType.h" //Component includes: #include "Component.h" @@ -68,6 +69,7 @@ #include "ShootingGalleryComponent.h" #include "RailActivatorComponent.h" #include "LUPExhibitComponent.h" +#include "TriggerComponent.h" Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) { m_ObjectID = objectID; @@ -76,7 +78,6 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) m_Character = nullptr; m_GMLevel = 0; m_CollectibleID = 0; - m_Trigger = nullptr; //new LUTriggers::Trigger(); m_NetworkID = 0; m_Groups = {}; m_OwnerOverride = LWOOBJID_EMPTY; @@ -132,30 +133,9 @@ void Entity::Initialize() { * Setup trigger */ - const auto triggerName = GetVarAsString(u"trigger_id"); + const auto triggerInfo = GetVarAsString(u"trigger_id"); - if (!triggerName.empty()) { - std::stringstream ss(triggerName); - std::vector<std::string> tokens; - std::string token; - while (std::getline(ss, token, ':')) { - tokens.push_back(token); - } - - uint32_t sceneID = std::stoi(tokens[0]); - uint32_t triggerID = std::stoi(tokens[1]); - - if (m_Trigger != nullptr) { - delete m_Trigger; - m_Trigger = nullptr; - } - - m_Trigger = dZoneManager::Instance()->GetZone()->GetTrigger(sceneID, triggerID); - - if (m_Trigger == nullptr) { - m_Trigger = new LUTriggers::Trigger(); - } - } + if (!triggerInfo.empty()) m_Components.emplace(COMPONENT_TYPE_TRIGGER, new TriggerComponent(this, triggerInfo)); /** * Setup groups @@ -769,7 +749,7 @@ void Entity::Initialize() { no_ghosting: - TriggerEvent("OnCreate"); + TriggerEvent(eTriggerEventType::CREATE); if (m_Character) { auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>(); @@ -946,12 +926,16 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke outBitStream->Write0(); //No ldf data } - if (m_Trigger != nullptr && m_Trigger->events.size() > 0) { - outBitStream->Write1(); - } else { + TriggerComponent* triggerComponent; + if (TryGetComponent(COMPONENT_TYPE_TRIGGER, triggerComponent)) { + // has trigger component, check to see if we have events to handle + auto* trigger = triggerComponent->GetTrigger(); + outBitStream->Write<bool>(trigger && trigger->events.size() > 0); + } else { // no trigger componenet, so definitely no triggers outBitStream->Write0(); } + if (m_ParentEntity != nullptr || m_SpawnerID != 0) { outBitStream->Write1(); if (m_ParentEntity != nullptr) outBitStream->Write(GeneralUtils::SetBit(m_ParentEntity->GetObjectID(), OBJECT_BIT_CLIENT)); @@ -1310,7 +1294,7 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) { switchComp->EntityEnter(other); } - TriggerEvent("OnEnter", other); + TriggerEvent(eTriggerEventType::ENTER, other); // POI system const auto& poi = GetVar<std::u16string>(u"POI"); @@ -1344,7 +1328,7 @@ void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) { auto* other = EntityManager::Instance()->GetEntity(otherEntity); if (!other) return; - TriggerEvent("OnLeave", other); + TriggerEvent(eTriggerEventType::EXIT, other); SwitchComponent* switchComp = GetComponent<SwitchComponent>(); if (switchComp) { @@ -1392,7 +1376,7 @@ void Entity::OnEmoteReceived(const int32_t emote, Entity* target) { } void Entity::OnUse(Entity* originator) { - TriggerEvent("OnInteract"); + TriggerEvent(eTriggerEventType::INTERACT); for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { script->OnUse(this, originator); @@ -1736,94 +1720,9 @@ bool Entity::IsPlayer() const { return m_TemplateID == 1 && GetSystemAddress() != UNASSIGNED_SYSTEM_ADDRESS; } -void Entity::TriggerEvent(std::string eventID, Entity* optionalTarget) { - if (m_Trigger != nullptr && m_Trigger->enabled) { - for (LUTriggers::Event* triggerEvent : m_Trigger->events) { - if (triggerEvent->eventID == eventID) { - for (LUTriggers::Command* cmd : triggerEvent->commands) { - HandleTriggerCommand(cmd->id, cmd->target, cmd->targetName, cmd->args, optionalTarget); - } - } - } - } -} - -// This should probably get it's own triggers class at some point... -void Entity::HandleTriggerCommand(std::string id, std::string target, std::string targetName, std::string args, Entity* optionalTarget) { - std::vector<std::string> argArray; - // Parse args - std::stringstream ssData(args); - std::string token; - char deliminator = ','; - - while (std::getline(ssData, token, deliminator)) { - std::string lowerToken; - for (char character : token) { - lowerToken.push_back(std::tolower(character)); // make lowercase to ensure it works - } - argArray.push_back(lowerToken); - } - - std::vector<Entity*> targetEntities; - if (target == "self") targetEntities.push_back(this); - if (target == "objGroup") targetEntities = EntityManager::Instance()->GetEntitiesInGroup(targetName); - if (optionalTarget) targetEntities.push_back(optionalTarget); - if (targetEntities.size() == 0) return; - for (Entity* targetEntity : targetEntities) { - if (!targetEntity) continue; - - if (id == "SetPhysicsVolumeEffect") { - PhantomPhysicsComponent* phanPhys = GetComponent<PhantomPhysicsComponent>(); - if (!phanPhys) return; - - phanPhys->SetPhysicsEffectActive(true); - uint32_t effectType = 0; - if (argArray[0] == "push") effectType = 0; - else if (argArray[0] == "attract") effectType = 1; - else if (argArray[0] == "repulse") effectType = 2; - else if (argArray[0] == "gravity") effectType = 3; - else if (argArray[0] == "friction") effectType = 4; - - phanPhys->SetEffectType(effectType); - phanPhys->SetDirectionalMultiplier(std::stof(argArray[1])); - if (argArray.size() > 4) { - NiPoint3 direction = NiPoint3::ZERO; - GeneralUtils::TryParse<float>(argArray[2], direction.x); - GeneralUtils::TryParse<float>(argArray[3], direction.y); - GeneralUtils::TryParse<float>(argArray[4], direction.z); - phanPhys->SetDirection(direction); - } - if (argArray.size() > 5) { - phanPhys->SetMin(std::stoi(argArray[6])); - phanPhys->SetMax(std::stoi(argArray[7])); - } - - if (target == "self") { - EntityManager::Instance()->ConstructEntity(this); - } - } else if (id == "updateMission") { - CDMissionTasksTable* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); - std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { - std::string lowerTargetGroup; - for (char character : entry.targetGroup) { - lowerTargetGroup.push_back(std::tolower(character)); // make lowercase to ensure it works - } - - return (lowerTargetGroup == argArray[4]); - }); - - for (const CDMissionTasks& task : missionTasks) { - MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>(); - if (!missionComponent) continue; - - missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray[2])); - } - } else if (id == "fireEvent") { - for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { - script->OnFireEventServerSide(targetEntity, this, args, 0, 0, 0); - } - } - } +void Entity::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) { + auto* triggerComponent = GetComponent<TriggerComponent>(); + if (triggerComponent) triggerComponent->TriggerEvent(event, optionalTarget); } Entity* Entity::GetOwner() const { diff --git a/dGame/Entity.h b/dGame/Entity.h index 248018c0..0bde01e2 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -18,9 +18,6 @@ namespace Loot { namespace tinyxml2 { class XMLDocument; }; -namespace LUTriggers { - struct Trigger; -}; class Player; class EntityInfo; @@ -33,6 +30,7 @@ class Component; class Item; class Character; class EntityCallbackTimer; +enum class eTriggerEventType; namespace CppScripts { class Script; @@ -67,8 +65,6 @@ public: Entity* GetParentEntity() const { return m_ParentEntity; } - LUTriggers::Trigger* GetTrigger() const { return m_Trigger; } - std::vector<std::string>& GetGroups() { return m_Groups; }; Spawner* GetSpawner() const { return m_Spawner; } @@ -221,9 +217,8 @@ public: void RegisterCoinDrop(uint64_t count); void ScheduleKillAfterUpdate(Entity* murderer = nullptr); - void TriggerEvent(std::string eveneventtID, Entity* optionalTarget = nullptr); + void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; } - void HandleTriggerCommand(std::string id, std::string target, std::string targetName, std::string args, Entity* optionalTarget); virtual NiPoint3 GetRespawnPosition() const { return NiPoint3::ZERO; } virtual NiQuaternion GetRespawnRotation() const { return NiQuaternion::IDENTITY; } @@ -308,8 +303,6 @@ protected: bool m_HasSpawnerNodeID; uint32_t m_SpawnerNodeID; - LUTriggers::Trigger* m_Trigger; - Character* m_Character; Entity* m_ParentEntity; //For spawners and the like diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 22c31291..dae27af6 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -19,6 +19,7 @@ #include "dLogger.h" #include "MessageIdentifiers.h" #include "dConfig.h" +#include "eTriggerEventType.h" EntityManager* EntityManager::m_Address = nullptr; @@ -585,7 +586,7 @@ void EntityManager::ScheduleForKill(Entity* entity) { SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>(); if (switchComp) { - entity->TriggerEvent("OnDectivated"); + entity->TriggerEvent(eTriggerEventType::DEACTIVATED); } const auto objectId = entity->GetObjectID(); diff --git a/dGame/dComponents/CMakeLists.txt b/dGame/dComponents/CMakeLists.txt index 0995428b..b396829a 100644 --- a/dGame/dComponents/CMakeLists.txt +++ b/dGame/dComponents/CMakeLists.txt @@ -38,5 +38,6 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp" "SkillComponent.cpp" "SoundTriggerComponent.cpp" "SwitchComponent.cpp" + "TriggerComponent.cpp" "VehiclePhysicsComponent.cpp" "VendorComponent.cpp" PARENT_SCOPE) diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index 2263a866..dbdf37a9 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -1,5 +1,6 @@ #include "SwitchComponent.h" #include "EntityManager.h" +#include "eTriggerEventType.h" std::vector<SwitchComponent*> SwitchComponent::petSwitches; @@ -42,7 +43,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { } m_Active = true; if (!m_Parent) return; - m_Parent->TriggerEvent("OnActivated"); + m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED); const auto grpName = m_Parent->GetVarAsString(u"grp_name"); @@ -78,7 +79,7 @@ void SwitchComponent::Update(float deltaTime) { if (m_Timer <= 0.0f) { m_Active = false; if (!m_Parent) return; - m_Parent->TriggerEvent("OnDectivated"); + m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED); const auto grpName = m_Parent->GetVarAsString(u"grp_name"); diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp new file mode 100644 index 00000000..4ed95a15 --- /dev/null +++ b/dGame/dComponents/TriggerComponent.cpp @@ -0,0 +1,187 @@ +#include "TriggerComponent.h" +#include "dZoneManager.h" +#include "LUTriggers.h" +#include "eTriggerCommandType.h" +#include "MissionComponent.h" +#include "PhantomPhysicsComponent.h" +#include "CDMissionTasksTable.h" + +TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) { + m_Parent = parent; + m_Trigger = nullptr; + + std::vector<std::string> tokens = GeneralUtils::SplitString(triggerInfo, ':'); + + uint32_t sceneID; + GeneralUtils::TryParse<uint32_t>(tokens.at(0), sceneID); + uint32_t triggerID; + GeneralUtils::TryParse<uint32_t>(tokens.at(1), triggerID); + + m_Trigger = dZoneManager::Instance()->GetZone()->GetTrigger(sceneID, triggerID); + + if (!m_Trigger) m_Trigger = new LUTriggers::Trigger(); +} + +void TriggerComponent::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) { + if (m_Trigger && m_Trigger->enabled) { + for (LUTriggers::Event* triggerEvent : m_Trigger->events) { + if (triggerEvent->id == event) { + for (LUTriggers::Command* command : triggerEvent->commands) { + HandleTriggerCommand(command, optionalTarget); + } + } + } + } +} + +void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget) { + auto argArray = GeneralUtils::SplitString(command->args, ','); + + // determine targets + std::vector<Entity*> targetEntities = GatherTargets(command, optionalTarget); + + // if we have no targets, then we are done + if (targetEntities.empty()) return; + + for (Entity* targetEntity : targetEntities) { + if (!targetEntity) continue; + + switch (command->id) { + case eTriggerCommandType::ZONE_PLAYER: break; + case eTriggerCommandType::FIRE_EVENT: + HandleFireEvent(targetEntity, command->args); + break; + case eTriggerCommandType::DESTROY_OBJ: break; + case eTriggerCommandType::TOGGLE_TRIGGER: break; + case eTriggerCommandType::RESET_REBUILD: break; + case eTriggerCommandType::SET_PATH: break; + case eTriggerCommandType::SET_PICK_TYPE: break; + case eTriggerCommandType::MOVE_OBJECT: break; + case eTriggerCommandType::ROTATE_OBJECT: break; + case eTriggerCommandType::PUSH_OBJECT: break; + case eTriggerCommandType::REPEL_OBJECT: break; + case eTriggerCommandType::SET_TIMER: break; + case eTriggerCommandType::CANCEL_TIMER: break; + case eTriggerCommandType::PLAY_CINEMATIC: break; + case eTriggerCommandType::TOGGLE_BBB: break; + case eTriggerCommandType::UPDATE_MISSION: + HandleUpdateMission(targetEntity, argArray); + break; + case eTriggerCommandType::SET_BOUNCER_STATE: break; + case eTriggerCommandType::BOUNCE_ALL_ON_BOUNCER: break; + case eTriggerCommandType::TURN_AROUND_ON_PATH: break; + case eTriggerCommandType::GO_FORWARD_ON_PATH: break; + case eTriggerCommandType::GO_BACKWARD_ON_PATH: break; + case eTriggerCommandType::STOP_PATHING: break; + case eTriggerCommandType::START_PATHING: break; + case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break; + case eTriggerCommandType::PLAY_EFFECT: break; + case eTriggerCommandType::STOP_EFFECT: break; + case eTriggerCommandType::ACTIVATE_MUSIC_CUE: break; + case eTriggerCommandType::DEACTIVATE_MUSIC_CUE: break; + case eTriggerCommandType::FLASH_MUSIC_CUE: break; + case eTriggerCommandType::SET_MUSIC_PARAMETER: break; + case eTriggerCommandType::PLAY_2D_AMBIENT_SOUND: break; + case eTriggerCommandType::STOP_2D_AMBIENT_SOUND: break; + case eTriggerCommandType::PLAY_3D_AMBIENT_SOUND: break; + case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break; + case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break; + case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break; + case eTriggerCommandType::CAST_SKILL: break; + case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: break; + case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT: + HandleSetPhysicsVolume(targetEntity, argArray, command->target); + break; + case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: break; + case eTriggerCommandType::SET_MODEL_TO_BUILD: break; + case eTriggerCommandType::SPAWN_MODEL_BRICKS: break; + case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: break; + case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: break; + case eTriggerCommandType::RESET_SPAWNER_NETWORK: break; + case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: break; + case eTriggerCommandType::GO_TO_WAYPOINT: break; + case eTriggerCommandType::ACTIVATE_PHYSICS: break; + default: + Game::logger->LogDebug("TriggerComponent", "Event %i was not handled!", command->id); + break; + } + } +} + +std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* command, Entity* optionalTarget) { + std::vector<Entity*> entities = {}; + + if (command->target == "self") entities.push_back(m_Parent); + else if (command->target == "zone") { /*TODO*/ } + else if (command->target == "target") { /*TODO*/ } + else if (command->target == "targetTeam") { /*TODO*/ } + else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); + else if (command->target == "allPlayers") { /*TODO*/ } + else if (command->target == "allNPCs") { /*TODO*/ } + + if (optionalTarget) entities.push_back(optionalTarget); + + return entities; +} + +void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target) { + PhantomPhysicsComponent* phanPhys = m_Parent->GetComponent<PhantomPhysicsComponent>(); + if (!phanPhys) return; + + phanPhys->SetPhysicsEffectActive(true); + uint32_t effectType = 0; + std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase + if (argArray.at(0) == "push") effectType = 0; + else if (argArray.at(0) == "attract") effectType = 1; + else if (argArray.at(0) == "repulse") effectType = 2; + else if (argArray.at(0) == "gravity") effectType = 3; + else if (argArray.at(0) == "friction") effectType = 4; + + phanPhys->SetEffectType(effectType); + phanPhys->SetDirectionalMultiplier(std::stof(argArray.at(1))); + if (argArray.size() > 4) { + NiPoint3 direction = NiPoint3::ZERO; + GeneralUtils::TryParse<float>(argArray.at(2), direction.x); + GeneralUtils::TryParse<float>(argArray.at(3), direction.y); + GeneralUtils::TryParse<float>(argArray.at(4), direction.z); + phanPhys->SetDirection(direction); + } + if (argArray.size() > 5) { + uint32_t min; + GeneralUtils::TryParse<uint32_t>(argArray.at(6), min); + phanPhys->SetMin(min); + + uint32_t max; + GeneralUtils::TryParse<uint32_t>(argArray.at(7), max); + phanPhys->SetMax(max); + } + + // TODO: why is this contruct and not serialize? + if (target == "self") EntityManager::Instance()->ConstructEntity(m_Parent); +} + +void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) { + CDMissionTasksTable* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); + std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { + std::string lowerTargetGroup; + for (char character : entry.targetGroup) { + lowerTargetGroup.push_back(std::tolower(character)); // make lowercase to ensure it works + } + + return (lowerTargetGroup == argArray[4]); + }); + + for (const CDMissionTasks& task : missionTasks) { + MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>(); + if (!missionComponent) continue; + + missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray[2])); + } +} + +void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) { + for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { + script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0); + } +} + diff --git a/dGame/dComponents/TriggerComponent.h b/dGame/dComponents/TriggerComponent.h new file mode 100644 index 00000000..d7711696 --- /dev/null +++ b/dGame/dComponents/TriggerComponent.h @@ -0,0 +1,34 @@ +#ifndef __TRIGGERCOMPONENT__H__ +#define __TRIGGERCOMPONENT__H__ + +#include "Component.h" + +namespace LUTriggers { + struct Trigger; + struct Command; +}; + +class TriggerComponent : public Component { +public: + static const uint32_t ComponentType = COMPONENT_TYPE_TRIGGER; + + explicit TriggerComponent(Entity* parent, const std::string triggerInfo); + + void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); + LUTriggers::Trigger* GetTrigger() const { return m_Trigger; } + +private: + + void HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget); + std::vector<std::string> ParseArgs(std::string args); + std::vector<Entity*> GatherTargets(LUTriggers::Command* command, Entity* optionalTarget); + + // Trigger Event Handlers + void HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target); + void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray); + void HandleFireEvent(Entity* targetEntity, std::string args); + void HandleCastSkill(Entity* targetEntity, uint32_t skillID); + + LUTriggers::Trigger* m_Trigger; +}; +#endif //!__TRIGGERCOMPONENT__H__ diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index d8be44c6..e558e19c 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -73,6 +73,7 @@ #include "MovingPlatformComponent.h" #include "dMessageIdentifiers.h" #include "eMissionState.h" +#include "TriggerComponent.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; @@ -1984,8 +1985,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Active: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetPhysicsEffectActive()))); } - if (closest->GetTrigger() != nullptr) { - ChatPackets::SendSystemMessage(sysAddr, u"Trigger: " + (GeneralUtils::to_u16string(closest->GetTrigger()->id))); + auto* triggerComponent = closest->GetComponent<TriggerComponent>(); + if (triggerComponent){ + auto trigger = triggerComponent->GetTrigger(); + if (trigger) { + ChatPackets::SendSystemMessage(sysAddr, u"Trigger: " + (GeneralUtils::to_u16string(trigger->id))); + } } } } diff --git a/dZoneManager/LUTriggers.h b/dZoneManager/LUTriggers.h index 1869b4c3..a93cd67d 100644 --- a/dZoneManager/LUTriggers.h +++ b/dZoneManager/LUTriggers.h @@ -6,17 +6,20 @@ class Command; class Event; +enum class eTriggerCommandType; +enum class eTriggerEventType; + namespace LUTriggers { struct Command { - std::string id; + eTriggerCommandType id; std::string target; std::string targetName; std::string args; }; struct Event { - std::string eventID; + eTriggerEventType id; std::vector<Command*> commands; }; diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 79d940af..c32f8447 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -14,6 +14,9 @@ #include "Spawner.h" #include "dZoneManager.h" +#include "eTriggerCommandType.h" +#include "eTriggerEventType.h" + Zone::Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) : m_ZoneID(mapID, instanceID, cloneID) { m_NumberOfScenesLoaded = 0; @@ -296,11 +299,11 @@ std::vector<LUTriggers::Trigger*> Zone::LoadLUTriggers(std::string triggerFile, auto currentEvent = currentTrigger->FirstChildElement("event"); while (currentEvent) { LUTriggers::Event* newEvent = new LUTriggers::Event(); - newEvent->eventID = currentEvent->Attribute("id"); + newEvent->id = TriggerEventType::StringToTriggerEventType(currentEvent->Attribute("id")); auto currentCommand = currentEvent->FirstChildElement("command"); while (currentCommand) { LUTriggers::Command* newCommand = new LUTriggers::Command(); - newCommand->id = currentCommand->Attribute("id"); + newCommand->id = TriggerCommandType::StringToTriggerCommandType(currentCommand->Attribute("id")); newCommand->target = currentCommand->Attribute("target"); if (currentCommand->Attribute("targetName") != NULL) { newCommand->targetName = currentCommand->Attribute("targetName"); From 3cd0d1ec3df09b1cc741cd333760dd94a11c276b Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 10 Feb 2023 02:30:17 -0600 Subject: [PATCH 129/166] Make wrapper for casting skills (#987) * Make wrapper for casting skills this is to reduce magic numbers in the code base Only updated one use of this to demo that this works. Will be do more in a sepearate PR. Also, inadvertantly fix damage stacking and self-damage in the teslapack * add skill<->behavior caching * explicit by reference * address emo's feedback --- dGame/dComponents/SkillComponent.cpp | 26 +++++++++++++++++++ dGame/dComponents/SkillComponent.h | 14 ++++++++++ .../EquipmentTriggers/CoilBackpackBase.cpp | 4 +-- dScripts/EquipmentTriggers/CoilBackpackBase.h | 4 +-- dScripts/EquipmentTriggers/GemPack.h | 3 +-- dScripts/EquipmentTriggers/ShardArmor.h | 3 +-- dScripts/EquipmentTriggers/TeslaPack.h | 3 +-- 7 files changed, 46 insertions(+), 11 deletions(-) diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 562c284a..2391dc3b 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -22,10 +22,13 @@ #include "EchoStartSkill.h" #include "dMessageIdentifiers.h" #include "DoClientProjectileImpact.h" +#include "CDClientManager.h" ProjectileSyncEntry::ProjectileSyncEntry() { } +std::unordered_map<uint32_t, uint32_t> SkillComponent::m_skillBehaviorCache = {}; + bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t skillUid, RakNet::BitStream* bitStream, const LWOOBJID target, uint32_t skillID) { auto* context = new BehaviorContext(this->m_Parent->GetObjectID()); @@ -210,6 +213,29 @@ void SkillComponent::RegisterCalculatedProjectile(const LWOOBJID projectileId, B this->m_managedProjectiles.push_back(entry); } +bool SkillComponent::CastSkill(const uint32_t skillId, LWOOBJID target, const LWOOBJID optionalOriginatorID){ + uint32_t behaviorId = -1; + // try to find it via the cache + const auto& pair = m_skillBehaviorCache.find(skillId); + + // if it's not in the cache look it up and cache it + if (pair == m_skillBehaviorCache.end()) { + auto skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + behaviorId = skillTable->GetSkillByID(skillId).behaviorID; + m_skillBehaviorCache.insert_or_assign(skillId, behaviorId); + } else { + behaviorId = pair->second; + } + + // check to see if we got back a valid behavior + if (behaviorId == -1) { + Game::logger->LogDebug("SkillComponent", "Tried to cast skill %i but found no behavior", skillId); + return false; + } + + return CalculateBehavior(skillId, behaviorId, target, false, false, optionalOriginatorID).success; +} + SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, const uint32_t behaviorId, const LWOOBJID target, const bool ignoreTarget, const bool clientInitalized, const LWOOBJID originatorOverride) { auto* bitStream = new RakNet::BitStream(); diff --git a/dGame/dComponents/SkillComponent.h b/dGame/dComponents/SkillComponent.h index f43276f1..2bdcb88f 100644 --- a/dGame/dComponents/SkillComponent.h +++ b/dGame/dComponents/SkillComponent.h @@ -119,6 +119,15 @@ public: */ void RegisterPlayerProjectile(LWOOBJID projectileId, BehaviorContext* context, const BehaviorBranchContext& branch, LOT lot); + /** + * Wrapper for CalculateBehavior that mimics the call structure in scripts and helps reduce magic numbers + * @param skillId the skill to cast + * @param target the target of the skill + * @param optionalOriginatorID change the originator of the skill + * @return if the case succeeded + */ + bool CastSkill(const uint32_t skillId, LWOOBJID target = LWOOBJID_EMPTY, const LWOOBJID optionalOriginatorID = LWOOBJID_EMPTY); + /** * Initializes a server-side skill calculation. * @param skillId the skill ID @@ -190,6 +199,11 @@ private: */ uint32_t m_skillUid; + /** + * Cache for looking up a behavior id via a skill ID + */ + static std::unordered_map<uint32_t, uint32_t> m_skillBehaviorCache; + /** * Sync a server-side projectile calculation. * @param entry the projectile information diff --git a/dScripts/EquipmentTriggers/CoilBackpackBase.cpp b/dScripts/EquipmentTriggers/CoilBackpackBase.cpp index d3102e0e..4e323a08 100644 --- a/dScripts/EquipmentTriggers/CoilBackpackBase.cpp +++ b/dScripts/EquipmentTriggers/CoilBackpackBase.cpp @@ -14,10 +14,10 @@ void CoilBackpackBase::NotifyHitOrHealResult(Entity* self, Entity* attacker, int if (self->GetVar<uint8_t>(u"coilCount") > 4) { auto* skillComponent = self->GetComponent<SkillComponent>(); if (!skillComponent) return; - skillComponent->CalculateBehavior(m_SkillId, m_BehaviorId, self->GetObjectID()); + skillComponent->CastSkill(m_SkillId); self->SetVar<uint8_t>(u"coilCount", 0); } - } + } } void CoilBackpackBase::OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) { diff --git a/dScripts/EquipmentTriggers/CoilBackpackBase.h b/dScripts/EquipmentTriggers/CoilBackpackBase.h index 290c6c0f..2d641346 100644 --- a/dScripts/EquipmentTriggers/CoilBackpackBase.h +++ b/dScripts/EquipmentTriggers/CoilBackpackBase.h @@ -5,9 +5,8 @@ class CoilBackpackBase: public CppScripts::Script { public: - CoilBackpackBase(uint32_t skillId, uint32_t behaviorId) { + CoilBackpackBase(uint32_t skillId) { m_SkillId = skillId; - m_BehaviorId = behaviorId; }; void OnFactionTriggerItemEquipped(Entity* itemOwner, LWOOBJID itemObjId) override; @@ -15,7 +14,6 @@ public: void OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) override; private: uint32_t m_SkillId = 0; - uint32_t m_BehaviorId = 0; }; #endif //!__GemPackBase__H__ diff --git a/dScripts/EquipmentTriggers/GemPack.h b/dScripts/EquipmentTriggers/GemPack.h index 13bf7b0b..d71181ab 100644 --- a/dScripts/EquipmentTriggers/GemPack.h +++ b/dScripts/EquipmentTriggers/GemPack.h @@ -5,10 +5,9 @@ class GemPack : public CoilBackpackBase { public: - GemPack() : CoilBackpackBase(skillId, behaviorId) {}; + GemPack() : CoilBackpackBase(skillId) {}; private: static const uint32_t skillId = 1488; - static const uint32_t behaviorId = 36779; }; #endif //!__GEMPACK__H__ diff --git a/dScripts/EquipmentTriggers/ShardArmor.h b/dScripts/EquipmentTriggers/ShardArmor.h index 01d2fe33..5486db54 100644 --- a/dScripts/EquipmentTriggers/ShardArmor.h +++ b/dScripts/EquipmentTriggers/ShardArmor.h @@ -5,10 +5,9 @@ class ShardArmor : public CoilBackpackBase { public: - ShardArmor() : CoilBackpackBase(skillId, behaviorId) {}; + ShardArmor() : CoilBackpackBase(skillId) {}; private: static const uint32_t skillId = 1249; - static const uint32_t behaviorId = 29086; }; #endif //!__SHARDARMOR__H__ diff --git a/dScripts/EquipmentTriggers/TeslaPack.h b/dScripts/EquipmentTriggers/TeslaPack.h index 6e8bc9a4..3ba09f5c 100644 --- a/dScripts/EquipmentTriggers/TeslaPack.h +++ b/dScripts/EquipmentTriggers/TeslaPack.h @@ -5,10 +5,9 @@ class TeslaPack : public CoilBackpackBase { public: - TeslaPack() : CoilBackpackBase(skillId, behaviorId) {}; + TeslaPack() : CoilBackpackBase(skillId) {}; private: static const uint32_t skillId = 1001; - static const uint32_t behaviorId = 20917; }; #endif //!__TESLAPACK__H__ From 72c93c8913957062eead0005fa0c15f3b6249650 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 13 Feb 2023 18:55:44 -0800 Subject: [PATCH 130/166] Further implement Property Behavior parsing (#936) Further implements the ControlBehavior processing and adds preparations for cheat detection --- CMakeLists.txt | 1 + dCommon/dEnums/dCommonVars.h | 3 +- dGame/dGameMessages/GameMessages.cpp | 2 +- dGame/dPropertyBehaviors/BehaviorStates.h | 5 +- dGame/dPropertyBehaviors/BlockDefinition.cpp | 9 + dGame/dPropertyBehaviors/BlockDefinition.h | 25 + dGame/dPropertyBehaviors/CMakeLists.txt | 10 +- .../AddActionMessage.cpp | 39 ++ .../AddActionMessage.h | 30 + .../ControlBehaviorMessages/AddMessage.cpp | 13 + .../ControlBehaviorMessages/AddMessage.h | 16 + .../AddStripMessage.cpp | 56 ++ .../ControlBehaviorMessages/AddStripMessage.h | 32 ++ .../BehaviorMessageBase.h | 48 ++ .../ControlBehaviorMessages/CMakeLists.txt | 16 + .../MergeStripsMessage.cpp | 20 + .../MergeStripsMessage.h | 26 + .../MigrateActionsMessage.cpp | 24 + .../MigrateActionsMessage.h | 28 + .../MoveToInventoryMessage.cpp | 11 + .../MoveToInventoryMessage.h | 19 + .../RearrangeStripMessage.cpp | 16 + .../RearrangeStripMessage.h | 22 + .../RemoveActionsMessage.cpp | 15 + .../RemoveActionsMessage.h | 22 + .../RemoveStripMessage.cpp | 8 + .../RemoveStripMessage.h | 18 + .../ControlBehaviorMessages/RenameMessage.cpp | 11 + .../ControlBehaviorMessages/RenameMessage.h | 18 + .../SplitStripMessage.cpp | 29 + .../SplitStripMessage.h | 30 + .../UpdateActionMessage.cpp | 38 ++ .../UpdateActionMessage.h | 30 + .../UpdateStripUiMessage.cpp | 20 + .../UpdateStripUiMessage.h | 24 + dGame/dPropertyBehaviors/ControlBehaviors.cpp | 540 +++++++----------- dGame/dPropertyBehaviors/ControlBehaviors.h | 47 +- tests/dGameTests/CMakeLists.txt | 2 + .../dGameMessagesTests/CMakeLists.txt | 5 + .../dGameMessagesTests/GameMessageTests.cpp | 191 ++++++- .../TestBitStreams/CMakeLists.txt | 24 + .../dGameMessagesTests/TestBitStreams/add | Bin 0 -> 1024 bytes .../TestBitStreams/addAction | Bin 0 -> 1024 bytes .../TestBitStreams/addStrip | Bin 0 -> 1024 bytes .../TestBitStreams/mergeStrips | Bin 0 -> 1024 bytes .../TestBitStreams/migrateActions | Bin 0 -> 1024 bytes .../TestBitStreams/modelTypeChanged | Bin 0 -> 1024 bytes .../TestBitStreams/rearrangeStrip | Bin 0 -> 1024 bytes .../TestBitStreams/removeActions | Bin 0 -> 1024 bytes .../TestBitStreams/removeStrip | Bin 0 -> 1024 bytes .../dGameMessagesTests/TestBitStreams/rename | Bin 0 -> 1024 bytes .../TestBitStreams/sendBehaviorListToClient | Bin 0 -> 1024 bytes .../TestBitStreams/splitStrip | Bin 0 -> 1024 bytes .../TestBitStreams/toggleExecutionUpdates | Bin 0 -> 1024 bytes .../TestBitStreams/updateAction | Bin 0 -> 1024 bytes .../TestBitStreams/updateStripUI | Bin 0 -> 1024 bytes 56 files changed, 1181 insertions(+), 362 deletions(-) create mode 100644 dGame/dPropertyBehaviors/BlockDefinition.cpp create mode 100644 dGame/dPropertyBehaviors/BlockDefinition.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/CMakeLists.txt create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/add create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/addAction create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/addStrip create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/mergeStrips create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/migrateActions create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/modelTypeChanged create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/rearrangeStrip create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/removeActions create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/removeStrip create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/rename create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/sendBehaviorListToClient create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/splitStrip create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/toggleExecutionUpdates create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/updateAction create mode 100644 tests/dGameTests/dGameMessagesTests/TestBitStreams/updateStripUI diff --git a/CMakeLists.txt b/CMakeLists.txt index 54f0d0dd..41d4219f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,6 +163,7 @@ set(INCLUDED_DIRECTORIES "dGame/dMission" "dGame/dEntity" "dGame/dPropertyBehaviors" + "dGame/dPropertyBehaviors/ControlBehaviorMessages" "dGame/dUtilities" "dPhysics" "dNavigation" diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index c90fd8e6..1d4a4c55 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -43,8 +43,7 @@ typedef uint32_t LWOCLONEID; //!< Used for Clone IDs typedef uint16_t LWOMAPID; //!< Used for Map IDs typedef uint16_t LWOINSTANCEID; //!< Used for Instance IDs typedef uint32_t PROPERTYCLONELIST; //!< Used for Property Clone IDs -typedef uint32_t STRIPID; -typedef uint32_t BEHAVIORSTATE; +typedef uint32_t StripId; typedef int32_t PetTamingPiece; //!< Pet Taming Pieces diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 58d72d3c..1d897727 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2475,7 +2475,7 @@ void GameMessages::HandleControlBehaviors(RakNet::BitStream* inStream, Entity* e auto owner = PropertyManagementComponent::Instance()->GetOwner(); if (!owner) return; - ControlBehaviors::ProcessCommand(entity, sysAddr, static_cast<AMFArrayValue*>(amfArguments.get()), command, owner); + ControlBehaviors::Instance().ProcessCommand(entity, sysAddr, static_cast<AMFArrayValue*>(amfArguments.get()), command, owner); } void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { diff --git a/dGame/dPropertyBehaviors/BehaviorStates.h b/dGame/dPropertyBehaviors/BehaviorStates.h index e09e45ba..80cb1dbb 100644 --- a/dGame/dPropertyBehaviors/BehaviorStates.h +++ b/dGame/dPropertyBehaviors/BehaviorStates.h @@ -3,12 +3,9 @@ #ifndef __BEHAVIORSTATES__H__ #define __BEHAVIORSTATES__H__ -#include <string> #include <cstdint> -#include "dCommonVars.h" - -enum States : BEHAVIORSTATE { +enum class BehaviorState : uint32_t { HOME_STATE = 0, //!< The HOME behavior state CIRCLE_STATE, //!< The CIRCLE behavior state SQUARE_STATE, //!< The SQUARE behavior state diff --git a/dGame/dPropertyBehaviors/BlockDefinition.cpp b/dGame/dPropertyBehaviors/BlockDefinition.cpp new file mode 100644 index 00000000..2950ac82 --- /dev/null +++ b/dGame/dPropertyBehaviors/BlockDefinition.cpp @@ -0,0 +1,9 @@ +#include "BlockDefinition.h" + +BlockDefinition BlockDefinition::blockDefinitionDefault{}; + +BlockDefinition::BlockDefinition(std::string defaultValue, float minimumValue, float maximumValue) { + this->defaultValue = defaultValue; + this->minimumValue = minimumValue; + this->maximumValue = maximumValue; +} diff --git a/dGame/dPropertyBehaviors/BlockDefinition.h b/dGame/dPropertyBehaviors/BlockDefinition.h new file mode 100644 index 00000000..3a5a6bf1 --- /dev/null +++ b/dGame/dPropertyBehaviors/BlockDefinition.h @@ -0,0 +1,25 @@ +#ifndef __BLOCKDEFINITION__H__ +#define __BLOCKDEFINITION__H__ + +#include <string> + +class AMFArrayValue; + +class BlockDefinition { +public: + BlockDefinition(std::string defaultValue = "", float minimumValue = 0.0f, float maximumValue = 0.0f); + static BlockDefinition blockDefinitionDefault; + + std::string& GetDefaultValue() { return defaultValue; }; + float GetMinimumValue() { return minimumValue; }; + float GetMaximumValue() { return maximumValue; }; + void SetDefaultValue(std::string value) { defaultValue = value; }; + void SetMinimumValue(float value) { minimumValue = value; }; + void SetMaximumValue(float value) { maximumValue = value; }; +private: + std::string defaultValue; + float minimumValue; + float maximumValue; +}; + +#endif //!__BLOCKDEFINITION__H__ diff --git a/dGame/dPropertyBehaviors/CMakeLists.txt b/dGame/dPropertyBehaviors/CMakeLists.txt index 4f5d60aa..5e33a5f5 100644 --- a/dGame/dPropertyBehaviors/CMakeLists.txt +++ b/dGame/dPropertyBehaviors/CMakeLists.txt @@ -1,4 +1,12 @@ set(DGAME_DPROPERTYBEHAVIORS_SOURCES + "BlockDefinition.cpp" "ControlBehaviors.cpp" - PARENT_SCOPE ) + +add_subdirectory(ControlBehaviorMessages) + +foreach(file ${DGAME_DPROPERTYBEHAVIORS_CONTROLBEHAVIORMESSAGES}) + set(DGAME_DPROPERTYBEHAVIORS_SOURCES ${DGAME_DPROPERTYBEHAVIORS_SOURCES} "ControlBehaviorMessages/${file}") +endforeach() + +set(DGAME_DPROPERTYBEHAVIORS_SOURCES ${DGAME_DPROPERTYBEHAVIORS_SOURCES} PARENT_SCOPE) diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp new file mode 100644 index 00000000..f91512fe --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp @@ -0,0 +1,39 @@ +#include "AddActionMessage.h" + +AddActionMessage::AddActionMessage(AMFArrayValue* arguments) { + auto* actionIndexAmf = arguments->FindValue<AMFDoubleValue>("actionIndex"); + if (!actionIndexAmf) return; + + actionIndex = static_cast<uint32_t>(actionIndexAmf->GetDoubleValue()); + + stripId = GetStripIDFromArgument(arguments); + + stateId = GetBehaviorStateFromArgument(arguments); + + type = ""; + valueParameterName = ""; + valueParameterString = ""; + valueParameterDouble = 0.0; + auto* action = arguments->FindValue<AMFArrayValue>("action"); + if (!action) return; + + for (auto& typeValueMap : action->GetAssociativeMap()) { + if (typeValueMap.first == "Type") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + valueParameterName = typeValueMap.first; + // Message is the only known string parameter + if (valueParameterName == "Message") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; + valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); + } + } + } + + behaviorId = GetBehaviorIDFromArgument(arguments); + Game::logger->LogDebug("AddActionMessage", "acnNdx %i stpId %i sttId %i t %s vpn %s vps %s vpd %f bhId %i", actionIndex, stripId, stateId, type.c_str(), valueParameterName.c_str(), valueParameterString.c_str(), valueParameterDouble, behaviorId); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h new file mode 100644 index 00000000..1f1577ec --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h @@ -0,0 +1,30 @@ +#ifndef __ADDACTIONMESSAGE__H__ +#define __ADDACTIONMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class AddActionMessage : public BehaviorMessageBase { +public: + AddActionMessage(AMFArrayValue* arguments); + const uint32_t GetActionIndex() { return actionIndex; }; + const StripId GetStripId() { return stripId; }; + const BehaviorState GetStateId() { return stateId; }; + const std::string& GetType() { return type; }; + const std::string& GetValueParameterName() { return valueParameterName; }; + const std::string& GetValueParameterString() { return valueParameterString; }; + const double GetValueParameterDouble() { return valueParameterDouble; }; + const uint32_t GetBehaviorId() { return behaviorId; }; +private: + uint32_t actionIndex; + StripId stripId; + BehaviorState stateId; + std::string type; + std::string valueParameterName; + std::string valueParameterString; + double valueParameterDouble; + uint32_t behaviorId; +}; + +#endif //!__ADDACTIONMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp new file mode 100644 index 00000000..ecddb8e3 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp @@ -0,0 +1,13 @@ +#include "AddMessage.h" + +AddMessage::AddMessage(AMFArrayValue* arguments) { + behaviorId = GetBehaviorIDFromArgument(arguments); + + behaviorIndex = 0; + auto* behaviorIndexValue = arguments->FindValue<AMFDoubleValue>("BehaviorIndex"); + + if (!behaviorIndexValue) return; + + behaviorIndex = static_cast<uint32_t>(behaviorIndexValue->GetDoubleValue()); + Game::logger->LogDebug("AddMessage", "bhId %i ndx %i", behaviorId, behaviorIndex); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h new file mode 100644 index 00000000..ff8e0c8b --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h @@ -0,0 +1,16 @@ +#ifndef __ADDMESSAGE__H__ +#define __ADDMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AddMessage : public BehaviorMessageBase { +public: + AddMessage(AMFArrayValue* arguments); + const uint32_t GetBehaviorIndex() { return behaviorIndex; }; + const uint32_t GetBehaviorId() { return behaviorId; }; +private: + uint32_t behaviorId; + uint32_t behaviorIndex; +}; + +#endif //!__ADDMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp new file mode 100644 index 00000000..23662174 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp @@ -0,0 +1,56 @@ +#include "AddStripMessage.h" + +AddStripMessage::AddStripMessage(AMFArrayValue* arguments) { + auto* strip = arguments->FindValue<AMFArrayValue>("strip"); + if (!strip) return; + + auto* actions = strip->FindValue<AMFArrayValue>("actions"); + if (!actions) return; + + auto* uiArray = arguments->FindValue<AMFArrayValue>("ui"); + if (!uiArray) return; + + auto* xPositionValue = uiArray->FindValue<AMFDoubleValue>("x"); + if (!xPositionValue) return; + + xPosition = xPositionValue->GetDoubleValue(); + + auto* yPositionValue = uiArray->FindValue<AMFDoubleValue>("y"); + if (!yPositionValue) return; + + yPosition = yPositionValue->GetDoubleValue(); + + stripId = GetStripIDFromArgument(arguments); + + stateId = GetBehaviorStateFromArgument(arguments); + + behaviorId = GetBehaviorIDFromArgument(arguments); + + type = ""; + valueParameterName = ""; + valueParameterString = ""; + valueParameterDouble = 0.0; + for (uint32_t position = 0; position < actions->GetDenseValueSize(); position++) { + auto* actionAsArray = actions->GetValueAt<AMFArrayValue>(position); + if (!actionAsArray) continue; + + for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { + if (typeValueMap.first == "Type") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + + type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + valueParameterName = typeValueMap.first; + // Message is the only known string parameter + if (valueParameterName == "Message") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; + valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); + } + } + } + Game::logger->LogDebug("AddStripMessage", "x %f y %f stpId %i sttId %i bhId %i t %s vpn %s vps %s vpd %f", xPosition, yPosition, stripId, stateId, behaviorId, type.c_str(), valueParameterName.c_str(), valueParameterString.c_str(), valueParameterDouble); + } +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h new file mode 100644 index 00000000..bb720bae --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h @@ -0,0 +1,32 @@ +#ifndef __ADDSTRIPMESSAGE__H__ +#define __ADDSTRIPMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class AddStripMessage : public BehaviorMessageBase { +public: + AddStripMessage(AMFArrayValue* arguments); + const StripId GetStripId() { return stripId; }; + const BehaviorState GetStateId() { return stateId; }; + const std::string& GetType() { return type; }; + const std::string& GetValueParameterName() { return valueParameterName; }; + const std::string& GetValueParameterString() { return valueParameterString; }; + const double GetXPosition() { return xPosition; }; + const double GetYPosition() { return yPosition; }; + const double GetValueParameterDouble() { return valueParameterDouble; }; + const uint32_t GetBehaviorId() { return behaviorId; }; +private: + double xPosition; + double yPosition; + StripId stripId; + BehaviorState stateId; + uint32_t behaviorId; + std::string type; + std::string valueParameterName; + std::string valueParameterString; + double valueParameterDouble; +}; + +#endif //!__ADDSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h new file mode 100644 index 00000000..78025672 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -0,0 +1,48 @@ +#ifndef __BEHAVIORMESSAGEBASE__H__ +#define __BEHAVIORMESSAGEBASE__H__ + +#include <stdexcept> +#include <string> + +#include "AMFFormat.h" +#include "BehaviorStates.h" +#include "dCommonVars.h" + +#include "Game.h" +#include "dLogger.h" + +class BehaviorMessageBase { +public: + uint32_t GetBehaviorIDFromArgument(AMFArrayValue* arguments, const std::string& key = "BehaviorID") { + auto* behaviorIDValue = arguments->FindValue<AMFStringValue>(key); + uint32_t behaviorID = -1; + + if (behaviorIDValue) { + behaviorID = std::stoul(behaviorIDValue->GetStringValue()); + } else if (arguments->FindValue<AMFUndefinedValue>(key) == nullptr) { + throw std::invalid_argument("Unable to find behavior ID from argument \"" + key + "\""); + } + + return behaviorID; + } + + BehaviorState GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key = "stateID") { + auto* stateIDValue = arguments->FindValue<AMFDoubleValue>(key); + if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); + + BehaviorState stateID = static_cast<BehaviorState>(stateIDValue->GetDoubleValue()); + + return stateID; + } + + StripId GetStripIDFromArgument(AMFArrayValue* arguments, const std::string& key = "stripID") { + auto* stripIDValue = arguments->FindValue<AMFDoubleValue>(key); + if (!stripIDValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); + + StripId stripID = static_cast<StripId>(stripIDValue->GetDoubleValue()); + + return stripID; + } +}; + +#endif //!__BEHAVIORMESSAGEBASE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt b/dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt new file mode 100644 index 00000000..8390cd22 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt @@ -0,0 +1,16 @@ +set(DGAME_DPROPERTYBEHAVIORS_CONTROLBEHAVIORMESSAGES + "AddActionMessage.cpp" + "AddMessage.cpp" + "AddStripMessage.cpp" + "MergeStripsMessage.cpp" + "MigrateActionsMessage.cpp" + "MoveToInventoryMessage.cpp" + "RearrangeStripMessage.cpp" + "RemoveActionsMessage.cpp" + "RemoveStripMessage.cpp" + "RenameMessage.cpp" + "SplitStripMessage.cpp" + "UpdateActionMessage.cpp" + "UpdateStripUiMessage.cpp" + PARENT_SCOPE +) diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp new file mode 100644 index 00000000..d810e861 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp @@ -0,0 +1,20 @@ +#include "MergeStripsMessage.h" + +MergeStripsMessage::MergeStripsMessage(AMFArrayValue* arguments) { + srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); + + dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); + + srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); + + auto* dstActionIndexValue = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); + if (!dstActionIndexValue) return; + + dstActionIndex = static_cast<uint32_t>(dstActionIndexValue->GetDoubleValue()); + + dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); + + behaviorID = GetBehaviorIDFromArgument(arguments); + Game::logger->LogDebug("MergeStripsMessage", "srcStpId %i dstStpId %i srcSttId %i dstSttId %i dstAcnNdx %i bhId %i", srcStripID, dstStripID, srcStateID, dstStateID, dstActionIndex, behaviorID); +} + diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h new file mode 100644 index 00000000..af3aa16f --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h @@ -0,0 +1,26 @@ +#ifndef __MERGESTRIPSMESSAGE__H__ +#define __MERGESTRIPSMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class MergeStripsMessage : public BehaviorMessageBase { +public: + MergeStripsMessage(AMFArrayValue* arguments); + const StripId GetSrcStripID() { return srcStripID; }; + const BehaviorState GetDstStateID() { return dstStateID; }; + const BehaviorState GetSrcStateID() { return srcStateID; }; + const uint32_t GetDstActionIndex() { return dstActionIndex; }; + const StripId GetDstStripID() { return dstStripID; }; + const uint32_t GetBehaviorID() { return behaviorID; }; +private: + StripId srcStripID; + BehaviorState dstStateID; + BehaviorState srcStateID; + uint32_t dstActionIndex; + StripId dstStripID; + uint32_t behaviorID; +}; + +#endif //!__MERGESTRIPSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp new file mode 100644 index 00000000..8bb4e819 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp @@ -0,0 +1,24 @@ +#include "MigrateActionsMessage.h" + +MigrateActionsMessage::MigrateActionsMessage(AMFArrayValue* arguments) { + auto* srcActionIndexAmf = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); + if (!srcActionIndexAmf) return; + + srcActionIndex = static_cast<uint32_t>(srcActionIndexAmf->GetDoubleValue()); + + srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); + + srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); + + auto* dstActionIndexAmf = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); + if (!dstActionIndexAmf) return; + + dstActionIndex = static_cast<uint32_t>(dstActionIndexAmf->GetDoubleValue()); + + dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); + + dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); + + behaviorID = GetBehaviorIDFromArgument(arguments); + Game::logger->LogDebug("MigrateActionsMessage", "srcAcnNdx %i dstAcnNdx %i srcStpId %i dstStpId %i srcSttId %i dstSttId %i bhid %i", srcActionIndex, dstActionIndex, srcStripID, dstStripID, srcStateID, dstStateID, behaviorID); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h new file mode 100644 index 00000000..26018d69 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -0,0 +1,28 @@ +#ifndef __MIGRATEACTIONSMESSAGE__H__ +#define __MIGRATEACTIONSMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class MigrateActionsMessage : public BehaviorMessageBase { +public: + MigrateActionsMessage(AMFArrayValue* arguments); + const uint32_t GetSrcActionIndex() { return srcActionIndex; }; + const StripId GetSrcStripID() { return srcStripID; }; + const BehaviorState GetSrcStateID() { return srcStateID; }; + const uint32_t GetDstActionIndex() { return dstActionIndex; }; + const StripId GetDstStripID() { return dstStripID; }; + const BehaviorState GetDstStateID() { return dstStateID; }; + const uint32_t GetBehaviorID() { return behaviorID; }; +private: + uint32_t srcActionIndex; + StripId srcStripID; + BehaviorState srcStateID; + uint32_t dstActionIndex; + StripId dstStripID; + BehaviorState dstStateID; + uint32_t behaviorID; +}; + +#endif //!__MIGRATEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp new file mode 100644 index 00000000..7ad7a875 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp @@ -0,0 +1,11 @@ +#include "MoveToInventoryMessage.h" + +MoveToInventoryMessage::MoveToInventoryMessage(AMFArrayValue* arguments) { + behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* behaviorIndexValue = arguments->FindValue<AMFDoubleValue>("BehaviorIndex"); + if (!behaviorIndexValue) return; + + behaviorIndex = static_cast<uint32_t>(behaviorIndexValue->GetDoubleValue()); + Game::logger->LogDebug("MoveToInventoryMessage", "bhId %i bhNdx %i", behaviorID, behaviorIndex); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h new file mode 100644 index 00000000..2cf71f3c --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h @@ -0,0 +1,19 @@ +#ifndef __MOVETOINVENTORYMESSAGE__H__ +#define __MOVETOINVENTORYMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +#pragma warning("This Control Behavior Message does not have a test yet. Non-developers can ignore this warning.") +class MoveToInventoryMessage: public BehaviorMessageBase { +public: + MoveToInventoryMessage(AMFArrayValue* arguments); + const uint32_t GetBehaviorID() { return behaviorID; }; + const uint32_t GetBehaviorIndex() { return behaviorIndex; }; +private: + uint32_t behaviorID; + uint32_t behaviorIndex; +}; + +#endif //!__MOVETOINVENTORYMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp new file mode 100644 index 00000000..0347aca6 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp @@ -0,0 +1,16 @@ +#include "RearrangeStripMessage.h" + +RearrangeStripMessage::RearrangeStripMessage(AMFArrayValue* arguments) { + auto* srcActionIndexValue = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); + srcActionIndex = static_cast<uint32_t>(srcActionIndexValue->GetDoubleValue()); + + stripID = GetStripIDFromArgument(arguments); + + behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* dstActionIndexValue = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); + dstActionIndex = static_cast<uint32_t>(dstActionIndexValue->GetDoubleValue()); + + stateID = GetBehaviorStateFromArgument(arguments); + Game::logger->LogDebug("RearrangeStripMessage", "srcAcnNdx %i dstAcnNdx %i stpId %i bhId %i sttId %i", srcActionIndex, dstActionIndex, stripID, behaviorID, stateID); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h new file mode 100644 index 00000000..4cca0827 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h @@ -0,0 +1,22 @@ +#ifndef __REARRANGESTRIPMESSAGE__H__ +#define __REARRANGESTRIPMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class RearrangeStripMessage : public BehaviorMessageBase { +public: + RearrangeStripMessage(AMFArrayValue* arguments); + const uint32_t GetSrcActionIndex() { return srcActionIndex; }; + const uint32_t GetStripID() { return stripID; }; + const uint32_t GetBehaviorID() { return behaviorID; }; + const uint32_t GetDstActionIndex() { return dstActionIndex; }; + const BehaviorState GetStateID() { return stateID; }; +private: + uint32_t srcActionIndex; + uint32_t stripID; + uint32_t behaviorID; + uint32_t dstActionIndex; + BehaviorState stateID; +}; + +#endif //!__REARRANGESTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp new file mode 100644 index 00000000..cb1226e3 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp @@ -0,0 +1,15 @@ +#include "RemoveActionsMessage.h" + +RemoveActionsMessage::RemoveActionsMessage(AMFArrayValue* arguments) { + behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* actionIndexAmf = arguments->FindValue<AMFDoubleValue>("actionIndex"); + if (!actionIndexAmf) return; + + actionIndex = static_cast<uint32_t>(actionIndexAmf->GetDoubleValue()); + + stripID = GetStripIDFromArgument(arguments); + + stateID = GetBehaviorStateFromArgument(arguments); + Game::logger->LogDebug("RemoveActionsMessage", "bhId %i acnNdx %i stpId %i sttId %i", behaviorID, actionIndex, stripID, stateID); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h new file mode 100644 index 00000000..33678f59 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h @@ -0,0 +1,22 @@ +#ifndef __REMOVEACTIONSMESSAGE__H__ +#define __REMOVEACTIONSMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class RemoveActionsMessage : public BehaviorMessageBase { +public: + RemoveActionsMessage(AMFArrayValue* arguments); + const uint32_t GetBehaviorID() { return behaviorID; }; + const uint32_t GetActionIndex() { return actionIndex; }; + const StripId GetStripID() { return stripID; }; + const BehaviorState GetStateID() { return stateID; }; +private: + uint32_t behaviorID; + uint32_t actionIndex; + StripId stripID; + BehaviorState stateID; +}; + +#endif //!__REMOVEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp new file mode 100644 index 00000000..3c48ed16 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp @@ -0,0 +1,8 @@ +#include "RemoveStripMessage.h" + +RemoveStripMessage::RemoveStripMessage(AMFArrayValue* arguments) { + stripId = GetStripIDFromArgument(arguments); + behaviorState = GetBehaviorStateFromArgument(arguments); + behaviorId = GetBehaviorIDFromArgument(arguments); + Game::logger->LogDebug("RemoveStripMessage", "stpId %i bhStt %i bhId %i", stripId, behaviorState, behaviorId); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h new file mode 100644 index 00000000..312bab31 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h @@ -0,0 +1,18 @@ +#ifndef __REMOVESTRIPMESSAGE__H__ +#define __REMOVESTRIPMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class RemoveStripMessage : public BehaviorMessageBase { +public: + RemoveStripMessage(AMFArrayValue* arguments); + const StripId GetStripId() { return stripId; }; + const BehaviorState GetBehaviorState() { return behaviorState; }; + const uint32_t GetBehaviorId() { return behaviorId; }; +private: + StripId stripId; + BehaviorState behaviorState; + uint32_t behaviorId; +}; + +#endif //!__REMOVESTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp new file mode 100644 index 00000000..38c49462 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp @@ -0,0 +1,11 @@ +#include "RenameMessage.h" + +RenameMessage::RenameMessage(AMFArrayValue* arguments) { + behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* nameAmf = arguments->FindValue<AMFStringValue>("Name"); + if (!nameAmf) return; + + name = nameAmf->GetStringValue(); + Game::logger->LogDebug("RenameMessage", "bhId %i n %s", behaviorID, name.c_str()); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h new file mode 100644 index 00000000..be42d66f --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h @@ -0,0 +1,18 @@ +#ifndef __RENAMEMESSAGE__H__ +#define __RENAMEMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class RenameMessage : public BehaviorMessageBase { +public: + RenameMessage(AMFArrayValue* arguments); + const uint32_t GetBehaviorID() { return behaviorID; }; + const std::string& GetName() { return name; }; +private: + uint32_t behaviorID; + std::string name; +}; + +#endif //!__RENAMEMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp new file mode 100644 index 00000000..d3493aeb --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp @@ -0,0 +1,29 @@ +#include "SplitStripMessage.h" + +SplitStripMessage::SplitStripMessage(AMFArrayValue* arguments) { + auto* srcActionIndexValue = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); + if (!srcActionIndexValue) return; + + srcActionIndex = static_cast<uint32_t>(srcActionIndexValue->GetDoubleValue()); + + srcStripId = GetStripIDFromArgument(arguments, "srcStripID"); + + srcStateId = GetBehaviorStateFromArgument(arguments, "srcStateID"); + + dstStripId = GetStripIDFromArgument(arguments, "dstStripID"); + + dstStateId = GetBehaviorStateFromArgument(arguments, "dstStateID"); + + auto* dstStripUiArray = arguments->FindValue<AMFArrayValue>("dstStripUI"); + if (!dstStripUiArray) return; + + auto* xPositionValue = dstStripUiArray->FindValue<AMFDoubleValue>("x"); + auto* yPositionValue = dstStripUiArray->FindValue<AMFDoubleValue>("y"); + if (!xPositionValue || !yPositionValue) return; + + yPosition = yPositionValue->GetDoubleValue(); + xPosition = xPositionValue->GetDoubleValue(); + + behaviorId = GetBehaviorIDFromArgument(arguments); + Game::logger->LogDebug("SplitStripMessage", "bhid %i x %f y %f srcStp %i dstStp %i srcStt %i dstStt %i srcActNdx %i", behaviorId, xPosition, yPosition, srcStripId, dstStripId, srcStateId, dstStateId, srcActionIndex); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h new file mode 100644 index 00000000..e06a9dc4 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h @@ -0,0 +1,30 @@ +#ifndef __SPLITSTRIPMESSAGE__H__ +#define __SPLITSTRIPMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class SplitStripMessage : public BehaviorMessageBase { +public: + SplitStripMessage(AMFArrayValue* arguments); + const uint32_t GetSrcActionIndex() { return srcActionIndex; }; + const StripId GetSrcStripId() { return srcStripId; }; + const BehaviorState GetSrcStateId() { return srcStateId; }; + const StripId GetDstStripId() { return dstStripId; }; + const BehaviorState GetDstStateId() { return dstStateId; }; + const double GetYPosition() { return yPosition; }; + const double GetXPosition() { return xPosition; }; + const uint32_t GetBehaviorId() { return behaviorId; }; +private: + uint32_t srcActionIndex; + StripId srcStripId; + BehaviorState srcStateId; + StripId dstStripId; + BehaviorState dstStateId; + double yPosition; + double xPosition; + uint32_t behaviorId; +}; + +#endif //!__SPLITSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp new file mode 100644 index 00000000..1d4cc868 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp @@ -0,0 +1,38 @@ +#include "UpdateActionMessage.h" + +UpdateActionMessage::UpdateActionMessage(AMFArrayValue* arguments) { + type = ""; + valueParameterName = ""; + valueParameterString = ""; + valueParameterDouble = 0.0; + auto* actionAsArray = arguments->FindValue<AMFArrayValue>("action"); + if (!actionAsArray) return; + for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { + if (typeValueMap.first == "Type") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + valueParameterName = typeValueMap.first; + // Message is the only known string parameter + if (valueParameterName == "Message") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; + valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); + } + } + } + + behaviorID = GetBehaviorIDFromArgument(arguments); + + auto* actionIndexValue = arguments->FindValue<AMFDoubleValue>("actionIndex"); + if (!actionIndexValue) return; + + actionIndex = static_cast<uint32_t>(actionIndexValue->GetDoubleValue()); + + stripID = GetStripIDFromArgument(arguments); + + stateID = GetBehaviorStateFromArgument(arguments); + Game::logger->LogDebug("UpdateActionMessage", "t %s vpn %s vps %s vpd %f bhId %i acnNdx %i stpId %i sttId %i", type.c_str(), valueParameterName.c_str(), valueParameterString.c_str(), valueParameterDouble, behaviorID, actionIndex, stripID, stateID); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h new file mode 100644 index 00000000..a42be22b --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h @@ -0,0 +1,30 @@ +#ifndef __UPDATEACTIONMESSAGE__H__ +#define __UPDATEACTIONMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class UpdateActionMessage : public BehaviorMessageBase { +public: + UpdateActionMessage(AMFArrayValue* arguments); + const std::string& GetType() { return type; }; + const std::string& GetValueParameterName() { return valueParameterName; }; + const std::string& GetValueParameterString() { return valueParameterString; }; + const double GetValueParameterDouble() { return valueParameterDouble; }; + const uint32_t GetBehaviorID() { return behaviorID; }; + const uint32_t GetActionIndex() { return actionIndex; }; + const StripId GetStripID() { return stripID; }; + const BehaviorState GetStateID() { return stateID; }; +private: + std::string type; + std::string valueParameterName; + std::string valueParameterString; + double valueParameterDouble; + uint32_t behaviorID; + uint32_t actionIndex; + StripId stripID; + BehaviorState stateID; +}; + +#endif //!__UPDATEACTIONMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp new file mode 100644 index 00000000..60e2f0f3 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp @@ -0,0 +1,20 @@ +#include "UpdateStripUiMessage.h" + +UpdateStripUiMessage::UpdateStripUiMessage(AMFArrayValue* arguments) { + auto* uiArray = arguments->FindValue<AMFArrayValue>("ui"); + if (!uiArray) return; + + auto* xPositionValue = uiArray->FindValue<AMFDoubleValue>("x"); + auto* yPositionValue = uiArray->FindValue<AMFDoubleValue>("y"); + if (!xPositionValue || !yPositionValue) return; + + yPosition = yPositionValue->GetDoubleValue(); + xPosition = xPositionValue->GetDoubleValue(); + + stripID = GetStripIDFromArgument(arguments); + + stateID = GetBehaviorStateFromArgument(arguments); + + behaviorID = GetBehaviorIDFromArgument(arguments); + Game::logger->LogDebug("UpdateStripUIMessage", "x %f y %f stpId %i sttId %i bhId %i", xPosition, yPosition, stripID, stateID, behaviorID); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h new file mode 100644 index 00000000..ca626120 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h @@ -0,0 +1,24 @@ +#ifndef __UPDATESTRIPUIMESSAGE__H__ +#define __UPDATESTRIPUIMESSAGE__H__ + +#include "BehaviorMessageBase.h" + +class AMFArrayValue; + +class UpdateStripUiMessage : public BehaviorMessageBase { +public: + UpdateStripUiMessage(AMFArrayValue* arguments); + const double GetYPosition() { return yPosition; }; + const double GetXPosition() { return xPosition; }; + const StripId GetStripID() { return stripID; }; + const BehaviorState GetStateID() { return stateID; }; + const uint32_t GetBehaviorID() { return behaviorID; }; +private: + double yPosition; + double xPosition; + StripId stripID; + BehaviorState stateID; + uint32_t behaviorID; +}; + +#endif //!__UPDATESTRIPUIMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 278b6929..3e8bbacc 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -7,40 +7,29 @@ #include "ModelComponent.h" #include "../../dWorldServer/ObjectIDManager.h" #include "dLogger.h" +#include "BehaviorStates.h" +#include "AssetManager.h" +#include "BlockDefinition.h" #include "User.h" +#include "tinyxml2.h" +#include "CDClientDatabase.h" -uint32_t GetBehaviorIDFromArgument(AMFArrayValue* arguments, const std::string& key = "BehaviorID") { - auto* behaviorIDValue = arguments->FindValue<AMFStringValue>(key); - uint32_t behaviorID = -1; +// Message includes +#include "AddActionMessage.h" +#include "AddStripMessage.h" +#include "AddMessage.h" +#include "MigrateActionsMessage.h" +#include "MoveToInventoryMessage.h" +#include "MergeStripsMessage.h" +#include "RearrangeStripMessage.h" +#include "RemoveActionsMessage.h" +#include "RemoveStripMessage.h" +#include "RenameMessage.h" +#include "SplitStripMessage.h" +#include "UpdateActionMessage.h" +#include "UpdateStripUiMessage.h" - if (behaviorIDValue) { - behaviorID = std::stoul(behaviorIDValue->GetStringValue()); - } else if (arguments->FindValue<AMFUndefinedValue>(key) == nullptr){ - throw std::invalid_argument("Unable to find behavior ID from argument \"" + key + "\""); - } - - return behaviorID; -} - -BEHAVIORSTATE GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key = "stateID") { - auto* stateIDValue = arguments->FindValue<AMFDoubleValue>(key); - if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); - - BEHAVIORSTATE stateID = static_cast<BEHAVIORSTATE>(stateIDValue->GetDoubleValue()); - - return stateID; -} - -STRIPID GetStripIDFromArgument(AMFArrayValue* arguments, const std::string& key = "stripID") { - auto* stripIDValue = arguments->FindValue<AMFDoubleValue>(key); - if (!stripIDValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); - - STRIPID stripID = static_cast<STRIPID>(stripIDValue->GetDoubleValue()); - - return stripID; -} - -void RequestUpdatedID(int32_t behaviorID, ModelComponent* modelComponent, Entity* modelOwner, const SystemAddress& sysAddr) { +void ControlBehaviors::RequestUpdatedID(int32_t behaviorID, ModelComponent* modelComponent, Entity* modelOwner, const SystemAddress& sysAddr) { // auto behavior = modelComponent->FindBehavior(behaviorID); // if (behavior->GetBehaviorID() == -1 || behavior->GetShouldSetNewID()) { // ObjectIDManager::Instance()->RequestPersistentID( @@ -66,11 +55,7 @@ void RequestUpdatedID(int32_t behaviorID, ModelComponent* modelComponent, Entity // } } -void SendBehaviorListToClient( - Entity* modelEntity, - const SystemAddress& sysAddr, - Entity* modelOwner - ) { +void ControlBehaviors::SendBehaviorListToClient(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner) { auto* modelComponent = modelEntity->GetComponent<ModelComponent>(); if (!modelComponent) return; @@ -98,7 +83,7 @@ void SendBehaviorListToClient( GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", &behaviorsToSerialize); } -void ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) { +void ControlBehaviors::ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) { auto* modelTypeAmf = arguments->FindValue<AMFDoubleValue>("ModelType"); if (!modelTypeAmf) return; @@ -107,292 +92,57 @@ void ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) //TODO Update the model type here } -void ToggleExecutionUpdates() { +void ControlBehaviors::ToggleExecutionUpdates() { //TODO do something with this info } -void AddStrip(AMFArrayValue* arguments) { - auto* strip = arguments->FindValue<AMFArrayValue>("strip"); - if (!strip) return; - - auto* actions = strip->FindValue<AMFArrayValue>("actions"); - if (!actions) return; - - auto* uiArray = arguments->FindValue<AMFArrayValue>("ui"); - if (!uiArray) return; - - auto* xPositionValue = uiArray->FindValue<AMFDoubleValue>("x"); - if (!xPositionValue) return; - - double xPosition = xPositionValue->GetDoubleValue(); - - auto* yPositionValue = uiArray->FindValue<AMFDoubleValue>("y"); - if (!yPositionValue) return; - - double yPosition = yPositionValue->GetDoubleValue(); - - STRIPID stripID = GetStripIDFromArgument(arguments); - - BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - std::string type = ""; - std::string valueParameterName = ""; - std::string valueParameterString = ""; - double valueParameterDouble = 0.0; - for (uint32_t position = 0; position < actions->GetDenseValueSize(); position++) { - auto* actionAsArray = actions->GetValueAt<AMFArrayValue>(position); - if (!actionAsArray) continue; - - for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { - if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - - type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - valueParameterName = typeValueMap.first; - // Message is the only known string parameter - if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); - } - } - } - // modelComponent->AddStrip(stateID, stripID, type, behaviorID, valueParameterName, valueParameterString, valueParameterDouble, "", xPosition, yPosition); - type.clear(); - valueParameterName.clear(); - valueParameterString.clear(); - valueParameterDouble = 0.0; - } - // RequestUpdatedID(behaviorID); +void ControlBehaviors::AddStrip(AMFArrayValue* arguments) { + AddStripMessage addStripMessage(arguments); } -void RemoveStrip(AMFArrayValue* arguments) { - STRIPID stripID = GetStripIDFromArgument(arguments); - - BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - // modelComponent->RemoveStrip(stateID, stripID, behaviorID); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::RemoveStrip(AMFArrayValue* arguments) { + RemoveStripMessage removeStrip(arguments); } -void MergeStrips(AMFArrayValue* arguments) { - STRIPID srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); - - BEHAVIORSTATE dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); - - BEHAVIORSTATE srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); - - auto* dstActionIndexValue = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); - if (!dstActionIndexValue) return; - - uint32_t dstActionIndex = static_cast<uint32_t>(dstActionIndexValue->GetDoubleValue()); - - STRIPID dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - // modelComponent->MergeStrips(srcStripID, dstStripID, srcStateID, dstStateID, behaviorID, dstActionIndex); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::MergeStrips(AMFArrayValue* arguments) { + MergeStripsMessage mergeStripsMessage(arguments); } -void SplitStrip(AMFArrayValue* arguments) { - auto* srcActionIndexValue = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); - if (!srcActionIndexValue) return; - - uint32_t srcActionIndex = static_cast<uint32_t>(srcActionIndexValue->GetDoubleValue()); - - STRIPID srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); - - BEHAVIORSTATE srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); - - STRIPID dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); - - BEHAVIORSTATE dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); - - auto* dstStripUIArray = arguments->FindValue<AMFArrayValue>("dstStripUI"); - if (!dstStripUIArray) return; - - auto* xPositionValue = dstStripUIArray->FindValue<AMFDoubleValue>("x"); - auto* yPositionValue = dstStripUIArray->FindValue<AMFDoubleValue>("y"); - if (!xPositionValue || !yPositionValue) return; - - // x and y position 15 are just where the game puts the strip by default if none is given. - double yPosition = yPositionValue->GetDoubleValue(); - double xPosition = xPositionValue->GetDoubleValue(); - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - // modelComponent->SplitStrip(srcActionIndex, srcStripID, srcStateID, dstStripID, dstStateID, behaviorID, yPosition, xPosition); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::SplitStrip(AMFArrayValue* arguments) { + SplitStripMessage splitStripMessage(arguments); } -void UpdateStripUI(AMFArrayValue* arguments) { - auto* uiArray = arguments->FindValue<AMFArrayValue>("ui"); - if (!uiArray) return; - - auto* xPositionValue = uiArray->FindValue<AMFDoubleValue>("x"); - auto* yPositionValue = uiArray->FindValue<AMFDoubleValue>("y"); - if (!xPositionValue || !yPositionValue) return; - - double yPosition = yPositionValue->GetDoubleValue(); - double xPosition = xPositionValue->GetDoubleValue(); - - STRIPID stripID = GetStripIDFromArgument(arguments); - - BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - // modelComponent->UpdateUIOfStrip(stateID, stripID, xPosition, yPosition, behaviorID); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::UpdateStripUI(AMFArrayValue* arguments) { + UpdateStripUiMessage updateStripUiMessage(arguments); } -void AddAction(AMFArrayValue* arguments) { - auto* actionIndexAmf = arguments->FindValue<AMFDoubleValue>("actionIndex"); - if (!actionIndexAmf) return; - - uint32_t actionIndex = static_cast<uint32_t>(actionIndexAmf->GetDoubleValue()); - - STRIPID stripID = GetStripIDFromArgument(arguments); - - BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); - - std::string type = ""; - std::string valueParameterName = ""; - std::string valueParameterString = ""; - double valueParameterDouble = 0.0; - auto* action = arguments->FindValue<AMFArrayValue>("action"); - if (!action) return; - - for (auto& typeValueMap : action->GetAssociativeMap()) { - if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - valueParameterName = typeValueMap.first; - // Message is the only known string parameter - if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); - } - } - } - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - // modelComponent->AddAction(stateID, stripID, type, valueParameterName, valueParameterString, valueParameterDouble, "", actionIndex, behaviorID); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::AddAction(AMFArrayValue* arguments) { + AddActionMessage addActionMessage(arguments); } -void MigrateActions(AMFArrayValue* arguments) { - auto* srcActionIndexAmf = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); - if (!srcActionIndexAmf) return; - - uint32_t srcActionIndex = static_cast<uint32_t>(srcActionIndexAmf->GetDoubleValue()); - - STRIPID srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); - - BEHAVIORSTATE srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); - - auto* dstActionIndexAmf = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); - if (!dstActionIndexAmf) return; - - uint32_t dstActionIndex = static_cast<uint32_t>(dstActionIndexAmf->GetDoubleValue()); - - STRIPID dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); - - BEHAVIORSTATE dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - // modelComponent->MigrateActions(srcActionIndex, srcStripID, srcStateID, dstActionIndex, dstStripID, dstStateID, behaviorID); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::MigrateActions(AMFArrayValue* arguments) { + MigrateActionsMessage migrateActionsMessage(arguments); } -void RearrangeStrip(AMFArrayValue* arguments) { - auto* srcActionIndexValue = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); - uint32_t srcActionIndex = static_cast<uint32_t>(srcActionIndexValue->GetDoubleValue()); - - uint32_t stripID = GetStripIDFromArgument(arguments); - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - auto* dstActionIndexValue = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); - uint32_t dstActionIndex = static_cast<uint32_t>(dstActionIndexValue->GetDoubleValue()); - - BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); - - // modelComponent->RearrangeStrip(stateID, stripID, srcActionIndex, dstActionIndex, behaviorID); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::RearrangeStrip(AMFArrayValue* arguments) { + RearrangeStripMessage rearrangeStripMessage(arguments); } -void Add(AMFArrayValue* arguments) { - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - uint32_t behaviorIndex = 0; - auto* behaviorIndexAmf = arguments->FindValue<AMFDoubleValue>("BehaviorIndex"); - - if (!behaviorIndexAmf) return; - - behaviorIndex = static_cast<uint32_t>(behaviorIndexAmf->GetDoubleValue()); - - // modelComponent->AddBehavior(behaviorID, behaviorIndex, modelOwner); - - // SendBehaviorListToClient(); +void ControlBehaviors::Add(AMFArrayValue* arguments) { + AddMessage addMessage(arguments); } -void RemoveActions(AMFArrayValue* arguments) { - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - auto* actionIndexAmf = arguments->FindValue<AMFDoubleValue>("actionIndex"); - if (!actionIndexAmf) return; - - uint32_t actionIndex = static_cast<uint32_t>(actionIndexAmf->GetDoubleValue()); - - STRIPID stripID = GetStripIDFromArgument(arguments); - - BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); - - // modelComponent->RemoveAction(stateID, stripID, actionIndex, behaviorID); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::RemoveActions(AMFArrayValue* arguments) { + RemoveActionsMessage removeActionsMessage(arguments); } -void Rename(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - auto* nameAmf = arguments->FindValue<AMFStringValue>("Name"); - if (!nameAmf) return; - - auto name = nameAmf->GetStringValue(); - - // modelComponent->Rename(behaviorID, name); - - SendBehaviorListToClient(modelEntity, sysAddr, modelOwner); - - // RequestUpdatedID(behaviorID); +void ControlBehaviors::Rename(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { + RenameMessage renameMessage(arguments); } // TODO This is also supposed to serialize the state of the behaviors in progress but those aren't implemented yet -void SendBehaviorBlocksToClient(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); +void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { + // uint32_t behaviorID = ControlBehaviors::GetBehaviorIDFromArgument(arguments); // auto modelBehavior = modelComponent->FindBehavior(behaviorID); @@ -496,47 +246,26 @@ void SendBehaviorBlocksToClient(ModelComponent* modelComponent, const SystemAddr // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorBlocks", &behaviorInfo); } -void UpdateAction(AMFArrayValue* arguments) { - std::string type = ""; - std::string valueParameterName = ""; - std::string valueParameterString = ""; - double valueParameterDouble = 0.0; - auto* actionAsArray = arguments->FindValue<AMFArrayValue>("action"); - if (!actionAsArray) return; - for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { - if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - valueParameterName = typeValueMap.first; - // Message is the only known string parameter - if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); - } +void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { + UpdateActionMessage updateActionMessage(arguments); + auto* blockDefinition = GetBlockInfo(updateActionMessage.GetType()); + + if (updateActionMessage.GetValueParameterString().size() > 0) { + if (updateActionMessage.GetValueParameterString().size() < blockDefinition->GetMinimumValue() || + updateActionMessage.GetValueParameterString().size() > blockDefinition->GetMaximumValue()) { + Game::logger->Log("ControlBehaviors", "Updated block %s is out of range. Ignoring update", updateActionMessage.GetType().c_str()); + return; + } + } else { + if (updateActionMessage.GetValueParameterDouble() < blockDefinition->GetMinimumValue() || + updateActionMessage.GetValueParameterDouble() > blockDefinition->GetMaximumValue()) { + Game::logger->Log("ControlBehaviors", "Updated block %s is out of range. Ignoring update", updateActionMessage.GetType().c_str()); + return; } } - - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - auto* actionIndexValue = arguments->FindValue<AMFDoubleValue>("actionIndex"); - if (!actionIndexValue) return; - - uint32_t actionIndex = static_cast<uint32_t>(actionIndexValue->GetDoubleValue()); - - STRIPID stripID = GetStripIDFromArgument(arguments); - - BEHAVIORSTATE stateID = GetBehaviorStateFromArgument(arguments); - - // modelComponent->UpdateAction(stateID, stripID, type, valueParameterName, valueParameterString, valueParameterDouble, "", actionIndex, behaviorID); - - // RequestUpdatedID(behaviorID); } -void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { +void ControlBehaviors::MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { // This closes the UI menu should it be open while the player is removing behaviors AMFArrayValue args; @@ -545,20 +274,13 @@ void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAdd GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "ToggleBehaviorEditor", &args); - uint32_t behaviorID = GetBehaviorIDFromArgument(arguments); - - auto* behaviorIndexValue = arguments->FindValue<AMFDoubleValue>("BehaviorIndex"); - if (!behaviorIndexValue) return; - - uint32_t behaviorIndex = static_cast<uint32_t>(behaviorIndexValue->GetDoubleValue()); - - // modelComponent->MoveBehaviorToInventory(behaviorID, behaviorIndex, modelOwner); + MoveToInventoryMessage moveToInventoryMessage(arguments); SendBehaviorListToClient(modelComponent->GetParent(), sysAddr, modelOwner); } void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) { - if (!modelEntity || !modelOwner || !arguments) return; + if (!isInitialized || !modelEntity || !modelOwner || !arguments) return; auto* modelComponent = modelEntity->GetComponent<ModelComponent>(); if (!modelComponent) return; @@ -600,3 +322,135 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& else Game::logger->Log("ControlBehaviors", "Unknown behavior command (%s)\n", command.c_str()); } + +ControlBehaviors::ControlBehaviors() { + auto blocksDefStreamBuffer = Game::assetManager->GetFileAsBuffer("ui\\ingame\\blocksdef.xml"); + if (!blocksDefStreamBuffer.m_Success) { + Game::logger->Log("ControlBehaviors", "failed to open blocksdef"); + return; + } + std::istream blocksBuffer(&blocksDefStreamBuffer); + if (!blocksBuffer.good()) { + Game::logger->Log("ControlBehaviors", "Blocks buffer is not good!"); + return; + } + + tinyxml2::XMLDocument m_Doc; + + std::string read{}; + + std::string buffer{}; + bool commentBlockStart = false; + while (std::getline(blocksBuffer, read)) { + // tinyxml2 should handle comment blocks but the client has one that fails the processing. + // This preprocessing just removes all comments from the read file out of an abundance of caution. + if (read.find("<!--") != std::string::npos) { + commentBlockStart = true; + } + if (read.find("-->") != std::string::npos) { + commentBlockStart = false; + continue; + } + if (!commentBlockStart) buffer += read; + } + + auto ret = m_Doc.Parse(buffer.c_str()); + if (ret == tinyxml2::XML_SUCCESS) { + Game::logger->LogDebug("ControlBehaviors", "Successfully parsed the blocksdef file!"); + } else { + Game::logger->Log("Character", "Failed to parse BlocksDef xmlData due to error %i!", ret); + return; + } + auto* blockLibrary = m_Doc.FirstChildElement(); + if (!blockLibrary) { + Game::logger->Log("ControlBehaviors", "No Block Library child element found."); + return; + } + + // Now parse the blocksdef for the cheat detection server side. + // The client does these checks, but a bad actor can bypass the client checks + auto* blockSections = blockLibrary->FirstChildElement(); + while (blockSections) { + auto* block = blockSections->FirstChildElement(); + std::string blockName{}; + while (block) { + blockName = block->Name(); + + BlockDefinition* blockDefinition = new BlockDefinition(); + std::string name{}; + std::string typeName{}; + + auto* argument = block->FirstChildElement("Argument"); + if (argument) { + auto* defaultDefinition = argument->FirstChildElement("DefaultValue"); + if (defaultDefinition) blockDefinition->SetDefaultValue(defaultDefinition->GetText()); + + auto* typeDefinition = argument->FirstChildElement("Type"); + if (typeDefinition) typeName = typeDefinition->GetText(); + + auto* nameDefinition = argument->FirstChildElement("Name"); + if (nameDefinition) name = nameDefinition->GetText(); + + // Now we parse the blocksdef file for the relevant information + if (typeName == "String") { + blockDefinition->SetMaximumValue(50); // The client has a hardcoded limit of 50 characters in a string field + } else if (typeName == "Float" || typeName == "Integer") { + auto* maximumDefinition = argument->FirstChildElement("Maximum"); + if (maximumDefinition) blockDefinition->SetMaximumValue(std::stof(maximumDefinition->GetText())); + + auto* minimumDefinition = argument->FirstChildElement("Minimum"); + if (minimumDefinition) blockDefinition->SetMinimumValue(std::stof(minimumDefinition->GetText())); + } else if (typeName == "Enumeration") { + auto* values = argument->FirstChildElement("Values"); + if (values) { + auto* value = values->FirstChildElement("Value"); + while (value) { + if (value->GetText() == blockDefinition->GetDefaultValue()) blockDefinition->GetDefaultValue() = std::to_string(blockDefinition->GetMaximumValue()); + blockDefinition->SetMaximumValue(blockDefinition->GetMaximumValue() + 1); + value = value->NextSiblingElement("Value"); + } + blockDefinition->SetMaximumValue(blockDefinition->GetMaximumValue() - 1); // Maximum value is 0 indexed + } else { + values = argument->FirstChildElement("EnumerationSource"); + if (!values) { + Game::logger->Log("ControlBehaviors", "Failed to parse EnumerationSource from block (%s)", blockName.c_str()); + continue; + } + + auto* serviceNameNode = values->FirstChildElement("ServiceName"); + if (!serviceNameNode) { + Game::logger->Log("ControlBehaviors", "Failed to parse ServiceName from block (%s)", blockName.c_str()); + continue; + } + + std::string serviceName = serviceNameNode->GetText(); + if (serviceName == "GetBehaviorSoundList") { + auto res = CDClientDatabase::ExecuteQuery("SELECT MAX(id) as countSounds FROM UGBehaviorSounds;"); + blockDefinition->SetMaximumValue(res.getIntField("countSounds")); + blockDefinition->SetDefaultValue("0"); + } else { + Game::logger->Log("ControlBehaviors", "Unsupported Enumeration ServiceType (%s)", serviceName.c_str()); + continue; + } + } + } else { + Game::logger->Log("ControlBehaviors", "Unsupported block value type (%s)!", typeName.c_str()); + continue; + } + } + blockTypes.insert(std::make_pair(blockName, blockDefinition)); + block = block->NextSiblingElement(); + } + blockSections = blockSections->NextSiblingElement(); + } + isInitialized = true; + Game::logger->LogDebug("ControlBehaviors", "Created all base block classes"); + for (auto b : blockTypes) { + Game::logger->LogDebug("ControlBehaviors", "block name is %s default %s min %f max %f", b.first.c_str(), b.second->GetDefaultValue().c_str(), b.second->GetMinimumValue(), b.second->GetMaximumValue()); + } +} + +BlockDefinition* ControlBehaviors::GetBlockInfo(const BlockName& blockName) { + auto blockDefinition = blockTypes.find(blockName); + return blockDefinition != blockTypes.end() ? blockDefinition->second : &BlockDefinition::blockDefinitionDefault; +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index d487f929..a562aafe 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -3,15 +3,23 @@ #ifndef __CONTROLBEHAVIORS__H__ #define __CONTROLBEHAVIORS__H__ +#include <map> #include <string> -#include "RakNetTypes.h" +#include "Singleton.h" -class Entity; class AMFArrayValue; +class BlockDefinition; +class Entity; class ModelComponent; +class SystemAddress; -namespace ControlBehaviors { +// Type definition to clarify what is used where +typedef std::string BlockName; //! A block name + +class ControlBehaviors: public Singleton<ControlBehaviors> { +public: + ControlBehaviors(); /** * @brief Main driver for processing Property Behavior commands * @@ -22,6 +30,39 @@ namespace ControlBehaviors { * @param modelOwner The owner of the model which sent this command */ void ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner); + + /** + * @brief Gets a blocks parameter values by the name + * No exception will be thrown in this function. + * + * @param blockName The block name to get the parameters of + * + * @return A pair of the block parameter name to its typing + */ + BlockDefinition* GetBlockInfo(const BlockName& blockName); +private: + void RequestUpdatedID(int32_t behaviorID, ModelComponent* modelComponent, Entity* modelOwner, const SystemAddress& sysAddr); + void SendBehaviorListToClient(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner); + void ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent); + void ToggleExecutionUpdates(); + void AddStrip(AMFArrayValue* arguments); + void RemoveStrip(AMFArrayValue* arguments); + void MergeStrips(AMFArrayValue* arguments); + void SplitStrip(AMFArrayValue* arguments); + void UpdateStripUI(AMFArrayValue* arguments); + void AddAction(AMFArrayValue* arguments); + void MigrateActions(AMFArrayValue* arguments); + void RearrangeStrip(AMFArrayValue* arguments); + void Add(AMFArrayValue* arguments); + void RemoveActions(AMFArrayValue* arguments); + void Rename(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); + void SendBehaviorBlocksToClient(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); + void UpdateAction(AMFArrayValue* arguments); + void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); + std::map<BlockName, BlockDefinition*> blockTypes{}; + + // If false, property behaviors will not be able to be edited. + bool isInitialized = false; }; #endif //!__CONTROLBEHAVIORS__H__ diff --git a/tests/dGameTests/CMakeLists.txt b/tests/dGameTests/CMakeLists.txt index ba7d4d1c..b1fdaa07 100644 --- a/tests/dGameTests/CMakeLists.txt +++ b/tests/dGameTests/CMakeLists.txt @@ -8,6 +8,8 @@ list(APPEND DGAMETEST_SOURCES ${DCOMPONENTS_TESTS}) add_subdirectory(dGameMessagesTests) list(APPEND DGAMETEST_SOURCES ${DGAMEMESSAGES_TESTS}) +file(COPY ${GAMEMESSAGE_TESTBITSTREAMS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + # Add the executable. Remember to add all tests above this! add_executable(dGameTests ${DGAMETEST_SOURCES}) diff --git a/tests/dGameTests/dGameMessagesTests/CMakeLists.txt b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt index 2417d29c..54c43777 100644 --- a/tests/dGameTests/dGameMessagesTests/CMakeLists.txt +++ b/tests/dGameTests/dGameMessagesTests/CMakeLists.txt @@ -5,5 +5,10 @@ SET(DGAMEMESSAGES_TESTS get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME) list(TRANSFORM DGAMEMESSAGES_TESTS PREPEND "${thisFolderName}/") +# Copy test files to testing directory +add_subdirectory(TestBitStreams) +list(TRANSFORM GAMEMESSAGE_TESTBITSTREAMS PREPEND "${thisFolderName}/") +set(GAMEMESSAGE_TESTBITSTREAMS ${GAMEMESSAGE_TESTBITSTREAMS} PARENT_SCOPE) + # Export to parent scope set(DGAMEMESSAGES_TESTS ${DGAMEMESSAGES_TESTS} PARENT_SCOPE) diff --git a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp index 3d8b2d04..7905c19a 100644 --- a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp +++ b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp @@ -1,15 +1,50 @@ #include "GameMessages.h" #include "GameDependencies.h" -#include <gtest/gtest.h> +#include "AMFDeserialize.h" -class GameMessageTests : public GameDependenciesTest { - protected: - void SetUp() override { - SetUpDependencies(); - } - void TearDown() override { - TearDownDependencies(); +#include "AddActionMessage.h" +#include "AddStripMessage.h" +#include "AddMessage.h" +#include "MigrateActionsMessage.h" +#include "MoveToInventoryMessage.h" +#include "MergeStripsMessage.h" +#include "RearrangeStripMessage.h" +#include "RemoveActionsMessage.h" +#include "RemoveStripMessage.h" +#include "RenameMessage.h" +#include "SplitStripMessage.h" +#include "UpdateActionMessage.h" +#include "UpdateStripUiMessage.h" + +#include <gtest/gtest.h> +#include <fstream> + +class GameMessageTests: public GameDependenciesTest { +protected: + void SetUp() override { + SetUpDependencies(); + } + void TearDown() override { + TearDownDependencies(); + } + + std::string ReadFromFile(std::string filename) { + std::ifstream file(filename, std::ios::binary); + std::string readFile; + while (file.good()) { + char readCharacter = file.get(); + readFile.push_back(readCharacter); } + + return readFile; + } + + AMFArrayValue* ReadArrayFromBitStream(RakNet::BitStream* inStream) { + AMFDeserialize des; + AMFValue* readArray = des.Read(inStream); + EXPECT_EQ(readArray->GetValueType(), AMFValueType::AMFArray); + return static_cast<AMFArrayValue*>(readArray); + } }; /** @@ -50,3 +85,143 @@ TEST_F(GameMessageTests, SendBlueprintLoadItemResponse) { ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0); } + +TEST_F(GameMessageTests, ControlBehaviorAddStrip) { + auto data = ReadFromFile("addStrip"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + AddStripMessage addStrip(ReadArrayFromBitStream(&inStream)); + ASSERT_FLOAT_EQ(addStrip.GetXPosition(), 50.65); + ASSERT_FLOAT_EQ(addStrip.GetYPosition(), 178.05); + ASSERT_EQ(addStrip.GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(addStrip.GetStateId()), 0); + ASSERT_EQ(addStrip.GetBehaviorId(), -1); + ASSERT_EQ(addStrip.GetType(), "DropImagination"); + ASSERT_EQ(addStrip.GetValueParameterName(), "Amount"); + ASSERT_EQ(addStrip.GetValueParameterString(), ""); + ASSERT_FLOAT_EQ(addStrip.GetValueParameterDouble(), 1.0); +} + +TEST_F(GameMessageTests, ControlBehaviorRemoveStrip) { + auto data = ReadFromFile("removeStrip"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + RemoveStripMessage removeStrip(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(static_cast<int32_t>(removeStrip.GetStripId()), 1); + ASSERT_EQ(static_cast<int32_t>(removeStrip.GetBehaviorState()), 0); + ASSERT_EQ(removeStrip.GetBehaviorId(), -1); +} + +TEST_F(GameMessageTests, ControlBehaviorMergeStrips) { + auto data = ReadFromFile("mergeStrips"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + MergeStripsMessage mergeStrips(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(mergeStrips.GetSrcStripID(), 2); + ASSERT_EQ(mergeStrips.GetDstStripID(), 0); + ASSERT_EQ(static_cast<uint32_t>(mergeStrips.GetSrcStateID()), 0); + ASSERT_EQ(static_cast<uint32_t>(mergeStrips.GetDstStateID()), 0); + ASSERT_EQ(mergeStrips.GetDstActionIndex(), 0); + ASSERT_EQ(mergeStrips.GetBehaviorID(), -1); +} + +TEST_F(GameMessageTests, ControlBehaviorSplitStrip) { + auto data = ReadFromFile("splitStrip"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + SplitStripMessage splitStrip(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(splitStrip.GetBehaviorId(), -1); + + ASSERT_FLOAT_EQ(splitStrip.GetXPosition(), 275.65); + ASSERT_FLOAT_EQ(splitStrip.GetYPosition(), 28.7); + ASSERT_EQ(splitStrip.GetSrcStripId(), 0); + ASSERT_EQ(splitStrip.GetDstStripId(), 2); + ASSERT_EQ(static_cast<uint32_t>(splitStrip.GetSrcStateId()), 0); + ASSERT_EQ(static_cast<uint32_t>(splitStrip.GetDstStateId()), 0); + ASSERT_EQ(splitStrip.GetSrcActionIndex(), 1); +} + +TEST_F(GameMessageTests, ControlBehaviorUpdateStripUI) { + auto data = ReadFromFile("updateStripUI"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + UpdateStripUiMessage updateStripUi(ReadArrayFromBitStream(&inStream)); + ASSERT_FLOAT_EQ(updateStripUi.GetXPosition(), 116.65); + ASSERT_FLOAT_EQ(updateStripUi.GetYPosition(), 35.35); + ASSERT_EQ(updateStripUi.GetStripID(), 0); + ASSERT_EQ(static_cast<uint32_t>(updateStripUi.GetStateID()), 0); + ASSERT_EQ(updateStripUi.GetBehaviorID(), -1); +} + +TEST_F(GameMessageTests, ControlBehaviorAddAction) { + auto data = ReadFromFile("addAction"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + AddActionMessage addAction(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(addAction.GetActionIndex(), 3); + ASSERT_EQ(addAction.GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(addAction.GetStateId()), 0); + ASSERT_EQ(addAction.GetType(), "DoDamage"); + ASSERT_EQ(addAction.GetValueParameterName(), ""); + ASSERT_EQ(addAction.GetValueParameterString(), ""); + ASSERT_EQ(addAction.GetValueParameterDouble(), 0.0); + ASSERT_EQ(addAction.GetBehaviorId(), -1); +} + +TEST_F(GameMessageTests, ControlBehaviorMigrateActions) { + auto data = ReadFromFile("migrateActions"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + MigrateActionsMessage migrateActions(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(migrateActions.GetSrcActionIndex(), 1); + ASSERT_EQ(migrateActions.GetDstActionIndex(), 2); + ASSERT_EQ(migrateActions.GetSrcStripID(), 1); + ASSERT_EQ(migrateActions.GetDstStripID(), 0); + ASSERT_EQ(static_cast<uint32_t>(migrateActions.GetSrcStateID()), 0); + ASSERT_EQ(static_cast<uint32_t>(migrateActions.GetDstStateID()), 0); + ASSERT_EQ(migrateActions.GetBehaviorID(), -1); +} + +TEST_F(GameMessageTests, ControlBehaviorRearrangeStrip) { + auto data = ReadFromFile("rearrangeStrip"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + RearrangeStripMessage rearrangeStrip(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(rearrangeStrip.GetSrcActionIndex(), 2); + ASSERT_EQ(rearrangeStrip.GetDstActionIndex(), 1); + ASSERT_EQ(rearrangeStrip.GetStripID(), 0); + ASSERT_EQ(rearrangeStrip.GetBehaviorID(), -1); + ASSERT_EQ(static_cast<uint32_t>(rearrangeStrip.GetStateID()), 0); +} + +TEST_F(GameMessageTests, ControlBehaviorAdd) { + auto data = ReadFromFile("add"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + AddMessage add(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(add.GetBehaviorId(), 10446); + ASSERT_EQ(add.GetBehaviorIndex(), 0); +} + +TEST_F(GameMessageTests, ControlBehaviorRemoveActions) { + auto data = ReadFromFile("removeActions"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + RemoveActionsMessage removeActions(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(removeActions.GetBehaviorID(), -1); + ASSERT_EQ(removeActions.GetActionIndex(), 1); + ASSERT_EQ(removeActions.GetStripID(), 0); + ASSERT_EQ(static_cast<uint32_t>(removeActions.GetStateID()), 0); +} + +TEST_F(GameMessageTests, ControlBehaviorRename) { + auto data = ReadFromFile("rename"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + RenameMessage rename(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(rename.GetName(), "test"); + ASSERT_EQ(rename.GetBehaviorID(), -1); +} + +TEST_F(GameMessageTests, ControlBehaviorUpdateAction) { + auto data = ReadFromFile("updateAction"); + RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); + UpdateActionMessage updateAction(ReadArrayFromBitStream(&inStream)); + ASSERT_EQ(updateAction.GetType(), "FlyDown"); + ASSERT_EQ(updateAction.GetValueParameterName(), "Distance"); + ASSERT_EQ(updateAction.GetValueParameterString(), ""); + ASSERT_EQ(updateAction.GetValueParameterDouble(), 50.0); + ASSERT_EQ(updateAction.GetBehaviorID(), -1); + ASSERT_EQ(updateAction.GetActionIndex(), 1); + ASSERT_EQ(updateAction.GetStripID(), 0); + ASSERT_EQ(static_cast<uint32_t>(updateAction.GetStateID()), 0); +} diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/CMakeLists.txt b/tests/dGameTests/dGameMessagesTests/TestBitStreams/CMakeLists.txt new file mode 100644 index 00000000..e32ed3ef --- /dev/null +++ b/tests/dGameTests/dGameMessagesTests/TestBitStreams/CMakeLists.txt @@ -0,0 +1,24 @@ +set(GAMEMESSAGE_TESTBITSTREAMS +"sendBehaviorListToClient" +"modelTypeChanged" +"toggleExecutionUpdates" +"addStrip" +"removeStrip" +"mergeStrips" +"splitStrip" +"updateStripUI" +"addAction" +"migrateActions" +"rearrangeStrip" +"add" +"removeActions" +"rename" +"updateAction" +) + +# Get the folder name and prepend it to the files above +get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME) +list(TRANSFORM GAMEMESSAGE_TESTBITSTREAMS PREPEND "${thisFolderName}/") + +# Export our list of files +set(GAMEMESSAGE_TESTBITSTREAMS ${GAMEMESSAGE_TESTBITSTREAMS} PARENT_SCOPE) diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/add b/tests/dGameTests/dGameMessagesTests/TestBitStreams/add new file mode 100644 index 0000000000000000000000000000000000000000..13c0dd922c3979d837799c25c92ac420f602bd1f GIT binary patch literal 1024 zcmd;N6m?3?NG!|DFY<I@<2E!fF)?FgW?*1QOi2NfV8B?$z`)1`WD0<}ObiJinu&=6 z%w;&>0HlG~!I2Tj0AW^6mI($x6&wna6$BU<IUWlzu&{vm49-{IN;x<%uo$);U=RQr z#}UCecYO>$P?Nw3BcKsLV-y~+@T<Al0M$E59ARJtnb+7LvAy<q0njKOg9eCEObiY{ z2Q%;&mn4>?db+RzRRMvB10%>$K(_~%6lE5G#ZZVEAg>&V^ME)Sh;z<`PQG5xzyP!j z1xP@74X3Y80?8-*TXy0<kZys}7EpTTq61)gpl`uo#llvwc`)^stG|QgxuNn5s@AI% za_29DaTTBpb|@_%&~gxD4>V{Qn1JFSK1|#Jst!hh<Y9Kh#E@xp|H9mT<Bj5Bkhw4b zvk&H9bnzX>AnIZMg{e3A4+$5TdYFGLCW?a1FSGFmhX+g^Myo^hO_&5x2Qx<is&50- zK7r#LU~^!!wrM5UyjM|eU|Il_Jb>VfndlV;V7h|oXXI*|j4b}t1elyA_1T`1y5k(S z`krG{^wWJH`8f|#>_PO0euz65p!UP)2M;As!f67-RIt4k|E7TH3$fF|bj<U^w(n$} z#69{T@eR{=0qRc}AC!wg0G6ASW2?aWA66weraimvoc8SVp`aaa4%&9zb@q6e;RH)B w4yoc0cR<rm!ZZaGK7;X}L&)*@z#hW?56a3w0CQ&-O90qDf&B~}pme<z0KNDLEdT%j literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/addAction b/tests/dGameTests/dGameMessagesTests/TestBitStreams/addAction new file mode 100644 index 0000000000000000000000000000000000000000..d91d0ee451448a87cab9c2caded85a01a15ea26b GIT binary patch literal 1024 zcmd;N<V{R2$;{8=WaJE~EJ$S&bjf!~%uP&BW#lg|DatJHbYW$H0&$2+&%Bh>3aB85 zgQ!z#Mq*iJevzjO15ig|Nh*>KMoysC#FP|AuoXZysz4s59r%sofEX7Ha+m`a8$}!# zk(EH*jYQP|+2uf-2gK1poO3R8^7VQK1{NS28Aw1m4X3Y80?8-*TXy0<kZys}7EpTT zq61)g1E~5H3tPeF!PHx>{tlMsh8eDEy-Fc>{xTR>0m@*9(gFf42SN6Ld;tPXKn&u; z#2r9_NB|@cvl~em&P4Yw%-uKMC>{ox3j;9wVE#oH-*F709_C+|dV~LvaDl0Z`PX8i zDA@cm8*gxUz~o`HI#l0;Nf31~a|EFJHbCtYIL-k!2S#g~R)WoY71ai&1sEYFelZih z!r;Kb0@KgP)ixO<0~3F0!oc7(sn7P5)E(!r)%P5uqMz;q$<KL^Vh^G}^h4ai0JR@R zKX@pC5>68srh@IY_%{ViUx=L!remHTwtXk-B<|4%iEo&`3s8T;_-r7{fB-}b0I_mx z6<GhnsszWhXV;z6o_#(PwByY|+pfFL9uG5|7@+CJAypjW4k$lingR-+!T8T1<oJAG b58)>;EC;7sm^-^z0>JhiIKt2YO4nNfCR7_k literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/addStrip b/tests/dGameTests/dGameMessagesTests/TestBitStreams/addStrip new file mode 100644 index 0000000000000000000000000000000000000000..60ba6521b2c17299eb4d6ced8ac2edd5a427a1a9 GIT binary patch literal 1024 zcmd;N<Ss5L$}Hey<WEd4$;{6y=458%WaM?s%`eR>VPyb=5B8iPl?AD6@-9XB1)jNy z>6v+nAhnFFrJ0<J%$2OOW&(j@ngeqMtBElX1baF#vSy}0wKFg<a&a>9z*X@f6!C*C z_jG})6m?3?NG!|DFY<I@07@p7q#{W&asZu^n356<a<KyzB_a+eN+7OBCToD4av;tF z;%FewITt$ldOZUJ3y_TrB%qvz(^n^f<P-iaJMkY#w?JtNC_Qu00kFIQRQ-yDtzh$D z>Md7)2g`HA3|F;YrI0&+8H}p{Ww1kO0fCl-AbUU_1py`?2JvCy4j@4!0FsB<jU)_b zqWc%-?i+6u4};8w0hoO-|DucUI0jJ<^Dj)j!GB1&z|_P1YcWw2Y<`)IH#j_C@-SK* zs&B$1h&q@#0#JP$p!NwI=Kz}nqqR*d!REb+Y6H^(j1UvQn2BCtaA078>1X6>n+%eH zi9a=AU~rn$XM0NOj&s=RdyY}jPxpc3=R8QU2hkt;A?{#++7F{2Jd{8QrwI&G!S-7G zn*ydU#7+m(G0zX%zLRwl_vnMfH%#9Js6SzRHjrgN0HOteSUI)|tp8zEf@9jV>&|J< zJ|7C&@#dgy*Ij3ihZ#-`(DdSvDh_c6l%Ft70fo<C{O1sId_J&;@Dmu8gVQa{on0&e N5O*JD=m4ebtpMsK9iadK literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/mergeStrips b/tests/dGameTests/dGameMessagesTests/TestBitStreams/mergeStrips new file mode 100644 index 0000000000000000000000000000000000000000..062fd10b5d3c351b4c28ddc195f98bb0659beac5 GIT binary patch literal 1024 zcmd;N6fG`F4lXImEbw$;Wq<$&QK!_5#Inr%B2O0v(Ujtn;F83WRD?VOL=UQ%EKr?e za!F=>o@ZW4Y6Z+JsD2dl85p^N7UiZErKf^zE{0h9!Jd&1B%YaG1T-3AR&h=y&~~71 zxZ@a*9mijc;xZ8jMh>6}i76>yJrHA&$r>Q19EkIPI2wp^&V^3CUeCb50%Rit2`H!G z^wmiq`GkMVPW%VbEl}D5O3z$$04#3+Rlj0kE7&}kddt<{!SW#gf`O{_Duvwn%V1mu zD1#kJ3kb9v1la@f1qd(!F^CTncK`_@0gyb*ZX{ti6WzZsci(uUco<|Z48ZJz`4?S$ z$1#X{n15mF4gN#I1*RV6UyF&NVDrmtyuslClZVmjP<<07LDa#_5rFF30JTrxI0x7q z7_Dtu2{!LlR2!HUV1$_X#Z2@Hg98H#Og|%6+hmXoO#G<{1B26~KHF1Lcbvmk-*b$L ze!34NKj%S;J&69$4{-+r)P5NK;GqOcI89)f3bxnc-xM%?A$B^Lj`<%l`=qRsxJMr( zzG3<<K>Z2hvw<uF0uU_##LBT%VEqrP5**W>U3X4<_W4lIjyDHwyY4!BJj`%nfTkCR tRB?zqp!|es3MhOA<3ERx<MV+%grC5$9Gq@p?(AX-0Nb}=qY_yERsga49ZdiL literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/migrateActions b/tests/dGameTests/dGameMessagesTests/TestBitStreams/migrateActions new file mode 100644 index 0000000000000000000000000000000000000000..217f44d95ab71b27de401415bd1127a420b4c72a GIT binary patch literal 1024 zcmd;Nlr1hwc1$kG%+K@8OG&L@WdMT@_M$-X;F6-u0#6r&m{V#-Vp(Q>k*5oTXi9NO za7kiGDqNm{0ip+0OctmP(|iU8h<;@A85kJ(fR^WGrWXN?faodC$pqR0R0VSc&=Mp^ z@E4=FK*WKO1872GN(xvH#4E^T4Ukg~#Cbp*4a7O;LMLCZXJB9fvXOxVl+$qf>LieS z!oOuF{sZY2C~X0yXD&JbmN$T^U$L+iY#vO#<?8QXd2X2Ds@AI%a_29DaTTBpb|@_% z&~gxD56BlFzy!n~K1|#JB!~n+@-VxRgyBqd|H9mT<Bj5Bkhw4bvk&H9bnzX>AnIZM zg{e3A4+$5TdYFGLCW?a1FSGFmhX+g^Myo^hO_&5x2Qx<is&50-K7r#LU~^!!wrM5U zyjM|eU|N6?V&WGw(JKrN3@kAHj9hJ#K{7D$rzQ*xPLuj<Pf6Wz4qJWCF)I4$K9KyJ z2PyU-`a?g&9Sl(WVf2HC5-8y`fnh4xUW<QI!1RUK>0ml${U4FjvQFY2eUSKu>AL{+ zCydVqvJ417v;Yt*$5w&$Kdee{OnY|SIqli!LqR*<9JKAa>+JC`!-)Z!UK~=zA?|?k p6Q(Jk@EMH%972xI2lfzt0>g4}x`ny3izNVT--dk*9iVi*6#%+o9`*nL literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/modelTypeChanged b/tests/dGameTests/dGameMessagesTests/TestBitStreams/modelTypeChanged new file mode 100644 index 0000000000000000000000000000000000000000..ef282ce2757f0f91ef87f904b07b6db11cfd7697 GIT binary patch literal 1024 zcmd;N6!y(eNzDnVEJ$T#fC5GVAR`wh?3|I9m!6sekz?cr(nYDc`DLlWB}JJ9i6yC? zE^v*a#YM@%C8%PuDa9p@$t9Wjd7gPGsTDA_4x&JDun|c58TmjKXQmecjezJW&dG$R zLbAjuH6yVsGr!2wg@L~q#WoQKMh>6}i76>ylOaw<CToD4av;tF;%FewITt$ldOZUJ z3y_TrB%qvz(^n^f<P-iaJMkY#w?JtNC_Qu00kFIQRQ-yDtzh$D>Md7)2g`#(4GdJR zS1IJqUk2kUKpE^%T0o%XAjlq&FF=3^h(UaqxC2NK34r8bb|VSHndtt7x%<W&#ls+T zVE|?y%)jX3JB~rr!~6?VZ}1-yE->{l|5{8G1)E=H;|&fEm^_SDhw7U!38D^WjsR5O z2B>`k$2q{}z-VpLO0apaqT0Z;03*c2FJ_`w7#tW_VEP%k+9rc!VB$|r7#N%;_1T`1 zy5k(S`krG{^wWJH`8f|#>_PO0euz65p!UP)2M;As!f67-RIt4k|E7TH3$fF|bd3N1 zyVqr%#69{T@eR{=0qRc}pABRg5P)b<CR2{B0_%TRmEf56?7DN>v(JZucDy-g+jZC3 z<6(vq12nxjq>4k_0p%x5Q$XP}82>qh9G?&DA^Ze}<=}J+b7vPz0N6f<{R|zTbiEY- D3ceex literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/rearrangeStrip b/tests/dGameTests/dGameMessagesTests/TestBitStreams/rearrangeStrip new file mode 100644 index 0000000000000000000000000000000000000000..06dda90b137e18dae0c1b41e46f13a57bc5a6ef0 GIT binary patch literal 1024 zcmd;Nlr1hwc1$kG%+K@8OG&L@Wq<$&{^F9N%mPmrm;i&QQ))(HS!RBbrwfB@N^uFM zrVsW&O^GF`NSYY=fW{T2CKeSX=B1|wgN$TIOi6+0&4ZeTsfz=s3#bgNz64BScL$nI z5eG(OolvhJQ8hqzIS}UoaWoL;oC}?Ny`F)A1;|DQ5>QUV>8q1K@(KTzo%j!=TcETB zl%Bch09f7ts(!`7R<L<6^_Hu@gXOtlhO1hyQplaZ48~P}GT5QCfI!PZkUbz@fB+K^ zgZMCU2aq5V0LjDbMiPcI(ftc^_l-A-he77T0L(s^f6>Kv9D}Hb`4^_%;6Ef>VCrH1 zwU{UhHowfq8yp@mc^It@)i+@hL><f=0jRzWQ2PXqbAZi((b}e!VDnx@wSj2?Mu>@D z%tWs+I54ol^fPj`O$N!p#GjflFgQ)>vppqs$2n~EJ;$i%r~5$ia~`DFgXj<a5O**@ z?T6719!j8u(*%a8V0$h8O##yvVyA=YnExTOPs%!pd-Or#8>a69)Soau8^|&s0MP<K ztQ=bf*8i|7!7=UGb?3BapAQA?cyrLU>#noM!we?|XnJu-6^FP3%1@Z4fWl`m{&NU9 eJ|Eaa_z4Wl!RZ#}&MuY!uze5qF?4{^^;Q6QY9CVo literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/removeActions b/tests/dGameTests/dGameMessagesTests/TestBitStreams/removeActions new file mode 100644 index 0000000000000000000000000000000000000000..56e158e5ec08c6615aa73733fc0cc81386f4c837 GIT binary patch literal 1024 zcmd;N6m?3?NG!|DFY<I@5Kl}l$;{95%u7kFU}XS<5BB`UB}JJ9o-R-U1_q!&Vo55J z03$C@X;Er!ep#v`*nnb)UIs=^AR{p)1tJP$qYC6PVwjEW8ccgQAjSoQ9OM9UFq#q( z2S#KiP*)&PH9&Sb5a$7LG!W;U3!Qwuo`Hb{$VLVdP)@_?tCK+T3ICRz_z$F8ptJ>) zp1J4%Sl$4te#OF8uz4``maD&m<+)*ot6Hy8$eq6o##Mka*rBw5K+8dpJs@9z022^{ z_%Lw?kRTEO$;0eM5{5I;{R?yVjW>#iLFU2$%s!ZZ(ZzQhgQ$o37pC6eKO|gW>S6x1 zm?#Q1zs$xP93C)v7_AP~H(?S)9n2g7sJ;zQ`vi`2fX#u?+NPCY^Ik=@foTCoh>2g! zM6WP7FtEV%Gjg>}2Fbw0pPDc*I8ExaJtcL=Ic)Vk$EfJ1`#|z@9;DcV=nwr6cQ8Qh zhtUrnN}z<(1cs?#doBJ=0n-;^r-SL3=Z9_I$vTO9^g-eqrtbpOpD;cf$TA=R(E>oM z99sp}|F9~-G40uP=d@>^4+ZUbbI`WyuCvF(3?~L?dT~e<hqwdEPnf2F!e=o4a|k&; dAJ{|q2@K1@=@#bBE|vhWeFu&(bb!+JRsfZm8chHI literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/removeStrip b/tests/dGameTests/dGameMessagesTests/TestBitStreams/removeStrip new file mode 100644 index 0000000000000000000000000000000000000000..46ca064086c0239b91e0ff03a8a3fbf2d82dd132 GIT binary patch literal 1024 zcmd;N6m?3?NG!|DFY<I@;4dyI$}I47VPyb=5B5NT#FA9F00RRfH&CW1H8;O3H5jB8 zRaUgPC^;BShipo5iDPm}W`3S$UP@{O)My3=QJ^^32xQawfTrhWrWXN?h3F~H$%Lqa zxru=R&B4en5OHAS0Gg1Pk^(jv><JX22FNQ1;yfUZ2I8D^p_8xIGcd3K*~mZw%4s-# zbrMKE;oq_o|ABN1l(vA<GZ!5I%Nsz|uUOa$HV>xWa`ktxJSfz_K-GGcLhk%!Fs=fW z!49Pb1X>P)>;d@#1ekyr#D|GHfCP~MNFHW4k}#Z!?q8U@Z@f`F3^Er6VD`cMi!Q$7 z7(_kHzcBR%{~_T5QxEg6#Y9oC`DHfV;P8OS!)SG=z6p~c>R{#wK=o~a+9z<F18feA z);6sKoA)ZJ4NMC#LQMQ(CVGXzfq@04pOLF=GDrp{{?vql!D&*T?J21{&S9(XIYvc4 z-3OAN^B~0@M1SaqxPt*|Ka76xPy!{KCNN9|+iUS}3YfkSI~`2N%nwhwChH{b(Fcid zn7#{8f5P}|Aj^ONL<<11a%>e?|HG;T$FyhHoztFuJ`}X$%|Y9)yUrdDGn^Qp>BS*c s9O4crKVg~z3ZKFF&mrXad|(gZCon7rr(2jiyI2Ci_8Dwa0_)!j0E?>|zW@LL literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/rename b/tests/dGameTests/dGameMessagesTests/TestBitStreams/rename new file mode 100644 index 0000000000000000000000000000000000000000..bc8827dcd5a07c742276cec210f2fad51750cf97 GIT binary patch literal 1024 zcmd;N<n&9-O=aUONi8lBbxO@hEX&L<@^oQfWMg1pC`!!(N<swqi%W_!3p`y|f#P5Q z6i6&dMG|1-1&WszqyR;OL25%i88Fpw0@Wm@q&Oy*Waj5V?ZQ;W0Z|1urUXnP>_v7Z znobc1Mr55}XQB`_Kwdcz=K*mv5a*l=oqWBXfq@0cMg|g4PQ&S|lR)wb|CXKj52Rb5 zv;~x&x#$2`-T<n8#llvwc`)^stG|QgxnYK@TCY;boxcpmRe&<sp|pTN%R!JmAYXt0 z6A**=FmVTvAQAw{!|X;9hBMLq3v>64H;RWr=E4BXKA3;e#djQosE7F%rrzK`BwS$X zVg9w4C<->e%*GoW9x!<rtq#>UVG=|g%p3uzz70_O1deln&4JO{rj=mxUPZNmX#qxv ziC@e_uP`_;u)y>)a<xqc$-u;)nlLapP3p5fC3VL+Z1p|IsOYErK=N}Qq}YS#5B(5# zFhK2x(GMO<poG%|hN)nCE&fdb(-&f=gXx&*^Ab+TI*EJqLE;;xZ+#RbeSqu$fd&SK z4p4dmWiA0AR*tO#>wj34;F$L8x^vpI&xe9`yg6vwb=TSBVTKa}G`%>aibLE1<tI#2 kK;bhO|2c#lpAYOI`~-&O;B*UfXBSHV*gk>%5O-_^021LB;s5{u literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/sendBehaviorListToClient b/tests/dGameTests/dGameMessagesTests/TestBitStreams/sendBehaviorListToClient new file mode 100644 index 0000000000000000000000000000000000000000..fcca696dc1b93ff923a04242791f4642f65fe9f5 GIT binary patch literal 1024 zcmd;NWRzfFU?@(_OL0ogNG!|DFY?JOE(ytZ&dE&8D*;L|Fff(@F(;5A0Om3=B!Flp zCJr!{;eZ2>24V+CMj!)(SvgrI7ywmpC`?umU|{5UEWp6R0^&0`Uwtd(;K0CQ*m{6L z0B9UX1moQGG5kPH0w;`sMgWabc)-H1=3)a>?<8@Afe~b0V}r!@+T#U4qj(G&AVx7U zI23uhFz^?bB$lLly08LO0fC4EBgj#SDJj7vMVSR)F%+T($SVipJRpt+;+%7#ldsn^ zFaT{s0iZAefrispCxPS>{w+K4A4s=AX$vSlbI}2?JkYmbuwr2=*gTke%hlh(^4w5) z236}-3c2%_!MF-g20N4%5NJ6FvIiQp3`{_A5FaM)096O0K=LrVVPeQMx_@ErzVSx! zFvwgOfY}H0FS_`SV-WQ)|H9N8{D*`KOg+rM786Cm=9k%cgTn(R52Mwg`X)?*sDqg! z0M)kvYM;Py4zM{eTHCY|Y~HJ=HZUy!N*+M)#Z2@H12A2|^fPj`O-2@fY6477llp8= zN!@V{TYb+lD*EX@ko=qnDfS@xLqEhF3{d-F^n-^IDB(1LVJg^Oi+@wV^o7{zU^?dc zVcU1IPU0SYkobn_y8!hkjL!zL3<y9pF!?hm$5w&$Kdee{OnY|SIqli!LqR*<9JKAa z>+JC`!wHsN98$$0?trGBglP&Wd<Nq`hmhm*fjxx(pBZEu0|U&RT`U1$`x*{2bb!+J FRsisU4MqR} literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/splitStrip b/tests/dGameTests/dGameMessagesTests/TestBitStreams/splitStrip new file mode 100644 index 0000000000000000000000000000000000000000..a23c1682fef381b86d6e9e4da202ba4c217e8426 GIT binary patch literal 1024 zcmd;Nlr1hwc1$kG%+K@8OG&L@WdMT@_M$-X;F6-u0#6sH7z2Z-Q))(HS!RBbrwfB< zN^wbWNn%MVvOHK1niyCe(40_DPDbWRRvlv?*lgp#T)~<K0#=0%j1aR>>~dh_0y?C) zASV-O3s45TBlwF^Tp;4W$N|)qn34k41MvznSp(#h192V@M+0%rxzNei>lqkWfNW$S z0p&EDzB&mcpYU(liT^;l1xi~$>6wcTfaMLK>Q^jm1)B#`Z@KzASe_eZxT^Ikh1~he zU|a<#gB?l>2(%mo*#q(g2rvOLhz}EY00|-ikUY$8Bw;uc-M=t*-*}^V7-TLC!0dzh z7hQbEF^GDYe_`qk{zJkArXJ>Bi;1FO^UG|!!QlauhtcX#eG?`@)WOUVfa==-wNKzU z2iP1Kt!-KfHt$tb8<-YggqZlnO!Nwa0|N_8KO<M$WRMI@{HX~8gVUrw+f!0^oWoY% zbBv09x(_5j=Rt}+i2l$IaR&p`ei;4Wp#(}eO<<S`w%6j{6fk`ub~>1j`5!X-q^y&; zM;|1<VfrpW{R!i<fh+?85G?@2%CS{o{ST`W9Mhg%cTRiu`B2b~HwSII?mBxs%y43W yrWc1)afmyh{Df%=D0~LvKZlUx^MO5tpTMvjoNi(6>|zN3+ZS+*p#zkzw*mkF+Z`$Z literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/toggleExecutionUpdates b/tests/dGameTests/dGameMessagesTests/TestBitStreams/toggleExecutionUpdates new file mode 100644 index 0000000000000000000000000000000000000000..02a72181616c6a1ab46e82146e603ec296fa3031 GIT binary patch literal 1024 zcmd;N<WJ2@Ov*`3VP+I#U|=Z8PfyQDb*)HEE-lH-&kHR`Ni0b%W?*3C1WF13F#`h= zLjss$;s8+$3<n&51Q0toG6ESO%*x3!!2qa`Lt(Ol00Se(V*v&h77(Ao`RZFK2L}cg z!`1@~0zl(9A{ghckKqSu5;$Q5Gy-Uh!UGn5H5VJ8dMAk^42&T28XF|G*B&nb8pUJK z05OV*!J)|0g@M1g1n53b7gnGuAP{k21UV`(B_+6|D6;@8hC<W;dF4Qy2gK1poO3R8 z^7VQK2B2*yKmy8ZIDK^zNIv1;vJ?M-bPJTWfYLJ;9RSM%eG3LF7Pf-TgQ>S%{T(dN z4V7n5wO*x=JAWCBs{m!NLumnlmV+RBpg{`^YX$}oA13YqRR^O$@-Vw$V#qYQe_`&v z@ka45$XpnJ*$4A4y7-P`5cM$s!qgl5hlC4EJ<Pur6Gg%1m)UrO!viJ{qt&7MCQO2; zgP9`$)wcm^pTKbrusJYV+q4pF-m9oKFf9N|9zgKLO!Nu^FkQj)Gjg>}Mizf+0!&Vm z`fN{0-Ej_Eea|r}`sqH9{G10V_8|I0Kg1mjQ2Sx@gNG6*;WU9^D%f6&e^bEph1ls} zI_CLd+jp`~;vRjF_=f4b0QDz~&jzv#2tYJ2`7<cTR)O_DtV(c9dv@J9?b+u;K|9_Y zwC%d<?C~(e36@?QQpF+efTo{>X$mNO2ID`6kmK`#J%pdYupFFjVeaf=2>{#oU>`#V IC|z#_09Q>B!~g&Q literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/updateAction b/tests/dGameTests/dGameMessagesTests/TestBitStreams/updateAction new file mode 100644 index 0000000000000000000000000000000000000000..e007d5e6b3f2d5b0ac733e3e925bcbf4ed522314 GIT binary patch literal 1024 zcmd;N<V{R2$;{8=WaJE~EJ$VJcgv}C$uG|nbjd6(Nz6-5Wn};ZPX|W+;*z4w0#6sH z2m^ySM5||BN@@jE@PoamQ))(HS!RBbrwap6M`B4Tk`6{5pkbv2DL_$2u(dc9asU-3 zrlbUetYl!2fH;DI2}obBXJ8NzXgT;FNIO8qVH8N-0LH;W*8s)JfjAF{qk%Z*T<Bzw zc`QISGJx6FaQf;bkbJ_wWhX%PwLobLC_Qu00kAyG&J_z=!REo#Tdw{Nmgj~Uu4=tX zA$R^V7*_$xV29E$e}Q}t0wDi@?1hOtfCP~Mss4qz`^Fo^!yt2E0A?S|zv$vSjzQGJ z{0mcW@E;N`F!eD1T1*rLn_p(*4Gs^OJd9R{>YFeLq7G(`094-wsC@#*Il$(?Xl>I< zuz9bd+Q75`BgDinW};VsiGc;CpOLF=GDrp{{?vql!D&*T?J21{&S9(XIYvc4-3OAN z^B~0@M1SaqxPt*|Ka76xPy!{KCNN9|+iUS}3YfkSI~`2N<a^p5lywsK=!3*JOy32l zKVf_}kYzvsq6L6hIkpO{|6x^vW7@Op&S}p+9}3#>=AdoYU1yJn8BPq)^x}{z4si#R ppD;}Uh0kF8=MZvyKCp-I6Bw3*(=E)MT`U1$`!?)j=m4ebtpEV}6u|%h literal 0 HcmV?d00001 diff --git a/tests/dGameTests/dGameMessagesTests/TestBitStreams/updateStripUI b/tests/dGameTests/dGameMessagesTests/TestBitStreams/updateStripUI new file mode 100644 index 0000000000000000000000000000000000000000..7d0eed926857d88dbe03d3ab1f097239101fb2a1 GIT binary patch literal 1024 zcmd;NWG&6)WMr;nJ#_{M);KyaSFp~S2?Uz44veBssTql7nfXPYE)4v|B}JJ9o-V8m zPyiH2EJ;NYVB`hLloq4_MT0?VLp?z%MN^7Pz+7aN+(3!k)S`5V!eWp*28IvzjC?>U zH#5BmXoO>ONoIataZV;gH^N>tM<KgG#DS3mXhLF23fM-Fp{Sq+$SnurJRpt+;+%7# zldsn^Ft7mG$Up+hX*hj#5=cJb-?9_`fpiO$wt&(z7aai08$i{sSl9|S52oI7^>?s5 z$iHBqYQ0J!cm6UMR{_dkhtdK9EeApNfP4W0Oh63c!^9mxf=B=)53?Id7|ulZFU;LH z-Y6ahnF|9j`(XY>7vFIVq8{d7n0kZ%kZ^&ihxylHqA1w>G8=Djc);Xgv^rGZgh>!} zFmnW;`ZhrA6FANRHU~y)n^uC&dll6NrUe)wCVnv!y~5zYzyj0H$kjF(Bm)zFYQn(a zG^x+_l++#Pu+{e*qoSYg1If>MkYW#_KlDS~!2q=%Mn8Bcff7y=7^Z^lwfHv$Okaqd z4yI$){}DMY>m=^c2Z?W(z6(%)!uV_;%YXnx3jnclY!z7l!>R<wv}f0y)1G}k6tv^b zLEEmo&K?gloEV_##UWK3;tnW3VVVL8pTYRgA>{acU=QIZFf0eBTbMh$SOUQIJ=n+4 I0ZP|f0dLVDp#T5? literal 0 HcmV?d00001 From 484488e47d511c680660f2764c19c1a27114ae8c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Thu, 16 Feb 2023 11:14:23 -0600 Subject: [PATCH 131/166] add bounds check to prevent crashing (#992) --- dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp b/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp index 78bbaee5..0dd91bf2 100644 --- a/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp @@ -7,9 +7,9 @@ void AgMonumentRaceGoal::OnStartup(Entity* self) { } void AgMonumentRaceGoal::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - if (name == "RaceGoal" && entering->IsPlayer() && status == "ENTER") { - auto* manager = EntityManager::Instance()->GetEntitiesInGroup("race_manager")[0]; - - manager->OnFireEventServerSide(entering, "course_finish"); + if (name == "RaceGoal" && entering && entering->IsPlayer() && status == "ENTER") { + auto managers = EntityManager::Instance()->GetEntitiesInGroup("race_manager"); + if (managers.empty() || !managers.at(0)) return; + managers.at(0)->OnFireEventServerSide(entering, "course_finish"); } } From d138b7b87885d536d01e6edc676e6bc343dd886c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 16 Feb 2023 09:30:33 -0800 Subject: [PATCH 132/166] Make ControlBehavior messages far more modular (#991) * Make case consistent * How modular can you go? Holy modular * Add comments * Initialize values --- .../ControlBehaviorMessages/Action.cpp | 31 +++++ .../ControlBehaviorMessages/Action.h | 25 ++++ .../ControlBehaviorMessages/ActionContext.cpp | 31 +++++ .../ControlBehaviorMessages/ActionContext.h | 26 ++++ .../AddActionMessage.cpp | 40 ++---- .../AddActionMessage.h | 24 ++-- .../ControlBehaviorMessages/AddMessage.cpp | 6 +- .../ControlBehaviorMessages/AddMessage.h | 6 +- .../AddStripMessage.cpp | 57 ++------- .../ControlBehaviorMessages/AddStripMessage.h | 35 +++--- .../BehaviorMessageBase.cpp | 33 +++++ .../BehaviorMessageBase.h | 43 ++----- .../ControlBehaviorMessages/CMakeLists.txt | 4 + .../MergeStripsMessage.cpp | 19 +-- .../MergeStripsMessage.h | 19 ++- .../MigrateActionsMessage.cpp | 25 +--- .../MigrateActionsMessage.h | 19 ++- .../MoveToInventoryMessage.cpp | 6 +- .../MoveToInventoryMessage.h | 8 +- .../RearrangeStripMessage.cpp | 16 +-- .../RearrangeStripMessage.h | 13 +- .../RemoveActionsMessage.cpp | 15 +-- .../RemoveActionsMessage.h | 13 +- .../RemoveStripMessage.cpp | 9 +- .../RemoveStripMessage.h | 13 +- .../ControlBehaviorMessages/RenameMessage.cpp | 6 +- .../ControlBehaviorMessages/RenameMessage.h | 6 +- .../SplitStripMessage.cpp | 30 +---- .../SplitStripMessage.h | 26 ++-- .../StripUiPosition.cpp | 22 ++++ .../ControlBehaviorMessages/StripUiPosition.h | 21 ++++ .../UpdateActionMessage.cpp | 39 ++---- .../UpdateActionMessage.h | 26 ++-- .../UpdateStripUiMessage.cpp | 20 +-- .../UpdateStripUiMessage.h | 20 +-- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 24 ++-- tests/dCommonTests/AMFDeserializeTests.cpp | 8 +- .../dGameMessagesTests/GameMessageTests.cpp | 115 +++++++++--------- 38 files changed, 461 insertions(+), 438 deletions(-) create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp new file mode 100644 index 00000000..7da286b0 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp @@ -0,0 +1,31 @@ +#include "Action.h" + +Action::Action() { + type = ""; + valueParameterName = ""; + valueParameterString = ""; + valueParameterDouble = 0.0; +} + +Action::Action(AMFArrayValue* arguments) { + type = ""; + valueParameterName = ""; + valueParameterString = ""; + valueParameterDouble = 0.0; + for (auto& typeValueMap : arguments->GetAssociativeMap()) { + if (typeValueMap.first == "Type") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + valueParameterName = typeValueMap.first; + // Message is the only known string parameter + if (valueParameterName == "Message") { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; + valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); + } else { + if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; + valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); + } + } + } +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h new file mode 100644 index 00000000..c97b4050 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h @@ -0,0 +1,25 @@ +#ifndef __ACTION__H__ +#define __ACTION__H__ + +#include "BehaviorMessageBase.h" + +/** + * @brief Sent if a ControlBehavior message has an Action associated with it + * + */ +class Action { +public: + Action(); + Action(AMFArrayValue* arguments); + const std::string& GetType() { return type; }; + const std::string& GetValueParameterName() { return valueParameterName; }; + const std::string& GetValueParameterString() { return valueParameterString; }; + const double GetValueParameterDouble() { return valueParameterDouble; }; +private: + std::string type; + std::string valueParameterName; + std::string valueParameterString; + double valueParameterDouble; +}; + +#endif //!__ACTION__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp new file mode 100644 index 00000000..480eef45 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp @@ -0,0 +1,31 @@ +#include "ActionContext.h" + +#include <stdexcept> + +#include "AMFFormat.h" + +ActionContext::ActionContext() { + stripId = 0; + stateId = BehaviorState::HOME_STATE; +} + +ActionContext::ActionContext(AMFArrayValue* arguments, std::string customStateKey, std::string customStripKey) { + stripId = 0; + stateId = BehaviorState::HOME_STATE; + stripId = GetStripIdFromArgument(arguments, customStripKey); + stateId = GetBehaviorStateFromArgument(arguments, customStateKey); +} + +BehaviorState ActionContext::GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key) { + auto* stateIDValue = arguments->FindValue<AMFDoubleValue>(key); + if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); + + return static_cast<BehaviorState>(stateIDValue->GetDoubleValue()); +} + +StripId ActionContext::GetStripIdFromArgument(AMFArrayValue* arguments, const std::string& key) { + auto* stripIdValue = arguments->FindValue<AMFDoubleValue>(key); + if (!stripIdValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); + + return static_cast<StripId>(stripIdValue->GetDoubleValue()); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h new file mode 100644 index 00000000..5f46fd8c --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h @@ -0,0 +1,26 @@ +#ifndef __ACTIONCONTEXT__H__ +#define __ACTIONCONTEXT__H__ + +#include "BehaviorStates.h" +#include "dCommonVars.h" + +class AMFArrayValue; + +/** + * @brief Sent if contextual State and Strip informationis needed for a ControlBehaviors message + * + */ +class ActionContext { +public: + ActionContext(); + ActionContext(AMFArrayValue* arguments, std::string customStateKey = "stateID", std::string customStripKey = "stripID"); + const StripId GetStripId() { return stripId; }; + const BehaviorState GetStateId() { return stateId; }; +private: + BehaviorState GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key); + StripId GetStripIdFromArgument(AMFArrayValue* arguments, const std::string& key); + StripId stripId; + BehaviorState stateId; +}; + +#endif //!__ACTIONCONTEXT__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp index f91512fe..4fc7f82b 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp @@ -1,39 +1,13 @@ #include "AddActionMessage.h" -AddActionMessage::AddActionMessage(AMFArrayValue* arguments) { - auto* actionIndexAmf = arguments->FindValue<AMFDoubleValue>("actionIndex"); - if (!actionIndexAmf) return; +AddActionMessage::AddActionMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + actionContext = ActionContext(arguments); + actionIndex = GetActionIndexFromArgument(arguments); - actionIndex = static_cast<uint32_t>(actionIndexAmf->GetDoubleValue()); + auto* actionValue = arguments->FindValue<AMFArrayValue>("action"); + if (!actionValue) return; - stripId = GetStripIDFromArgument(arguments); + action = Action(actionValue); - stateId = GetBehaviorStateFromArgument(arguments); - - type = ""; - valueParameterName = ""; - valueParameterString = ""; - valueParameterDouble = 0.0; - auto* action = arguments->FindValue<AMFArrayValue>("action"); - if (!action) return; - - for (auto& typeValueMap : action->GetAssociativeMap()) { - if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - valueParameterName = typeValueMap.first; - // Message is the only known string parameter - if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); - } - } - } - - behaviorId = GetBehaviorIDFromArgument(arguments); - Game::logger->LogDebug("AddActionMessage", "acnNdx %i stpId %i sttId %i t %s vpn %s vps %s vpd %f bhId %i", actionIndex, stripId, stateId, type.c_str(), valueParameterName.c_str(), valueParameterString.c_str(), valueParameterDouble, behaviorId); + Game::logger->LogDebug("AddActionMessage", "actionIndex %i stripId %i stateId %i type %s valueParameterName %s valueParameterString %s valueParameterDouble %f behaviorId %i", actionIndex, actionContext.GetStripId(), actionContext.GetStateId(), action.GetType().c_str(), action.GetValueParameterName().c_str(), action.GetValueParameterString().c_str(), action.GetValueParameterDouble(), behaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h index 1f1577ec..4faf6a53 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h @@ -1,30 +1,26 @@ #ifndef __ADDACTIONMESSAGE__H__ #define __ADDACTIONMESSAGE__H__ +#include "Action.h" +#include "ActionContext.h" #include "BehaviorMessageBase.h" class AMFArrayValue; +/** + * @brief Send if a player takes an Action A from the toolbox and adds it to an already existing strip + * + */ class AddActionMessage : public BehaviorMessageBase { public: AddActionMessage(AMFArrayValue* arguments); const uint32_t GetActionIndex() { return actionIndex; }; - const StripId GetStripId() { return stripId; }; - const BehaviorState GetStateId() { return stateId; }; - const std::string& GetType() { return type; }; - const std::string& GetValueParameterName() { return valueParameterName; }; - const std::string& GetValueParameterString() { return valueParameterString; }; - const double GetValueParameterDouble() { return valueParameterDouble; }; - const uint32_t GetBehaviorId() { return behaviorId; }; + Action GetAction() { return action; }; + ActionContext GetActionContext() { return actionContext; }; private: uint32_t actionIndex; - StripId stripId; - BehaviorState stateId; - std::string type; - std::string valueParameterName; - std::string valueParameterString; - double valueParameterDouble; - uint32_t behaviorId; + ActionContext actionContext; + Action action; }; #endif //!__ADDACTIONMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp index ecddb8e3..4f2123b4 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp @@ -1,13 +1,11 @@ #include "AddMessage.h" -AddMessage::AddMessage(AMFArrayValue* arguments) { - behaviorId = GetBehaviorIDFromArgument(arguments); - +AddMessage::AddMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { behaviorIndex = 0; auto* behaviorIndexValue = arguments->FindValue<AMFDoubleValue>("BehaviorIndex"); if (!behaviorIndexValue) return; behaviorIndex = static_cast<uint32_t>(behaviorIndexValue->GetDoubleValue()); - Game::logger->LogDebug("AddMessage", "bhId %i ndx %i", behaviorId, behaviorIndex); + Game::logger->LogDebug("AddMessage", "behaviorId %i index %i", behaviorId, behaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h index ff8e0c8b..a46d5f98 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h @@ -3,13 +3,15 @@ #include "BehaviorMessageBase.h" +/** + * @brief Sent when a player adds a Behavior A from their inventory to a model. + * + */ class AddMessage : public BehaviorMessageBase { public: AddMessage(AMFArrayValue* arguments); const uint32_t GetBehaviorIndex() { return behaviorIndex; }; - const uint32_t GetBehaviorId() { return behaviorId; }; private: - uint32_t behaviorId; uint32_t behaviorIndex; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp index 23662174..c4729c57 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp @@ -1,56 +1,25 @@ #include "AddStripMessage.h" -AddStripMessage::AddStripMessage(AMFArrayValue* arguments) { +#include "Action.h" + +AddStripMessage::AddStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + actionContext = ActionContext(arguments); + + position = StripUiPosition(arguments); + auto* strip = arguments->FindValue<AMFArrayValue>("strip"); if (!strip) return; auto* actions = strip->FindValue<AMFArrayValue>("actions"); if (!actions) return; - auto* uiArray = arguments->FindValue<AMFArrayValue>("ui"); - if (!uiArray) return; + for (uint32_t actionNumber = 0; actionNumber < actions->GetDenseValueSize(); actionNumber++) { + auto* actionValue = actions->GetValueAt<AMFArrayValue>(actionNumber); + if (!actionValue) continue; - auto* xPositionValue = uiArray->FindValue<AMFDoubleValue>("x"); - if (!xPositionValue) return; + actionsToAdd.push_back(Action(actionValue)); - xPosition = xPositionValue->GetDoubleValue(); - - auto* yPositionValue = uiArray->FindValue<AMFDoubleValue>("y"); - if (!yPositionValue) return; - - yPosition = yPositionValue->GetDoubleValue(); - - stripId = GetStripIDFromArgument(arguments); - - stateId = GetBehaviorStateFromArgument(arguments); - - behaviorId = GetBehaviorIDFromArgument(arguments); - - type = ""; - valueParameterName = ""; - valueParameterString = ""; - valueParameterDouble = 0.0; - for (uint32_t position = 0; position < actions->GetDenseValueSize(); position++) { - auto* actionAsArray = actions->GetValueAt<AMFArrayValue>(position); - if (!actionAsArray) continue; - - for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { - if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - - type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - valueParameterName = typeValueMap.first; - // Message is the only known string parameter - if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); - } - } - } - Game::logger->LogDebug("AddStripMessage", "x %f y %f stpId %i sttId %i bhId %i t %s vpn %s vps %s vpd %f", xPosition, yPosition, stripId, stateId, behaviorId, type.c_str(), valueParameterName.c_str(), valueParameterString.c_str(), valueParameterDouble); + Game::logger->LogDebug("AddStripMessage", "xPosition %f yPosition %f stripId %i stateId %i behaviorId %i t %s valueParameterName %s valueParameterString %s valueParameterDouble %f", position.GetX(), position.GetY(), actionContext.GetStripId(), actionContext.GetStateId(), behaviorId, actionsToAdd.back().GetType().c_str(), actionsToAdd.back().GetValueParameterName().c_str(), actionsToAdd.back().GetValueParameterString().c_str(), actionsToAdd.back().GetValueParameterDouble()); } + Game::logger->Log("AddStripMessage", "number of actions %i", actionsToAdd.size()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h index bb720bae..db75aef7 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h @@ -1,32 +1,31 @@ #ifndef __ADDSTRIPMESSAGE__H__ #define __ADDSTRIPMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" +#include "StripUiPosition.h" +#include <vector> + +class Action; class AMFArrayValue; +/** + * @brief Sent in 2 contexts: + * A player adds an Action A from their toolbox without attaching it to an existing Strip. In this case, only 1 action is sent. + * A player moves a Strip from BehaviorState A directly to BehaviorState B. In this case, a list of actions are sent. + * + */ class AddStripMessage : public BehaviorMessageBase { public: AddStripMessage(AMFArrayValue* arguments); - const StripId GetStripId() { return stripId; }; - const BehaviorState GetStateId() { return stateId; }; - const std::string& GetType() { return type; }; - const std::string& GetValueParameterName() { return valueParameterName; }; - const std::string& GetValueParameterString() { return valueParameterString; }; - const double GetXPosition() { return xPosition; }; - const double GetYPosition() { return yPosition; }; - const double GetValueParameterDouble() { return valueParameterDouble; }; - const uint32_t GetBehaviorId() { return behaviorId; }; + StripUiPosition GetPosition() { return position; }; + ActionContext GetActionContext() { return actionContext; }; + std::vector<Action> GetActionsToAdd() { return actionsToAdd; }; private: - double xPosition; - double yPosition; - StripId stripId; - BehaviorState stateId; - uint32_t behaviorId; - std::string type; - std::string valueParameterName; - std::string valueParameterString; - double valueParameterDouble; + StripUiPosition position; + ActionContext actionContext; + std::vector<Action> actionsToAdd; }; #endif //!__ADDSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp new file mode 100644 index 00000000..b3d98d51 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp @@ -0,0 +1,33 @@ +#include "BehaviorMessageBase.h" + +#include "AMFFormat.h" +#include "BehaviorStates.h" +#include "dCommonVars.h" + +BehaviorMessageBase::BehaviorMessageBase(AMFArrayValue* arguments) { + behaviorId = 0; + behaviorId = GetBehaviorIdFromArgument(arguments); +} + +int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) { + const auto* key = "BehaviorID"; + auto* behaviorIDValue = arguments->FindValue<AMFStringValue>(key); + int32_t behaviorID = -1; + + if (behaviorIDValue) { + behaviorID = std::stoul(behaviorIDValue->GetStringValue()); + } else if (!arguments->FindValue<AMFUndefinedValue>(key)) { + throw std::invalid_argument("Unable to find behavior ID"); + } + + return behaviorID; +} + +uint32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName) { + auto* actionIndexAmf = arguments->FindValue<AMFDoubleValue>(keyName); + if (!actionIndexAmf) { + throw std::invalid_argument("Unable to find actionIndex"); + } + + return static_cast<uint32_t>(actionIndexAmf->GetDoubleValue()); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h index 78025672..13b00a35 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -5,44 +5,25 @@ #include <string> #include "AMFFormat.h" -#include "BehaviorStates.h" #include "dCommonVars.h" #include "Game.h" #include "dLogger.h" +enum class BehaviorState : uint32_t; + +/** + * @brief The behaviorID target of this ControlBehaviors message + * + */ class BehaviorMessageBase { public: - uint32_t GetBehaviorIDFromArgument(AMFArrayValue* arguments, const std::string& key = "BehaviorID") { - auto* behaviorIDValue = arguments->FindValue<AMFStringValue>(key); - uint32_t behaviorID = -1; - - if (behaviorIDValue) { - behaviorID = std::stoul(behaviorIDValue->GetStringValue()); - } else if (arguments->FindValue<AMFUndefinedValue>(key) == nullptr) { - throw std::invalid_argument("Unable to find behavior ID from argument \"" + key + "\""); - } - - return behaviorID; - } - - BehaviorState GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key = "stateID") { - auto* stateIDValue = arguments->FindValue<AMFDoubleValue>(key); - if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); - - BehaviorState stateID = static_cast<BehaviorState>(stateIDValue->GetDoubleValue()); - - return stateID; - } - - StripId GetStripIDFromArgument(AMFArrayValue* arguments, const std::string& key = "stripID") { - auto* stripIDValue = arguments->FindValue<AMFDoubleValue>(key); - if (!stripIDValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); - - StripId stripID = static_cast<StripId>(stripIDValue->GetDoubleValue()); - - return stripID; - } + const uint32_t GetBehaviorId() { return behaviorId; }; +protected: + BehaviorMessageBase(AMFArrayValue* arguments); + int32_t GetBehaviorIdFromArgument(AMFArrayValue* arguments); + uint32_t GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName = "actionIndex"); + int32_t behaviorId = -1; }; #endif //!__BEHAVIORMESSAGEBASE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt b/dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt index 8390cd22..49b0f460 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/CMakeLists.txt @@ -1,7 +1,10 @@ set(DGAME_DPROPERTYBEHAVIORS_CONTROLBEHAVIORMESSAGES + "Action.cpp" + "ActionContext.cpp" "AddActionMessage.cpp" "AddMessage.cpp" "AddStripMessage.cpp" + "BehaviorMessageBase.cpp" "MergeStripsMessage.cpp" "MigrateActionsMessage.cpp" "MoveToInventoryMessage.cpp" @@ -10,6 +13,7 @@ set(DGAME_DPROPERTYBEHAVIORS_CONTROLBEHAVIORMESSAGES "RemoveStripMessage.cpp" "RenameMessage.cpp" "SplitStripMessage.cpp" + "StripUiPosition.cpp" "UpdateActionMessage.cpp" "UpdateStripUiMessage.cpp" PARENT_SCOPE diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp index d810e861..df50641a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp @@ -1,20 +1,11 @@ #include "MergeStripsMessage.h" -MergeStripsMessage::MergeStripsMessage(AMFArrayValue* arguments) { - srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); +MergeStripsMessage::MergeStripsMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + sourceActionContext = ActionContext(arguments, "srcStateID", "srcStripID"); - dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); + destinationActionContext = ActionContext(arguments, "dstStateID", "dstStripID"); + dstActionIndex = GetActionIndexFromArgument(arguments, "dstActionIndex"); - srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); - - auto* dstActionIndexValue = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); - if (!dstActionIndexValue) return; - - dstActionIndex = static_cast<uint32_t>(dstActionIndexValue->GetDoubleValue()); - - dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); - - behaviorID = GetBehaviorIDFromArgument(arguments); - Game::logger->LogDebug("MergeStripsMessage", "srcStpId %i dstStpId %i srcSttId %i dstSttId %i dstAcnNdx %i bhId %i", srcStripID, dstStripID, srcStateID, dstStateID, dstActionIndex, behaviorID); + Game::logger->LogDebug("MergeStripsMessage", "srcstripId %i dststripId %i srcstateId %i dststateId %i dstactionIndex %i behaviorId %i", sourceActionContext.GetStripId(), destinationActionContext.GetStripId(), sourceActionContext.GetStateId(), destinationActionContext.GetStateId(), dstActionIndex, behaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h index af3aa16f..0aff7f3a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h @@ -1,26 +1,25 @@ #ifndef __MERGESTRIPSMESSAGE__H__ #define __MERGESTRIPSMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" class AMFArrayValue; +/** + * @brief Sent when a player adds the first Action of Strip A to a Strip B + * + */ class MergeStripsMessage : public BehaviorMessageBase { public: MergeStripsMessage(AMFArrayValue* arguments); - const StripId GetSrcStripID() { return srcStripID; }; - const BehaviorState GetDstStateID() { return dstStateID; }; - const BehaviorState GetSrcStateID() { return srcStateID; }; const uint32_t GetDstActionIndex() { return dstActionIndex; }; - const StripId GetDstStripID() { return dstStripID; }; - const uint32_t GetBehaviorID() { return behaviorID; }; + ActionContext GetSourceActionContext() { return sourceActionContext; }; + ActionContext GetDestinationActionContext() { return destinationActionContext; }; private: - StripId srcStripID; - BehaviorState dstStateID; - BehaviorState srcStateID; + ActionContext sourceActionContext; + ActionContext destinationActionContext; uint32_t dstActionIndex; - StripId dstStripID; - uint32_t behaviorID; }; #endif //!__MERGESTRIPSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp index 8bb4e819..08f830a4 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp @@ -1,24 +1,11 @@ #include "MigrateActionsMessage.h" -MigrateActionsMessage::MigrateActionsMessage(AMFArrayValue* arguments) { - auto* srcActionIndexAmf = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); - if (!srcActionIndexAmf) return; +MigrateActionsMessage::MigrateActionsMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + sourceActionContext = ActionContext(arguments, "srcStateID", "srcStripID"); + srcActionIndex = GetActionIndexFromArgument(arguments, "srcActionIndex"); - srcActionIndex = static_cast<uint32_t>(srcActionIndexAmf->GetDoubleValue()); + destinationActionContext = ActionContext(arguments, "dstStateID", "dstStripID"); + dstActionIndex = GetActionIndexFromArgument(arguments, "dstActionIndex"); - srcStripID = GetStripIDFromArgument(arguments, "srcStripID"); - - srcStateID = GetBehaviorStateFromArgument(arguments, "srcStateID"); - - auto* dstActionIndexAmf = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); - if (!dstActionIndexAmf) return; - - dstActionIndex = static_cast<uint32_t>(dstActionIndexAmf->GetDoubleValue()); - - dstStripID = GetStripIDFromArgument(arguments, "dstStripID"); - - dstStateID = GetBehaviorStateFromArgument(arguments, "dstStateID"); - - behaviorID = GetBehaviorIDFromArgument(arguments); - Game::logger->LogDebug("MigrateActionsMessage", "srcAcnNdx %i dstAcnNdx %i srcStpId %i dstStpId %i srcSttId %i dstSttId %i bhid %i", srcActionIndex, dstActionIndex, srcStripID, dstStripID, srcStateID, dstStateID, behaviorID); + Game::logger->LogDebug("MigrateActionsMessage", "srcactionIndex %i dstactionIndex %i srcstripId %i dststripId %i srcstateId %i dststateId %i behaviorId %i", srcActionIndex, dstActionIndex, sourceActionContext.GetStripId(), destinationActionContext.GetStripId(), sourceActionContext.GetStateId(), destinationActionContext.GetStateId(), behaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h index 26018d69..f60e8748 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -1,28 +1,27 @@ #ifndef __MIGRATEACTIONSMESSAGE__H__ #define __MIGRATEACTIONSMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" class AMFArrayValue; +/** + * @brief Sent when a player moves an Action after the first Action to a different Strip + * + */ class MigrateActionsMessage : public BehaviorMessageBase { public: MigrateActionsMessage(AMFArrayValue* arguments); const uint32_t GetSrcActionIndex() { return srcActionIndex; }; - const StripId GetSrcStripID() { return srcStripID; }; - const BehaviorState GetSrcStateID() { return srcStateID; }; const uint32_t GetDstActionIndex() { return dstActionIndex; }; - const StripId GetDstStripID() { return dstStripID; }; - const BehaviorState GetDstStateID() { return dstStateID; }; - const uint32_t GetBehaviorID() { return behaviorID; }; + ActionContext GetSourceActionContext() { return sourceActionContext; }; + ActionContext GetDestinationActionContext() { return destinationActionContext; }; private: + ActionContext sourceActionContext; + ActionContext destinationActionContext; uint32_t srcActionIndex; - StripId srcStripID; - BehaviorState srcStateID; uint32_t dstActionIndex; - StripId dstStripID; - BehaviorState dstStateID; - uint32_t behaviorID; }; #endif //!__MIGRATEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp index 7ad7a875..92700076 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp @@ -1,11 +1,9 @@ #include "MoveToInventoryMessage.h" -MoveToInventoryMessage::MoveToInventoryMessage(AMFArrayValue* arguments) { - behaviorID = GetBehaviorIDFromArgument(arguments); - +MoveToInventoryMessage::MoveToInventoryMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { auto* behaviorIndexValue = arguments->FindValue<AMFDoubleValue>("BehaviorIndex"); if (!behaviorIndexValue) return; behaviorIndex = static_cast<uint32_t>(behaviorIndexValue->GetDoubleValue()); - Game::logger->LogDebug("MoveToInventoryMessage", "bhId %i bhNdx %i", behaviorID, behaviorIndex); + Game::logger->LogDebug("MoveToInventoryMessage", "behaviorId %i behaviorIndex %i", behaviorId, behaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h index 2cf71f3c..c48f7d17 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h @@ -5,14 +5,16 @@ class AMFArrayValue; +/** + * @brief Sent when a player moves a Behavior A at position B to their inventory. + * + */ #pragma warning("This Control Behavior Message does not have a test yet. Non-developers can ignore this warning.") -class MoveToInventoryMessage: public BehaviorMessageBase { +class MoveToInventoryMessage : public BehaviorMessageBase { public: MoveToInventoryMessage(AMFArrayValue* arguments); - const uint32_t GetBehaviorID() { return behaviorID; }; const uint32_t GetBehaviorIndex() { return behaviorIndex; }; private: - uint32_t behaviorID; uint32_t behaviorIndex; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp index 0347aca6..4018a423 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp @@ -1,16 +1,10 @@ #include "RearrangeStripMessage.h" -RearrangeStripMessage::RearrangeStripMessage(AMFArrayValue* arguments) { - auto* srcActionIndexValue = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); - srcActionIndex = static_cast<uint32_t>(srcActionIndexValue->GetDoubleValue()); +RearrangeStripMessage::RearrangeStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + actionContext = ActionContext(arguments); + srcActionIndex = GetActionIndexFromArgument(arguments, "srcActionIndex"); - stripID = GetStripIDFromArgument(arguments); + dstActionIndex = GetActionIndexFromArgument(arguments, "dstActionIndex"); - behaviorID = GetBehaviorIDFromArgument(arguments); - - auto* dstActionIndexValue = arguments->FindValue<AMFDoubleValue>("dstActionIndex"); - dstActionIndex = static_cast<uint32_t>(dstActionIndexValue->GetDoubleValue()); - - stateID = GetBehaviorStateFromArgument(arguments); - Game::logger->LogDebug("RearrangeStripMessage", "srcAcnNdx %i dstAcnNdx %i stpId %i bhId %i sttId %i", srcActionIndex, dstActionIndex, stripID, behaviorID, stateID); + Game::logger->LogDebug("RearrangeStripMessage", "srcactionIndex %i dstactionIndex %i stripId %i behaviorId %i stateId %i", srcActionIndex, dstActionIndex, actionContext.GetStripId(), behaviorId, actionContext.GetStateId()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h index 4cca0827..46819404 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h @@ -1,22 +1,23 @@ #ifndef __REARRANGESTRIPMESSAGE__H__ #define __REARRANGESTRIPMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" +/** + * @brief Sent when a player moves an Action around in the same strip + * + */ class RearrangeStripMessage : public BehaviorMessageBase { public: RearrangeStripMessage(AMFArrayValue* arguments); const uint32_t GetSrcActionIndex() { return srcActionIndex; }; - const uint32_t GetStripID() { return stripID; }; - const uint32_t GetBehaviorID() { return behaviorID; }; const uint32_t GetDstActionIndex() { return dstActionIndex; }; - const BehaviorState GetStateID() { return stateID; }; + ActionContext GetActionContext() { return actionContext; }; private: + ActionContext actionContext; uint32_t srcActionIndex; - uint32_t stripID; - uint32_t behaviorID; uint32_t dstActionIndex; - BehaviorState stateID; }; #endif //!__REARRANGESTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp index cb1226e3..8f00d2b0 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp @@ -1,15 +1,8 @@ #include "RemoveActionsMessage.h" -RemoveActionsMessage::RemoveActionsMessage(AMFArrayValue* arguments) { - behaviorID = GetBehaviorIDFromArgument(arguments); +RemoveActionsMessage::RemoveActionsMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + actionContext = ActionContext(arguments); + actionIndex = GetActionIndexFromArgument(arguments); - auto* actionIndexAmf = arguments->FindValue<AMFDoubleValue>("actionIndex"); - if (!actionIndexAmf) return; - - actionIndex = static_cast<uint32_t>(actionIndexAmf->GetDoubleValue()); - - stripID = GetStripIDFromArgument(arguments); - - stateID = GetBehaviorStateFromArgument(arguments); - Game::logger->LogDebug("RemoveActionsMessage", "bhId %i acnNdx %i stpId %i sttId %i", behaviorID, actionIndex, stripID, stateID); + Game::logger->LogDebug("RemoveActionsMessage", "behaviorId %i actionIndex %i stripId %i stateId %i", behaviorId, actionIndex, actionContext.GetStripId(), actionContext.GetStateId()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h index 33678f59..457ddba8 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h @@ -1,22 +1,23 @@ #ifndef __REMOVEACTIONSMESSAGE__H__ #define __REMOVEACTIONSMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" class AMFArrayValue; +/** + * @brief Sent when a player removes any Action after the first one from a Strip + * + */ class RemoveActionsMessage : public BehaviorMessageBase { public: RemoveActionsMessage(AMFArrayValue* arguments); - const uint32_t GetBehaviorID() { return behaviorID; }; const uint32_t GetActionIndex() { return actionIndex; }; - const StripId GetStripID() { return stripID; }; - const BehaviorState GetStateID() { return stateID; }; + ActionContext GetActionContext() { return actionContext; }; private: - uint32_t behaviorID; + ActionContext actionContext; uint32_t actionIndex; - StripId stripID; - BehaviorState stateID; }; #endif //!__REMOVEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp index 3c48ed16..40288b07 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp @@ -1,8 +1,7 @@ #include "RemoveStripMessage.h" -RemoveStripMessage::RemoveStripMessage(AMFArrayValue* arguments) { - stripId = GetStripIDFromArgument(arguments); - behaviorState = GetBehaviorStateFromArgument(arguments); - behaviorId = GetBehaviorIDFromArgument(arguments); - Game::logger->LogDebug("RemoveStripMessage", "stpId %i bhStt %i bhId %i", stripId, behaviorState, behaviorId); +RemoveStripMessage::RemoveStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + actionContext = ActionContext(arguments); + + Game::logger->LogDebug("RemoveStripMessage", "stripId %i stateId %i behaviorId %i", actionContext.GetStripId(), actionContext.GetStateId(), behaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h index 312bab31..36e2e401 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h @@ -1,18 +1,19 @@ #ifndef __REMOVESTRIPMESSAGE__H__ #define __REMOVESTRIPMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" +/** + * @brief Sent when a player removes the first Action from a strip. + * + */ class RemoveStripMessage : public BehaviorMessageBase { public: RemoveStripMessage(AMFArrayValue* arguments); - const StripId GetStripId() { return stripId; }; - const BehaviorState GetBehaviorState() { return behaviorState; }; - const uint32_t GetBehaviorId() { return behaviorId; }; + ActionContext GetActionContext() { return actionContext; }; private: - StripId stripId; - BehaviorState behaviorState; - uint32_t behaviorId; + ActionContext actionContext; }; #endif //!__REMOVESTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp index 38c49462..0ea3b6d6 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp @@ -1,11 +1,9 @@ #include "RenameMessage.h" -RenameMessage::RenameMessage(AMFArrayValue* arguments) { - behaviorID = GetBehaviorIDFromArgument(arguments); - +RenameMessage::RenameMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { auto* nameAmf = arguments->FindValue<AMFStringValue>("Name"); if (!nameAmf) return; name = nameAmf->GetStringValue(); - Game::logger->LogDebug("RenameMessage", "bhId %i n %s", behaviorID, name.c_str()); + Game::logger->LogDebug("RenameMessage", "behaviorId %i n %s", behaviorId, name.c_str()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h index be42d66f..ba181f63 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h @@ -5,13 +5,15 @@ class AMFArrayValue; +/** + * @brief Sent when a player renames this behavior + * + */ class RenameMessage : public BehaviorMessageBase { public: RenameMessage(AMFArrayValue* arguments); - const uint32_t GetBehaviorID() { return behaviorID; }; const std::string& GetName() { return name; }; private: - uint32_t behaviorID; std::string name; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp index d3493aeb..b4601a17 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp @@ -1,29 +1,11 @@ #include "SplitStripMessage.h" -SplitStripMessage::SplitStripMessage(AMFArrayValue* arguments) { - auto* srcActionIndexValue = arguments->FindValue<AMFDoubleValue>("srcActionIndex"); - if (!srcActionIndexValue) return; +SplitStripMessage::SplitStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + sourceActionContext = ActionContext(arguments, "srcStateID", "srcStripID"); + srcActionIndex = GetActionIndexFromArgument(arguments, "srcActionIndex"); - srcActionIndex = static_cast<uint32_t>(srcActionIndexValue->GetDoubleValue()); + destinationActionContext = ActionContext(arguments, "dstStateID", "dstStripID"); + destinationPosition = StripUiPosition(arguments, "dstStripUI"); - srcStripId = GetStripIDFromArgument(arguments, "srcStripID"); - - srcStateId = GetBehaviorStateFromArgument(arguments, "srcStateID"); - - dstStripId = GetStripIDFromArgument(arguments, "dstStripID"); - - dstStateId = GetBehaviorStateFromArgument(arguments, "dstStateID"); - - auto* dstStripUiArray = arguments->FindValue<AMFArrayValue>("dstStripUI"); - if (!dstStripUiArray) return; - - auto* xPositionValue = dstStripUiArray->FindValue<AMFDoubleValue>("x"); - auto* yPositionValue = dstStripUiArray->FindValue<AMFDoubleValue>("y"); - if (!xPositionValue || !yPositionValue) return; - - yPosition = yPositionValue->GetDoubleValue(); - xPosition = xPositionValue->GetDoubleValue(); - - behaviorId = GetBehaviorIDFromArgument(arguments); - Game::logger->LogDebug("SplitStripMessage", "bhid %i x %f y %f srcStp %i dstStp %i srcStt %i dstStt %i srcActNdx %i", behaviorId, xPosition, yPosition, srcStripId, dstStripId, srcStateId, dstStateId, srcActionIndex); + Game::logger->LogDebug("SplitStripMessage", "behaviorId %i xPosition %f yPosition %f sourceStrip %i destinationStrip %i sourceState %i destinationState %i srcActindex %i", behaviorId, destinationPosition.GetX(), destinationPosition.GetY(), sourceActionContext.GetStripId(), destinationActionContext.GetStripId(), sourceActionContext.GetStateId(), destinationActionContext.GetStateId(), srcActionIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h index e06a9dc4..9210efb0 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h @@ -1,30 +1,28 @@ #ifndef __SPLITSTRIPMESSAGE__H__ #define __SPLITSTRIPMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" +#include "StripUiPosition.h" class AMFArrayValue; +/** + * @brief Sent when a player takes an Action from Strip A and does not add it to an existing strip + * + */ class SplitStripMessage : public BehaviorMessageBase { public: SplitStripMessage(AMFArrayValue* arguments); + ActionContext GetSourceActionContext() { return sourceActionContext; }; + ActionContext GetDestinationActionContext() { return destinationActionContext; }; const uint32_t GetSrcActionIndex() { return srcActionIndex; }; - const StripId GetSrcStripId() { return srcStripId; }; - const BehaviorState GetSrcStateId() { return srcStateId; }; - const StripId GetDstStripId() { return dstStripId; }; - const BehaviorState GetDstStateId() { return dstStateId; }; - const double GetYPosition() { return yPosition; }; - const double GetXPosition() { return xPosition; }; - const uint32_t GetBehaviorId() { return behaviorId; }; + StripUiPosition GetPosition() { return destinationPosition; }; private: + ActionContext sourceActionContext; + ActionContext destinationActionContext; uint32_t srcActionIndex; - StripId srcStripId; - BehaviorState srcStateId; - StripId dstStripId; - BehaviorState dstStateId; - double yPosition; - double xPosition; - uint32_t behaviorId; + StripUiPosition destinationPosition; }; #endif //!__SPLITSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp new file mode 100644 index 00000000..4ddccc55 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp @@ -0,0 +1,22 @@ +#include "StripUiPosition.h" + +#include "AMFFormat.h" + +StripUiPosition::StripUiPosition() { + xPosition = 0.0; + yPosition = 0.0; +} + +StripUiPosition::StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName) { + xPosition = 0.0; + yPosition = 0.0; + auto* uiArray = arguments->FindValue<AMFArrayValue>(uiKeyName); + if (!uiArray) return; + + auto* xPositionValue = uiArray->FindValue<AMFDoubleValue>("x"); + auto* yPositionValue = uiArray->FindValue<AMFDoubleValue>("y"); + if (!xPositionValue || !yPositionValue) return; + + yPosition = yPositionValue->GetDoubleValue(); + xPosition = xPositionValue->GetDoubleValue(); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h new file mode 100644 index 00000000..809f8890 --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h @@ -0,0 +1,21 @@ +#ifndef __STRIPUIPOSITION__H__ +#define __STRIPUIPOSITION__H__ + +class AMFArrayValue; + +/** + * @brief The position of the first Action in a Strip + * + */ +class StripUiPosition { +public: + StripUiPosition(); + StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName = "ui"); + double GetX() { return xPosition; }; + double GetY() { return yPosition; }; +private: + double xPosition; + double yPosition; +}; + +#endif //!__STRIPUIPOSITION__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp index 1d4cc868..53e2d570 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp @@ -1,38 +1,15 @@ #include "UpdateActionMessage.h" -UpdateActionMessage::UpdateActionMessage(AMFArrayValue* arguments) { - type = ""; - valueParameterName = ""; - valueParameterString = ""; - valueParameterDouble = 0.0; - auto* actionAsArray = arguments->FindValue<AMFArrayValue>("action"); - if (!actionAsArray) return; - for (auto& typeValueMap : actionAsArray->GetAssociativeMap()) { - if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - type = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - valueParameterName = typeValueMap.first; - // Message is the only known string parameter - if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast<AMFStringValue*>(typeValueMap.second)->GetStringValue(); - } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast<AMFDoubleValue*>(typeValueMap.second)->GetDoubleValue(); - } - } - } +#include "Action.h" - behaviorID = GetBehaviorIDFromArgument(arguments); +UpdateActionMessage::UpdateActionMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + actionContext = ActionContext(arguments); - auto* actionIndexValue = arguments->FindValue<AMFDoubleValue>("actionIndex"); - if (!actionIndexValue) return; + auto* actionValue = arguments->FindValue<AMFArrayValue>("action"); + if (!actionValue) return; - actionIndex = static_cast<uint32_t>(actionIndexValue->GetDoubleValue()); + action = Action(actionValue); + actionIndex = GetActionIndexFromArgument(arguments); - stripID = GetStripIDFromArgument(arguments); - - stateID = GetBehaviorStateFromArgument(arguments); - Game::logger->LogDebug("UpdateActionMessage", "t %s vpn %s vps %s vpd %f bhId %i acnNdx %i stpId %i sttId %i", type.c_str(), valueParameterName.c_str(), valueParameterString.c_str(), valueParameterDouble, behaviorID, actionIndex, stripID, stateID); + Game::logger->LogDebug("UpdateActionMessage", "type %s valueParameterName %s valueParameterString %s valueParameterDouble %f behaviorId %i actionIndex %i stripId %i stateId %i", action.GetType().c_str(), action.GetValueParameterName().c_str(), action.GetValueParameterString().c_str(), action.GetValueParameterDouble(), behaviorId, actionIndex, actionContext.GetStripId(), actionContext.GetStateId()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h index a42be22b..0a03ce9e 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h @@ -1,30 +1,26 @@ #ifndef __UPDATEACTIONMESSAGE__H__ #define __UPDATEACTIONMESSAGE__H__ +#include "Action.h" +#include "ActionContext.h" #include "BehaviorMessageBase.h" class AMFArrayValue; +/** + * @brief Sent when a player updates the value in an Action + * + */ class UpdateActionMessage : public BehaviorMessageBase { public: UpdateActionMessage(AMFArrayValue* arguments); - const std::string& GetType() { return type; }; - const std::string& GetValueParameterName() { return valueParameterName; }; - const std::string& GetValueParameterString() { return valueParameterString; }; - const double GetValueParameterDouble() { return valueParameterDouble; }; - const uint32_t GetBehaviorID() { return behaviorID; }; const uint32_t GetActionIndex() { return actionIndex; }; - const StripId GetStripID() { return stripID; }; - const BehaviorState GetStateID() { return stateID; }; + ActionContext GetActionContext() { return actionContext; }; + Action GetAction() { return action; }; private: - std::string type; - std::string valueParameterName; - std::string valueParameterString; - double valueParameterDouble; - uint32_t behaviorID; uint32_t actionIndex; - StripId stripID; - BehaviorState stateID; -}; + ActionContext actionContext; + Action action; +}; #endif //!__UPDATEACTIONMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp index 60e2f0f3..073db9b4 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp @@ -1,20 +1,8 @@ #include "UpdateStripUiMessage.h" -UpdateStripUiMessage::UpdateStripUiMessage(AMFArrayValue* arguments) { - auto* uiArray = arguments->FindValue<AMFArrayValue>("ui"); - if (!uiArray) return; +UpdateStripUiMessage::UpdateStripUiMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { + position = StripUiPosition(arguments); + actionContext = ActionContext(arguments); - auto* xPositionValue = uiArray->FindValue<AMFDoubleValue>("x"); - auto* yPositionValue = uiArray->FindValue<AMFDoubleValue>("y"); - if (!xPositionValue || !yPositionValue) return; - - yPosition = yPositionValue->GetDoubleValue(); - xPosition = xPositionValue->GetDoubleValue(); - - stripID = GetStripIDFromArgument(arguments); - - stateID = GetBehaviorStateFromArgument(arguments); - - behaviorID = GetBehaviorIDFromArgument(arguments); - Game::logger->LogDebug("UpdateStripUIMessage", "x %f y %f stpId %i sttId %i bhId %i", xPosition, yPosition, stripID, stateID, behaviorID); + Game::logger->LogDebug("UpdateStripUIMessage", "xPosition %f yPosition %f stripId %i stateId %i behaviorId %i", position.GetX(), position.GetY(), actionContext.GetStripId(), actionContext.GetStateId(), behaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h index ca626120..6d96f90c 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h @@ -1,24 +1,24 @@ #ifndef __UPDATESTRIPUIMESSAGE__H__ #define __UPDATESTRIPUIMESSAGE__H__ +#include "ActionContext.h" #include "BehaviorMessageBase.h" +#include "StripUiPosition.h" class AMFArrayValue; +/** + * @brief Sent when a player moves the first Action in a Strip + * + */ class UpdateStripUiMessage : public BehaviorMessageBase { public: UpdateStripUiMessage(AMFArrayValue* arguments); - const double GetYPosition() { return yPosition; }; - const double GetXPosition() { return xPosition; }; - const StripId GetStripID() { return stripID; }; - const BehaviorState GetStateID() { return stateID; }; - const uint32_t GetBehaviorID() { return behaviorID; }; + StripUiPosition GetPosition() { return position; }; + ActionContext GetActionContext() { return actionContext; }; private: - double yPosition; - double xPosition; - StripId stripID; - BehaviorState stateID; - uint32_t behaviorID; + StripUiPosition position; + ActionContext actionContext; }; #endif //!__UPDATESTRIPUIMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 3e8bbacc..dfb22b59 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -15,6 +15,7 @@ #include "CDClientDatabase.h" // Message includes +#include "Action.h" #include "AddActionMessage.h" #include "AddStripMessage.h" #include "AddMessage.h" @@ -248,18 +249,23 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { UpdateActionMessage updateActionMessage(arguments); - auto* blockDefinition = GetBlockInfo(updateActionMessage.GetType()); + auto* blockDefinition = GetBlockInfo(updateActionMessage.GetAction().GetType()); - if (updateActionMessage.GetValueParameterString().size() > 0) { - if (updateActionMessage.GetValueParameterString().size() < blockDefinition->GetMinimumValue() || - updateActionMessage.GetValueParameterString().size() > blockDefinition->GetMaximumValue()) { - Game::logger->Log("ControlBehaviors", "Updated block %s is out of range. Ignoring update", updateActionMessage.GetType().c_str()); + if (!blockDefinition) { + Game::logger->Log("ControlBehaviors", "Received undefined block type %s. Ignoring.", updateActionMessage.GetAction().GetType().c_str()); + return; + } + + if (updateActionMessage.GetAction().GetValueParameterString().size() > 0) { + if (updateActionMessage.GetAction().GetValueParameterString().size() < blockDefinition->GetMinimumValue() || + updateActionMessage.GetAction().GetValueParameterString().size() > blockDefinition->GetMaximumValue()) { + Game::logger->Log("ControlBehaviors", "Updated block %s is out of range. Ignoring update", updateActionMessage.GetAction().GetType().c_str()); return; } } else { - if (updateActionMessage.GetValueParameterDouble() < blockDefinition->GetMinimumValue() || - updateActionMessage.GetValueParameterDouble() > blockDefinition->GetMaximumValue()) { - Game::logger->Log("ControlBehaviors", "Updated block %s is out of range. Ignoring update", updateActionMessage.GetType().c_str()); + if (updateActionMessage.GetAction().GetValueParameterDouble() < blockDefinition->GetMinimumValue() || + updateActionMessage.GetAction().GetValueParameterDouble() > blockDefinition->GetMaximumValue()) { + Game::logger->Log("ControlBehaviors", "Updated block %s is out of range. Ignoring update", updateActionMessage.GetAction().GetType().c_str()); return; } } @@ -452,5 +458,5 @@ ControlBehaviors::ControlBehaviors() { BlockDefinition* ControlBehaviors::GetBlockInfo(const BlockName& blockName) { auto blockDefinition = blockTypes.find(blockName); - return blockDefinition != blockTypes.end() ? blockDefinition->second : &BlockDefinition::blockDefinitionDefault; + return blockDefinition != blockTypes.end() ? blockDefinition->second : nullptr; } diff --git a/tests/dCommonTests/AMFDeserializeTests.cpp b/tests/dCommonTests/AMFDeserializeTests.cpp index a823b0dc..3811a706 100644 --- a/tests/dCommonTests/AMFDeserializeTests.cpp +++ b/tests/dCommonTests/AMFDeserializeTests.cpp @@ -258,9 +258,9 @@ TEST(dCommonTests, AMFDeserializeLivePacketTest) { ASSERT_EQ(actionIndex->GetDoubleValue(), 0.0f); - auto stripIDExecution = stripsPosition0->FindValue<AMFDoubleValue>("id"); + auto stripIdExecution = stripsPosition0->FindValue<AMFDoubleValue>("id"); - ASSERT_EQ(stripIDExecution->GetDoubleValue(), 0.0f); + ASSERT_EQ(stripIdExecution->GetDoubleValue(), 0.0f); auto stateIDExecution = executionState->FindValue<AMFDoubleValue>("stateID"); @@ -298,9 +298,9 @@ TEST(dCommonTests, AMFDeserializeLivePacketTest) { ASSERT_EQ(xPos->GetDoubleValue(), 103.0f); ASSERT_EQ(yPos->GetDoubleValue(), 82.0f); - auto stripID = firstStrip->FindValue<AMFDoubleValue>("id"); + auto stripId = firstStrip->FindValue<AMFDoubleValue>("id"); - ASSERT_EQ(stripID->GetDoubleValue(), 0.0f); + ASSERT_EQ(stripId->GetDoubleValue(), 0.0f); auto firstAction = dynamic_cast<AMFArrayValue*>(actionsInFirstStrip[0]); diff --git a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp index 7905c19a..631f0d2d 100644 --- a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp +++ b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp @@ -1,7 +1,12 @@ +#include "Action.h" +#include "AMFFormat.h" +#include "AMFDeserialize.h" #include "GameMessages.h" #include "GameDependencies.h" -#include "AMFDeserialize.h" +#include <gtest/gtest.h> + +// Message includes #include "AddActionMessage.h" #include "AddStripMessage.h" #include "AddMessage.h" @@ -16,9 +21,6 @@ #include "UpdateActionMessage.h" #include "UpdateStripUiMessage.h" -#include <gtest/gtest.h> -#include <fstream> - class GameMessageTests: public GameDependenciesTest { protected: void SetUp() override { @@ -27,7 +29,6 @@ protected: void TearDown() override { TearDownDependencies(); } - std::string ReadFromFile(std::string filename) { std::ifstream file(filename, std::ios::binary); std::string readFile; @@ -35,10 +36,8 @@ protected: char readCharacter = file.get(); readFile.push_back(readCharacter); } - return readFile; } - AMFArrayValue* ReadArrayFromBitStream(RakNet::BitStream* inStream) { AMFDeserialize des; AMFValue* readArray = des.Read(inStream); @@ -90,23 +89,23 @@ TEST_F(GameMessageTests, ControlBehaviorAddStrip) { auto data = ReadFromFile("addStrip"); RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); AddStripMessage addStrip(ReadArrayFromBitStream(&inStream)); - ASSERT_FLOAT_EQ(addStrip.GetXPosition(), 50.65); - ASSERT_FLOAT_EQ(addStrip.GetYPosition(), 178.05); - ASSERT_EQ(addStrip.GetStripId(), 0); - ASSERT_EQ(static_cast<uint32_t>(addStrip.GetStateId()), 0); + ASSERT_FLOAT_EQ(addStrip.GetPosition().GetX(), 50.65); + ASSERT_FLOAT_EQ(addStrip.GetPosition().GetY(), 178.05); + ASSERT_EQ(addStrip.GetActionContext().GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(addStrip.GetActionContext().GetStateId()), 0); ASSERT_EQ(addStrip.GetBehaviorId(), -1); - ASSERT_EQ(addStrip.GetType(), "DropImagination"); - ASSERT_EQ(addStrip.GetValueParameterName(), "Amount"); - ASSERT_EQ(addStrip.GetValueParameterString(), ""); - ASSERT_FLOAT_EQ(addStrip.GetValueParameterDouble(), 1.0); + ASSERT_EQ(addStrip.GetActionsToAdd().front().GetType(), "DropImagination"); + ASSERT_EQ(addStrip.GetActionsToAdd().front().GetValueParameterName(), "Amount"); + ASSERT_EQ(addStrip.GetActionsToAdd().front().GetValueParameterString(), ""); + ASSERT_FLOAT_EQ(addStrip.GetActionsToAdd().front().GetValueParameterDouble(), 1.0); } TEST_F(GameMessageTests, ControlBehaviorRemoveStrip) { auto data = ReadFromFile("removeStrip"); RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); RemoveStripMessage removeStrip(ReadArrayFromBitStream(&inStream)); - ASSERT_EQ(static_cast<int32_t>(removeStrip.GetStripId()), 1); - ASSERT_EQ(static_cast<int32_t>(removeStrip.GetBehaviorState()), 0); + ASSERT_EQ(static_cast<int32_t>(removeStrip.GetActionContext().GetStripId()), 1); + ASSERT_EQ(static_cast<int32_t>(removeStrip.GetActionContext().GetStateId()), 0); ASSERT_EQ(removeStrip.GetBehaviorId(), -1); } @@ -114,12 +113,12 @@ TEST_F(GameMessageTests, ControlBehaviorMergeStrips) { auto data = ReadFromFile("mergeStrips"); RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); MergeStripsMessage mergeStrips(ReadArrayFromBitStream(&inStream)); - ASSERT_EQ(mergeStrips.GetSrcStripID(), 2); - ASSERT_EQ(mergeStrips.GetDstStripID(), 0); - ASSERT_EQ(static_cast<uint32_t>(mergeStrips.GetSrcStateID()), 0); - ASSERT_EQ(static_cast<uint32_t>(mergeStrips.GetDstStateID()), 0); + ASSERT_EQ(mergeStrips.GetSourceActionContext().GetStripId(), 2); + ASSERT_EQ(mergeStrips.GetDestinationActionContext().GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(mergeStrips.GetSourceActionContext().GetStateId()), 0); + ASSERT_EQ(static_cast<uint32_t>(mergeStrips.GetDestinationActionContext().GetStateId()), 0); ASSERT_EQ(mergeStrips.GetDstActionIndex(), 0); - ASSERT_EQ(mergeStrips.GetBehaviorID(), -1); + ASSERT_EQ(mergeStrips.GetBehaviorId(), -1); } TEST_F(GameMessageTests, ControlBehaviorSplitStrip) { @@ -128,12 +127,12 @@ TEST_F(GameMessageTests, ControlBehaviorSplitStrip) { SplitStripMessage splitStrip(ReadArrayFromBitStream(&inStream)); ASSERT_EQ(splitStrip.GetBehaviorId(), -1); - ASSERT_FLOAT_EQ(splitStrip.GetXPosition(), 275.65); - ASSERT_FLOAT_EQ(splitStrip.GetYPosition(), 28.7); - ASSERT_EQ(splitStrip.GetSrcStripId(), 0); - ASSERT_EQ(splitStrip.GetDstStripId(), 2); - ASSERT_EQ(static_cast<uint32_t>(splitStrip.GetSrcStateId()), 0); - ASSERT_EQ(static_cast<uint32_t>(splitStrip.GetDstStateId()), 0); + ASSERT_FLOAT_EQ(splitStrip.GetPosition().GetX(), 275.65); + ASSERT_FLOAT_EQ(splitStrip.GetPosition().GetY(), 28.7); + ASSERT_EQ(splitStrip.GetSourceActionContext().GetStripId(), 0); + ASSERT_EQ(splitStrip.GetDestinationActionContext().GetStripId(), 2); + ASSERT_EQ(static_cast<uint32_t>(splitStrip.GetSourceActionContext().GetStateId()), 0); + ASSERT_EQ(static_cast<uint32_t>(splitStrip.GetDestinationActionContext().GetStateId()), 0); ASSERT_EQ(splitStrip.GetSrcActionIndex(), 1); } @@ -141,11 +140,11 @@ TEST_F(GameMessageTests, ControlBehaviorUpdateStripUI) { auto data = ReadFromFile("updateStripUI"); RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); UpdateStripUiMessage updateStripUi(ReadArrayFromBitStream(&inStream)); - ASSERT_FLOAT_EQ(updateStripUi.GetXPosition(), 116.65); - ASSERT_FLOAT_EQ(updateStripUi.GetYPosition(), 35.35); - ASSERT_EQ(updateStripUi.GetStripID(), 0); - ASSERT_EQ(static_cast<uint32_t>(updateStripUi.GetStateID()), 0); - ASSERT_EQ(updateStripUi.GetBehaviorID(), -1); + ASSERT_FLOAT_EQ(updateStripUi.GetPosition().GetX(), 116.65); + ASSERT_FLOAT_EQ(updateStripUi.GetPosition().GetY(), 35.35); + ASSERT_EQ(updateStripUi.GetActionContext().GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(updateStripUi.GetActionContext().GetStateId()), 0); + ASSERT_EQ(updateStripUi.GetBehaviorId(), -1); } TEST_F(GameMessageTests, ControlBehaviorAddAction) { @@ -153,12 +152,12 @@ TEST_F(GameMessageTests, ControlBehaviorAddAction) { RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); AddActionMessage addAction(ReadArrayFromBitStream(&inStream)); ASSERT_EQ(addAction.GetActionIndex(), 3); - ASSERT_EQ(addAction.GetStripId(), 0); - ASSERT_EQ(static_cast<uint32_t>(addAction.GetStateId()), 0); - ASSERT_EQ(addAction.GetType(), "DoDamage"); - ASSERT_EQ(addAction.GetValueParameterName(), ""); - ASSERT_EQ(addAction.GetValueParameterString(), ""); - ASSERT_EQ(addAction.GetValueParameterDouble(), 0.0); + ASSERT_EQ(addAction.GetActionContext().GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(addAction.GetActionContext().GetStateId()), 0); + ASSERT_EQ(addAction.GetAction().GetType(), "DoDamage"); + ASSERT_EQ(addAction.GetAction().GetValueParameterName(), ""); + ASSERT_EQ(addAction.GetAction().GetValueParameterString(), ""); + ASSERT_EQ(addAction.GetAction().GetValueParameterDouble(), 0.0); ASSERT_EQ(addAction.GetBehaviorId(), -1); } @@ -168,11 +167,11 @@ TEST_F(GameMessageTests, ControlBehaviorMigrateActions) { MigrateActionsMessage migrateActions(ReadArrayFromBitStream(&inStream)); ASSERT_EQ(migrateActions.GetSrcActionIndex(), 1); ASSERT_EQ(migrateActions.GetDstActionIndex(), 2); - ASSERT_EQ(migrateActions.GetSrcStripID(), 1); - ASSERT_EQ(migrateActions.GetDstStripID(), 0); - ASSERT_EQ(static_cast<uint32_t>(migrateActions.GetSrcStateID()), 0); - ASSERT_EQ(static_cast<uint32_t>(migrateActions.GetDstStateID()), 0); - ASSERT_EQ(migrateActions.GetBehaviorID(), -1); + ASSERT_EQ(migrateActions.GetSourceActionContext().GetStripId(), 1); + ASSERT_EQ(migrateActions.GetDestinationActionContext().GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(migrateActions.GetSourceActionContext().GetStateId()), 0); + ASSERT_EQ(static_cast<uint32_t>(migrateActions.GetDestinationActionContext().GetStateId()), 0); + ASSERT_EQ(migrateActions.GetBehaviorId(), -1); } TEST_F(GameMessageTests, ControlBehaviorRearrangeStrip) { @@ -181,9 +180,9 @@ TEST_F(GameMessageTests, ControlBehaviorRearrangeStrip) { RearrangeStripMessage rearrangeStrip(ReadArrayFromBitStream(&inStream)); ASSERT_EQ(rearrangeStrip.GetSrcActionIndex(), 2); ASSERT_EQ(rearrangeStrip.GetDstActionIndex(), 1); - ASSERT_EQ(rearrangeStrip.GetStripID(), 0); - ASSERT_EQ(rearrangeStrip.GetBehaviorID(), -1); - ASSERT_EQ(static_cast<uint32_t>(rearrangeStrip.GetStateID()), 0); + ASSERT_EQ(rearrangeStrip.GetActionContext().GetStripId(), 0); + ASSERT_EQ(rearrangeStrip.GetBehaviorId(), -1); + ASSERT_EQ(static_cast<uint32_t>(rearrangeStrip.GetActionContext().GetStateId()), 0); } TEST_F(GameMessageTests, ControlBehaviorAdd) { @@ -198,10 +197,10 @@ TEST_F(GameMessageTests, ControlBehaviorRemoveActions) { auto data = ReadFromFile("removeActions"); RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); RemoveActionsMessage removeActions(ReadArrayFromBitStream(&inStream)); - ASSERT_EQ(removeActions.GetBehaviorID(), -1); + ASSERT_EQ(removeActions.GetBehaviorId(), -1); ASSERT_EQ(removeActions.GetActionIndex(), 1); - ASSERT_EQ(removeActions.GetStripID(), 0); - ASSERT_EQ(static_cast<uint32_t>(removeActions.GetStateID()), 0); + ASSERT_EQ(removeActions.GetActionContext().GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(removeActions.GetActionContext().GetStateId()), 0); } TEST_F(GameMessageTests, ControlBehaviorRename) { @@ -209,19 +208,19 @@ TEST_F(GameMessageTests, ControlBehaviorRename) { RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); RenameMessage rename(ReadArrayFromBitStream(&inStream)); ASSERT_EQ(rename.GetName(), "test"); - ASSERT_EQ(rename.GetBehaviorID(), -1); + ASSERT_EQ(rename.GetBehaviorId(), -1); } TEST_F(GameMessageTests, ControlBehaviorUpdateAction) { auto data = ReadFromFile("updateAction"); RakNet::BitStream inStream((unsigned char*)data.c_str(), data.length(), true); UpdateActionMessage updateAction(ReadArrayFromBitStream(&inStream)); - ASSERT_EQ(updateAction.GetType(), "FlyDown"); - ASSERT_EQ(updateAction.GetValueParameterName(), "Distance"); - ASSERT_EQ(updateAction.GetValueParameterString(), ""); - ASSERT_EQ(updateAction.GetValueParameterDouble(), 50.0); - ASSERT_EQ(updateAction.GetBehaviorID(), -1); + ASSERT_EQ(updateAction.GetAction().GetType(), "FlyDown"); + ASSERT_EQ(updateAction.GetAction().GetValueParameterName(), "Distance"); + ASSERT_EQ(updateAction.GetAction().GetValueParameterString(), ""); + ASSERT_EQ(updateAction.GetAction().GetValueParameterDouble(), 50.0); + ASSERT_EQ(updateAction.GetBehaviorId(), -1); ASSERT_EQ(updateAction.GetActionIndex(), 1); - ASSERT_EQ(updateAction.GetStripID(), 0); - ASSERT_EQ(static_cast<uint32_t>(updateAction.GetStateID()), 0); + ASSERT_EQ(updateAction.GetActionContext().GetStripId(), 0); + ASSERT_EQ(static_cast<uint32_t>(updateAction.GetActionContext().GetStateId()), 0); } From 6d989f37f1df153eb33d3654b1b681ee91de5da5 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sun, 19 Feb 2023 06:29:14 -0600 Subject: [PATCH 133/166] Breakout ServerDisconnectIdentifiers into an enum (#995) --- dCommon/dEnums/dCommonVars.h | 14 ----------- dCommon/dEnums/eServerDisconnectIdentifiers.h | 24 +++++++++++++++++++ dGame/User.cpp | 3 ++- dGame/dUtilities/SlashCommandHandler.cpp | 5 ++-- dNet/AuthPackets.cpp | 1 + dNet/dServer.cpp | 2 +- dNet/dServer.h | 3 ++- dWorldServer/WorldServer.cpp | 13 +++++----- 8 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 dCommon/dEnums/eServerDisconnectIdentifiers.h diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 1d4a4c55..2ba8b209 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -261,20 +261,6 @@ enum eReplicaPacketType { PACKET_TYPE_DESTRUCTION //!< A destruction packet }; -enum ServerDisconnectIdentifiers { - SERVER_DISCON_UNKNOWN_SERVER_ERROR = 0, //!< Unknown server error - SERVER_DISCON_DUPLICATE_LOGIN = 4, //!< Used when another user with the same username is logged in (duplicate login) - SERVER_DISCON_SERVER_SHUTDOWN = 5, //!< Used when the server is shutdown - SERVER_DISCON_SERVER_MAP_LOAD_FAILURE = 6, //!< Used when the server cannot load a map - SERVER_DISCON_INVALID_SESSION_KEY = 7, //!< Used if the session is invalid - SERVER_DISCON_ACCOUNT_NOT_IN_PENDING_LIST = 8, //!< ??? - SERVER_DISCON_CHARACTER_NOT_FOUND = 9, //!< Used if a character that the server has is not found (i.e, corruption with user-player data) - SERVER_DISCON_CHARACTER_CORRUPTED = 10, //!< Similar to abovce - SERVER_DISCON_KICK = 11, //!< Used if the user is kicked from the server - SERVER_DISCON_FREE_TRIAL_EXPIRED = 12, //!< Used if the user's free trial expired - SERVER_DISCON_PLAY_SCHEDULE_TIME_DONE = 13 //!< Used if the user's play time is used up -}; - //! The Behavior Types for use with the AI system enum eCombatBehaviorTypes : uint32_t { PASSIVE = 0, //!< The object is passive diff --git a/dCommon/dEnums/eServerDisconnectIdentifiers.h b/dCommon/dEnums/eServerDisconnectIdentifiers.h new file mode 100644 index 00000000..99d2cd44 --- /dev/null +++ b/dCommon/dEnums/eServerDisconnectIdentifiers.h @@ -0,0 +1,24 @@ +#ifndef __ESERVERDISCONNECTIDENTIFIERS__H__ +#define __ESERVERDISCONNECTIDENTIFIERS__H__ + +#include <cstdint> + +enum class eServerDisconnectIdentifiers : uint32_t { + UNKNOWN_SERVER_ERROR = 0, + WRONG_GAME_VERSION, + WRONG_SERVER_VERSION, + CONNECTION_ON_INVALID_PORT, + DUPLICATE_LOGIN, + SERVER_SHUTDOWN, + SERVER_MAP_LOAD_FAILURE, + INVALID_SESSION_KEY, + ACCOUNT_NOT_IN_PENDING_LIST, + CHARACTER_NOT_FOUND, + CHARACTER_CORRUPTED, + KICK, + SAVE_FAILURE, + FREE_TRIAL_EXPIRED, + PLAY_SCHEDULE_TIME_DONE +}; + +#endif //!__ESERVERDISCONNECTIDENTIFIERS__H__ diff --git a/dGame/User.cpp b/dGame/User.cpp index 20cc3ab4..dc607cd0 100644 --- a/dGame/User.cpp +++ b/dGame/User.cpp @@ -5,6 +5,7 @@ #include "dLogger.h" #include "Game.h" #include "dZoneManager.h" +#include "eServerDisconnectIdentifiers.h" User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) { m_AccountID = 0; @@ -126,6 +127,6 @@ void User::UserOutOfSync() { if (m_AmountOfTimesOutOfSync > m_MaxDesyncAllowed) { //YEET Game::logger->Log("User", "User %s was out of sync %i times out of %i, disconnecting for suspected speedhacking.", m_Username.c_str(), m_AmountOfTimesOutOfSync, m_MaxDesyncAllowed); - Game::server->Disconnect(this->m_SystemAddress, SERVER_DISCON_KICK); + Game::server->Disconnect(this->m_SystemAddress, eServerDisconnectIdentifiers::PLAY_SCHEDULE_TIME_DONE); } } diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index e558e19c..8ae0b441 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -74,6 +74,7 @@ #include "dMessageIdentifiers.h" #include "eMissionState.h" #include "TriggerComponent.h" +#include "eServerDisconnectIdentifiers.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; @@ -1094,7 +1095,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - Game::server->Disconnect(player->GetSystemAddress(), SERVER_DISCON_KICK); + Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::KICK); ChatPackets::SendSystemMessage(sysAddr, u"Kicked: " + username); } else { @@ -1140,7 +1141,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit delete userUpdate; if (player != nullptr) { - Game::server->Disconnect(player->GetSystemAddress(), SERVER_DISCON_KICK); + Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::FREE_TRIAL_EXPIRED); } ChatPackets::SendSystemMessage(sysAddr, u"Banned: " + GeneralUtils::ASCIIToUTF16(args[0])); diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 636f3fcf..4e7cb0a6 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -21,6 +21,7 @@ #include "Game.h" #include "dConfig.h" +#include "eServerDisconnectIdentifiers.h" void AuthPackets::HandleHandshake(dServer* server, Packet* packet) { RakNet::BitStream inStream(packet->data, packet->length, false); diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index a3961d45..c91c7508 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -164,7 +164,7 @@ void dServer::SendToMaster(RakNet::BitStream* bitStream) { mMasterPeer->Send(bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, mMasterSystemAddress, false); } -void dServer::Disconnect(const SystemAddress& sysAddr, uint32_t disconNotifyID) { +void dServer::Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID) { RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, SERVER, MSG_SERVER_DISCONNECT_NOTIFY); bitStream.Write(disconNotifyID); diff --git a/dNet/dServer.h b/dNet/dServer.h index d9e74d2e..797647b6 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -6,6 +6,7 @@ class dLogger; class dConfig; +enum class eServerDisconnectIdentifiers : uint32_t; enum class ServerType : uint32_t { Master, @@ -41,7 +42,7 @@ public: virtual void Send(RakNet::BitStream* bitStream, const SystemAddress& sysAddr, bool broadcast); void SendToMaster(RakNet::BitStream* bitStream); - void Disconnect(const SystemAddress& sysAddr, uint32_t disconNotifyID); + void Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID); bool IsConnected(const SystemAddress& sysAddr); const std::string& GetIP() const { return mIP; } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index b655bef3..f8d50f5b 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -63,6 +63,7 @@ #include "eBlueprintSaveResponseType.h" #include "AMFFormat.h" #include "NiPoint3.h" +#include "eServerDisconnectIdentifiers.h" #include "ZCompression.h" @@ -765,7 +766,7 @@ void HandlePacket(Packet* packet) { //Verify it: if (userHash != it->second.hash) { Game::logger->Log("WorldServer", "SOMEONE IS TRYING TO HACK? SESSION KEY MISMATCH: ours: %s != master: %s", userHash.c_str(), it->second.hash.c_str()); - Game::server->Disconnect(it->second.sysAddr, SERVER_DISCON_INVALID_SESSION_KEY); + Game::server->Disconnect(it->second.sysAddr, eServerDisconnectIdentifiers::INVALID_SESSION_KEY); return; } else { Game::logger->Log("WorldServer", "User %s authenticated with correct key.", username.c_str()); @@ -855,7 +856,7 @@ void HandlePacket(Packet* packet) { //Check the key: if (sessionKey != std::atoi(user->GetSessionKey().c_str())) { Game::logger->Log("WorldServer", "Got new session alert for user %s, but the session key is invalid.", username.c_str()); - Game::server->Disconnect(user->GetSystemAddress(), SERVER_DISCON_INVALID_SESSION_KEY); + Game::server->Disconnect(user->GetSystemAddress(), eServerDisconnectIdentifiers::INVALID_SESSION_KEY); return; } break; @@ -896,7 +897,7 @@ void HandlePacket(Packet* packet) { // Developers may skip this check if (gmLevel < 8 && clientDatabaseChecksum != databaseChecksum) { Game::logger->Log("WorldServer", "Client's database checksum does not match the server's, aborting connection."); - Game::server->Disconnect(packet->systemAddress, SERVER_DISCON_KICK); + Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::WRONG_GAME_VERSION); return; } } @@ -1184,7 +1185,7 @@ void HandlePacket(Packet* packet) { } } else { Game::logger->Log("WorldServer", "Couldn't find character to log in with for user %s (%i)!", user->GetUsername().c_str(), user->GetAccountID()); - Game::server->Disconnect(packet->systemAddress, SERVER_DISCON_CHARACTER_NOT_FOUND); + Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::CHARACTER_NOT_FOUND); } } else { Game::logger->Log("WorldServer", "Couldn't get user for level load complete!"); @@ -1269,7 +1270,7 @@ void HandlePacket(Packet* packet) { if (user) { user->UserOutOfSync(); } else { - Game::server->Disconnect(packet->systemAddress, SERVER_DISCON_KICK); + Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::KICK); } break; } @@ -1309,7 +1310,7 @@ void WorldShutdownProcess(uint32_t zoneId) { while (Game::server->GetReplicaManager()->GetParticipantCount() > 0) { const auto& player = Game::server->GetReplicaManager()->GetParticipantAtIndex(0); - Game::server->Disconnect(player, SERVER_DISCON_KICK); + Game::server->Disconnect(player, eServerDisconnectIdentifiers::SERVER_SHUTDOWN); } SendShutdownMessageToMaster(); } From b6fc959433d03849ef96b071a77cc7248e62b97a Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 28 Feb 2023 15:30:28 -0800 Subject: [PATCH 134/166] Fix shark stinky fish death animation (#1004) --- dScripts/02_server/Objects/StinkyFishTarget.cpp | 4 +++- dScripts/02_server/Objects/StinkyFishTarget.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dScripts/02_server/Objects/StinkyFishTarget.cpp b/dScripts/02_server/Objects/StinkyFishTarget.cpp index 21d92fac..459e0bbe 100644 --- a/dScripts/02_server/Objects/StinkyFishTarget.cpp +++ b/dScripts/02_server/Objects/StinkyFishTarget.cpp @@ -1,6 +1,7 @@ #include "StinkyFishTarget.h" #include "EntityManager.h" #include "EntityInfo.h" +#include "Entity.h" void StinkyFishTarget::OnStartup(Entity* self) { auto position = self->GetPosition(); @@ -16,6 +17,7 @@ void StinkyFishTarget::OnSkillEventFired(Entity* self, Entity* caster, const std self->SetVar<LWOOBJID>(u"player", caster->GetObjectID()); EntityInfo entityInfo{}; + entityInfo.lot = SHARK_LOT; entityInfo.pos = self->GetPosition(); entityInfo.rot = self->GetRotation(); entityInfo.spawnerID = self->GetObjectID(); @@ -35,7 +37,7 @@ void StinkyFishTarget::OnTimerDone(Entity* self, std::string timerName) { const auto playerID = self->GetVar<LWOOBJID>(u"player"); auto* fish = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"fish")); - if (fish != nullptr) { + if (fish) { fish->Smash(playerID); self->Smash(playerID); } diff --git a/dScripts/02_server/Objects/StinkyFishTarget.h b/dScripts/02_server/Objects/StinkyFishTarget.h index 6c52171d..b8f9e9ae 100644 --- a/dScripts/02_server/Objects/StinkyFishTarget.h +++ b/dScripts/02_server/Objects/StinkyFishTarget.h @@ -2,7 +2,10 @@ #include "CppScripts.h" class StinkyFishTarget : public CppScripts::Script { +public: void OnStartup(Entity* self) override; void OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) override; void OnTimerDone(Entity* self, std::string timerName) override; +private: + const LOT SHARK_LOT = 8570; }; From 3e482602d4f29103ebba4fb29a8a28c3a0166150 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 3 Mar 2023 18:45:01 -0800 Subject: [PATCH 135/166] Fix non-parallel timers in CombatAIComponent (#1008) * Fix non-parelell timers --- dGame/dComponents/BaseCombatAIComponent.cpp | 41 ++++++++------------- dGame/dComponents/BaseCombatAIComponent.h | 5 --- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 081496a4..8e778d1d 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -22,6 +22,7 @@ #include "SkillComponent.h" #include "RebuildComponent.h" #include "DestroyableComponent.h" +#include "Metrics.hpp" BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): Component(parent) { m_Target = LWOOBJID_EMPTY; @@ -228,6 +229,18 @@ void BaseCombatAIComponent::Update(const float deltaTime) { void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { + bool hasSkillToCast = false; + for (auto& entry : m_SkillEntries) { + if (entry.cooldown > 0.0f) { + entry.cooldown -= deltaTime; + } else { + hasSkillToCast = true; + } + } + + bool hadRemainingDowntime = m_SkillTime > 0.0f; + if (m_SkillTime > 0.0f) m_SkillTime -= deltaTime; + auto* rebuild = m_Parent->GetComponent<RebuildComponent>(); if (rebuild != nullptr) { @@ -258,9 +271,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { m_Stunned = false; } - if (m_Stunned) { - return; - } + if (m_Stunned || hadRemainingDowntime) return; auto newTarget = FindTarget(); @@ -325,27 +336,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { SetAiState(AiState::idle); } - for (auto i = 0; i < m_SkillEntries.size(); ++i) { - auto entry = m_SkillEntries.at(i); - - if (entry.cooldown > 0) { - entry.cooldown -= deltaTime; - - m_SkillEntries[i] = entry; - } - } - - if (m_SkillTime > 0) { - m_SkillTime -= deltaTime; - - return; - } - - if (m_Downtime > 0) { - m_Downtime -= deltaTime; - - return; - } + if (!hasSkillToCast) return; if (m_Target == LWOOBJID_EMPTY) { SetAiState(AiState::idle); @@ -353,8 +344,6 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { return; } - m_Downtime = 0.5f; - auto* target = GetTargetEntity(); if (target != nullptr) { diff --git a/dGame/dComponents/BaseCombatAIComponent.h b/dGame/dComponents/BaseCombatAIComponent.h index 1f17d562..6e55a4b1 100644 --- a/dGame/dComponents/BaseCombatAIComponent.h +++ b/dGame/dComponents/BaseCombatAIComponent.h @@ -340,11 +340,6 @@ private: */ bool m_StunImmune = false; - /** - * Time taken between actions - */ - float m_Downtime = 0; - /** * How long this entity needs to execute its skill */ From a0c0a879564279f035066eeff65481c14ae90aab Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 3 Mar 2023 22:58:29 -0800 Subject: [PATCH 136/166] Fix Trigger Missions (#1010) --- dGame/dComponents/TriggerComponent.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index 4ed95a15..fe3c7792 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -163,19 +163,14 @@ void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector< void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) { CDMissionTasksTable* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { - std::string lowerTargetGroup; - for (char character : entry.targetGroup) { - lowerTargetGroup.push_back(std::tolower(character)); // make lowercase to ensure it works - } - - return (lowerTargetGroup == argArray[4]); + return (entry.targetGroup == argArray.at(4)); }); for (const CDMissionTasks& task : missionTasks) { MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>(); if (!missionComponent) continue; - missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray[2])); + missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray.at(2))); } } From 2837f68f44a814c27e1d5dbffb4bd9ab1c09106d Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 3 Mar 2023 22:59:37 -0800 Subject: [PATCH 137/166] Fix stuns with mast teleport (#1003) --- dScripts/02_server/Map/GF/MastTeleport.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index dac5783c..6e50c6ec 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -2,6 +2,7 @@ #include "EntityManager.h" #include "GameMessages.h" #include "Preconditions.h" +#include "DestroyableComponent.h" #ifdef _WIN32 #define _USE_MATH_DEFINES @@ -19,6 +20,8 @@ void MastTeleport::OnRebuildComplete(Entity* self, Entity* target) { GameMessages::SendSetStunned(target->GetObjectID(), eStateChangeType::PUSH, target->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); + auto* destroyableComponent = target->GetComponent<DestroyableComponent>(); + if (destroyableComponent) destroyableComponent->SetStatusImmunity(eStateChangeType::PUSH, true, true, true, true, true, false, false, true, true); self->AddTimer("Start", 3); } @@ -55,7 +58,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendPlayFXEffect(playerId, 6039, u"hook", "hook", LWOOBJID_EMPTY, 1, 1, true); - GameMessages::SendPlayAnimation(player, u"crow-swing-no-equip"); + GameMessages::SendPlayAnimation(player, u"crow-swing-no-equip", 4.0f); GameMessages::SendPlayAnimation(self, u"swing"); @@ -84,5 +87,8 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendSetStunned(playerId, eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, true, true, true, true, true, true, true ); + auto* destroyableComponent = player->GetComponent<DestroyableComponent>(); + if (destroyableComponent) destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true, true, true, true, true, false, false, true, true); + EntityManager::Instance()->SerializeEntity(player); } } From e524b86e12503144f14b538c6bfd523a7d0c4e31 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sat, 4 Mar 2023 01:16:37 -0600 Subject: [PATCH 138/166] breakout the component types into a scoped enum (#1002) * breakout the component types into a scoped enum tested that things are the same as they were before * fix missed rename * fix brick-by-brick name to be crafting because that's what it is --- dCommon/GeneralUtils.h | 6 + dCommon/dEnums/dCommonVars.h | 51 --- dCommon/dEnums/eReplicaComponentType.h | 127 +++++++ .../Tables/CDComponentsRegistryTable.cpp | 5 +- dDatabase/Tables/CDComponentsRegistryTable.h | 6 +- dGame/Entity.cpp | 309 +++++++++--------- dGame/Entity.h | 15 +- dGame/EntityManager.cpp | 5 +- dGame/EntityManager.h | 3 +- dGame/Player.cpp | 5 +- dGame/dBehaviors/BehaviorContext.cpp | 7 +- dGame/dBehaviors/HealBehavior.cpp | 3 +- dGame/dBehaviors/RepairBehavior.cpp | 3 +- dGame/dBehaviors/SpawnBehavior.cpp | 3 +- dGame/dBehaviors/StunBehavior.cpp | 7 +- dGame/dComponents/BaseCombatAIComponent.cpp | 2 +- dGame/dComponents/BaseCombatAIComponent.h | 7 +- dGame/dComponents/BouncerComponent.h | 3 +- dGame/dComponents/BuffComponent.h | 3 +- dGame/dComponents/BuildBorderComponent.h | 3 +- dGame/dComponents/CharacterComponent.h | 3 +- .../ControllablePhysicsComponent.h | 3 +- dGame/dComponents/DestroyableComponent.cpp | 8 +- dGame/dComponents/DestroyableComponent.h | 3 +- dGame/dComponents/InventoryComponent.cpp | 12 +- dGame/dComponents/InventoryComponent.h | 3 +- dGame/dComponents/LUPExhibitComponent.h | 3 +- dGame/dComponents/LevelProgressionComponent.h | 3 +- dGame/dComponents/MissionComponent.h | 3 +- dGame/dComponents/MissionOfferComponent.cpp | 4 +- dGame/dComponents/MissionOfferComponent.h | 3 +- dGame/dComponents/ModelComponent.cpp | 2 +- dGame/dComponents/ModelComponent.h | 3 +- dGame/dComponents/ModuleAssemblyComponent.h | 3 +- dGame/dComponents/MovementAIComponent.cpp | 6 +- dGame/dComponents/MovementAIComponent.h | 3 +- dGame/dComponents/MovingPlatformComponent.h | 3 +- dGame/dComponents/PetComponent.h | 3 +- dGame/dComponents/PhantomPhysicsComponent.cpp | 4 +- dGame/dComponents/PhantomPhysicsComponent.h | 3 +- .../PlayerForcedMovementComponent.h | 3 +- dGame/dComponents/PossessableComponent.h | 3 +- dGame/dComponents/PossessorComponent.h | 3 +- dGame/dComponents/PropertyComponent.h | 3 +- dGame/dComponents/PropertyEntranceComponent.h | 3 +- .../PropertyManagementComponent.cpp | 2 +- .../dComponents/PropertyManagementComponent.h | 3 +- dGame/dComponents/PropertyVendorComponent.h | 3 +- dGame/dComponents/ProximityMonitorComponent.h | 3 +- dGame/dComponents/RacingControlComponent.h | 3 +- dGame/dComponents/RailActivatorComponent.h | 3 +- dGame/dComponents/RebuildComponent.cpp | 2 +- dGame/dComponents/RebuildComponent.h | 3 +- dGame/dComponents/RenderComponent.cpp | 2 +- dGame/dComponents/RenderComponent.h | 3 +- .../RigidbodyPhantomPhysicsComponent.h | 3 +- dGame/dComponents/RocketLaunchLupComponent.h | 3 +- .../RocketLaunchpadControlComponent.h | 3 +- .../dComponents/ScriptedActivityComponent.cpp | 2 +- dGame/dComponents/ScriptedActivityComponent.h | 3 +- dGame/dComponents/ShootingGalleryComponent.h | 3 +- dGame/dComponents/SimplePhysicsComponent.h | 3 +- dGame/dComponents/SkillComponent.cpp | 2 +- dGame/dComponents/SkillComponent.h | 3 +- dGame/dComponents/SoundTriggerComponent.h | 3 +- dGame/dComponents/SwitchComponent.h | 3 +- dGame/dComponents/TriggerComponent.h | 3 +- dGame/dComponents/VehiclePhysicsComponent.h | 3 +- dGame/dComponents/VendorComponent.cpp | 2 +- dGame/dComponents/VendorComponent.h | 3 +- dGame/dGameMessages/GameMessageHandler.cpp | 7 +- dGame/dGameMessages/GameMessages.cpp | 107 +++--- dGame/dInventory/Inventory.cpp | 5 +- dGame/dInventory/Item.cpp | 5 +- dGame/dMission/Mission.cpp | 4 +- dGame/dMission/MissionTask.cpp | 3 +- dGame/dUtilities/Loot.cpp | 4 +- dGame/dUtilities/Mail.cpp | 5 +- dGame/dUtilities/SlashCommandHandler.cpp | 41 +-- dNet/ClientPackets.cpp | 4 +- .../Enemy/AG/BossSpiderQueenEnemyServer.cpp | 9 +- .../02_server/Enemy/General/BaseEnemyMech.cpp | 3 +- .../02_server/Map/AG/AgCagedBricksServer.cpp | 3 +- .../02_server/Map/AG/AgLaserSensorServer.cpp | 5 +- .../02_server/Map/AG/NpcNjAssistantServer.cpp | 5 +- .../02_server/Map/AG/RemoveRentalGear.cpp | 3 +- dScripts/02_server/Map/FV/FvCandle.cpp | 7 +- dScripts/02_server/Map/GF/GfTikiTorch.cpp | 3 +- .../Map/General/TokenConsoleServer.cpp | 3 +- .../Map/General/TouchMissionUpdateServer.cpp | 3 +- .../Property/AG_Small/EnemySpiderSpawner.cpp | 3 +- .../Map/Property/AG_Small/ZoneAgProperty.cpp | 3 +- .../02_server/Map/SS/SsModularBuildServer.cpp | 3 +- dScripts/NtFactionSpyServer.cpp | 3 +- dScripts/ScriptComponent.h | 3 +- dScripts/ai/AG/AgFans.cpp | 9 +- dScripts/ai/AG/AgImagSmashable.cpp | 3 +- dScripts/ai/AG/AgJetEffectServer.cpp | 5 +- dScripts/ai/AG/AgStromlingProperty.cpp | 3 +- dScripts/ai/GF/GfCampfire.cpp | 5 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 3 +- dScripts/ai/NP/NpcNpSpacemanBob.cpp | 5 +- dScripts/ai/NS/NsGetFactionMissionServer.cpp | 3 +- dScripts/ai/NS/NsModularBuild.cpp | 3 +- .../ai/SPEC/SpecialImaginePowerupSpawner.cpp | 5 +- .../DestroyableComponentTests.cpp | 5 +- 106 files changed, 598 insertions(+), 430 deletions(-) create mode 100644 dCommon/dEnums/eReplicaComponentType.h diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index d43ad9b1..a2a52b45 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -15,6 +15,7 @@ #include "dLogger.h" enum eInventoryType : uint32_t; +enum class eReplicaComponentType : uint32_t; /*! \file GeneralUtils.hpp @@ -181,6 +182,11 @@ namespace GeneralUtils { return static_cast<eInventoryType>(std::stoul(value)); } + template <> + inline eReplicaComponentType Parse(const char* value) { + return static_cast<eReplicaComponentType>(std::stoul(value)); + } + template <typename T> bool TryParse(const char* value, T& dst) { try { diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 2ba8b209..da8a2e18 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -365,57 +365,6 @@ enum eNotifyType { NOTIFY_TYPE_NAMINGPET }; -enum eReplicaComponentType : int32_t { - COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1, //!< The ControllablePhysics Component - COMPONENT_TYPE_RENDER = 2, //!< The Render Component - COMPONENT_TYPE_SIMPLE_PHYSICS = 3, //!< The SimplePhysics Component - COMPONENT_TYPE_CHARACTER = 4, //!< The Character Component - COMPONENT_TYPE_SCRIPT = 5, //!< The Script Component - COMPONENT_TYPE_BOUNCER = 6, //!< The Bouncer Component - COMPONENT_TYPE_BUFF = 7, //!< The Buff Component - COMPONENT_TYPE_SKILL = 9, //!< The Skill Component - COMPONENT_TYPE_ITEM = 11, //!< The Item Component - COMPONENT_TYPE_VENDOR = 16, //!< The Vendor Component - COMPONENT_TYPE_INVENTORY = 17, //!< The Inventory Component - COMPONENT_TYPE_SHOOTING_GALLERY = 19, //!< The Shooting Gallery Component - COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20, //!< The RigidBodyPhantomPhysics Component - COMPONENT_TYPE_COLLECTIBLE = 23, //!< The Collectible Component - COMPONENT_TYPE_MOVING_PLATFORM = 25, //!< The MovingPlatform Component - COMPONENT_TYPE_PET = 26, //!< The Pet Component - COMPONENT_TYPE_VEHICLE_PHYSICS = 30, //!< The VehiclePhysics Component - COMPONENT_TYPE_MOVEMENT_AI = 31, //!< The MovementAI Component - COMPONENT_TYPE_PROPERTY = 36, //!< The Property Component - COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39, //!< The ScriptedActivity Component - COMPONENT_TYPE_PHANTOM_PHYSICS = 40, //!< The PhantomPhysics Component - COMPONENT_TYPE_MODEL = 42, //!< The Model Component - COMPONENT_TYPE_PROPERTY_ENTRANCE = 43, //!< The PhantomPhysics Component - COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45, //!< The PropertyManagement Component - COMPONENT_TYPE_REBUILD = 48, //!< The Rebuild Component - COMPONENT_TYPE_SWITCH = 49, //!< The Switch Component - COMPONENT_TYPE_ZONE_CONTROL = 50, //!< The ZoneControl Component - COMPONENT_TYPE_PACKAGE = 53, //!< The Package Component - COMPONENT_TYPE_PLAYER_FLAG = 58, //!< The PlayerFlag Component - COMPONENT_TYPE_BASE_COMBAT_AI = 60, //!< The BaseCombatAI Component - COMPONENT_TYPE_MODULE_ASSEMBLY = 61, //!< The ModuleAssembly Component - COMPONENT_TYPE_PROPERTY_VENDOR = 65, //!< The PropertyVendor Component - COMPONENT_TYPE_ROCKET_LAUNCH = 67, //!< The RocketLaunch Component - COMPONENT_TYPE_TRIGGER = 69, - COMPONENT_TYPE_RACING_CONTROL = 71, //!< The RacingControl Component - COMPONENT_TYPE_MISSION_OFFER = 73, //!< The MissionOffer Component - COMPONENT_TYPE_EXHIBIT = 75, //!< The Exhibit Component - COMPONENT_TYPE_RACING_STATS = 74, //!< The Racing Stats Component - COMPONENT_TYPE_SOUND_TRIGGER = 77, //!< The Sound Trigger Component - COMPONENT_TYPE_PROXIMITY_MONITOR = 78, //!< The Proximity Monitor Component - COMPONENT_TYPE_MISSION = 84, //!< The Mission Component - COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97, //!< The LUP Launchpad Componen - COMPONENT_TYPE_RAIL_ACTIVATOR = 104, //!< The Rail Activator Component - COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT = 106, //!< The Player Forced Movement Component - COMPONENT_TYPE_POSSESSABLE = 108, //!< The Possessable Component - COMPONENT_TYPE_LEVEL_PROGRESSION = 109, //!< The Level Progression Component - COMPONENT_TYPE_POSSESSOR = 110, //!< The Possessor Component - COMPONENT_TYPE_BUILD_BORDER = 114, //!< The Build Border Component - COMPONENT_TYPE_DESTROYABLE = 1000, //!< The Destroyable Component -}; enum class UseItemResponse : uint32_t { NoImaginationForPet = 1, diff --git a/dCommon/dEnums/eReplicaComponentType.h b/dCommon/dEnums/eReplicaComponentType.h new file mode 100644 index 00000000..3eee16f3 --- /dev/null +++ b/dCommon/dEnums/eReplicaComponentType.h @@ -0,0 +1,127 @@ +#ifndef __EREPLICACOMPONENTTYPE__H__ +#define __EREPLICACOMPONENTTYPE__H__ + +#include <cstdint> + +enum class eReplicaComponentType : uint32_t { + INVALID = 0, + CONTROLLABLE_PHYSICS, + RENDER, + SIMPLE_PHYSICS, + CHARACTER, + SCRIPT, + BOUNCER, + BUFF, // buff is really 98, this is DESTROYABLE + GHOST, + SKILL, + SPAWNER, + ITEM, + REBUILD, + REBUILD_START, + REBUILD_ACTIVATOR, + ICON_ONLY, + VENDOR, + INVENTORY, + PROJECTILE_PHYSICS, + SHOOTING_GALLERY, + RIGID_BODY_PHANTOM_PHYSICS, + DROP_EFFECT, + CHEST, + COLLECTIBLE, + BLUEPRINT, + MOVING_PLATFORM, + PET, + PLATFORM_BOUNDARY, + MODULE, + ARCADE, + VEHICLE_PHYSICS, // Havok demo based + MOVEMENT_AI, + EXHIBIT, + OVERHEAD_ICON, + PET_CONTROL, + MINIFIG, + PROPERTY, + PET_CREATOR, + MODEL_BUILDER, + SCRIPTED_ACTIVITY, + PHANTOM_PHYSICS, + SPRINGPAD, + MODEL, + PROPERTY_ENTRANCE, + FX, + PROPERTY_MANAGEMENT, + VEHICLE_PHYSICS_NEW, // internal physics based on havok + PHYSICS_SYSTEM, + QUICK_BUILD, + SWITCH, + ZONE_CONTROL, // Minigame + CHANGLING, + CHOICE_BUILD, + PACKAGE, + SOUND_REPEATER, + SOUND_AMBIENT_2D, + SOUND_AMBIENT_3D, + PRECONDITION, + PLAYER_FLAG, + CUSTOM_BUILD_ASSEMBLY, + BASE_COMBAT_AI, + MODULE_ASSEMBLY, + SHOWCASE_MODEL_HANDLER, + RACING_MODULE, + GENERIC_ACTIVATOR, + PROPERTY_VENDOR, + HF_LIGHT_DIRECTION_GADGET, + ROCKET_LAUNCH, + ROCKET_LANDING, + TRIGGER, + DROPPED_LOOT, + RACING_CONTROL, + FACTION_TRIGGER, + MISSION_OFFER, + RACING_STATS, + LUP_EXHIBIT, + BBB, + SOUND_TRIGGER, + PROXIMITY_MONITOR, + RACING_SOUND_TRIGGER, + CHAT, + FRIENDS_LIST, + GUILD, + LOCAL_SYSTEM, + MISSION, + MUTABLE_MODEL_BEHAVIORS, + PATHFINDING, + PET_TAMING_CONTROL, + PROPERTY_EDITOR, + SKINNED_RENDER, + SLASH_COMMAND, + STATUS_EFFECT, + TEAMS, + TEXT_EFFECT, + TRADE, + USER_CONTROL, + IGNORE_LIST, + ROCKET_LAUNCH_LUP, + BUFF_REAL, // the real buff component, should just be name BUFF + INTERACTION_MANAGER, + DONATION_VENDOR, + COMBAT_MEDIATOR, + COMMENDATION_VENDOR, + UNKNOWN_103, + RAIL_ACTIVATOR, + ROLLER, + PLAYER_FORCED_MOVEMENT, + CRAFTING, + POSSESSABLE, + LEVEL_PROGRESSION, + POSSESSOR, + MOUNT_CONTROL, + UNKNOWN_112, + PROPERTY_PLAQUE, + BUILD_BORDER, + UNKOWN_115, + CULLING_PLANE, + DESTROYABLE = 1000 // Actually 7 +}; + +#endif //!__EREPLICACOMPONENTTYPE__H__ diff --git a/dDatabase/Tables/CDComponentsRegistryTable.cpp b/dDatabase/Tables/CDComponentsRegistryTable.cpp index 987c66ab..88bb04cc 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.cpp +++ b/dDatabase/Tables/CDComponentsRegistryTable.cpp @@ -1,4 +1,5 @@ #include "CDComponentsRegistryTable.h" +#include "eReplicaComponentType.h" #define CDCLIENT_CACHE_ALL @@ -25,7 +26,7 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) { while (!tableData.eof()) { CDComponentsRegistry entry; entry.id = tableData.getIntField("id", -1); - entry.component_type = tableData.getIntField("component_type", -1); + entry.component_type = static_cast<eReplicaComponentType>(tableData.getIntField("component_type", 0)); entry.component_id = tableData.getIntField("component_id", -1); this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id); @@ -63,7 +64,7 @@ std::string CDComponentsRegistryTable::GetName(void) const { return "ComponentsRegistry"; } -int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue) { +int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) { const auto& iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); if (iter == this->mappedEntries.end()) { diff --git a/dDatabase/Tables/CDComponentsRegistryTable.h b/dDatabase/Tables/CDComponentsRegistryTable.h index c3eb0ed2..91e3800c 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.h +++ b/dDatabase/Tables/CDComponentsRegistryTable.h @@ -7,11 +7,11 @@ \file CDComponentsRegistryTable.hpp \brief Contains data for the ComponentsRegistry table */ - +enum class eReplicaComponentType : uint32_t; //! ComponentsRegistry Entry Struct struct CDComponentsRegistry { unsigned int id; //!< The LOT is used as the ID - unsigned int component_type; //!< See ComponentTypes enum for values + eReplicaComponentType component_type; //!< See ComponentTypes enum for values unsigned int component_id; //!< The ID used within the component's table (0 may either mean it's non-networked, or that the ID is actually 0 }; @@ -36,5 +36,5 @@ public: */ std::string GetName(void) const override; - int32_t GetByIDAndType(uint32_t id, uint32_t componentType, int32_t defaultValue = 0); + int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0); }; diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 94693385..77692966 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -70,6 +70,7 @@ #include "RailActivatorComponent.h" #include "LUPExhibitComponent.h" #include "TriggerComponent.h" +#include "eReplicaComponentType.h" Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) { m_ObjectID = objectID; @@ -135,7 +136,7 @@ void Entity::Initialize() { const auto triggerInfo = GetVarAsString(u"trigger_id"); - if (!triggerInfo.empty()) m_Components.emplace(COMPONENT_TYPE_TRIGGER, new TriggerComponent(this, triggerInfo)); + if (!triggerInfo.empty()) m_Components.emplace(eReplicaComponentType::TRIGGER, new TriggerComponent(this, triggerInfo)); /** * Setup groups @@ -164,23 +165,23 @@ void Entity::Initialize() { */ if (m_TemplateID == 14) { - const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SIMPLE_PHYSICS); + const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS); SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_SIMPLE_PHYSICS, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp)); ModelComponent* modelcomp = new ModelComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_MODEL, modelcomp)); + m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, modelcomp)); RenderComponent* render = new RenderComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_RENDER, render)); + m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render)); auto destroyableComponent = new DestroyableComponent(this); destroyableComponent->SetHealth(1); destroyableComponent->SetMaxHealth(1.0f); destroyableComponent->SetFaction(-1, true); destroyableComponent->SetIsSmashable(true); - m_Components.insert(std::make_pair(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)); + m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent)); // We have all our components. return; } @@ -193,47 +194,47 @@ void Entity::Initialize() { if (GetParentUser()) { auto missions = new MissionComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_MISSION, missions)); + m_Components.insert(std::make_pair(eReplicaComponentType::MISSION, missions)); missions->LoadFromXml(m_Character->GetXMLDoc()); } - uint32_t petComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PET); + uint32_t petComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PET); if (petComponentId > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_PET, new PetComponent(this, petComponentId))); + m_Components.insert(std::make_pair(eReplicaComponentType::PET, new PetComponent(this, petComponentId))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_ZONE_CONTROL) > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_ZONE_CONTROL, nullptr)); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ZONE_CONTROL) > 0) { + m_Components.insert(std::make_pair(eReplicaComponentType::ZONE_CONTROL, nullptr)); } - uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_POSSESSABLE); + uint32_t possessableComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::POSSESSABLE); if (possessableComponentId > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_POSSESSABLE, new PossessableComponent(this, possessableComponentId))); + m_Components.insert(std::make_pair(eReplicaComponentType::POSSESSABLE, new PossessableComponent(this, possessableComponentId))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MODULE_ASSEMBLY) > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_MODULE_ASSEMBLY, new ModuleAssemblyComponent(this))); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODULE_ASSEMBLY) > 0) { + m_Components.insert(std::make_pair(eReplicaComponentType::MODULE_ASSEMBLY, new ModuleAssemblyComponent(this))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_RACING_STATS) > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_RACING_STATS, nullptr)); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_STATS) > 0) { + m_Components.insert(std::make_pair(eReplicaComponentType::RACING_STATS, nullptr)); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_EXHIBIT, -1) >= 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_EXHIBIT, new LUPExhibitComponent(this))); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::LUP_EXHIBIT, -1) >= 0) { + m_Components.insert(std::make_pair(eReplicaComponentType::LUP_EXHIBIT, new LUPExhibitComponent(this))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_RACING_CONTROL) > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_RACING_CONTROL, new RacingControlComponent(this))); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_CONTROL) > 0) { + m_Components.insert(std::make_pair(eReplicaComponentType::RACING_CONTROL, new RacingControlComponent(this))); } - const auto propertyEntranceComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PROPERTY_ENTRANCE); + const auto propertyEntranceComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_ENTRANCE); if (propertyEntranceComponentID > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_PROPERTY_ENTRANCE, + m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY_ENTRANCE, new PropertyEntranceComponent(propertyEntranceComponentID, this))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_CONTROLLABLE_PHYSICS) > 0) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CONTROLLABLE_PHYSICS) > 0) { ControllablePhysicsComponent* controllablePhysics = new ControllablePhysicsComponent(this); if (m_Character) { @@ -268,61 +269,61 @@ void Entity::Initialize() { controllablePhysics->SetRotation(m_DefaultRotation); } - m_Components.insert(std::make_pair(COMPONENT_TYPE_CONTROLLABLE_PHYSICS, controllablePhysics)); + m_Components.insert(std::make_pair(eReplicaComponentType::CONTROLLABLE_PHYSICS, controllablePhysics)); } // If an entity is marked a phantom, simple physics is made into phantom phyics. bool markedAsPhantom = GetVar<bool>(u"markedAsPhantom"); - const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SIMPLE_PHYSICS); + const auto simplePhysicsComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SIMPLE_PHYSICS); if (!markedAsPhantom && simplePhysicsComponentID > 0) { SimplePhysicsComponent* comp = new SimplePhysicsComponent(simplePhysicsComponentID, this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_SIMPLE_PHYSICS, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::SIMPLE_PHYSICS, comp)); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS) > 0) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS) > 0) { RigidbodyPhantomPhysicsComponent* comp = new RigidbodyPhantomPhysicsComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS, comp)); } - if (markedAsPhantom || compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PHANTOM_PHYSICS) > 0) { + if (markedAsPhantom || compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PHANTOM_PHYSICS) > 0) { PhantomPhysicsComponent* phantomPhysics = new PhantomPhysicsComponent(this); phantomPhysics->SetPhysicsEffectActive(false); - m_Components.insert(std::make_pair(COMPONENT_TYPE_PHANTOM_PHYSICS, phantomPhysics)); + m_Components.insert(std::make_pair(eReplicaComponentType::PHANTOM_PHYSICS, phantomPhysics)); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_VEHICLE_PHYSICS) > 0) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VEHICLE_PHYSICS) > 0) { VehiclePhysicsComponent* vehiclePhysicsComponent = new VehiclePhysicsComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_VEHICLE_PHYSICS, vehiclePhysicsComponent)); + m_Components.insert(std::make_pair(eReplicaComponentType::VEHICLE_PHYSICS, vehiclePhysicsComponent)); vehiclePhysicsComponent->SetPosition(m_DefaultPosition); vehiclePhysicsComponent->SetRotation(m_DefaultRotation); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SOUND_TRIGGER, -1) != -1) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SOUND_TRIGGER, -1) != -1) { auto* comp = new SoundTriggerComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_SOUND_TRIGGER, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::SOUND_TRIGGER, comp)); } //Also check for the collectible id: m_CollectibleID = GetVarAs<int32_t>(u"collectible_id"); - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_BUFF) > 0) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF) > 0) { BuffComponent* comp = new BuffComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_BUFF, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::BUFF, comp)); } - int collectibleComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_COLLECTIBLE); + int collectibleComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::COLLECTIBLE); if (collectibleComponentID > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_COLLECTIBLE, nullptr)); + m_Components.insert(std::make_pair(eReplicaComponentType::COLLECTIBLE, nullptr)); } /** * Multiple components require the destructible component. */ - int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_BUFF); - int rebuildComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_REBUILD); + int buffComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUFF); + int rebuildComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD); int componentID = 0; if (collectibleComponentID > 0) componentID = collectibleComponentID; @@ -341,7 +342,7 @@ void Entity::Initialize() { std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); if (destCompData.size() > 0) { - if (HasComponent(COMPONENT_TYPE_RACING_STATS)) { + if (HasComponent(eReplicaComponentType::RACING_STATS)) { destCompData[0].imagination = 60; } @@ -385,8 +386,8 @@ void Entity::Initialize() { comp->AddFaction(6); //Smashables // A race car has 60 imagination, other entities defaults to 0. - comp->SetImagination(HasComponent(COMPONENT_TYPE_RACING_STATS) ? 60 : 0); - comp->SetMaxImagination(HasComponent(COMPONENT_TYPE_RACING_STATS) ? 60 : 0); + comp->SetImagination(HasComponent(eReplicaComponentType::RACING_STATS) ? 60 : 0); + comp->SetMaxImagination(HasComponent(eReplicaComponentType::RACING_STATS) ? 60 : 0); } } @@ -404,35 +405,35 @@ void Entity::Initialize() { } } - m_Components.insert(std::make_pair(COMPONENT_TYPE_DESTROYABLE, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, comp)); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_CHARACTER) > 0 || m_Character) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::CHARACTER) > 0 || m_Character) { // Character Component always has a possessor, level, and forced movement components - m_Components.insert(std::make_pair(COMPONENT_TYPE_POSSESSOR, new PossessorComponent(this))); + m_Components.insert(std::make_pair(eReplicaComponentType::POSSESSOR, new PossessorComponent(this))); // load in the xml for the level auto* levelComp = new LevelProgressionComponent(this); levelComp->LoadFromXml(m_Character->GetXMLDoc()); - m_Components.insert(std::make_pair(COMPONENT_TYPE_LEVEL_PROGRESSION, levelComp)); + m_Components.insert(std::make_pair(eReplicaComponentType::LEVEL_PROGRESSION, levelComp)); - m_Components.insert(std::make_pair(COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT, new PlayerForcedMovementComponent(this))); + m_Components.insert(std::make_pair(eReplicaComponentType::PLAYER_FORCED_MOVEMENT, new PlayerForcedMovementComponent(this))); CharacterComponent* charComp = new CharacterComponent(this, m_Character); charComp->LoadFromXml(m_Character->GetXMLDoc()); - m_Components.insert(std::make_pair(COMPONENT_TYPE_CHARACTER, charComp)); + m_Components.insert(std::make_pair(eReplicaComponentType::CHARACTER, charComp)); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_INVENTORY) > 0 || m_Character) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::INVENTORY) > 0 || m_Character) { InventoryComponent* comp = nullptr; if (m_Character) comp = new InventoryComponent(this, m_Character->GetXMLDoc()); else comp = new InventoryComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_INVENTORY, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::INVENTORY, comp)); } // if this component exists, then we initialize it. it's value is always 0 - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_ROCKET_LAUNCH_LUP, -1) != -1) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH_LUP, -1) != -1) { auto comp = new RocketLaunchLupComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_ROCKET_LAUNCH_LUP, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::ROCKET_LAUNCH_LUP, comp)); } /** @@ -440,7 +441,7 @@ void Entity::Initialize() { */ CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent"); - int32_t scriptComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SCRIPT, -1); + int32_t scriptComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPT, -1); std::string scriptName = ""; bool client = false; @@ -483,7 +484,7 @@ void Entity::Initialize() { } if (!scriptName.empty() || client || m_Character || scriptComponentID >= 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_SCRIPT, new ScriptComponent(this, scriptName, true, client && scriptName.empty()))); + m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, new ScriptComponent(this, scriptName, true, client && scriptName.empty()))); } // ZoneControl script @@ -497,24 +498,24 @@ void Entity::Initialize() { CDScriptComponent zoneScriptData = scriptCompTable->GetByID(zoneScriptID); ScriptComponent* comp = new ScriptComponent(this, zoneScriptData.script_name, true); - m_Components.insert(std::make_pair(COMPONENT_TYPE_SCRIPT, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPT, comp)); } } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SKILL, -1) != -1 || m_Character) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SKILL, -1) != -1 || m_Character) { SkillComponent* comp = new SkillComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_SKILL, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::SKILL, comp)); } - const auto combatAiId = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_BASE_COMBAT_AI); + const auto combatAiId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BASE_COMBAT_AI); if (combatAiId > 0) { BaseCombatAIComponent* comp = new BaseCombatAIComponent(this, combatAiId); - m_Components.insert(std::make_pair(COMPONENT_TYPE_BASE_COMBAT_AI, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::BASE_COMBAT_AI, comp)); } - if (int componentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_REBUILD) > 0) { + if (int componentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::QUICK_BUILD) > 0) { RebuildComponent* comp = new RebuildComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_REBUILD, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::QUICK_BUILD, comp)); CDRebuildComponentTable* rebCompTable = CDClientManager::Instance()->GetTable<CDRebuildComponentTable>("RebuildComponent"); std::vector<CDRebuildComponent> rebCompData = rebCompTable->Query([=](CDRebuildComponent entry) { return (entry.id == rebuildComponentID); }); @@ -554,87 +555,87 @@ void Entity::Initialize() { } } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SWITCH, -1) != -1) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SWITCH, -1) != -1) { SwitchComponent* comp = new SwitchComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_SWITCH, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::SWITCH, comp)); } - if ((compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_VENDOR) > 0)) { + if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) { VendorComponent* comp = new VendorComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_VENDOR, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::VENDOR, comp)); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PROPERTY_VENDOR, -1) != -1) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) { auto* component = new PropertyVendorComponent(this); - m_Components.insert_or_assign(COMPONENT_TYPE_PROPERTY_VENDOR, component); + m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_VENDOR, component); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PROPERTY_MANAGEMENT, -1) != -1) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_MANAGEMENT, -1) != -1) { auto* component = new PropertyManagementComponent(this); - m_Components.insert_or_assign(COMPONENT_TYPE_PROPERTY_MANAGEMENT, component); + m_Components.insert_or_assign(eReplicaComponentType::PROPERTY_MANAGEMENT, component); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_BOUNCER, -1) != -1) { // you have to determine it like this because all bouncers have a componentID of 0 + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BOUNCER, -1) != -1) { // you have to determine it like this because all bouncers have a componentID of 0 BouncerComponent* comp = new BouncerComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_BOUNCER, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::BOUNCER, comp)); } - if ((compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_RENDER) > 0 && m_TemplateID != 2365) || m_Character) { + if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER) > 0 && m_TemplateID != 2365) || m_Character) { RenderComponent* render = new RenderComponent(this); - m_Components.insert(std::make_pair(COMPONENT_TYPE_RENDER, render)); + m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render)); } - if ((compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MISSION_OFFER) > 0) || m_Character) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_MISSION_OFFER, new MissionOfferComponent(this, m_TemplateID))); + if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MISSION_OFFER) > 0) || m_Character) { + m_Components.insert(std::make_pair(eReplicaComponentType::MISSION_OFFER, new MissionOfferComponent(this, m_TemplateID))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_BUILD_BORDER, -1) != -1) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_BUILD_BORDER, new BuildBorderComponent(this))); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::BUILD_BORDER, -1) != -1) { + m_Components.insert(std::make_pair(eReplicaComponentType::BUILD_BORDER, new BuildBorderComponent(this))); } // Scripted activity component - int scriptedActivityID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SCRIPTED_ACTIVITY); + int scriptedActivityID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPTED_ACTIVITY); if ((scriptedActivityID > 0)) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_SCRIPTED_ACTIVITY, new ScriptedActivityComponent(this, scriptedActivityID))); + m_Components.insert(std::make_pair(eReplicaComponentType::SCRIPTED_ACTIVITY, new ScriptedActivityComponent(this, scriptedActivityID))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MODEL, -1) != -1 && !GetComponent<PetComponent>()) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_MODEL, new ModelComponent(this))); - if (m_Components.find(COMPONENT_TYPE_DESTROYABLE) == m_Components.end()) { + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MODEL, -1) != -1 && !GetComponent<PetComponent>()) { + m_Components.insert(std::make_pair(eReplicaComponentType::MODEL, new ModelComponent(this))); + if (m_Components.find(eReplicaComponentType::DESTROYABLE) == m_Components.end()) { auto destroyableComponent = new DestroyableComponent(this); destroyableComponent->SetHealth(1); destroyableComponent->SetMaxHealth(1.0f); destroyableComponent->SetFaction(-1, true); destroyableComponent->SetIsSmashable(true); - m_Components.insert(std::make_pair(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)); + m_Components.insert(std::make_pair(eReplicaComponentType::DESTROYABLE, destroyableComponent)); } } PetComponent* petComponent; - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_ITEM) > 0 && !TryGetComponent(COMPONENT_TYPE_PET, petComponent) && !HasComponent(COMPONENT_TYPE_MODEL)) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_ITEM, nullptr)); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ITEM) > 0 && !TryGetComponent(eReplicaComponentType::PET, petComponent) && !HasComponent(eReplicaComponentType::MODEL)) { + m_Components.insert(std::make_pair(eReplicaComponentType::ITEM, nullptr)); } // Shooting gallery component - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_SHOOTING_GALLERY) > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_SHOOTING_GALLERY, new ShootingGalleryComponent(this))); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SHOOTING_GALLERY) > 0) { + m_Components.insert(std::make_pair(eReplicaComponentType::SHOOTING_GALLERY, new ShootingGalleryComponent(this))); } - if (compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PROPERTY, -1) != -1) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_PROPERTY, new PropertyComponent(this))); + if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY, -1) != -1) { + m_Components.insert(std::make_pair(eReplicaComponentType::PROPERTY, new PropertyComponent(this))); } - const int rocketId = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_ROCKET_LAUNCH); + const int rocketId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ROCKET_LAUNCH); if ((rocketId > 0)) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_ROCKET_LAUNCH, new RocketLaunchpadControlComponent(this, rocketId))); + m_Components.insert(std::make_pair(eReplicaComponentType::ROCKET_LAUNCH, new RocketLaunchpadControlComponent(this, rocketId))); } - const int32_t railComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_RAIL_ACTIVATOR); + const int32_t railComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RAIL_ACTIVATOR); if (railComponentID > 0) { - m_Components.insert(std::make_pair(COMPONENT_TYPE_RAIL_ACTIVATOR, new RailActivatorComponent(this, railComponentID))); + m_Components.insert(std::make_pair(eReplicaComponentType::RAIL_ACTIVATOR, new RailActivatorComponent(this, railComponentID))); } - int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_MOVEMENT_AI); + int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI); if (movementAIID > 0) { CDMovementAIComponentTable* moveAITable = CDClientManager::Instance()->GetTable<CDMovementAIComponentTable>("MovementAIComponent"); std::vector<CDMovementAIComponent> moveAIComp = moveAITable->Query([=](CDMovementAIComponent entry) {return (entry.id == movementAIID); }); @@ -659,7 +660,7 @@ void Entity::Initialize() { } } - m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); + m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); } } else if (petComponentId > 0 || combatAiId > 0 && GetComponent<BaseCombatAIComponent>()->GetTetherSpeed() > 0) { MovementAIInfo moveInfo = MovementAIInfo(); @@ -670,7 +671,7 @@ void Entity::Initialize() { moveInfo.wanderDelayMax = 5; moveInfo.wanderDelayMin = 2; - m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); + m_Components.insert(std::make_pair(eReplicaComponentType::MOVEMENT_AI, new MovementAIComponent(this, moveInfo))); } std::string pathName = GetVarAsString(u"attached_path"); @@ -681,7 +682,7 @@ void Entity::Initialize() { // if we have a moving platform path, then we need a moving platform component if (path->pathType == PathType::MovingPlatform) { MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); - m_Components.insert(std::make_pair(COMPONENT_TYPE_MOVING_PLATFORM, plat)); + m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat)); // else if we are a movement path } /*else if (path->pathType == PathType::Movement) { auto movementAIcomp = GetComponent<MovementAIComponent>(); @@ -693,14 +694,14 @@ void Entity::Initialize() { }*/ } - int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, COMPONENT_TYPE_PROXIMITY_MONITOR); + int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR); if (proximityMonitorID > 0) { CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance()->GetTable<CDProximityMonitorComponentTable>("ProximityMonitorComponent"); std::vector<CDProximityMonitorComponent> proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); }); if (proxCompData.size() > 0) { std::vector<std::string> proximityStr = GeneralUtils::SplitString(proxCompData[0].Proximities, ','); ProximityMonitorComponent* comp = new ProximityMonitorComponent(this, std::stoi(proximityStr[0]), std::stoi(proximityStr[1])); - m_Components.insert(std::make_pair(COMPONENT_TYPE_PROXIMITY_MONITOR, comp)); + m_Components.insert(std::make_pair(eReplicaComponentType::PROXIMITY_MONITOR, comp)); } } @@ -713,7 +714,7 @@ void Entity::Initialize() { if (!m_Character && EntityManager::Instance()->GetGhostingEnabled()) { // Don't ghost what is likely large scene elements - if (m_Components.size() == 2 && HasComponent(COMPONENT_TYPE_SIMPLE_PHYSICS) && HasComponent(COMPONENT_TYPE_RENDER)) { + if (m_Components.size() == 2 && HasComponent(eReplicaComponentType::SIMPLE_PHYSICS) && HasComponent(eReplicaComponentType::RENDER)) { goto no_ghosting; } @@ -725,14 +726,14 @@ void Entity::Initialize() { */ if ( !EntityManager::IsExcludedFromGhosting(GetLOT()) && - !HasComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY) && - !HasComponent(COMPONENT_TYPE_MOVING_PLATFORM) && - !HasComponent(COMPONENT_TYPE_PHANTOM_PHYSICS) && - !HasComponent(COMPONENT_TYPE_PROPERTY) && - !HasComponent(COMPONENT_TYPE_RACING_CONTROL) && - !HasComponent(COMPONENT_TYPE_VEHICLE_PHYSICS) + !HasComponent(eReplicaComponentType::SCRIPTED_ACTIVITY) && + !HasComponent(eReplicaComponentType::MOVING_PLATFORM) && + !HasComponent(eReplicaComponentType::PHANTOM_PHYSICS) && + !HasComponent(eReplicaComponentType::PROPERTY) && + !HasComponent(eReplicaComponentType::RACING_CONTROL) && + !HasComponent(eReplicaComponentType::VEHICLE_PHYSICS) ) - //if (HasComponent(COMPONENT_TYPE_BASE_COMBAT_AI)) + //if (HasComponent(eReplicaComponentType::BASE_COMBAT_AI)) { m_IsGhostingCandidate = true; } @@ -742,7 +743,7 @@ void Entity::Initialize() { } // Special case for collectibles in Ninjago - if (HasComponent(COMPONENT_TYPE_COLLECTIBLE) && Game::server->GetZoneID() == 2000) { + if (HasComponent(eReplicaComponentType::COLLECTIBLE) && Game::server->GetZoneID() == 2000) { m_IsGhostingCandidate = true; } } @@ -777,7 +778,7 @@ User* Entity::GetParentUser() const { return static_cast<const Player*>(this)->GetParentUser(); } -Component* Entity::GetComponent(int32_t componentID) const { +Component* Entity::GetComponent(eReplicaComponentType componentID) const { const auto& index = m_Components.find(componentID); if (index == m_Components.end()) { @@ -787,11 +788,11 @@ Component* Entity::GetComponent(int32_t componentID) const { return index->second; } -bool Entity::HasComponent(const int32_t componentId) const { +bool Entity::HasComponent(const eReplicaComponentType componentId) const { return m_Components.find(componentId) != m_Components.end(); } -void Entity::AddComponent(const int32_t componentId, Component* component) { +void Entity::AddComponent(const eReplicaComponentType componentId, Component* component) { if (HasComponent(componentId)) { return; } @@ -801,8 +802,8 @@ void Entity::AddComponent(const int32_t componentId, Component* component) { std::vector<ScriptComponent*> Entity::GetScriptComponents() { std::vector<ScriptComponent*> comps; - for (std::pair<int32_t, void*> p : m_Components) { - if (p.first == COMPONENT_TYPE_SCRIPT) { + for (std::pair<eReplicaComponentType, void*> p : m_Components) { + if (p.first == eReplicaComponentType::SCRIPT) { comps.push_back(static_cast<ScriptComponent*>(p.second)); } } @@ -830,7 +831,7 @@ void Entity::SetProximityRadius(float proxRadius, std::string name) { ProximityMonitorComponent* proxMon = GetComponent<ProximityMonitorComponent>(); if (!proxMon) { proxMon = new ProximityMonitorComponent(this); - m_Components.insert_or_assign(COMPONENT_TYPE_PROXIMITY_MONITOR, proxMon); + m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon); } proxMon->SetProximityRadius(proxRadius, name); } @@ -839,7 +840,7 @@ void Entity::SetProximityRadius(dpEntity* entity, std::string name) { ProximityMonitorComponent* proxMon = GetComponent<ProximityMonitorComponent>(); if (!proxMon) { proxMon = new ProximityMonitorComponent(this); - m_Components.insert_or_assign(COMPONENT_TYPE_PROXIMITY_MONITOR, proxMon); + m_Components.insert_or_assign(eReplicaComponentType::PROXIMITY_MONITOR, proxMon); } proxMon->SetProximityRadius(entity, name); } @@ -927,7 +928,7 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke } TriggerComponent* triggerComponent; - if (TryGetComponent(COMPONENT_TYPE_TRIGGER, triggerComponent)) { + if (TryGetComponent(eReplicaComponentType::TRIGGER, triggerComponent)) { // has trigger component, check to see if we have events to handle auto* trigger = triggerComponent->GetTrigger(); outBitStream->Write<bool>(trigger && trigger->events.size() > 0); @@ -993,59 +994,59 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType unsigned int flags = 0; PossessableComponent* possessableComponent; - if (TryGetComponent(COMPONENT_TYPE_POSSESSABLE, possessableComponent)) { + if (TryGetComponent(eReplicaComponentType::POSSESSABLE, possessableComponent)) { possessableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } ModuleAssemblyComponent* moduleAssemblyComponent; - if (TryGetComponent(COMPONENT_TYPE_MODULE_ASSEMBLY, moduleAssemblyComponent)) { + if (TryGetComponent(eReplicaComponentType::MODULE_ASSEMBLY, moduleAssemblyComponent)) { moduleAssemblyComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } ControllablePhysicsComponent* controllablePhysicsComponent; - if (TryGetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS, controllablePhysicsComponent)) { + if (TryGetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS, controllablePhysicsComponent)) { controllablePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } SimplePhysicsComponent* simplePhysicsComponent; - if (TryGetComponent(COMPONENT_TYPE_SIMPLE_PHYSICS, simplePhysicsComponent)) { + if (TryGetComponent(eReplicaComponentType::SIMPLE_PHYSICS, simplePhysicsComponent)) { simplePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } RigidbodyPhantomPhysicsComponent* rigidbodyPhantomPhysics; - if (TryGetComponent(COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS, rigidbodyPhantomPhysics)) { + if (TryGetComponent(eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS, rigidbodyPhantomPhysics)) { rigidbodyPhantomPhysics->Serialize(outBitStream, bIsInitialUpdate, flags); } VehiclePhysicsComponent* vehiclePhysicsComponent; - if (TryGetComponent(COMPONENT_TYPE_VEHICLE_PHYSICS, vehiclePhysicsComponent)) { + if (TryGetComponent(eReplicaComponentType::VEHICLE_PHYSICS, vehiclePhysicsComponent)) { vehiclePhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } PhantomPhysicsComponent* phantomPhysicsComponent; - if (TryGetComponent(COMPONENT_TYPE_PHANTOM_PHYSICS, phantomPhysicsComponent)) { + if (TryGetComponent(eReplicaComponentType::PHANTOM_PHYSICS, phantomPhysicsComponent)) { phantomPhysicsComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } SoundTriggerComponent* soundTriggerComponent; - if (TryGetComponent(COMPONENT_TYPE_SOUND_TRIGGER, soundTriggerComponent)) { + if (TryGetComponent(eReplicaComponentType::SOUND_TRIGGER, soundTriggerComponent)) { soundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } BuffComponent* buffComponent; - if (TryGetComponent(COMPONENT_TYPE_BUFF, buffComponent)) { + if (TryGetComponent(eReplicaComponentType::BUFF, buffComponent)) { buffComponent->Serialize(outBitStream, bIsInitialUpdate, flags); DestroyableComponent* destroyableComponent; - if (TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)) { + if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent)) { destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } destroyableSerialized = true; } - if (HasComponent(COMPONENT_TYPE_COLLECTIBLE)) { + if (HasComponent(eReplicaComponentType::COLLECTIBLE)) { DestroyableComponent* destroyableComponent; - if (TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent) && !destroyableSerialized) { + if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } destroyableSerialized = true; @@ -1053,15 +1054,15 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType } PetComponent* petComponent; - if (TryGetComponent(COMPONENT_TYPE_PET, petComponent)) { + if (TryGetComponent(eReplicaComponentType::PET, petComponent)) { petComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } CharacterComponent* characterComponent; - if (TryGetComponent(COMPONENT_TYPE_CHARACTER, characterComponent)) { + if (TryGetComponent(eReplicaComponentType::CHARACTER, characterComponent)) { PossessorComponent* possessorComponent; - if (TryGetComponent(COMPONENT_TYPE_POSSESSOR, possessorComponent)) { + if (TryGetComponent(eReplicaComponentType::POSSESSOR, possessorComponent)) { possessorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } else { // Should never happen, but just to be safe @@ -1069,7 +1070,7 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType } LevelProgressionComponent* levelProgressionComponent; - if (TryGetComponent(COMPONENT_TYPE_LEVEL_PROGRESSION, levelProgressionComponent)) { + if (TryGetComponent(eReplicaComponentType::LEVEL_PROGRESSION, levelProgressionComponent)) { levelProgressionComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } else { // Should never happen, but just to be safe @@ -1077,7 +1078,7 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType } PlayerForcedMovementComponent* playerForcedMovementComponent; - if (TryGetComponent(COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT, playerForcedMovementComponent)) { + if (TryGetComponent(eReplicaComponentType::PLAYER_FORCED_MOVEMENT, playerForcedMovementComponent)) { playerForcedMovementComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } else { // Should never happen, but just to be safe @@ -1087,34 +1088,34 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType characterComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } - if (HasComponent(COMPONENT_TYPE_ITEM)) { + if (HasComponent(eReplicaComponentType::ITEM)) { outBitStream->Write0(); } InventoryComponent* inventoryComponent; - if (TryGetComponent(COMPONENT_TYPE_INVENTORY, inventoryComponent)) { + if (TryGetComponent(eReplicaComponentType::INVENTORY, inventoryComponent)) { inventoryComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } ScriptComponent* scriptComponent; - if (TryGetComponent(COMPONENT_TYPE_SCRIPT, scriptComponent)) { + if (TryGetComponent(eReplicaComponentType::SCRIPT, scriptComponent)) { scriptComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } SkillComponent* skillComponent; - if (TryGetComponent(COMPONENT_TYPE_SKILL, skillComponent)) { + if (TryGetComponent(eReplicaComponentType::SKILL, skillComponent)) { skillComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } BaseCombatAIComponent* baseCombatAiComponent; - if (TryGetComponent(COMPONENT_TYPE_BASE_COMBAT_AI, baseCombatAiComponent)) { + if (TryGetComponent(eReplicaComponentType::BASE_COMBAT_AI, baseCombatAiComponent)) { baseCombatAiComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } RebuildComponent* rebuildComponent; - if (TryGetComponent(COMPONENT_TYPE_REBUILD, rebuildComponent)) { + if (TryGetComponent(eReplicaComponentType::QUICK_BUILD, rebuildComponent)) { DestroyableComponent* destroyableComponent; - if (TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent) && !destroyableSerialized) { + if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } destroyableSerialized = true; @@ -1122,64 +1123,64 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType } MovingPlatformComponent* movingPlatformComponent; - if (TryGetComponent(COMPONENT_TYPE_MOVING_PLATFORM, movingPlatformComponent)) { + if (TryGetComponent(eReplicaComponentType::MOVING_PLATFORM, movingPlatformComponent)) { movingPlatformComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } SwitchComponent* switchComponent; - if (TryGetComponent(COMPONENT_TYPE_SWITCH, switchComponent)) { + if (TryGetComponent(eReplicaComponentType::SWITCH, switchComponent)) { switchComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } VendorComponent* vendorComponent; - if (TryGetComponent(COMPONENT_TYPE_VENDOR, vendorComponent)) { + if (TryGetComponent(eReplicaComponentType::VENDOR, vendorComponent)) { vendorComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } BouncerComponent* bouncerComponent; - if (TryGetComponent(COMPONENT_TYPE_BOUNCER, bouncerComponent)) { + if (TryGetComponent(eReplicaComponentType::BOUNCER, bouncerComponent)) { bouncerComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } ScriptedActivityComponent* scriptedActivityComponent; - if (TryGetComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY, scriptedActivityComponent)) { + if (TryGetComponent(eReplicaComponentType::SCRIPTED_ACTIVITY, scriptedActivityComponent)) { scriptedActivityComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } ShootingGalleryComponent* shootingGalleryComponent; - if (TryGetComponent(COMPONENT_TYPE_SHOOTING_GALLERY, shootingGalleryComponent)) { + if (TryGetComponent(eReplicaComponentType::SHOOTING_GALLERY, shootingGalleryComponent)) { shootingGalleryComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } RacingControlComponent* racingControlComponent; - if (TryGetComponent(COMPONENT_TYPE_RACING_CONTROL, racingControlComponent)) { + if (TryGetComponent(eReplicaComponentType::RACING_CONTROL, racingControlComponent)) { racingControlComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } LUPExhibitComponent* lupExhibitComponent; - if (TryGetComponent(COMPONENT_TYPE_EXHIBIT, lupExhibitComponent)) { + if (TryGetComponent(eReplicaComponentType::LUP_EXHIBIT, lupExhibitComponent)) { lupExhibitComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } ModelComponent* modelComponent; - if (TryGetComponent(COMPONENT_TYPE_MODEL, modelComponent)) { + if (TryGetComponent(eReplicaComponentType::MODEL, modelComponent)) { modelComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } RenderComponent* renderComponent; - if (TryGetComponent(COMPONENT_TYPE_RENDER, renderComponent)) { + if (TryGetComponent(eReplicaComponentType::RENDER, renderComponent)) { renderComponent->Serialize(outBitStream, bIsInitialUpdate, flags); } if (modelComponent) { DestroyableComponent* destroyableComponent; - if (TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent) && !destroyableSerialized) { + if (TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent) && !destroyableSerialized) { destroyableComponent->Serialize(outBitStream, bIsInitialUpdate, flags); destroyableSerialized = true; } } - if (HasComponent(COMPONENT_TYPE_ZONE_CONTROL)) { + if (HasComponent(eReplicaComponentType::ZONE_CONTROL)) { outBitStream->Write<uint32_t>(0x40000000); } diff --git a/dGame/Entity.h b/dGame/Entity.h index 0bde01e2..ae16fb82 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -31,6 +31,7 @@ class Item; class Character; class EntityCallbackTimer; enum class eTriggerEventType; +enum class eReplicaComponentType : uint32_t; namespace CppScripts { class Script; @@ -131,17 +132,17 @@ public: * Component management */ - Component* GetComponent(int32_t componentID) const; + Component* GetComponent(eReplicaComponentType componentID) const; template<typename T> T* GetComponent() const; template<typename T> - bool TryGetComponent(int32_t componentId, T*& component) const; + bool TryGetComponent(eReplicaComponentType componentId, T*& component) const; - bool HasComponent(int32_t componentId) const; + bool HasComponent(eReplicaComponentType componentId) const; - void AddComponent(int32_t componentId, Component* component); + void AddComponent(eReplicaComponentType componentId, Component* component); std::vector<ScriptComponent*> GetScriptComponents(); @@ -164,7 +165,7 @@ public: void AddToGroup(const std::string& group); bool IsPlayer() const; - std::unordered_map<int32_t, Component*>& GetComponents() { return m_Components; } // TODO: Remove + std::unordered_map<eReplicaComponentType, Component*>& GetComponents() { return m_Components; } // TODO: Remove void WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacketType packetType); void WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType packetType); @@ -314,7 +315,7 @@ protected: std::vector<std::function<void()>> m_DieCallbacks; std::vector<std::function<void(Entity* target)>> m_PhantomCollisionCallbacks; - std::unordered_map<int32_t, Component*> m_Components; //The int is the ID of the component + std::unordered_map<eReplicaComponentType, Component*> m_Components; std::vector<EntityTimer*> m_Timers; std::vector<EntityTimer*> m_PendingTimers; std::vector<EntityCallbackTimer*> m_CallbackTimers; @@ -344,7 +345,7 @@ protected: */ template<typename T> -bool Entity::TryGetComponent(const int32_t componentId, T*& component) const { +bool Entity::TryGetComponent(const eReplicaComponentType componentId, T*& component) const { const auto& index = m_Components.find(componentId); if (index == m_Components.end()) { diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index dae27af6..e79ada25 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -20,6 +20,7 @@ #include "MessageIdentifiers.h" #include "dConfig.h" #include "eTriggerEventType.h" +#include "eReplicaComponentType.h" EntityManager* EntityManager::m_Address = nullptr; @@ -268,10 +269,10 @@ std::vector<Entity*> EntityManager::GetEntitiesInGroup(const std::string& group) return entitiesInGroup; } -std::vector<Entity*> EntityManager::GetEntitiesByComponent(const int componentType) const { +std::vector<Entity*> EntityManager::GetEntitiesByComponent(const eReplicaComponentType componentType) const { std::vector<Entity*> withComp; for (const auto& entity : m_Entities) { - if (componentType != -1 && !entity.second->HasComponent(componentType)) continue; + if (componentType != eReplicaComponentType::INVALID && !entity.second->HasComponent(componentType)) continue; withComp.push_back(entity.second); } diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 8a930de3..0314cc09 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -11,6 +11,7 @@ class Entity; class EntityInfo; class Player; class User; +enum class eReplicaComponentType : uint32_t; struct SystemAddress; @@ -35,7 +36,7 @@ public: void DestroyEntity(Entity* entity); Entity* GetEntity(const LWOOBJID& objectId) const; std::vector<Entity*> GetEntitiesInGroup(const std::string& group); - std::vector<Entity*> GetEntitiesByComponent(int componentType) const; + std::vector<Entity*> GetEntitiesByComponent(eReplicaComponentType componentType) const; std::vector<Entity*> GetEntitiesByLOT(const LOT& lot) const; Entity* GetZoneControlEntity() const; diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 4f4bc951..2e194e6a 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -16,6 +16,7 @@ #include "User.h" #include "CppScripts.h" #include "Loot.h" +#include "eReplicaComponentType.h" std::vector<Player*> Player::m_Players = {}; @@ -223,7 +224,7 @@ Player* Player::GetPlayer(const SystemAddress& sysAddr) { } Player* Player::GetPlayer(const std::string& name) { - const auto characters = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_CHARACTER); + const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); for (auto* character : characters) { if (!character->IsPlayer()) continue; @@ -289,7 +290,7 @@ Player::~Player() { script->OnPlayerExit(zoneControl, this); } - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY); + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index 26d1e9e6..397e0c72 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -15,6 +15,7 @@ #include "EchoSyncSkill.h" #include "PhantomPhysicsComponent.h" #include "RebuildComponent.h" +#include "eReplicaComponentType.h" BehaviorSyncEntry::BehaviorSyncEntry() { } @@ -311,13 +312,13 @@ std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, in } } - if (ignoreFaction || includeFaction || (!entity->HasComponent(COMPONENT_TYPE_PHANTOM_PHYSICS) && targets.empty())) { + if (ignoreFaction || includeFaction || (!entity->HasComponent(eReplicaComponentType::PHANTOM_PHYSICS) && targets.empty())) { DestroyableComponent* destroyableComponent; - if (!entity->TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)) { + if (!entity->TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent)) { return targets; } - auto entities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS); + auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS); for (auto* candidate : entities) { const auto id = candidate->GetObjectID(); diff --git a/dGame/dBehaviors/HealBehavior.cpp b/dGame/dBehaviors/HealBehavior.cpp index 2799d2e2..66fe2c79 100644 --- a/dGame/dBehaviors/HealBehavior.cpp +++ b/dGame/dBehaviors/HealBehavior.cpp @@ -4,6 +4,7 @@ #include "dLogger.h" #include "EntityManager.h" #include "DestroyableComponent.h" +#include "eReplicaComponentType.h" void HealBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { @@ -15,7 +16,7 @@ void HealBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_strea return; } - auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (destroyable == nullptr) { Game::logger->Log("HealBehavior", "Failed to find destroyable component for %(llu)!", branch.target); diff --git a/dGame/dBehaviors/RepairBehavior.cpp b/dGame/dBehaviors/RepairBehavior.cpp index a48141d3..ce2e5fd2 100644 --- a/dGame/dBehaviors/RepairBehavior.cpp +++ b/dGame/dBehaviors/RepairBehavior.cpp @@ -5,6 +5,7 @@ #include "EntityManager.h" #include "dLogger.h" #include "Game.h" +#include "eReplicaComponentType.h" void RepairBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { auto* entity = EntityManager::Instance()->GetEntity(branch.target); @@ -15,7 +16,7 @@ void RepairBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_str return; } - auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (destroyable == nullptr) { Game::logger->Log("RepairBehavior", "Failed to find destroyable component for %(llu)!", branch.target); diff --git a/dGame/dBehaviors/SpawnBehavior.cpp b/dGame/dBehaviors/SpawnBehavior.cpp index 8b2020b1..75c84f6c 100644 --- a/dGame/dBehaviors/SpawnBehavior.cpp +++ b/dGame/dBehaviors/SpawnBehavior.cpp @@ -9,6 +9,7 @@ #include "RebuildComponent.h" #include "Entity.h" #include "EntityInfo.h" +#include "eReplicaComponentType.h" void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { auto* origin = EntityManager::Instance()->GetEntity(context->originator); @@ -86,7 +87,7 @@ void SpawnBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext return; } - auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + auto* destroyable = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (destroyable == nullptr) { entity->Smash(context->originator); diff --git a/dGame/dBehaviors/StunBehavior.cpp b/dGame/dBehaviors/StunBehavior.cpp index 065b7220..4e34d3a2 100644 --- a/dGame/dBehaviors/StunBehavior.cpp +++ b/dGame/dBehaviors/StunBehavior.cpp @@ -7,6 +7,7 @@ #include "Game.h" #include "dLogger.h" #include "DestroyableComponent.h" +#include "eReplicaComponentType.h" void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { @@ -32,7 +33,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream * If our target is an enemy we can go ahead and stun it. */ - auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI)); + auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(eReplicaComponentType::BASE_COMBAT_AI)); if (combatAiComponent == nullptr) { return; @@ -55,7 +56,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr * See if we can stun ourselves */ - auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(self->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI)); + auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(self->GetComponent(eReplicaComponentType::BASE_COMBAT_AI)); if (combatAiComponent == nullptr) { return; @@ -90,7 +91,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr * If our target is an enemy we can go ahead and stun it. */ - auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI)); + auto* combatAiComponent = static_cast<BaseCombatAIComponent*>(target->GetComponent(eReplicaComponentType::BASE_COMBAT_AI)); if (combatAiComponent == nullptr) { return; diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 8e778d1d..a5255b07 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -106,7 +106,7 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): int32_t collisionGroup = (COLLISION_GROUP_DYNAMIC | COLLISION_GROUP_ENEMY); CDComponentsRegistryTable* componentRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - auto componentID = componentRegistryTable->GetByIDAndType(parent->GetLOT(), COMPONENT_TYPE_CONTROLLABLE_PHYSICS); + auto componentID = componentRegistryTable->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::CONTROLLABLE_PHYSICS); CDPhysicsComponentTable* physicsComponentTable = CDClientManager::Instance()->GetTable<CDPhysicsComponentTable>("PhysicsComponent"); diff --git a/dGame/dComponents/BaseCombatAIComponent.h b/dGame/dComponents/BaseCombatAIComponent.h index 6e55a4b1..8bf6140a 100644 --- a/dGame/dComponents/BaseCombatAIComponent.h +++ b/dGame/dComponents/BaseCombatAIComponent.h @@ -8,6 +8,7 @@ #include "dpWorld.h" #include "dpEntity.h" #include "Component.h" +#include "eReplicaComponentType.h" #include <vector> #include <map> @@ -46,7 +47,7 @@ struct AiSkillEntry */ class BaseCombatAIComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_BASE_COMBAT_AI; + static const eReplicaComponentType ComponentType = eReplicaComponentType::BASE_COMBAT_AI; BaseCombatAIComponent(Entity* parentEntity, uint32_t id); ~BaseCombatAIComponent() override; @@ -245,7 +246,7 @@ private: /** * @brief Sets the AiState and prepares the entity for serialization next frame. - * + * */ void SetAiState(AiState newState); @@ -377,7 +378,7 @@ private: /** * Whether or not the Component has dirty information and should update next frame - * + * */ bool m_DirtyStateOrTarget = false; diff --git a/dGame/dComponents/BouncerComponent.h b/dGame/dComponents/BouncerComponent.h index f179998b..15665cc1 100644 --- a/dGame/dComponents/BouncerComponent.h +++ b/dGame/dComponents/BouncerComponent.h @@ -5,13 +5,14 @@ #include "RakNetTypes.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Attached to bouncer entities, allowing other entities to bounce off of it */ class BouncerComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_BOUNCER; + static const eReplicaComponentType ComponentType = eReplicaComponentType::BOUNCER; BouncerComponent(Entity* parentEntity); ~BouncerComponent() override; diff --git a/dGame/dComponents/BuffComponent.h b/dGame/dComponents/BuffComponent.h index 7f7c6b0f..d9175883 100644 --- a/dGame/dComponents/BuffComponent.h +++ b/dGame/dComponents/BuffComponent.h @@ -7,6 +7,7 @@ #include <unordered_map> #include <map> #include "Component.h" +#include "eReplicaComponentType.h" class Entity; @@ -41,7 +42,7 @@ struct Buff */ class BuffComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_BUFF; + static const eReplicaComponentType ComponentType = eReplicaComponentType::BUFF; explicit BuffComponent(Entity* parent); diff --git a/dGame/dComponents/BuildBorderComponent.h b/dGame/dComponents/BuildBorderComponent.h index ba677e37..dc5afc8a 100644 --- a/dGame/dComponents/BuildBorderComponent.h +++ b/dGame/dComponents/BuildBorderComponent.h @@ -9,13 +9,14 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Component for the build border, allowing the user to start building when interacting with it */ class BuildBorderComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_BUILD_BORDER; + static const eReplicaComponentType ComponentType = eReplicaComponentType::BUILD_BORDER; BuildBorderComponent(Entity* parent); ~BuildBorderComponent() override; diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index 196dfa01..613f2322 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -9,6 +9,7 @@ #include <string> #include "CDMissionsTable.h" #include "tinyxml2.h" +#include "eReplicaComponentType.h" /** * The statistics that can be achieved per zone @@ -59,7 +60,7 @@ enum StatisticID { */ class CharacterComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_CHARACTER; + static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER; CharacterComponent(Entity* parent, Character* character); ~CharacterComponent() override; diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index a05a11fd..a7359a26 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -10,6 +10,7 @@ #include "dpCollisionChecks.h" #include "PhantomPhysicsComponent.h" #include "eBubbleType.h" +#include "eReplicaComponentType.h" class Entity; class dpEntity; @@ -19,7 +20,7 @@ class dpEntity; */ class ControllablePhysicsComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_CONTROLLABLE_PHYSICS; + static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS; ControllablePhysicsComponent(Entity* entity); ~ControllablePhysicsComponent() override; diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 4763c863..51d68a12 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -76,9 +76,9 @@ DestroyableComponent::~DestroyableComponent() { void DestroyableComponent::Reinitialize(LOT templateID) { CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - int32_t buffComponentID = compRegistryTable->GetByIDAndType(templateID, COMPONENT_TYPE_BUFF); - int32_t collectibleComponentID = compRegistryTable->GetByIDAndType(templateID, COMPONENT_TYPE_COLLECTIBLE); - int32_t rebuildComponentID = compRegistryTable->GetByIDAndType(templateID, COMPONENT_TYPE_REBUILD); + int32_t buffComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::BUFF); + int32_t collectibleComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::COLLECTIBLE); + int32_t rebuildComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::QUICK_BUILD); int32_t componentID = 0; if (collectibleComponentID > 0) componentID = collectibleComponentID; @@ -810,7 +810,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType script->OnPlayerDied(zoneControl, m_Parent); } - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY); + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 854144d9..47be96a0 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -6,6 +6,7 @@ #include "tinyxml2.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" namespace CppScripts { class Script; @@ -17,7 +18,7 @@ namespace CppScripts { */ class DestroyableComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_DESTROYABLE; + static const eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE; DestroyableComponent(Entity* parentEntity); ~DestroyableComponent() override; diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 8925554e..df292e2a 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -48,7 +48,7 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do } auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - const auto componentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_INVENTORY); + const auto componentId = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::INVENTORY); auto* inventoryComponentTable = CDClientManager::Instance()->GetTable<CDInventoryComponentTable>("InventoryComponent"); auto items = inventoryComponentTable->Query([=](const CDInventoryComponent entry) { return entry.id == componentId; }); @@ -181,7 +181,7 @@ void InventoryComponent::AddItem( inventoryType = Inventory::FindInventoryTypeForLot(lot); } - auto* missions = static_cast<MissionComponent*>(this->m_Parent->GetComponent(COMPONENT_TYPE_MISSION)); + auto* missions = static_cast<MissionComponent*>(this->m_Parent->GetComponent(eReplicaComponentType::MISSION)); auto* inventory = GetInventory(inventoryType); @@ -818,7 +818,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { if (character != nullptr && !skipChecks) { // Hacky proximity rocket if (item->GetLot() == 6416) { - const auto rocketLauchPads = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_ROCKET_LAUNCH); + const auto rocketLauchPads = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::ROCKET_LAUNCH); const auto position = m_Parent->GetPosition(); @@ -914,7 +914,7 @@ void InventoryComponent::UnEquipItem(Item* item) { void InventoryComponent::EquipScripts(Item* equippedItem) { CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); if (!compRegistryTable) return; - int32_t scriptComponentID = compRegistryTable->GetByIDAndType(equippedItem->GetLot(), COMPONENT_TYPE_SCRIPT, -1); + int32_t scriptComponentID = compRegistryTable->GetByIDAndType(equippedItem->GetLot(), eReplicaComponentType::SCRIPT, -1); if (scriptComponentID > -1) { CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent"); CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID); @@ -929,7 +929,7 @@ void InventoryComponent::EquipScripts(Item* equippedItem) { void InventoryComponent::UnequipScripts(Item* unequippedItem) { CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); if (!compRegistryTable) return; - int32_t scriptComponentID = compRegistryTable->GetByIDAndType(unequippedItem->GetLot(), COMPONENT_TYPE_SCRIPT, -1); + int32_t scriptComponentID = compRegistryTable->GetByIDAndType(unequippedItem->GetLot(), eReplicaComponentType::SCRIPT, -1); if (scriptComponentID > -1) { CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent"); CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID); @@ -1331,7 +1331,7 @@ std::vector<uint32_t> InventoryComponent::FindBuffs(Item* item, bool castOnEquip return entry.objectTemplate == static_cast<unsigned int>(item->GetLot()); }); - auto* missions = static_cast<MissionComponent*>(m_Parent->GetComponent(COMPONENT_TYPE_MISSION)); + auto* missions = static_cast<MissionComponent*>(m_Parent->GetComponent(eReplicaComponentType::MISSION)); for (const auto& result : results) { if (result.castOnType == 1) { diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index b660de15..d695737c 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -20,6 +20,7 @@ #include "eItemSetPassiveAbilityID.h" #include "PossessorComponent.h" #include "eInventoryType.h" +#include "eReplicaComponentType.h" class Entity; class ItemSet; @@ -36,7 +37,7 @@ enum class eItemType : int32_t; class InventoryComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_INVENTORY; + static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY; explicit InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document = nullptr); void Update(float deltaTime) override; diff --git a/dGame/dComponents/LUPExhibitComponent.h b/dGame/dComponents/LUPExhibitComponent.h index 2d128f6c..587d1b2f 100644 --- a/dGame/dComponents/LUPExhibitComponent.h +++ b/dGame/dComponents/LUPExhibitComponent.h @@ -2,6 +2,7 @@ #include "Component.h" #include "Entity.h" +#include "eReplicaComponentType.h" /** * Component that handles the LOT that is shown in the LUP exhibit in the LUP world. Works by setting a timer and @@ -10,7 +11,7 @@ class LUPExhibitComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_EXHIBIT; + static const eReplicaComponentType ComponentType = eReplicaComponentType::EXHIBIT; LUPExhibitComponent(Entity* parent); ~LUPExhibitComponent(); diff --git a/dGame/dComponents/LevelProgressionComponent.h b/dGame/dComponents/LevelProgressionComponent.h index dd3fbfbb..06908a81 100644 --- a/dGame/dComponents/LevelProgressionComponent.h +++ b/dGame/dComponents/LevelProgressionComponent.h @@ -4,6 +4,7 @@ #include "GameMessages.h" #include "Component.h" #include "eCharacterVersion.h" +#include "eReplicaComponentType.h" /** * Component that handles level progression and serilization. @@ -12,7 +13,7 @@ class LevelProgressionComponent : public Component { public: - static const uint32_t ComponentType = eReplicaComponentType::COMPONENT_TYPE_LEVEL_PROGRESSION; + static const eReplicaComponentType ComponentType = eReplicaComponentType::LEVEL_PROGRESSION; /** * Constructor for this component diff --git a/dGame/dComponents/MissionComponent.h b/dGame/dComponents/MissionComponent.h index 231b3321..eeaaa726 100644 --- a/dGame/dComponents/MissionComponent.h +++ b/dGame/dComponents/MissionComponent.h @@ -16,6 +16,7 @@ #include "CDClientManager.h" #include "CDMissionsTable.h" #include "Component.h" +#include "eReplicaComponentType.h" class AchievementCacheKey; @@ -26,7 +27,7 @@ class AchievementCacheKey; class MissionComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_MISSION; + static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION; explicit MissionComponent(Entity* parent); ~MissionComponent() override; diff --git a/dGame/dComponents/MissionOfferComponent.cpp b/dGame/dComponents/MissionOfferComponent.cpp index f8446868..ad315314 100644 --- a/dGame/dComponents/MissionOfferComponent.cpp +++ b/dGame/dComponents/MissionOfferComponent.cpp @@ -40,7 +40,7 @@ bool OfferedMission::GetAcceptMission() const { MissionOfferComponent::MissionOfferComponent(Entity* parent, const LOT parentLot) : Component(parent) { auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - auto value = compRegistryTable->GetByIDAndType(parentLot, COMPONENT_TYPE_MISSION_OFFER, -1); + auto value = compRegistryTable->GetByIDAndType(parentLot, eReplicaComponentType::MISSION_OFFER, -1); if (value != -1) { const uint32_t componentId = value; @@ -77,7 +77,7 @@ void MissionOfferComponent::OnUse(Entity* originator) { void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifiedMissionId) { // First, get the entity's MissionComponent. If there is not one, then we cannot offer missions to this entity. - auto* missionComponent = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); + auto* missionComponent = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); if (!missionComponent) { Game::logger->Log("MissionOfferComponent", "Unable to get mission component for Entity %llu", entity->GetObjectID()); diff --git a/dGame/dComponents/MissionOfferComponent.h b/dGame/dComponents/MissionOfferComponent.h index 42aad3c4..6e22ca05 100644 --- a/dGame/dComponents/MissionOfferComponent.h +++ b/dGame/dComponents/MissionOfferComponent.h @@ -10,6 +10,7 @@ #include "Component.h" #include <vector> #include <stdint.h> +#include "eReplicaComponentType.h" class Entity; @@ -60,7 +61,7 @@ private: */ class MissionOfferComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_MISSION_OFFER; + static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER; MissionOfferComponent(Entity* parent, LOT parentLot); ~MissionOfferComponent() override; diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 8fa085f2..74f614d1 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -10,7 +10,7 @@ ModelComponent::ModelComponent(Entity* parent) : Component(parent) { void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { // ItemComponent Serialization. Pets do not get this serialization. - if (!m_Parent->HasComponent(COMPONENT_TYPE_PET)) { + if (!m_Parent->HasComponent(eReplicaComponentType::PET)) { outBitStream->Write1(); outBitStream->Write<LWOOBJID>(m_userModelID != LWOOBJID_EMPTY ? m_userModelID : m_Parent->GetObjectID()); outBitStream->Write<int>(0); diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 81342059..b5224869 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -4,6 +4,7 @@ #include "NiPoint3.h" #include "NiQuaternion.h" #include "Component.h" +#include "eReplicaComponentType.h" class Entity; @@ -12,7 +13,7 @@ class Entity; */ class ModelComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_MODEL; + static const eReplicaComponentType ComponentType = eReplicaComponentType::MODEL; ModelComponent(Entity* parent); diff --git a/dGame/dComponents/ModuleAssemblyComponent.h b/dGame/dComponents/ModuleAssemblyComponent.h index 24e1c1ee..c6e217ed 100644 --- a/dGame/dComponents/ModuleAssemblyComponent.h +++ b/dGame/dComponents/ModuleAssemblyComponent.h @@ -3,6 +3,7 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Component that belongs to an object that may be modularly built, like cars and rockets. Note that this is not the @@ -11,7 +12,7 @@ */ class ModuleAssemblyComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_MODULE_ASSEMBLY; + static const eReplicaComponentType ComponentType = eReplicaComponentType::MODULE_ASSEMBLY; ModuleAssemblyComponent(Entity* MSG_CHAT_INTERNAL_PLAYER_REMOVED_NOTIFICATION); ~ModuleAssemblyComponent() override; diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 92397a55..fa54eb6d 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -19,7 +19,7 @@ MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : m_BaseCombatAI = nullptr; - m_BaseCombatAI = reinterpret_cast<BaseCombatAIComponent*>(m_Parent->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI)); + m_BaseCombatAI = reinterpret_cast<BaseCombatAIComponent*>(m_Parent->GetComponent(eReplicaComponentType::BASE_COMBAT_AI)); //Try and fix the insane values: if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius = m_Info.wanderRadius * 0.5f; @@ -286,7 +286,7 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) { int32_t componentID; CDPhysicsComponent* physicsComponent = nullptr; - componentID = componentRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_CONTROLLABLE_PHYSICS, -1); + componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::CONTROLLABLE_PHYSICS, -1); if (componentID != -1) { physicsComponent = physicsComponentTable->GetByID(componentID); @@ -294,7 +294,7 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) { goto foundComponent; } - componentID = componentRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_SIMPLE_PHYSICS, -1); + componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1); if (componentID != -1) { physicsComponent = physicsComponentTable->GetByID(componentID); diff --git a/dGame/dComponents/MovementAIComponent.h b/dGame/dComponents/MovementAIComponent.h index 82cd48a0..3c9044aa 100644 --- a/dGame/dComponents/MovementAIComponent.h +++ b/dGame/dComponents/MovementAIComponent.h @@ -13,6 +13,7 @@ #include "Game.h" #include "dLogger.h" #include "Component.h" +#include "eReplicaComponentType.h" #include <vector> class ControllablePhysicsComponent; @@ -56,7 +57,7 @@ struct MovementAIInfo { */ class MovementAIComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_MOVEMENT_AI; + static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI; MovementAIComponent(Entity* parentEntity, MovementAIInfo info); ~MovementAIComponent() override; diff --git a/dGame/dComponents/MovingPlatformComponent.h b/dGame/dComponents/MovingPlatformComponent.h index 38b15143..9e4c1ecf 100644 --- a/dGame/dComponents/MovingPlatformComponent.h +++ b/dGame/dComponents/MovingPlatformComponent.h @@ -14,6 +14,7 @@ #include "EntityManager.h" #include "Component.h" #include "eMovementPlatformState.h" +#include "eReplicaComponentType.h" class Path; @@ -105,7 +106,7 @@ public: */ class MovingPlatformComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_MOVING_PLATFORM; + static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM; MovingPlatformComponent(Entity* parent, const std::string& pathName); ~MovingPlatformComponent() override; diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index efde0e8a..e3c1556b 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -4,6 +4,7 @@ #include "MovementAIComponent.h" #include "Component.h" #include "Preconditions.h" +#include "eReplicaComponentType.h" enum class PetAbilityType { @@ -20,7 +21,7 @@ enum class PetAbilityType class PetComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PET; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PET; explicit PetComponent(Entity* parentEntity, uint32_t componentId); ~PetComponent() override; diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index aa3ced46..b95b7cdd 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -144,7 +144,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : Component(par if (!m_HasCreatedPhysics) { CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), COMPONENT_TYPE_PHANTOM_PHYSICS); + auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS); CDPhysicsComponentTable* physComp = CDClientManager::Instance()->GetTable<CDPhysicsComponentTable>("PhysicsComponent"); @@ -254,7 +254,7 @@ void PhantomPhysicsComponent::CreatePhysics() { z = m_Parent->GetVar<float>(u"primitiveModelValueZ"); } else { CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), COMPONENT_TYPE_PHANTOM_PHYSICS); + auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS); CDPhysicsComponentTable* physComp = CDClientManager::Instance()->GetTable<CDPhysicsComponentTable>("PhysicsComponent"); diff --git a/dGame/dComponents/PhantomPhysicsComponent.h b/dGame/dComponents/PhantomPhysicsComponent.h index 1e9a7b60..0b27db05 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.h +++ b/dGame/dComponents/PhantomPhysicsComponent.h @@ -12,6 +12,7 @@ #include "CppScripts.h" #include "InvalidScript.h" #include "Component.h" +#include "eReplicaComponentType.h" class LDFBaseData; class Entity; @@ -25,7 +26,7 @@ class dpEntity; */ class PhantomPhysicsComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PHANTOM_PHYSICS; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS; PhantomPhysicsComponent(Entity* parent); ~PhantomPhysicsComponent() override; diff --git a/dGame/dComponents/PlayerForcedMovementComponent.h b/dGame/dComponents/PlayerForcedMovementComponent.h index 43b99997..90708c9a 100644 --- a/dGame/dComponents/PlayerForcedMovementComponent.h +++ b/dGame/dComponents/PlayerForcedMovementComponent.h @@ -2,6 +2,7 @@ #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Component that handles player forced movement @@ -9,7 +10,7 @@ */ class PlayerForcedMovementComponent : public Component { public: - static const uint32_t ComponentType = eReplicaComponentType::COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PLAYER_FORCED_MOVEMENT; /** * Constructor for this component diff --git a/dGame/dComponents/PossessableComponent.h b/dGame/dComponents/PossessableComponent.h index e1dc5ccd..2026c11e 100644 --- a/dGame/dComponents/PossessableComponent.h +++ b/dGame/dComponents/PossessableComponent.h @@ -6,6 +6,7 @@ #include "Item.h" #include "PossessorComponent.h" #include "eAninmationFlags.h" +#include "eReplicaComponentType.h" /** * Represents an entity that can be controlled by some other entity, generally used by cars to indicate that some @@ -13,7 +14,7 @@ */ class PossessableComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_POSSESSABLE; + static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSABLE; PossessableComponent(Entity* parentEntity, uint32_t componentId); diff --git a/dGame/dComponents/PossessorComponent.h b/dGame/dComponents/PossessorComponent.h index 00b24445..4456af27 100644 --- a/dGame/dComponents/PossessorComponent.h +++ b/dGame/dComponents/PossessorComponent.h @@ -3,6 +3,7 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" // possession types enum class ePossessionType : uint8_t { @@ -17,7 +18,7 @@ enum class ePossessionType : uint8_t { */ class PossessorComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_POSSESSOR; + static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSOR; PossessorComponent(Entity* parent); ~PossessorComponent() override; diff --git a/dGame/dComponents/PropertyComponent.h b/dGame/dComponents/PropertyComponent.h index 2096a475..41f93677 100644 --- a/dGame/dComponents/PropertyComponent.h +++ b/dGame/dComponents/PropertyComponent.h @@ -9,6 +9,7 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" struct PropertyState { LWOOBJID ownerID; @@ -21,7 +22,7 @@ struct PropertyState { */ class PropertyComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PROPERTY; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY; explicit PropertyComponent(Entity* parentEntity); ~PropertyComponent() override; [[nodiscard]] PropertyState* GetPropertyState() const { return m_PropertyState; }; diff --git a/dGame/dComponents/PropertyEntranceComponent.h b/dGame/dComponents/PropertyEntranceComponent.h index 4110e7d9..e37d1daa 100644 --- a/dGame/dComponents/PropertyEntranceComponent.h +++ b/dGame/dComponents/PropertyEntranceComponent.h @@ -6,13 +6,14 @@ #include "Entity.h" #include "EntityManager.h" #include "GameMessages.h" +#include "eReplicaComponentType.h" /** * Represents the launch pad that's used to select and browse properties */ class PropertyEntranceComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PROPERTY_ENTRANCE; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE; explicit PropertyEntranceComponent(uint32_t componentID, Entity* parent); /** diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index ce2c8e5e..0b05b10e 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -255,7 +255,7 @@ void PropertyManagementComponent::OnStartBuilding() { LWOMAPID zoneId = 1100; - const auto entrance = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_PROPERTY_ENTRANCE); + const auto entrance = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE); originalPrivacyOption = privacyOption; diff --git a/dGame/dComponents/PropertyManagementComponent.h b/dGame/dComponents/PropertyManagementComponent.h index d9526015..2ee010a8 100644 --- a/dGame/dComponents/PropertyManagementComponent.h +++ b/dGame/dComponents/PropertyManagementComponent.h @@ -3,6 +3,7 @@ #include <chrono> #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Information regarding which players may visit this property @@ -31,7 +32,7 @@ enum class PropertyPrivacyOption class PropertyManagementComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PROPERTY_MANAGEMENT; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT; PropertyManagementComponent(Entity* parent); static PropertyManagementComponent* Instance(); diff --git a/dGame/dComponents/PropertyVendorComponent.h b/dGame/dComponents/PropertyVendorComponent.h index f947d745..5055b445 100644 --- a/dGame/dComponents/PropertyVendorComponent.h +++ b/dGame/dComponents/PropertyVendorComponent.h @@ -2,6 +2,7 @@ #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * The property guard that stands on a property before it's claimed, allows entities to attempt claiming this property. @@ -9,7 +10,7 @@ class PropertyVendorComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PROPERTY_VENDOR; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_VENDOR; explicit PropertyVendorComponent(Entity* parent); /** diff --git a/dGame/dComponents/ProximityMonitorComponent.h b/dGame/dComponents/ProximityMonitorComponent.h index a98397a2..2f51917d 100644 --- a/dGame/dComponents/ProximityMonitorComponent.h +++ b/dGame/dComponents/ProximityMonitorComponent.h @@ -11,6 +11,7 @@ #include "dpWorld.h" #include "dpEntity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Utility component for detecting how close entities are to named proximities for this entity. Allows you to store @@ -18,7 +19,7 @@ */ class ProximityMonitorComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PROXIMITY_MONITOR; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR; ProximityMonitorComponent(Entity* parentEntity, int smallRadius = -1, int largeRadius = -1); ~ProximityMonitorComponent() override; diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index 933178cc..91ab2fd4 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -7,6 +7,7 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Information for each player in the race @@ -104,7 +105,7 @@ struct RacingPlayerInfo { */ class RacingControlComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_RACING_CONTROL; + static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL; RacingControlComponent(Entity* parentEntity); ~RacingControlComponent(); diff --git a/dGame/dComponents/RailActivatorComponent.h b/dGame/dComponents/RailActivatorComponent.h index 8f67e7e3..5d625d2a 100644 --- a/dGame/dComponents/RailActivatorComponent.h +++ b/dGame/dComponents/RailActivatorComponent.h @@ -4,6 +4,7 @@ #include <string> #include "dCommonVars.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Component that handles the traveling using rails, e.g. the ninjago posts that can be used to travel using Spinjitzu. @@ -14,7 +15,7 @@ public: explicit RailActivatorComponent(Entity* parent, int32_t componentID); ~RailActivatorComponent() override; - static const uint32_t ComponentType = COMPONENT_TYPE_RAIL_ACTIVATOR; + static const eReplicaComponentType ComponentType = eReplicaComponentType::RAIL_ACTIVATOR; /** * Handles the OnUse event from some entity, initiates the rail movement diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index bf7bd3e5..abd21873 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -53,7 +53,7 @@ RebuildComponent::~RebuildComponent() { } void RebuildComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) { - if (m_Parent->GetComponent(COMPONENT_TYPE_DESTROYABLE) == nullptr) { + if (m_Parent->GetComponent(eReplicaComponentType::DESTROYABLE) == nullptr) { if (bIsInitialUpdate) { outBitStream->Write(false); } diff --git a/dGame/dComponents/RebuildComponent.h b/dGame/dComponents/RebuildComponent.h index bd3edd7d..a8e11e4c 100644 --- a/dGame/dComponents/RebuildComponent.h +++ b/dGame/dComponents/RebuildComponent.h @@ -9,6 +9,7 @@ #include "ScriptedActivityComponent.h" #include "Preconditions.h" #include "Component.h" +#include "eReplicaComponentType.h" class Entity; @@ -19,7 +20,7 @@ class Entity; */ class RebuildComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_REBUILD; + static const eReplicaComponentType ComponentType = eReplicaComponentType::QUICK_BUILD; RebuildComponent(Entity* entity); ~RebuildComponent() override; diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index 3002ae33..f188859d 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -22,7 +22,7 @@ RenderComponent::RenderComponent(Entity* parent) : Component(parent) { /* auto* table = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - const auto entry = table->GetByIDAndType(parent->GetLOT(), COMPONENT_TYPE_RENDER); + const auto entry = table->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::RENDER); std::stringstream query; diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index e6184564..de8b2907 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -8,6 +8,7 @@ #include "AMFFormat.h" #include "Component.h" +#include "eReplicaComponentType.h" class Entity; @@ -55,7 +56,7 @@ struct Effect { */ class RenderComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_RENDER; + static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER; RenderComponent(Entity* entity); ~RenderComponent() override; diff --git a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h index c8faa930..480f9b81 100644 --- a/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h +++ b/dGame/dComponents/RigidbodyPhantomPhysicsComponent.h @@ -11,6 +11,7 @@ #include "NiPoint3.h" #include "NiQuaternion.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Component that handles rigid bodies that can be interacted with, mostly client-side rendered. An example is the @@ -18,7 +19,7 @@ */ class RigidbodyPhantomPhysicsComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_PHANTOM_PHYSICS; + static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS; RigidbodyPhantomPhysicsComponent(Entity* parent); ~RigidbodyPhantomPhysicsComponent() override; diff --git a/dGame/dComponents/RocketLaunchLupComponent.h b/dGame/dComponents/RocketLaunchLupComponent.h index 3fc0b444..226fa1b2 100644 --- a/dGame/dComponents/RocketLaunchLupComponent.h +++ b/dGame/dComponents/RocketLaunchLupComponent.h @@ -3,6 +3,7 @@ #include "Entity.h" #include "GameMessages.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Component that handles the LUP/WBL rocket launchpad that can be interacted with to travel to WBL worlds. @@ -10,7 +11,7 @@ */ class RocketLaunchLupComponent : public Component { public: - static const uint32_t ComponentType = eReplicaComponentType::COMPONENT_TYPE_ROCKET_LAUNCH_LUP; + static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH_LUP; /** * Constructor for this component, builds the m_LUPWorlds vector diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.h b/dGame/dComponents/RocketLaunchpadControlComponent.h index 8a10f0f7..84cff22d 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.h +++ b/dGame/dComponents/RocketLaunchpadControlComponent.h @@ -9,6 +9,7 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" class PreconditionExpression; @@ -17,7 +18,7 @@ class PreconditionExpression; */ class RocketLaunchpadControlComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_ROCKET_LAUNCH; + static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH; RocketLaunchpadControlComponent(Entity* parent, int rocketId); ~RocketLaunchpadControlComponent() override; diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 067446e7..4a034187 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -137,7 +137,7 @@ void ScriptedActivityComponent::PlayerJoin(Entity* player) { } void ScriptedActivityComponent::PlayerJoinLobby(Entity* player) { - if (!m_Parent->HasComponent(COMPONENT_TYPE_REBUILD)) + if (!m_Parent->HasComponent(eReplicaComponentType::QUICK_BUILD)) GameMessages::SendMatchResponse(player, player->GetSystemAddress(), 0); // tell the client they joined a lobby LobbyPlayer* newLobbyPlayer = new LobbyPlayer(); newLobbyPlayer->entityID = player->GetObjectID(); diff --git a/dGame/dComponents/ScriptedActivityComponent.h b/dGame/dComponents/ScriptedActivityComponent.h index 8bb17093..a4aad048 100644 --- a/dGame/dComponents/ScriptedActivityComponent.h +++ b/dGame/dComponents/ScriptedActivityComponent.h @@ -11,6 +11,7 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Represents an instance of an activity, having participants and score @@ -153,7 +154,7 @@ struct ActivityPlayer { */ class ScriptedActivityComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_SCRIPTED_ACTIVITY; + static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPTED_ACTIVITY; ScriptedActivityComponent(Entity* parent, int activityID); ~ScriptedActivityComponent() override; diff --git a/dGame/dComponents/ShootingGalleryComponent.h b/dGame/dComponents/ShootingGalleryComponent.h index c43f20c2..c31575f1 100644 --- a/dGame/dComponents/ShootingGalleryComponent.h +++ b/dGame/dComponents/ShootingGalleryComponent.h @@ -3,6 +3,7 @@ #include "NiPoint3.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Parameters for the shooting gallery that change during playtime @@ -72,7 +73,7 @@ struct StaticShootingGalleryParams { */ class ShootingGalleryComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_SHOOTING_GALLERY; + static const eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY; explicit ShootingGalleryComponent(Entity* parent); ~ShootingGalleryComponent(); diff --git a/dGame/dComponents/SimplePhysicsComponent.h b/dGame/dComponents/SimplePhysicsComponent.h index ebb8b124..51356710 100644 --- a/dGame/dComponents/SimplePhysicsComponent.h +++ b/dGame/dComponents/SimplePhysicsComponent.h @@ -11,6 +11,7 @@ #include "NiPoint3.h" #include "NiQuaternion.h" #include "Component.h" +#include "eReplicaComponentType.h" class Entity; @@ -27,7 +28,7 @@ enum class eClimbableType : int32_t { */ class SimplePhysicsComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_SIMPLE_PHYSICS; + static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS; SimplePhysicsComponent(uint32_t componentID, Entity* parent); ~SimplePhysicsComponent() override; diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 2391dc3b..625f1f30 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -128,7 +128,7 @@ void SkillComponent::RegisterPlayerProjectile(const LWOOBJID projectileId, Behav } void SkillComponent::Update(const float deltaTime) { - if (!m_Parent->HasComponent(COMPONENT_TYPE_BASE_COMBAT_AI) && m_Parent->GetLOT() != 1) { + if (!m_Parent->HasComponent(eReplicaComponentType::BASE_COMBAT_AI) && m_Parent->GetLOT() != 1) { CalculateUpdate(deltaTime); } diff --git a/dGame/dComponents/SkillComponent.h b/dGame/dComponents/SkillComponent.h index 2bdcb88f..034e65ce 100644 --- a/dGame/dComponents/SkillComponent.h +++ b/dGame/dComponents/SkillComponent.h @@ -13,6 +13,7 @@ #include "Component.h" #include "Entity.h" #include "dLogger.h" +#include "eReplicaComponentType.h" struct ProjectileSyncEntry { LWOOBJID id = LWOOBJID_EMPTY; @@ -58,7 +59,7 @@ struct SkillExecutionResult { */ class SkillComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_SKILL; + static const eReplicaComponentType ComponentType = eReplicaComponentType::SKILL; explicit SkillComponent(Entity* parent); ~SkillComponent() override; diff --git a/dGame/dComponents/SoundTriggerComponent.h b/dGame/dComponents/SoundTriggerComponent.h index e1178150..954d8495 100644 --- a/dGame/dComponents/SoundTriggerComponent.h +++ b/dGame/dComponents/SoundTriggerComponent.h @@ -3,6 +3,7 @@ #include "Entity.h" #include "GUID.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Music that should be played by the client @@ -19,7 +20,7 @@ struct MusicCue { */ class SoundTriggerComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_SOUND_TRIGGER; + static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER; explicit SoundTriggerComponent(Entity* parent); ~SoundTriggerComponent() override; diff --git a/dGame/dComponents/SwitchComponent.h b/dGame/dComponents/SwitchComponent.h index ea5955d8..fde3cfc0 100644 --- a/dGame/dComponents/SwitchComponent.h +++ b/dGame/dComponents/SwitchComponent.h @@ -9,13 +9,14 @@ #include "BouncerComponent.h" #include <algorithm> #include "Component.h" +#include "eReplicaComponentType.h" /** * A component for switches in game, including pet triggered switches. */ class SwitchComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_SWITCH; + static const eReplicaComponentType ComponentType = eReplicaComponentType::SWITCH; SwitchComponent(Entity* parent); ~SwitchComponent() override; diff --git a/dGame/dComponents/TriggerComponent.h b/dGame/dComponents/TriggerComponent.h index d7711696..492b0449 100644 --- a/dGame/dComponents/TriggerComponent.h +++ b/dGame/dComponents/TriggerComponent.h @@ -2,6 +2,7 @@ #define __TRIGGERCOMPONENT__H__ #include "Component.h" +#include "eReplicaComponentType.h" namespace LUTriggers { struct Trigger; @@ -10,7 +11,7 @@ namespace LUTriggers { class TriggerComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_TRIGGER; + static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER; explicit TriggerComponent(Entity* parent, const std::string triggerInfo); diff --git a/dGame/dComponents/VehiclePhysicsComponent.h b/dGame/dComponents/VehiclePhysicsComponent.h index f5ab1917..551cce42 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.h +++ b/dGame/dComponents/VehiclePhysicsComponent.h @@ -3,13 +3,14 @@ #include "BitStream.h" #include "Entity.h" #include "Component.h" +#include "eReplicaComponentType.h" /** * Physics component for vehicles. */ class VehiclePhysicsComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_VEHICLE_PHYSICS; + static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS; VehiclePhysicsComponent(Entity* parentEntity); ~VehiclePhysicsComponent() override; diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index 96dfb2c0..e9599b71 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -119,7 +119,7 @@ void VendorComponent::RefreshInventory(bool isCreation) { void VendorComponent::SetupConstants() { auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - int componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), COMPONENT_TYPE_VENDOR); + int componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::VENDOR); auto* vendorComponentTable = CDClientManager::Instance()->GetTable<CDVendorComponentTable>("VendorComponent"); std::vector<CDVendorComponent> vendorComps = vendorComponentTable->Query([=](CDVendorComponent entry) { return (entry.id == componentID); }); diff --git a/dGame/dComponents/VendorComponent.h b/dGame/dComponents/VendorComponent.h index 72a5816d..bf372bf2 100644 --- a/dGame/dComponents/VendorComponent.h +++ b/dGame/dComponents/VendorComponent.h @@ -7,13 +7,14 @@ #include "Entity.h" #include "GameMessages.h" #include "RakNetTypes.h" +#include "eReplicaComponentType.h" /** * A component for vendor NPCs. A vendor sells items to the player. */ class VendorComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_VENDOR; + static const eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR; VendorComponent(Entity* parent); ~VendorComponent() override; diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 16942ecc..b63f1c6d 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -32,6 +32,7 @@ #include "EchoStartSkill.h" #include "EchoSyncSkill.h" #include "eMissionTaskType.h" +#include "eReplicaComponentType.h" using namespace std; @@ -122,7 +123,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System destroyable->SetImagination(destroyable->GetImagination()); EntityManager::Instance()->SerializeEntity(entity); - std::vector<Entity*> racingControllers = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_RACING_CONTROL); + std::vector<Entity*> racingControllers = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL); for (Entity* racingController : racingControllers) { auto* racingComponent = racingController->GetComponent<RacingControlComponent>(); if (racingComponent != nullptr) { @@ -135,7 +136,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System script->OnPlayerLoaded(zoneControl, player); } - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPT); + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -241,7 +242,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case GAME_MSG_REQUEST_RESURRECT: { GameMessages::SendResurrect(entity); - /*auto* dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + /*auto* dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth(4); dest->SetArmor(0); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 1d897727..9dcd2d74 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -80,6 +80,7 @@ #include "eBlueprintSaveResponseType.h" #include "eAninmationFlags.h" #include "AMFFormat_BitStream.h" +#include "eReplicaComponentType.h" void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) { CBITSTREAM; @@ -914,7 +915,7 @@ void GameMessages::SendSetJetPackMode(Entity* entity, bool use, bool bypassCheck } void GameMessages::SendResurrect(Entity* entity) { - DestroyableComponent* dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + DestroyableComponent* dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest != nullptr && entity->GetLOT() == 1) { auto* levelComponent = entity->GetComponent<LevelProgressionComponent>(); @@ -924,7 +925,7 @@ void GameMessages::SendResurrect(Entity* entity) { } } - auto cont = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); + auto cont = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (cont && entity->GetLOT() == 1) { cont->SetPosition(entity->GetRespawnPosition()); cont->SetRotation(entity->GetRespawnRotation()); @@ -1121,7 +1122,7 @@ void GameMessages::SendPlayerReachedRespawnCheckpoint(Entity* entity, const NiPo bitStream.Write(position.y); bitStream.Write(position.z); - auto con = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); + auto con = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (con) { auto rot = con->GetRotation(); bitStream.Write(rot.x); @@ -1256,7 +1257,7 @@ void GameMessages::SendVendorStatusUpdate(Entity* entity, const SystemAddress& s CBITSTREAM; CMSGHEADER; - VendorComponent* vendor = static_cast<VendorComponent*>(entity->GetComponent(COMPONENT_TYPE_VENDOR)); + VendorComponent* vendor = static_cast<VendorComponent*>(entity->GetComponent(eReplicaComponentType::VENDOR)); if (!vendor) return; std::map<LOT, int> vendorItems = vendor->GetInventory(); @@ -1378,7 +1379,7 @@ void GameMessages::SendMoveInventoryBatch(Entity* entity, uint32_t stackCount, i CBITSTREAM; CMSGHEADER; - InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; Item* itemStack = inv->FindItemById(iObjID); @@ -1682,7 +1683,7 @@ void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Game::logger->Log("Activity State Change", "%s [%i, %i] from %i to %i", GeneralUtils::UTF16ToWTF8(stringValue).c_str(), value1, value2, entity->GetLOT(), assosiate != nullptr ? assosiate->GetLOT() : 0); - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SHOOTING_GALLERY); + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY); for (Entity* scriptEntity : scriptedActs) { scriptEntity->OnActivityStateChangeRequest(objectID, value1, value2, stringValue); } @@ -2211,24 +2212,24 @@ void GameMessages::HandleQueryPropertyData(RakNet::BitStream* inStream, Entity* Game::logger->Log("HandleQueryPropertyData", "Entity (%i) requesting data", entity->GetLOT()); /* - auto entites = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_PROPERTY_VENDOR); + auto entites = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_VENDOR); entity = entites[0]; */ - auto* propertyVendorComponent = static_cast<PropertyVendorComponent*>(entity->GetComponent(COMPONENT_TYPE_PROPERTY_VENDOR)); + auto* propertyVendorComponent = static_cast<PropertyVendorComponent*>(entity->GetComponent(eReplicaComponentType::PROPERTY_VENDOR)); if (propertyVendorComponent != nullptr) { propertyVendorComponent->OnQueryPropertyData(entity, sysAddr); } /* - entites = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_PROPERTY_MANAGEMENT); + entites = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_MANAGEMENT); entity = entites[0]; */ - auto* propertyManagerComponent = static_cast<PropertyManagementComponent*>(entity->GetComponent(COMPONENT_TYPE_PROPERTY_MANAGEMENT)); + auto* propertyManagerComponent = static_cast<PropertyManagementComponent*>(entity->GetComponent(eReplicaComponentType::PROPERTY_MANAGEMENT)); if (propertyManagerComponent != nullptr) { propertyManagerComponent->OnQueryPropertyData(entity, sysAddr); @@ -2272,7 +2273,7 @@ void GameMessages::HandleSetBuildMode(RakNet::BitStream* inStream, Entity* entit } void GameMessages::HandleStartBuildingWithItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - if (!entity->HasComponent(COMPONENT_TYPE_PROPERTY_MANAGEMENT)) { + if (!entity->HasComponent(eReplicaComponentType::PROPERTY_MANAGEMENT)) { return; } @@ -2901,7 +2902,7 @@ void GameMessages::HandleCinematicUpdate(RakNet::BitStream* inStream, Entity* en inStream->Read<int32_t>(waypoint); } - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPT); + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); for (Entity* scriptEntity : scriptedActs) { scriptEntity->OnCinematicUpdate(scriptEntity, entity, event, pathName, pathTime, overallTime, waypoint); } @@ -3868,7 +3869,7 @@ void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* racingControlComponent->HandleMessageBoxResponse(userEntity, GeneralUtils::UTF16ToWTF8(identifier)); } - for (auto* shootingGallery : EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SHOOTING_GALLERY)) { + for (auto* shootingGallery : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { shootingGallery->OnMessageBoxResponse(userEntity, iButton, identifier, userData); } } @@ -4665,7 +4666,7 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); if (!player) return; - auto* propertyVendorComponent = static_cast<PropertyVendorComponent*>(entity->GetComponent(COMPONENT_TYPE_PROPERTY_VENDOR)); + auto* propertyVendorComponent = static_cast<PropertyVendorComponent*>(entity->GetComponent(eReplicaComponentType::PROPERTY_VENDOR)); if (propertyVendorComponent != nullptr) { propertyVendorComponent->OnBuyFromVendor(player, bConfirmed, item, count); @@ -4675,16 +4676,16 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti const auto isCommendationVendor = entity->GetLOT() == 13806; - VendorComponent* vend = static_cast<VendorComponent*>(entity->GetComponent(COMPONENT_TYPE_VENDOR)); + VendorComponent* vend = static_cast<VendorComponent*>(entity->GetComponent(eReplicaComponentType::VENDOR)); if (!vend && !isCommendationVendor) return; - InventoryComponent* inv = static_cast<InventoryComponent*>(player->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); - int itemCompID = compRegistryTable->GetByIDAndType(item, COMPONENT_TYPE_ITEM); + int itemCompID = compRegistryTable->GetByIDAndType(item, eReplicaComponentType::ITEM); CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); Character* character = player->GetCharacter(); @@ -4764,10 +4765,10 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit if (!player) return; Character* character = player->GetCharacter(); if (!character) return; - InventoryComponent* inv = static_cast<InventoryComponent*>(player->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; - VendorComponent* vend = static_cast<VendorComponent*>(entity->GetComponent(COMPONENT_TYPE_VENDOR)); + VendorComponent* vend = static_cast<VendorComponent*>(entity->GetComponent(eReplicaComponentType::VENDOR)); if (!vend) return; Item* item = inv->FindItemById(iObjID); @@ -4776,7 +4777,7 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); - int itemCompID = compRegistryTable->GetByIDAndType(item->GetLot(), COMPONENT_TYPE_ITEM); + int itemCompID = compRegistryTable->GetByIDAndType(item->GetLot(), eReplicaComponentType::ITEM); CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); // Items with a base value of 0 or max int are special items that should not be sold if they're not sub items @@ -4814,10 +4815,10 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* if (!player) return; Character* character = player->GetCharacter(); if (!character) return; - InventoryComponent* inv = static_cast<InventoryComponent*>(player->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; - VendorComponent* vend = static_cast<VendorComponent*>(entity->GetComponent(COMPONENT_TYPE_VENDOR)); + VendorComponent* vend = static_cast<VendorComponent*>(entity->GetComponent(eReplicaComponentType::VENDOR)); if (!vend) return; Item* item = inv->FindItemById(iObjID); @@ -4826,7 +4827,7 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); - int itemCompID = compRegistryTable->GetByIDAndType(item->GetLot(), COMPONENT_TYPE_ITEM); + int itemCompID = compRegistryTable->GetByIDAndType(item->GetLot(), eReplicaComponentType::ITEM); CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); float sellScalar = vend->GetSellScalar(); @@ -4968,7 +4969,7 @@ void GameMessages::HandleRebuildCancel(RakNet::BitStream* inStream, Entity* enti inStream->Read(bEarlyRelease); inStream->Read(userID); - RebuildComponent* rebComp = static_cast<RebuildComponent*>(entity->GetComponent(COMPONENT_TYPE_REBUILD)); + RebuildComponent* rebComp = static_cast<RebuildComponent*>(entity->GetComponent(eReplicaComponentType::QUICK_BUILD)); if (!rebComp) return; rebComp->CancelRebuild(EntityManager::Instance()->GetEntity(userID), eFailReason::REASON_CANCELED_EARLY); @@ -5001,7 +5002,7 @@ void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, if (bIsMultiInteractUse) { if (multiInteractType == 0) { - auto* missionOfferComponent = static_cast<MissionOfferComponent*>(interactedObject->GetComponent(COMPONENT_TYPE_MISSION_OFFER)); + auto* missionOfferComponent = static_cast<MissionOfferComponent*>(interactedObject->GetComponent(eReplicaComponentType::MISSION_OFFER)); if (missionOfferComponent != nullptr) { missionOfferComponent->OfferMissions(entity, multiInteractID); @@ -5014,7 +5015,7 @@ void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, } //Perform use task if possible: - auto missionComponent = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); + auto missionComponent = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); if (missionComponent == nullptr) return; @@ -5050,7 +5051,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) } } else { Game::logger->LogDebug("GameMessages", "Target ID is empty, using backup"); - const auto scriptedEntities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPT); + const auto scriptedEntities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); const auto& referencePoint = entity->GetPosition(); @@ -5080,7 +5081,7 @@ void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream* inStream, E if (!user) return; Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); if (!character) return; - InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; auto* item = inv->FindItemById(modelID); @@ -5123,7 +5124,7 @@ void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* e inStream->Read(isDefaultReward); if (isDefaultReward) inStream->Read(reward); - MissionComponent* missionComponent = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); + MissionComponent* missionComponent = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); if (!missionComponent) { Game::logger->Log("GameMessages", "Unable to get mission component for entity %llu to handle RespondToMission", playerID); return; @@ -5166,7 +5167,7 @@ void GameMessages::HandleMissionDialogOK(RakNet::BitStream* inStream, Entity* en } // Get the player's mission component - MissionComponent* missionComponent = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); + MissionComponent* missionComponent = static_cast<MissionComponent*>(player->GetComponent(eReplicaComponentType::MISSION)); if (!missionComponent) { Game::logger->Log("GameMessages", "Unable to get mission component for entity %llu to handle MissionDialogueOK", player->GetObjectID()); return; @@ -5190,7 +5191,7 @@ void GameMessages::HandleRequestLinkedMission(RakNet::BitStream* inStream, Entit auto* player = EntityManager::Instance()->GetEntity(playerId); - auto* missionOfferComponent = static_cast<MissionOfferComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION_OFFER)); + auto* missionOfferComponent = static_cast<MissionOfferComponent*>(entity->GetComponent(eReplicaComponentType::MISSION_OFFER)); if (missionOfferComponent != nullptr) { missionOfferComponent->OfferMissions(player, 0); @@ -5204,7 +5205,7 @@ void GameMessages::HandleHasBeenCollected(RakNet::BitStream* inStream, Entity* e Entity* player = EntityManager::Instance()->GetEntity(playerID); if (!player || !entity || entity->GetCollectibleID() == 0) return; - MissionComponent* missionComponent = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); + MissionComponent* missionComponent = static_cast<MissionComponent*>(player->GetComponent(eReplicaComponentType::MISSION)); if (missionComponent) { missionComponent->Progress(eMissionTaskType::COLLECTION, entity->GetLOT(), entity->GetObjectID()); } @@ -5307,7 +5308,7 @@ void GameMessages::HandleEquipItem(RakNet::BitStream* inStream, Entity* entity) inStream->Read(immediate); //twice? inStream->Read(objectID); - InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; Item* item = inv->FindItemById(objectID); @@ -5326,7 +5327,7 @@ void GameMessages::HandleUnequipItem(RakNet::BitStream* inStream, Entity* entity inStream->Read(immediate); inStream->Read(objectID); - InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; auto* item = inv->FindItemById(objectID); @@ -5401,7 +5402,7 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, En inStream->Read(iTradeIDIsDefault); if (iTradeIDIsDefault) inStream->Read(iTradeID); - InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; auto* item = inv->FindItemById(iObjID); @@ -5444,7 +5445,7 @@ void GameMessages::HandleMoveItemInInventory(RakNet::BitStream* inStream, Entity inStream->Read(responseCode); inStream->Read(slot); - InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; auto* item = inv->FindItemById(iObjID); @@ -5521,7 +5522,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* if (!user) return; Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); if (!character) return; - InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; Game::logger->Log("GameMessages", "Build finished"); @@ -5586,7 +5587,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* } } - ScriptComponent* script = static_cast<ScriptComponent*>(entity->GetComponent(COMPONENT_TYPE_SCRIPT)); + ScriptComponent* script = static_cast<ScriptComponent*>(entity->GetComponent(eReplicaComponentType::SCRIPT)); for (CppScripts::Script* script : CppScripts::GetEntityScripts(entity)) { script->OnModularBuildExit(entity, character, count >= 3, modList); @@ -5609,7 +5610,7 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti if (!user) return; Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); if (!character) return; - InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; /** @@ -5660,7 +5661,7 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti */ if (PropertyManagementComponent::Instance() != nullptr) { - const auto& buildAreas = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_BUILD_BORDER); + const auto& buildAreas = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::BUILD_BORDER); const auto& entities = EntityManager::Instance()->GetEntitiesInGroup("PropertyPlaque"); @@ -5727,7 +5728,7 @@ void GameMessages::HandleModularBuildMoveAndEquip(RakNet::BitStream* inStream, E inStream->Read(templateID); - InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; auto* item = inv->FindItemByLot(templateID, TEMP_MODELS); @@ -5768,7 +5769,7 @@ void GameMessages::HandleResurrect(RakNet::BitStream* inStream, Entity* entity) script->OnPlayerResurrected(zoneControl, entity); } - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY); + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -5779,13 +5780,13 @@ void GameMessages::HandleResurrect(RakNet::BitStream* inStream, Entity* entity) } void GameMessages::HandlePushEquippedItemsState(RakNet::BitStream* inStream, Entity* entity) { - InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; inv->PushEquippedItems(); } void GameMessages::HandlePopEquippedItemsState(RakNet::BitStream* inStream, Entity* entity) { - InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; inv->PopEquippedItems(); EntityManager::Instance()->SerializeEntity(entity); // so it updates on client side @@ -5797,7 +5798,7 @@ void GameMessages::HandleClientItemConsumed(RakNet::BitStream* inStream, Entity* inStream->Read(itemConsumed); - auto* inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto* inventory = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (inventory == nullptr) { return; @@ -5811,7 +5812,7 @@ void GameMessages::HandleClientItemConsumed(RakNet::BitStream* inStream, Entity* item->Consume(); - auto* missions = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); + auto* missions = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); if (missions != nullptr) { missions->Progress(eMissionTaskType::USE_ITEM, itemLot); } @@ -5823,7 +5824,7 @@ void GameMessages::HandleUseNonEquipmentItem(RakNet::BitStream* inStream, Entity inStream->Read(itemConsumed); - auto* inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto* inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; @@ -5854,11 +5855,11 @@ void GameMessages::HandleMatchRequest(RakNet::BitStream* inStream, Entity* entit inStream->Read(type); inStream->Read(value); - std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY); + std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); if (type == 0) { // join if (value != 0) { for (Entity* scriptedAct : scriptedActs) { - ScriptedActivityComponent* comp = static_cast<ScriptedActivityComponent*>(scriptedAct->GetComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY)); + ScriptedActivityComponent* comp = static_cast<ScriptedActivityComponent*>(scriptedAct->GetComponent(eReplicaComponentType::SCRIPTED_ACTIVITY)); if (!comp) continue; if (comp->GetActivityID() == value) { comp->PlayerJoin(entity); @@ -5869,7 +5870,7 @@ void GameMessages::HandleMatchRequest(RakNet::BitStream* inStream, Entity* entit } } else if (type == 1) { // ready/unready for (Entity* scriptedAct : scriptedActs) { - ScriptedActivityComponent* comp = static_cast<ScriptedActivityComponent*>(scriptedAct->GetComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY)); + ScriptedActivityComponent* comp = static_cast<ScriptedActivityComponent*>(scriptedAct->GetComponent(eReplicaComponentType::SCRIPTED_ACTIVITY)); if (!comp) continue; if (comp->PlayerIsInQueue(entity)) { comp->PlayerReady(entity, value); @@ -5987,7 +5988,7 @@ void GameMessages::HandleReportBug(RakNet::BitStream* inStream, Entity* entity) void GameMessages::HandleClientRailMovementReady(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_RAIL_ACTIVATOR); + const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (const auto* possibleRail : possibleRails) { const auto* rail = possibleRail->GetComponent<RailActivatorComponent>(); if (rail != nullptr) { @@ -5999,7 +6000,7 @@ GameMessages::HandleClientRailMovementReady(RakNet::BitStream* inStream, Entity* void GameMessages::HandleCancelRailMovement(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { const auto immediate = inStream->ReadBit(); - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_RAIL_ACTIVATOR); + const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (const auto* possibleRail : possibleRails) { auto* rail = possibleRail->GetComponent<RailActivatorComponent>(); if (rail != nullptr) { @@ -6023,7 +6024,7 @@ void GameMessages::HandlePlayerRailArrivedNotification(RakNet::BitStream* inStre int32_t waypointNumber; inStream->Read(waypointNumber); - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_RAIL_ACTIVATOR); + const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (auto* possibleRail : possibleRails) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(possibleRail)) { script->OnPlayerRailArrived(possibleRail, entity, pathName, waypointNumber); diff --git a/dGame/dInventory/Inventory.cpp b/dGame/dInventory/Inventory.cpp index 69a643ae..b35281eb 100644 --- a/dGame/dInventory/Inventory.cpp +++ b/dGame/dInventory/Inventory.cpp @@ -4,6 +4,7 @@ #include "Item.h" #include "InventoryComponent.h" #include "eItemType.h" +#include "eReplicaComponentType.h" std::vector<LOT> Inventory::m_GameMasterRestrictedItems = { 1727, // GM Only - JetPack @@ -277,7 +278,7 @@ const CDItemComponent& Inventory::FindItemComponent(const LOT lot) { auto* itemComponents = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); - const auto componentId = registry->GetByIDAndType(lot, COMPONENT_TYPE_ITEM); + const auto componentId = registry->GetByIDAndType(lot, eReplicaComponentType::ITEM); if (componentId == 0) { Game::logger->Log("Inventory", "Failed to find item component for (%i)!", lot); @@ -293,7 +294,7 @@ const CDItemComponent& Inventory::FindItemComponent(const LOT lot) { bool Inventory::IsValidItem(const LOT lot) { auto* registry = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - const auto componentId = registry->GetByIDAndType(lot, COMPONENT_TYPE_ITEM); + const auto componentId = registry->GetByIDAndType(lot, eReplicaComponentType::ITEM); return componentId != 0; } diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 2a054ae8..0df1723d 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -16,6 +16,7 @@ #include "AssetManager.h" #include "InventoryComponent.h" #include "Loot.h" +#include "eReplicaComponentType.h" Item::Item(const LWOOBJID id, const LOT lot, Inventory* inventory, const uint32_t slot, const uint32_t count, const bool bound, const std::vector<LDFBaseData*>& config, const LWOOBJID parent, LWOOBJID subKey, eLootSourceType lootSourceType) { if (!Inventory::IsValidItem(lot)) { @@ -297,7 +298,7 @@ void Item::UseNonEquip(Item* item) { auto inventory = item->GetInventory(); if (inventory && inventory->GetType() == eInventoryType::ITEMS) { auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_PACKAGE); + const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::PACKAGE); if (packageComponentId == 0) return; @@ -381,7 +382,7 @@ void Item::Disassemble(const eInventoryType inventoryType) { void Item::DisassembleModel() { auto* table = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - const auto componentId = table->GetByIDAndType(GetLot(), COMPONENT_TYPE_RENDER); + const auto componentId = table->GetByIDAndType(GetLot(), eReplicaComponentType::RENDER); auto query = CDClientDatabase::CreatePreppedStmt( "SELECT render_asset FROM RenderComponent WHERE id = ?;"); diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 0e1acdac..68384652 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -23,7 +23,7 @@ #include "eMissionState.h" #include "eMissionTaskType.h" #include "eMissionLockState.h" - +#include "eReplicaComponentType.h" Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_MissionComponent = missionComponent; @@ -370,7 +370,7 @@ void Mission::CheckCompletion() { void Mission::Catchup() { auto* entity = GetAssociate(); - auto* inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto* inventory = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); for (auto* task : m_Tasks) { const auto type = task->GetType(); diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index e339d232..344427c6 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -14,6 +14,7 @@ #include "InventoryComponent.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "eReplicaComponentType.h" MissionTask::MissionTask(Mission* mission, CDMissionTasks* info, uint32_t mask) { this->info = info; @@ -237,7 +238,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - activity = static_cast<ScriptedActivityComponent*>(entity->GetComponent(COMPONENT_TYPE_REBUILD)); + activity = static_cast<ScriptedActivityComponent*>(entity->GetComponent(eReplicaComponentType::QUICK_BUILD)); if (activity == nullptr) { break; } diff --git a/dGame/dUtilities/Loot.cpp b/dGame/dUtilities/Loot.cpp index 44e35a91..415c976c 100644 --- a/dGame/dUtilities/Loot.cpp +++ b/dGame/dUtilities/Loot.cpp @@ -14,7 +14,7 @@ #include "InventoryComponent.h" #include "MissionComponent.h" #include "eMissionState.h" - +#include "eReplicaComponentType.h" LootGenerator::LootGenerator() { CDLootTableTable* lootTableTable = CDClientManager::Instance()->GetTable<CDLootTableTable>("LootTable"); @@ -38,7 +38,7 @@ LootGenerator::LootGenerator() { uniqueItems.erase(std::unique(uniqueItems.begin(), uniqueItems.end()), uniqueItems.end()); for (const uint32_t itemID : uniqueItems) { - uint32_t itemComponentID = componentsRegistryTable->GetByIDAndType(itemID, COMPONENT_TYPE_ITEM); + uint32_t itemComponentID = componentsRegistryTable->GetByIDAndType(itemID, eReplicaComponentType::ITEM); const CDItemComponent& item = itemComponentTable->GetItemComponentByID(itemComponentID); m_ItemRarities.insert({ itemID, item.rarity }); diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index 48f21a5d..9490f748 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -25,6 +25,7 @@ #include "dZoneManager.h" #include "WorldConfig.h" #include "eMissionTaskType.h" +#include "eReplicaComponentType.h" void Mail::SendMail(const Entity* recipient, const std::string& subject, const std::string& body, const LOT attachment, const uint16_t attachmentCount) { @@ -196,7 +197,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd //Inventory::InventoryType itemType; int mailCost = dZoneManager::Instance()->GetWorldConfig()->mailBaseFee; int stackSize = 0; - auto inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); Item* item = nullptr; if (itemID > 0 && attachmentCount > 0 && inv) { @@ -355,7 +356,7 @@ void Mail::HandleAttachmentCollect(RakNet::BitStream* packet, const SystemAddres attachmentCount = res->getInt(2); } - auto inv = static_cast<InventoryComponent*>(player->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; inv->AddItem(attachmentLOT, attachmentCount, eLootSourceType::LOOT_SOURCE_MAIL); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 8ae0b441..443ba41d 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -75,6 +75,7 @@ #include "eMissionState.h" #include "TriggerComponent.h" #include "eServerDisconnectIdentifiers.h" +#include "eReplicaComponentType.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; @@ -561,7 +562,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (inventory) { auto* items = inventory->GetInventory(ITEMS); @@ -611,7 +612,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - auto comp = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); + auto comp = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); if (comp) comp->AcceptMission(missionID, true); return; } @@ -626,7 +627,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - auto comp = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); + auto comp = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); if (comp) comp->CompleteMission(missionID, true); return; } @@ -676,7 +677,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - auto* comp = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION)); + auto* comp = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); if (comp == nullptr) { return; @@ -753,7 +754,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "getnavmeshheight" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { - auto control = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); + auto control = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!control) return; float y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(control->GetPosition()); @@ -770,7 +771,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); inventory->AddItem(itemLOT, 1, eLootSourceType::LOOT_SOURCE_MODERATION); } else if (args.size() == 2) { @@ -788,7 +789,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY)); + InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); inventory->AddItem(itemLOT, count, eLootSourceType::LOOT_SOURCE_MODERATION); } else { @@ -934,7 +935,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "tpall" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { const auto pos = entity->GetPosition(); - const auto characters = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_CHARACTER); + const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); for (auto* character : characters) { GameMessages::SendTeleport(character->GetObjectID(), pos, NiQuaternion(), character->GetSystemAddress()); @@ -1153,7 +1154,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //------------------------------------------------- if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { - auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth(999); dest->SetMaxHealth(999.0f); @@ -1177,7 +1178,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { - auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth(9); dest->SetMaxHealth(9.0f); @@ -1191,7 +1192,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { - auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth((int)dest->GetMaxHealth()); dest->SetArmor((int)dest->GetMaxArmor()); @@ -1224,7 +1225,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { - ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); + ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!comp) return; uint32_t lot; @@ -1655,18 +1656,18 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= 6) { //Go tell physics to spawn all the vertices: - auto entities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_PHANTOM_PHYSICS); + auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS); for (auto en : entities) { - auto phys = static_cast<PhantomPhysicsComponent*>(en->GetComponent(COMPONENT_TYPE_PHANTOM_PHYSICS)); + auto phys = static_cast<PhantomPhysicsComponent*>(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (phys) phys->SpawnVertices(); } } if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= 6) { - auto entities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_PROXIMITY_MONITOR); + auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR); for (auto en : entities) { - auto phys = static_cast<ProximityMonitorComponent*>(en->GetComponent(COMPONENT_TYPE_PROXIMITY_MONITOR)); + auto phys = static_cast<ProximityMonitorComponent*>(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR)); if (phys) { for (auto prox : phys->GetProximitiesData()) { if (!prox.second) continue; @@ -1760,7 +1761,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit Game::config->ReloadConfig(); VanityUtilities::SpawnVanity(); dpWorld::Instance().Reload(); - auto entities = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPTED_ACTIVITY); + auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (auto entity : entities) { auto* scriptedActivityComponent = entity->GetComponent<ScriptedActivityComponent>(); if (!scriptedActivityComponent) continue; @@ -1839,14 +1840,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "inspect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { Entity* closest = nullptr; - int32_t component; + eReplicaComponentType component; std::u16string ldf; bool isLDF = false; if (!GeneralUtils::TryParse(args[0], component)) { - component = -1; + component = eReplicaComponentType::INVALID; ldf = GeneralUtils::UTF8ToUTF16(args[0]); @@ -1906,7 +1907,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit std::stringstream stream; - stream << "Component [" << std::to_string(id) << "]"; + stream << "Component [" << std::to_string(static_cast<uint32_t>(id)) << "]"; ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(stream.str())); } diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 9e8153cc..100efac5 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -32,7 +32,7 @@ #include "CharacterComponent.h" #include "Database.h" #include "dMessageIdentifiers.h" - +#include "eReplicaComponentType.h" void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) { User* user = UserManager::Instance()->GetUser(sysAddr); @@ -89,7 +89,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac Entity* entity = EntityManager::Instance()->GetEntity(user->GetLastUsedChar()->GetObjectID()); if (!entity) return; - ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); + ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!comp) return; /* diff --git a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp index ef81c888..c584f05b 100644 --- a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp @@ -13,6 +13,7 @@ #include "GameMessages.h" #include "SkillComponent.h" +#include "eReplicaComponentType.h" #include <vector> @@ -27,9 +28,9 @@ void BossSpiderQueenEnemyServer::OnStartup(Entity* self) { //self:SetStatusImmunity{ StateChangeType = "PUSH", bImmuneToPullToPoint = true, bImmuneToKnockback = true, bImmuneToInterrupt = true } //Get our components: - destroyable = static_cast<DestroyableComponent*>(self->GetComponent(COMPONENT_TYPE_DESTROYABLE)); - controllable = static_cast<ControllablePhysicsComponent*>(self->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); - combat = static_cast<BaseCombatAIComponent*>(self->GetComponent(COMPONENT_TYPE_BASE_COMBAT_AI)); + destroyable = static_cast<DestroyableComponent*>(self->GetComponent(eReplicaComponentType::DESTROYABLE)); + controllable = static_cast<ControllablePhysicsComponent*>(self->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); + combat = static_cast<BaseCombatAIComponent*>(self->GetComponent(eReplicaComponentType::BASE_COMBAT_AI)); if (!destroyable || !controllable) return; @@ -397,7 +398,7 @@ void BossSpiderQueenEnemyServer::RapidFireShooterManager(Entity* self) { void BossSpiderQueenEnemyServer::RunRapidFireShooter(Entity* self) { /* - const auto targets = EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_CHARACTER); + const auto targets = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); */ const auto targets = self->GetTargetsInPhantom(); diff --git a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp index 8c200566..ce42585c 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp @@ -6,6 +6,7 @@ #include "EntityInfo.h" #include "GeneralUtils.h" #include "DestroyableComponent.h" +#include "eReplicaComponentType.h" void BaseEnemyMech::OnStartup(Entity* self) { auto* destroyableComponent = self->GetComponent<DestroyableComponent>(); @@ -15,7 +16,7 @@ void BaseEnemyMech::OnStartup(Entity* self) { } void BaseEnemyMech::OnDie(Entity* self, Entity* killer) { - ControllablePhysicsComponent* controlPhys = static_cast<ControllablePhysicsComponent*>(self->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); + ControllablePhysicsComponent* controlPhys = static_cast<ControllablePhysicsComponent*>(self->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!controlPhys) return; NiPoint3 newLoc = { controlPhys->GetPosition().x, dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(controlPhys->GetPosition()), controlPhys->GetPosition().z }; diff --git a/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp b/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp index 6d1360de..3c400e5d 100644 --- a/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp +++ b/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp @@ -3,6 +3,7 @@ #include "GameMessages.h" #include "Character.h" #include "EntityManager.h" +#include "eReplicaComponentType.h" void AgCagedBricksServer::OnUse(Entity* self, Entity* user) { //Tell the client to spawn the baby spiderling: @@ -19,7 +20,7 @@ void AgCagedBricksServer::OnUse(Entity* self, Entity* user) { character->SetPlayerFlag(74, true); //Remove the maelstrom cube: - auto inv = static_cast<InventoryComponent*>(user->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto inv = static_cast<InventoryComponent*>(user->GetComponent(eReplicaComponentType::INVENTORY)); if (inv) { inv->RemoveItem(14553, 1); diff --git a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp index 9efae1ca..c09000be 100644 --- a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp +++ b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp @@ -5,10 +5,11 @@ #include "EntityManager.h" #include "AgMonumentLaserServer.h" #include "EntityManager.h" +#include "eReplicaComponentType.h" void AgLaserSensorServer::OnStartup(Entity* self) { - PhantomPhysicsComponent* physComp = static_cast<PhantomPhysicsComponent*>(self->GetComponent(COMPONENT_TYPE_PHANTOM_PHYSICS)); + PhantomPhysicsComponent* physComp = static_cast<PhantomPhysicsComponent*>(self->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); physComp->SetPhysicsEffectActive(true); physComp->SetEffectType(2); // repulse (prolly should make definitions of these are in Entity.cpp) physComp->SetDirectionalMultiplier(static_cast<float>(m_RepelForce)); @@ -25,7 +26,7 @@ void AgLaserSensorServer::OnCollisionPhantom(Entity* self, Entity* target) { Entity* laser = nullptr; - for (auto script : EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_SCRIPT)) { + for (auto script : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT)) { AgMonumentLaserServer* hasLaser = (AgMonumentLaserServer*)script; diff --git a/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp b/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp index 183765d7..8ee2e988 100644 --- a/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp +++ b/dScripts/02_server/Map/AG/NpcNjAssistantServer.cpp @@ -4,6 +4,7 @@ #include "MissionComponent.h" #include "Item.h" #include "eMissionState.h" +#include "eReplicaComponentType.h" void NpcNjAssistantServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionID != mailMission) return; @@ -11,7 +12,7 @@ void NpcNjAssistantServer::OnMissionDialogueOK(Entity* self, Entity* target, int if (missionState == eMissionState::COMPLETE || missionState == eMissionState::READY_TO_COMPLETE) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"switch", 0, 0, LWOOBJID_EMPTY, "", target->GetSystemAddress()); - auto* inv = static_cast<InventoryComponent*>(target->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto* inv = static_cast<InventoryComponent*>(target->GetComponent(eReplicaComponentType::INVENTORY)); // If we are ready to complete our missions, we take the kit from you: if (inv && missionState == eMissionState::READY_TO_COMPLETE) { @@ -22,7 +23,7 @@ void NpcNjAssistantServer::OnMissionDialogueOK(Entity* self, Entity* target, int } } } else if (missionState == eMissionState::AVAILABLE) { - auto* missionComponent = static_cast<MissionComponent*>(target->GetComponent(COMPONENT_TYPE_MISSION)); + auto* missionComponent = static_cast<MissionComponent*>(target->GetComponent(eReplicaComponentType::MISSION)); missionComponent->CompleteMission(mailAchievement, true); } } diff --git a/dScripts/02_server/Map/AG/RemoveRentalGear.cpp b/dScripts/02_server/Map/AG/RemoveRentalGear.cpp index 6e7bd4de..18177e57 100644 --- a/dScripts/02_server/Map/AG/RemoveRentalGear.cpp +++ b/dScripts/02_server/Map/AG/RemoveRentalGear.cpp @@ -3,6 +3,7 @@ #include "Item.h" #include "eMissionState.h" #include "Character.h" +#include "eReplicaComponentType.h" /* -------------------------------------------------------------- @@ -21,7 +22,7 @@ void RemoveRentalGear::OnMissionDialogueOK(Entity* self, Entity* target, int mis if (missionID != defaultMission && missionID != 313) return; if (missionState == eMissionState::COMPLETE || missionState == eMissionState::READY_TO_COMPLETE) { - auto inv = static_cast<InventoryComponent*>(target->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto inv = static_cast<InventoryComponent*>(target->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; //remove the inventory items diff --git a/dScripts/02_server/Map/FV/FvCandle.cpp b/dScripts/02_server/Map/FV/FvCandle.cpp index efd717ee..0c4344d0 100644 --- a/dScripts/02_server/Map/FV/FvCandle.cpp +++ b/dScripts/02_server/Map/FV/FvCandle.cpp @@ -1,11 +1,12 @@ #include "FvCandle.h" #include "MissionComponent.h" #include "RenderComponent.h" +#include "eReplicaComponentType.h" std::vector<int32_t> FvCandle::m_Missions = { 850, 1431, 1529, 1566, 1603 }; void FvCandle::OnStartup(Entity* self) { - auto* render = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* render = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); if (render == nullptr) return; @@ -22,7 +23,7 @@ void FvCandle::BlowOutCandle(Entity* self, Entity* blower) { if (self->GetBoolean(u"AmHit")) return; - auto* render = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* render = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); if (render == nullptr) return; @@ -46,7 +47,7 @@ void FvCandle::BlowOutCandle(Entity* self, Entity* blower) { void FvCandle::OnTimerDone(Entity* self, std::string timerName) { self->SetBoolean(u"AmHit", false); - auto* render = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* render = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); if (render == nullptr) return; diff --git a/dScripts/02_server/Map/GF/GfTikiTorch.cpp b/dScripts/02_server/Map/GF/GfTikiTorch.cpp index db7ee6b5..22420679 100644 --- a/dScripts/02_server/Map/GF/GfTikiTorch.cpp +++ b/dScripts/02_server/Map/GF/GfTikiTorch.cpp @@ -4,6 +4,7 @@ #include "MissionComponent.h" #include "RenderComponent.h" #include "eMissionTaskType.h" +#include "eReplicaComponentType.h" void GfTikiTorch::OnStartup(Entity* self) { LightTorch(self); @@ -42,7 +43,7 @@ void GfTikiTorch::OnTimerDone(Entity* self, std::string timerName) { } void GfTikiTorch::LightTorch(Entity* self) { - auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); if (renderComponent == nullptr) return; diff --git a/dScripts/02_server/Map/General/TokenConsoleServer.cpp b/dScripts/02_server/Map/General/TokenConsoleServer.cpp index f21938d1..5212a9b5 100644 --- a/dScripts/02_server/Map/General/TokenConsoleServer.cpp +++ b/dScripts/02_server/Map/General/TokenConsoleServer.cpp @@ -2,11 +2,12 @@ #include "InventoryComponent.h" #include "GameMessages.h" #include "Character.h" +#include "eReplicaComponentType.h" //2021-05-03 - max - added script, omitted some parts related to inheritance in lua which we don't need void TokenConsoleServer::OnUse(Entity* self, Entity* user) { - auto* inv = static_cast<InventoryComponent*>(user->GetComponent(COMPONENT_TYPE_INVENTORY)); + auto* inv = static_cast<InventoryComponent*>(user->GetComponent(eReplicaComponentType::INVENTORY)); //make sure the user has the required amount of infected bricks if (inv && inv->GetLotCount(6194) >= bricksToTake) { diff --git a/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp b/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp index 00c1b900..7b2495d0 100644 --- a/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp +++ b/dScripts/02_server/Map/General/TouchMissionUpdateServer.cpp @@ -4,6 +4,7 @@ #include "GameMessages.h" #include "MissionComponent.h" #include "eMissionState.h" +#include "eReplicaComponentType.h" void TouchMissionUpdateServer::OnStartup(Entity* self) { self->SetProximityRadius(20, "touchCheck"); // Those does not have a collider for some reason? @@ -16,7 +17,7 @@ void TouchMissionUpdateServer::OnCollisionPhantom(Entity* self, Entity* target) return; } - auto* missionComponent = static_cast<MissionComponent*>(target->GetComponent(COMPONENT_TYPE_MISSION)); + auto* missionComponent = static_cast<MissionComponent*>(target->GetComponent(eReplicaComponentType::MISSION)); if (missionComponent == nullptr) { return; diff --git a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp index 695bd92f..0d4f568e 100644 --- a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "EntityInfo.h" #include "DestroyableComponent.h" +#include "eReplicaComponentType.h" //---------------------------------------------- //--Initiate egg hatching on call @@ -14,7 +15,7 @@ void EnemySpiderSpawner::OnFireEventServerSide(Entity* self, Entity* sender, std GameMessages::SendPlayFXEffect(self->GetObjectID(), 2856, u"maelstrom", "test", LWOOBJID_EMPTY, 1.0f, 1.0f, true); // Make indestructible - auto dest = static_cast<DestroyableComponent*>(self->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + auto dest = static_cast<DestroyableComponent*>(self->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetFaction(-1); } diff --git a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp index b6172df1..215e22c2 100644 --- a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp @@ -7,6 +7,7 @@ #include "RenderComponent.h" #include "MissionComponent.h" #include "eMissionState.h" +#include "eReplicaComponentType.h" void ZoneAgProperty::SetGameVariables(Entity* self) { self->SetVar<std::string>(GuardGroup, "Guard"); @@ -256,7 +257,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { DeactivateSpawner(self->GetVar<std::string>(SpiderScreamSpawner)); DestroySpawner(self->GetVar<std::string>(SpiderScreamSpawner)); - for (auto* player : EntityManager::Instance()->GetEntitiesByComponent(COMPONENT_TYPE_CHARACTER)) { + for (auto* player : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER)) { GameMessages::SendStop2DAmbientSound(player, true, GUIDMaelstrom); GameMessages::SendPlay2DAmbientSound(player, GUIDPeaceful); } diff --git a/dScripts/02_server/Map/SS/SsModularBuildServer.cpp b/dScripts/02_server/Map/SS/SsModularBuildServer.cpp index 82c802cc..dfb29168 100644 --- a/dScripts/02_server/Map/SS/SsModularBuildServer.cpp +++ b/dScripts/02_server/Map/SS/SsModularBuildServer.cpp @@ -1,12 +1,13 @@ #include "SsModularBuildServer.h" #include "MissionComponent.h" #include "eMissionState.h" +#include "eReplicaComponentType.h" void SsModularBuildServer::OnModularBuildExit(Entity* self, Entity* player, bool bCompleted, std::vector<LOT> modules) { int missionNum = 1732; if (bCompleted) { - MissionComponent* mission = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); + MissionComponent* mission = static_cast<MissionComponent*>(player->GetComponent(eReplicaComponentType::MISSION)); Mission* rocketMission = mission->GetMission(missionNum); if (rocketMission->GetMissionState() == eMissionState::ACTIVE) { diff --git a/dScripts/NtFactionSpyServer.cpp b/dScripts/NtFactionSpyServer.cpp index 684e6a0e..dc62855a 100644 --- a/dScripts/NtFactionSpyServer.cpp +++ b/dScripts/NtFactionSpyServer.cpp @@ -5,6 +5,7 @@ #include "GameMessages.h" #include "MissionComponent.h" #include "eMissionState.h" +#include "eReplicaComponentType.h" void NtFactionSpyServer::OnStartup(Entity* self) { SetVariables(self); @@ -13,7 +14,7 @@ void NtFactionSpyServer::OnStartup(Entity* self) { auto* proximityMonitor = self->GetComponent<ProximityMonitorComponent>(); if (proximityMonitor == nullptr) { proximityMonitor = new ProximityMonitorComponent(self, -1, -1); - self->AddComponent(COMPONENT_TYPE_PROXIMITY_MONITOR, proximityMonitor); + self->AddComponent(eReplicaComponentType::PROXIMITY_MONITOR, proximityMonitor); } proximityMonitor->SetProximityRadius(self->GetVar<float_t>(m_SpyProximityVariable), m_ProximityName); diff --git a/dScripts/ScriptComponent.h b/dScripts/ScriptComponent.h index 94226627..77dff5bf 100644 --- a/dScripts/ScriptComponent.h +++ b/dScripts/ScriptComponent.h @@ -9,6 +9,7 @@ #include "CppScripts.h" #include "Component.h" #include <string> +#include "eReplicaComponentType.h" class Entity; @@ -18,7 +19,7 @@ class Entity; */ class ScriptComponent : public Component { public: - static const uint32_t ComponentType = COMPONENT_TYPE_SCRIPT; + static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPT; ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client = false); ~ScriptComponent() override; diff --git a/dScripts/ai/AG/AgFans.cpp b/dScripts/ai/AG/AgFans.cpp index 27d3b940..e05fe68d 100644 --- a/dScripts/ai/AG/AgFans.cpp +++ b/dScripts/ai/AG/AgFans.cpp @@ -4,6 +4,7 @@ #include "GameMessages.h" #include "PhantomPhysicsComponent.h" #include "RenderComponent.h" +#include "eReplicaComponentType.h" void AgFans::OnStartup(Entity* self) { self->SetVar<bool>(u"alive", true); @@ -11,7 +12,7 @@ void AgFans::OnStartup(Entity* self) { ToggleFX(self, false); - auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); if (renderComponent == nullptr) { return; @@ -24,7 +25,7 @@ void AgFans::ToggleFX(Entity* self, bool hit) { std::string fanGroup = self->GetGroups()[0]; std::vector<Entity*> fanVolumes = EntityManager::Instance()->GetEntitiesInGroup(fanGroup); - auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* renderComponent = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); if (renderComponent == nullptr) { return; @@ -39,7 +40,7 @@ void AgFans::ToggleFX(Entity* self, bool hit) { self->SetVar<bool>(u"on", false); for (Entity* volume : fanVolumes) { - PhantomPhysicsComponent* volumePhys = static_cast<PhantomPhysicsComponent*>(volume->GetComponent(COMPONENT_TYPE_PHANTOM_PHYSICS)); + PhantomPhysicsComponent* volumePhys = static_cast<PhantomPhysicsComponent*>(volume->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(false); EntityManager::Instance()->SerializeEntity(volume); @@ -55,7 +56,7 @@ void AgFans::ToggleFX(Entity* self, bool hit) { self->SetVar<bool>(u"on", true); for (Entity* volume : fanVolumes) { - PhantomPhysicsComponent* volumePhys = static_cast<PhantomPhysicsComponent*>(volume->GetComponent(COMPONENT_TYPE_PHANTOM_PHYSICS)); + PhantomPhysicsComponent* volumePhys = static_cast<PhantomPhysicsComponent*>(volume->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(true); EntityManager::Instance()->SerializeEntity(volume); diff --git a/dScripts/ai/AG/AgImagSmashable.cpp b/dScripts/ai/AG/AgImagSmashable.cpp index 195f7b9a..5e8331b1 100644 --- a/dScripts/ai/AG/AgImagSmashable.cpp +++ b/dScripts/ai/AG/AgImagSmashable.cpp @@ -4,12 +4,13 @@ #include "GameMessages.h" #include "EntityInfo.h" #include "DestroyableComponent.h" +#include "eReplicaComponentType.h" void AgImagSmashable::OnDie(Entity* self, Entity* killer) { bool maxImagGreaterThanZero = false; if (killer) { - DestroyableComponent* dest = static_cast<DestroyableComponent*>(killer->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + DestroyableComponent* dest = static_cast<DestroyableComponent*>(killer->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { maxImagGreaterThanZero = dest->GetMaxImagination() > 0; } diff --git a/dScripts/ai/AG/AgJetEffectServer.cpp b/dScripts/ai/AG/AgJetEffectServer.cpp index 8c7eca3b..9546bc4d 100644 --- a/dScripts/ai/AG/AgJetEffectServer.cpp +++ b/dScripts/ai/AG/AgJetEffectServer.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "EntityManager.h" #include "SkillComponent.h" +#include "eReplicaComponentType.h" void AgJetEffectServer::OnUse(Entity* self, Entity* user) { if (inUse) { @@ -86,12 +87,12 @@ void AgJetEffectServer::OnTimerDone(Entity* self, std::string timerName) { auto* mortar = entities[selected]; - Game::logger->Log("AgJetEffectServer", "Mortar (%i) (&d)", mortar->GetLOT(), mortar->HasComponent(COMPONENT_TYPE_SKILL)); + Game::logger->Log("AgJetEffectServer", "Mortar (%i) (&d)", mortar->GetLOT(), mortar->HasComponent(eReplicaComponentType::SKILL)); mortar->SetOwnerOverride(builder); SkillComponent* skillComponent; - if (!mortar->TryGetComponent(COMPONENT_TYPE_SKILL, skillComponent)) { + if (!mortar->TryGetComponent(eReplicaComponentType::SKILL, skillComponent)) { return; } diff --git a/dScripts/ai/AG/AgStromlingProperty.cpp b/dScripts/ai/AG/AgStromlingProperty.cpp index 36d8d378..9a9ae33b 100644 --- a/dScripts/ai/AG/AgStromlingProperty.cpp +++ b/dScripts/ai/AG/AgStromlingProperty.cpp @@ -1,5 +1,6 @@ #include "AgStromlingProperty.h" #include "MovementAIComponent.h" +#include "eReplicaComponentType.h" void AgStromlingProperty::OnStartup(Entity* self) { auto movementInfo = MovementAIInfo{ @@ -12,5 +13,5 @@ void AgStromlingProperty::OnStartup(Entity* self) { }; auto* movementAIComponent = new MovementAIComponent(self, movementInfo); - self->AddComponent(COMPONENT_TYPE_MOVEMENT_AI, movementAIComponent); + self->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAIComponent); } diff --git a/dScripts/ai/GF/GfCampfire.cpp b/dScripts/ai/GF/GfCampfire.cpp index 95e29a9a..6a10b39e 100644 --- a/dScripts/ai/GF/GfCampfire.cpp +++ b/dScripts/ai/GF/GfCampfire.cpp @@ -4,13 +4,14 @@ #include "MissionComponent.h" #include "RenderComponent.h" #include "EntityManager.h" +#include "eReplicaComponentType.h" void GfCampfire::OnStartup(Entity* self) { self->SetI32(u"counter", static_cast<int32_t>(0)); self->SetProximityRadius(2.0f, "placeholder"); self->SetBoolean(u"isBurning", true); - auto* render = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* render = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); if (render == nullptr) return; @@ -20,7 +21,7 @@ void GfCampfire::OnStartup(Entity* self) { void GfCampfire::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { if (args == "physicsReady") { - auto* render = static_cast<RenderComponent*>(self->GetComponent(COMPONENT_TYPE_RENDER)); + auto* render = static_cast<RenderComponent*>(self->GetComponent(eReplicaComponentType::RENDER)); render->PlayEffect(295, u"running", "Burn"); } diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 2948ae3d..703c6bbd 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -14,6 +14,7 @@ #include "Loot.h" #include "InventoryComponent.h" #include "eMissionTaskType.h" +#include "eReplicaComponentType.h" void SGCannon::OnStartup(Entity* self) { Game::logger->Log("SGCannon", "OnStartup"); @@ -295,7 +296,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { if (true) { auto* movementAI = new MovementAIComponent(enemy, {}); - enemy->AddComponent(COMPONENT_TYPE_MOVEMENT_AI, movementAI); + enemy->AddComponent(eReplicaComponentType::MOVEMENT_AI, movementAI); movementAI->SetSpeed(toSpawn.initialSpeed); movementAI->SetCurrentSpeed(toSpawn.initialSpeed); diff --git a/dScripts/ai/NP/NpcNpSpacemanBob.cpp b/dScripts/ai/NP/NpcNpSpacemanBob.cpp index d242d08f..2195f4b4 100644 --- a/dScripts/ai/NP/NpcNpSpacemanBob.cpp +++ b/dScripts/ai/NP/NpcNpSpacemanBob.cpp @@ -2,12 +2,13 @@ #include "DestroyableComponent.h" #include "MissionComponent.h" #include "eMissionState.h" +#include "eReplicaComponentType.h" void NpcNpSpacemanBob::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionState == eMissionState::READY_TO_COMPLETE && missionID == 173) { - DestroyableComponent* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE)); + DestroyableComponent* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(eReplicaComponentType::DESTROYABLE)); destroyable->SetImagination(6); - MissionComponent* mission = static_cast<MissionComponent*>(target->GetComponent(COMPONENT_TYPE_MISSION)); + MissionComponent* mission = static_cast<MissionComponent*>(target->GetComponent(eReplicaComponentType::MISSION)); mission->CompleteMission(664); } diff --git a/dScripts/ai/NS/NsGetFactionMissionServer.cpp b/dScripts/ai/NS/NsGetFactionMissionServer.cpp index d759e3ad..cfecb249 100644 --- a/dScripts/ai/NS/NsGetFactionMissionServer.cpp +++ b/dScripts/ai/NS/NsGetFactionMissionServer.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "MissionComponent.h" #include "Character.h" +#include "eReplicaComponentType.h" void NsGetFactionMissionServer::OnRespondToMission(Entity* self, int missionID, Entity* player, int reward) { if (missionID != 474) return; @@ -44,7 +45,7 @@ void NsGetFactionMissionServer::OnRespondToMission(Entity* self, int missionID, player->GetCharacter()->SetPlayerFlag(flagID, true); } - MissionComponent* mis = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); + MissionComponent* mis = static_cast<MissionComponent*>(player->GetComponent(eReplicaComponentType::MISSION)); for (int mission : factionMissions) { mis->AcceptMission(mission); diff --git a/dScripts/ai/NS/NsModularBuild.cpp b/dScripts/ai/NS/NsModularBuild.cpp index 2e00aa19..1922eb17 100644 --- a/dScripts/ai/NS/NsModularBuild.cpp +++ b/dScripts/ai/NS/NsModularBuild.cpp @@ -1,10 +1,11 @@ #include "NsModularBuild.h" #include "MissionComponent.h" #include "eMissionState.h" +#include "eReplicaComponentType.h" void NsModularBuild::OnModularBuildExit(Entity* self, Entity* player, bool bCompleted, std::vector<LOT> modules) { if (bCompleted) { - MissionComponent* mission = static_cast<MissionComponent*>(player->GetComponent(COMPONENT_TYPE_MISSION)); + MissionComponent* mission = static_cast<MissionComponent*>(player->GetComponent(eReplicaComponentType::MISSION)); if (mission->GetMissionState(m_MissionNum) == eMissionState::ACTIVE) { for (LOT mod : modules) { diff --git a/dScripts/ai/SPEC/SpecialImaginePowerupSpawner.cpp b/dScripts/ai/SPEC/SpecialImaginePowerupSpawner.cpp index c6cab294..43ae9e89 100644 --- a/dScripts/ai/SPEC/SpecialImaginePowerupSpawner.cpp +++ b/dScripts/ai/SPEC/SpecialImaginePowerupSpawner.cpp @@ -4,6 +4,7 @@ #include "SkillComponent.h" #include "DestroyableComponent.h" #include "EntityManager.h" +#include "eReplicaComponentType.h" void SpecialImaginePowerupSpawner::OnStartup(Entity* self) { self->SetProximityRadius(1.5f, "powerupEnter"); @@ -26,7 +27,7 @@ void SpecialImaginePowerupSpawner::OnProximityUpdate(Entity* self, Entity* enter GameMessages::SendPlayFXEffect(self, -1, u"pickup", "", LWOOBJID_EMPTY, 1, 1, true); SkillComponent* skillComponent; - if (!self->TryGetComponent(COMPONENT_TYPE_SKILL, skillComponent)) { + if (!self->TryGetComponent(eReplicaComponentType::SKILL, skillComponent)) { return; } @@ -35,7 +36,7 @@ void SpecialImaginePowerupSpawner::OnProximityUpdate(Entity* self, Entity* enter skillComponent->CalculateBehavior(13, 20, source); DestroyableComponent* destroyableComponent; - if (!self->TryGetComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent)) { + if (!self->TryGetComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent)) { return; } diff --git a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp index 5448a4c2..7399456d 100644 --- a/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/DestroyableComponentTests.cpp @@ -4,6 +4,7 @@ #include "BitStream.h" #include "DestroyableComponent.h" #include "Entity.h" +#include "eReplicaComponentType.h" class DestroyableTest : public GameDependenciesTest { protected: @@ -15,7 +16,7 @@ protected: SetUpDependencies(); baseEntity = new Entity(15, GameDependenciesTest::info); destroyableComponent = new DestroyableComponent(baseEntity); - baseEntity->AddComponent(COMPONENT_TYPE_DESTROYABLE, destroyableComponent); + baseEntity->AddComponent(eReplicaComponentType::DESTROYABLE, destroyableComponent); // Initialize some values to be not default destroyableComponent->SetMaxHealth(12345.0f); destroyableComponent->SetHealth(23); @@ -317,7 +318,7 @@ TEST_F(DestroyableTest, DestroyableComponentFactionTest) { TEST_F(DestroyableTest, DestroyableComponentValiditiyTest) { auto* enemyEntity = new Entity(19, info); auto* enemyDestroyableComponent = new DestroyableComponent(enemyEntity); - enemyEntity->AddComponent(COMPONENT_TYPE_DESTROYABLE, enemyDestroyableComponent); + enemyEntity->AddComponent(eReplicaComponentType::DESTROYABLE, enemyDestroyableComponent); enemyDestroyableComponent->AddFactionNoLookup(16); destroyableComponent->AddEnemyFaction(16); EXPECT_TRUE(destroyableComponent->IsEnemy(enemyEntity)); From 9d65d871d0b0096804523be35c098feeea7c9bb0 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sun, 5 Mar 2023 13:11:32 -0600 Subject: [PATCH 139/166] fix compatibility with nexus dash (#1011) * add some more utility to the masterserver -a command fix compatability with nexus dash * cleanup code some more user logger where it makes sense only take in password if it is needed log a better error if account cannot be created * update message * return before success statement if catching error --- dMasterServer/MasterServer.cpp | 88 +++++++++++++++++++-------- migrations/dlu/8_foreign_play_key.sql | 1 + 2 files changed, 64 insertions(+), 25 deletions(-) create mode 100644 migrations/dlu/8_foreign_play_key.sql diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 77571e22..bcf1a540 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -212,43 +212,81 @@ int main(int argc, char** argv) { std::cout << "Enter a username: "; std::cin >> username; + std::unique_ptr<sql::PreparedStatement> userLookupStatement(Database::CreatePreppedStmt("SELECT id FROM accounts WHERE name=? LIMIT 1;")); + userLookupStatement->setString(1, username.c_str()); + std::unique_ptr<sql::ResultSet> res(userLookupStatement->executeQuery()); + if (res->rowsCount() > 0) { + Game::logger->Log("MasterServer", "Account with name \"%s\" already exists", username.c_str()); + std::cout << "Do you want to change the password of that account? [y/n]?"; + std::string prompt = ""; + std::cin >> prompt; + if (prompt == "y" || prompt == "yes"){ + uint32_t accountId = 0; + res->next(); + accountId = res->getUInt(1); + if (accountId == 0) return EXIT_FAILURE; + + //Read the password from the console without echoing it. + #ifdef __linux__ + //This function is obsolete, but it only meant to be used by the + //sysadmin to create their first account. + password = getpass("Enter a password: "); + #else + std::cout << "Enter a password: "; + std::cin >> password; + #endif + + // Regenerate hash based on new password + char salt[BCRYPT_HASHSIZE]; + char hash[BCRYPT_HASHSIZE]; + int32_t bcryptState = ::bcrypt_gensalt(12, salt); + assert(bcryptState == 0); + bcryptState = ::bcrypt_hashpw(password.c_str(), salt, hash); + assert(bcryptState == 0); + + std::unique_ptr<sql::PreparedStatement> userUpdateStatement(Database::CreatePreppedStmt("UPDATE accounts SET password = ? WHERE id = ?;")); + userUpdateStatement->setString(1, std::string(hash, BCRYPT_HASHSIZE).c_str()); + userUpdateStatement->setUInt(2, accountId); + userUpdateStatement->execute(); + + Game::logger->Log("MasterServer", "Account \"%s\" password updated successfully!", username.c_str()); + } else { + Game::logger->Log("MasterServer", "Account \"%s\" was not updated.", username.c_str()); + } + return EXIT_SUCCESS; + } + //Read the password from the console without echoing it. -#ifdef __linux__ - //This function is obsolete, but it only meant to be used by the - //sysadmin to create their first account. - password = getpass("Enter a password: "); -#else - std::cout << "Enter a password: "; - std::cin >> password; -#endif + #ifdef __linux__ + //This function is obsolete, but it only meant to be used by the + //sysadmin to create their first account. + password = getpass("Enter a password: "); + #else + std::cout << "Enter a password: "; + std::cin >> password; + #endif //Generate new hash for bcrypt - char salt[BCRYPT_HASHSIZE]; char hash[BCRYPT_HASHSIZE]; - int32_t bcryptState = ::bcrypt_gensalt(12, salt); - assert(bcryptState == 0); - bcryptState = ::bcrypt_hashpw(password.c_str(), salt, hash); - assert(bcryptState == 0); //Create account + try { + std::unique_ptr<sql::PreparedStatement> statement(Database::CreatePreppedStmt("INSERT INTO accounts (name, password, gm_level) VALUES (?, ?, ?);")); + statement->setString(1, username.c_str()); + statement->setString(2, std::string(hash, BCRYPT_HASHSIZE).c_str()); + statement->setInt(3, 9); + statement->execute(); + } catch(sql::SQLException& e) { + Game::logger->Log("MasterServer", "A SQL error occurred!:\n %s", e.what()); + return EXIT_FAILURE; + } - auto* statement = Database::CreatePreppedStmt("INSERT INTO accounts (name, password, ""gm_level) VALUES (?, ?, ?);"); - statement->setString(1, username.c_str()); - statement->setString(2, std::string(hash, BCRYPT_HASHSIZE).c_str()); - statement->setInt(3, 9); - - statement->execute(); - - delete statement; - - std::cout << "Account created successfully!\n"; - - + Game::logger->Log("MasterServer", "Account created successfully!"); return EXIT_SUCCESS; } diff --git a/migrations/dlu/8_foreign_play_key.sql b/migrations/dlu/8_foreign_play_key.sql new file mode 100644 index 00000000..6f171bb5 --- /dev/null +++ b/migrations/dlu/8_foreign_play_key.sql @@ -0,0 +1 @@ +ALTER TABLE accounts MODIFY play_key_id INT DEFAULT NULL; From 49047a267b9f78af4a814b262ae0908dd5828b6a Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 5 Mar 2023 12:34:59 -0800 Subject: [PATCH 140/166] Fix racing imagination loss on death (#1006) * Fix imagination on death * Fix defaults * Fix visuals --- dCommon/dEnums/dMessageIdentifiers.h | 2 + dGame/dComponents/RacingControlComponent.cpp | 81 ++++++++++++-------- dGame/dGameMessages/GameMessages.cpp | 30 ++++++++ dGame/dGameMessages/GameMessages.h | 6 +- 4 files changed, 85 insertions(+), 34 deletions(-) diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index c1afc497..e11f9e7f 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -546,6 +546,8 @@ enum GAME_MSG : unsigned short { GAME_MSG_REMOVE_RUN_SPEED_MODIFIER = 1506, GAME_MSG_UPDATE_PROPERTY_PERFORMANCE_COST = 1547, GAME_MSG_PROPERTY_ENTRANCE_BEGIN = 1553, + GAME_MSG_SET_RESURRECT_RESTORE_VALUES = 1591, + GAME_MSG_VEHICLE_STOP_BOOST = 1617, GAME_MSG_REMOVE_BUFF = 1648, GAME_MSG_REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1666, GAME_MSG_RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1667, diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 4b27ac0f..fe4f1faf 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -306,30 +306,58 @@ void RacingControlComponent::OnRequestDie(Entity* player) { auto* vehicle = EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); - if (vehicle == nullptr) { - return; - } + if (!vehicle) return; if (!racingPlayer.noSmashOnReload) { racingPlayer.smashedTimes++; + GameMessages::SendDie(vehicle, vehicle->GetObjectID(), LWOOBJID_EMPTY, true, + VIOLENT, u"", 0, 0, 90.0f, false, true, 0); + + auto* destroyableComponent = vehicle->GetComponent<DestroyableComponent>(); + uint32_t respawnImagination = 0; + // Reset imagination to half its current value, rounded up to the nearest value divisible by 10, as it was done in live. + // Do not actually change the value yet. Do that on respawn. + if (destroyableComponent) { + respawnImagination = static_cast<int32_t>(ceil(destroyableComponent->GetImagination() / 2.0f / 10.0f)) * 10.0f; + GameMessages::SendSetResurrectRestoreValues(vehicle, -1, -1, respawnImagination); + } + + // Respawn the player in 2 seconds, as was done in live. Not sure if this value is in a setting somewhere else... + vehicle->AddCallbackTimer(2.0f, [=]() { + if (!vehicle || !this->m_Parent) return; + GameMessages::SendRacingResetPlayerToLastReset( + m_Parent->GetObjectID(), racingPlayer.playerID, + UNASSIGNED_SYSTEM_ADDRESS); + + GameMessages::SendVehicleStopBoost(vehicle, player->GetSystemAddress(), true); + + GameMessages::SendRacingSetPlayerResetInfo( + m_Parent->GetObjectID(), racingPlayer.lap, + racingPlayer.respawnIndex, player->GetObjectID(), + racingPlayer.respawnPosition, racingPlayer.respawnIndex + 1, + UNASSIGNED_SYSTEM_ADDRESS); + + GameMessages::SendResurrect(vehicle); + auto* destroyableComponent = vehicle->GetComponent<DestroyableComponent>(); + // Reset imagination to half its current value, rounded up to the nearest value divisible by 10, as it was done in live. + if (destroyableComponent) destroyableComponent->SetImagination(respawnImagination); + EntityManager::Instance()->SerializeEntity(vehicle); + }); + + auto* characterComponent = player->GetComponent<CharacterComponent>(); + if (characterComponent != nullptr) { + characterComponent->UpdatePlayerStatistic(RacingTimesWrecked); + } + } else { + GameMessages::SendRacingSetPlayerResetInfo( + m_Parent->GetObjectID(), racingPlayer.lap, + racingPlayer.respawnIndex, player->GetObjectID(), + racingPlayer.respawnPosition, racingPlayer.respawnIndex + 1, + UNASSIGNED_SYSTEM_ADDRESS); + GameMessages::SendRacingResetPlayerToLastReset( + m_Parent->GetObjectID(), racingPlayer.playerID, + UNASSIGNED_SYSTEM_ADDRESS); } - - // Reset player to last checkpoint - GameMessages::SendRacingSetPlayerResetInfo( - m_Parent->GetObjectID(), racingPlayer.lap, - racingPlayer.respawnIndex, player->GetObjectID(), - racingPlayer.respawnPosition, racingPlayer.respawnIndex + 1, - UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendRacingResetPlayerToLastReset( - m_Parent->GetObjectID(), racingPlayer.playerID, - UNASSIGNED_SYSTEM_ADDRESS); - - auto* characterComponent = player->GetComponent<CharacterComponent>(); - if (characterComponent != nullptr) { - characterComponent->UpdatePlayerStatistic(RacingTimesWrecked); - } - - return; } } @@ -348,19 +376,6 @@ void RacingControlComponent::OnRacingPlayerInfoResetFinished(Entity* player) { return; } - if (!racingPlayer.noSmashOnReload) { - GameMessages::SendDie(vehicle, LWOOBJID_EMPTY, LWOOBJID_EMPTY, true, - VIOLENT, u"", 0, 0, 0, true, false, 0); - - GameMessages::SendVehicleUnlockInput(racingPlayer.vehicleID, false, - UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendVehicleSetWheelLockState( - racingPlayer.vehicleID, false, false, - UNASSIGNED_SYSTEM_ADDRESS); - - GameMessages::SendResurrect(vehicle); - } - racingPlayer.noSmashOnReload = false; return; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 9dcd2d74..c8860283 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4396,6 +4396,36 @@ void GameMessages::SendRacingResetPlayerToLastReset(LWOOBJID objectId, LWOOBJID SEND_PACKET; } +void GameMessages::SendVehicleStopBoost(Entity* targetEntity, const SystemAddress& playerSysAddr, bool affectPassive) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(targetEntity->GetObjectID()); + bitStream.Write(GAME_MSG::GAME_MSG_VEHICLE_STOP_BOOST); + + bitStream.Write(affectPassive); + + SEND_PACKET_BROADCAST; +} + +void GameMessages::SendSetResurrectRestoreValues(Entity* targetEntity, int32_t armorRestore, int32_t healthRestore, int32_t imaginationRestore) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(targetEntity->GetObjectID()); + bitStream.Write(GAME_MSG::GAME_MSG_SET_RESURRECT_RESTORE_VALUES); + + bitStream.Write(armorRestore != -1); + if (armorRestore != -1) bitStream.Write(armorRestore); + + bitStream.Write(healthRestore != -1); + if (healthRestore != -1) bitStream.Write(healthRestore); + + bitStream.Write(imaginationRestore != -1); + if (imaginationRestore != -1) bitStream.Write(imaginationRestore); + + SEND_PACKET_BROADCAST; +} void GameMessages::SendNotifyRacingClient(LWOOBJID objectId, int32_t eventType, int32_t param1, LWOOBJID paramObj, std::u16string paramStr, LWOOBJID singleClient, const SystemAddress& sysAddr) { CBITSTREAM; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 0675ae76..5d199995 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -31,7 +31,8 @@ namespace GameMessages { void SendPlayerAllowedRespawn(LWOOBJID entityID, bool doNotPromptRespawn, const SystemAddress& systemAddress); void SendInvalidZoneTransferList(Entity* entity, const SystemAddress& sysAddr, const std::u16string& feedbackURL, const std::u16string& invalidMapTransferList, bool feedbackOnExit, bool feedbackOnInvalidTransfer); void SendKnockback(const LWOOBJID& objectID, const LWOOBJID& caster, const LWOOBJID& originator, int knockBackTimeMS, const NiPoint3& vector); - + // https://lcdruniverse.org/lu_packets/lu_packets/world/gm/client/struct.VehicleStopBoost.html + void SendVehicleStopBoost(Entity* targetEntity, const SystemAddress& playerSysAddr, bool affectPassive); void SendStartArrangingWithItem( Entity* entity, const SystemAddress& sysAddr, @@ -125,6 +126,9 @@ namespace GameMessages { void HandleUnUseModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void SendStartCelebrationEffect(Entity* entity, const SystemAddress& sysAddr, int celebrationID); + // https://lcdruniverse.org/lu_packets/lu_packets/world/gm/client/struct.SetResurrectRestoreValues.html + void SendSetResurrectRestoreValues(Entity* targetEntity, int32_t armorRestore, int32_t healthRestore, int32_t imaginationRestore); + /** * Sends a message to an Entity to smash itself, but not delete or destroy itself from the world * From ff0336793cfd051adf70a4cdddadb5894c6b374f Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Wed, 8 Mar 2023 07:31:45 -0600 Subject: [PATCH 141/166] add stun immunity script (#1015) several summons use this script to be immune to stuns --- dScripts/CppScripts.cpp | 3 +++ dScripts/EquipmentScripts/CMakeLists.txt | 3 ++- dScripts/EquipmentScripts/StunImmunity.cpp | 19 +++++++++++++++++++ dScripts/EquipmentScripts/StunImmunity.h | 6 ++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 dScripts/EquipmentScripts/StunImmunity.cpp create mode 100644 dScripts/EquipmentScripts/StunImmunity.h diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 745a74ae..24b30dee 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -281,6 +281,7 @@ #include "GemPack.h" #include "ShardArmor.h" #include "TeslaPack.h" +#include "StunImmunity.h" // Survival scripts #include "AgSurvivalStromling.h" @@ -846,6 +847,8 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr script = new ShardArmor(); else if (scriptName == "scripts\\equipmenttriggers\\coilbackpack.lua") script = new TeslaPack(); + else if (scriptName == "scripts\\EquipmentScripts\\stunImmunity.lua") + script = new StunImmunity(); // FB else if (scriptName == "scripts\\ai\\NS\\WH\\L_ROCKHYDRANT_BROKEN.lua") diff --git a/dScripts/EquipmentScripts/CMakeLists.txt b/dScripts/EquipmentScripts/CMakeLists.txt index c870ae31..696be03d 100644 --- a/dScripts/EquipmentScripts/CMakeLists.txt +++ b/dScripts/EquipmentScripts/CMakeLists.txt @@ -1,4 +1,4 @@ -set(DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS +set(DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS "Sunflower.cpp" "AnvilOfArmor.cpp" "FountainOfImagination.cpp" @@ -6,4 +6,5 @@ set(DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS "PersonalFortress.cpp" "BuccaneerValiantShip.cpp" "FireFirstSkillonStartup.cpp" + "StunImmunity.cpp" PARENT_SCOPE) diff --git a/dScripts/EquipmentScripts/StunImmunity.cpp b/dScripts/EquipmentScripts/StunImmunity.cpp new file mode 100644 index 00000000..f35fe261 --- /dev/null +++ b/dScripts/EquipmentScripts/StunImmunity.cpp @@ -0,0 +1,19 @@ +#include "StunImmunity.h" +#include "DestroyableComponent.h" +#include "ControllablePhysicsComponent.h" + +void StunImmunity::OnStartup(Entity* self) { + auto* destroyableComponent = self->GetComponent<DestroyableComponent>(); + if (destroyableComponent) { + destroyableComponent->SetStatusImmunity( + eStateChangeType::PUSH, false, false, true, true, false, false, false, false, true + ); + } + + auto* controllablePhysicsComponent = self->GetComponent<ControllablePhysicsComponent>(); + if (controllablePhysicsComponent) { + controllablePhysicsComponent->SetStunImmunity( + eStateChangeType::PUSH, self->GetObjectID(), true + ); + } +} diff --git a/dScripts/EquipmentScripts/StunImmunity.h b/dScripts/EquipmentScripts/StunImmunity.h new file mode 100644 index 00000000..0faaf061 --- /dev/null +++ b/dScripts/EquipmentScripts/StunImmunity.h @@ -0,0 +1,6 @@ +#pragma once +#include "CppScripts.h" + +class StunImmunity : public CppScripts::Script { + void OnStartup(Entity* self) override; +}; From a532bc15d8cc2d0bb5b22d3bb6b64f7847d7d66e Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 8 Mar 2023 05:32:03 -0800 Subject: [PATCH 142/166] Fix zombie bug (#1014) --- dGame/dGameMessages/GameMessages.cpp | 22 +++++++++++++++------- dScripts/ai/ACT/ActPlayerDeathTrigger.cpp | 2 ++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c8860283..8da37bf5 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -915,15 +915,23 @@ void GameMessages::SendSetJetPackMode(Entity* entity, bool use, bool bypassCheck } void GameMessages::SendResurrect(Entity* entity) { - DestroyableComponent* dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); + // Restore the players health after the animation for respawning has finished. + // This is when the health appered back in live, not immediately upon requesting respawn + // Add a half second in case someone decides to cheat and move during the death animation + // and just make sure the client has time to be ready. + constexpr float respawnTime = 3.66700005531311f + 0.5f; + entity->AddCallbackTimer(respawnTime, [=]() { + auto* destroyableComponent = entity->GetComponent<DestroyableComponent>(); - if (dest != nullptr && entity->GetLOT() == 1) { - auto* levelComponent = entity->GetComponent<LevelProgressionComponent>(); - if (levelComponent) { - dest->SetHealth(levelComponent->GetLevel() >= 45 ? 8 : 4); - dest->SetImagination(levelComponent->GetLevel() >= 45 ? 20 : 6); + if (destroyableComponent != nullptr && entity->GetLOT() == 1) { + auto* levelComponent = entity->GetComponent<LevelProgressionComponent>(); + if (levelComponent) { + destroyableComponent->SetHealth(levelComponent->GetLevel() >= 45 ? 8 : 4); + destroyableComponent->SetImagination(levelComponent->GetLevel() >= 45 ? 20 : 6); + } } - } + }); + auto cont = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (cont && entity->GetLOT() == 1) { diff --git a/dScripts/ai/ACT/ActPlayerDeathTrigger.cpp b/dScripts/ai/ACT/ActPlayerDeathTrigger.cpp index 28f1ef43..0674f0dd 100644 --- a/dScripts/ai/ACT/ActPlayerDeathTrigger.cpp +++ b/dScripts/ai/ACT/ActPlayerDeathTrigger.cpp @@ -1,5 +1,7 @@ #include "ActPlayerDeathTrigger.h" +#include "Entity.h" + void ActPlayerDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { if (!target->IsPlayer() || target->GetIsDead() || !target->GetPlayerReadyForUpdates()) return; //Don't kill already dead players or players not ready From 137a5e5c3d5d443883b95bdedde55be2528a6f53 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 12 Mar 2023 07:21:27 -0700 Subject: [PATCH 143/166] Players no longer respawn if they were alive at the end of Battle of Nimbus Station (#1017) --- dScripts/02_server/Map/NS/Waves/ZoneNsWaves.h | 2 ++ dScripts/BaseWavesServer.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.h b/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.h index 06503d19..637aceb7 100644 --- a/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.h +++ b/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.h @@ -1,6 +1,8 @@ #pragma once #include "BaseWavesServer.h" +#include "dCommonVars.h" + enum SpawnerName { interior_A, interior_B, diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index ad40a77d..00340bd0 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -430,7 +430,7 @@ void BaseWavesServer::SpawnWave(Entity* self) { for (const auto& playerID : state.players) { auto* player = EntityManager::Instance()->GetEntity(playerID); - if (player != nullptr) { + if (player && player->GetIsDead()) { player->Resurrect(); } } From c3723371cf27775e12ed071e263332d1e31762ec Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 14 Mar 2023 04:12:26 -0700 Subject: [PATCH 144/166] Patch divide by zero when advancing waypoints (#1020) --- dGame/dComponents/MovementAIComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index fa54eb6d..1f774690 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -93,7 +93,7 @@ void MovementAIComponent::Update(const float deltaTime) { NiPoint3 velocity = NiPoint3::ZERO; - if (AdvanceWaypointIndex()) // Do we have another waypoint to seek? + if (m_Acceleration > 0 && m_BaseSpeed > 0 && AdvanceWaypointIndex()) // Do we have another waypoint to seek? { m_NextWaypoint = GetCurrentWaypoint(); From 2bcf862f9308215a4184d8565a46bdaeaa65a43c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 14 Mar 2023 05:50:12 -0700 Subject: [PATCH 145/166] Development inventory command improvements (#1022) --- dGame/dUtilities/SlashCommandHandler.cpp | 50 +++++++++++++++++------- docs/Commands.md | 2 +- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 443ba41d..fb9485b8 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -552,21 +552,42 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { - if (args.size() != 1) return; - + if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { uint32_t size; - if (!GeneralUtils::TryParse(args[0], size)) { + if (!GeneralUtils::TryParse(args.at(0), size)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid size."); return; } - InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY)); - if (inventory) { - auto* items = inventory->GetInventory(ITEMS); + eInventoryType selectedInventory = eInventoryType::ITEMS; - items->SetSize(size); + // a possible inventory was provided if we got more than 1 argument + if (args.size() >= 2) { + selectedInventory = eInventoryType::INVALID; + if (!GeneralUtils::TryParse(args.at(1), selectedInventory)) { + // In this case, we treat the input as a string and try to find it in the reflection list + std::transform(args.at(1).begin(), args.at(1).end(), args.at(1).begin(), ::toupper); + for (uint32_t index = 0; index < NUMBER_OF_INVENTORIES; index++) { + if (std::string_view(args.at(1)) == std::string_view(InventoryType::InventoryTypeToString(static_cast<eInventoryType>(index)))) selectedInventory = static_cast<eInventoryType>(index); + } + } + if (selectedInventory == eInventoryType::INVALID) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid inventory."); + return; + } + + ChatPackets::SendSystemMessage(sysAddr, u"Setting inventory " + + GeneralUtils::ASCIIToUTF16(args.at(1)) + + u" to size " + + GeneralUtils::to_u16string(size)); + } else ChatPackets::SendSystemMessage(sysAddr, u"Setting inventory ITEMS to size " + GeneralUtils::to_u16string(size)); + + auto* inventoryComponent = entity->GetComponent<InventoryComponent>(); + if (inventoryComponent) { + auto* inventory = inventoryComponent->GetInventory(selectedInventory); + + inventory->SetSize(size); } return; @@ -581,10 +602,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto buf = Game::assetManager->GetFileAsBuffer(("macros/" + args[0] + ".scm").c_str()); - if (!buf.m_Success){ + if (!buf.m_Success) { ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?"); return; - } + } std::istream infile(&buf); @@ -1331,9 +1352,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit eLootSourceType lootType = eLootSourceType::LOOT_SOURCE_MODERATION; int32_t type; - if (args.size() >= 2 && GeneralUtils::TryParse(args[1], type)) - { - lootType = (eLootSourceType) type; + if (args.size() >= 2 && GeneralUtils::TryParse(args[1], type)) { + lootType = (eLootSourceType)type; } GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType); @@ -1814,7 +1834,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit eInventoryType inventoryType = eInventoryType::INVALID; if (!GeneralUtils::TryParse(args[0], inventoryType)) { // In this case, we treat the input as a string and try to find it in the reflection list - std::transform(args[0].begin(), args[0].end(),args[0].begin(), ::toupper); + std::transform(args[0].begin(), args[0].end(), args[0].begin(), ::toupper); Game::logger->Log("SlashCommandHandler", "looking for inventory %s", args[0].c_str()); for (uint32_t index = 0; index < NUMBER_OF_INVENTORIES; index++) { if (std::string_view(args[0]) == std::string_view(InventoryType::InventoryTypeToString(static_cast<eInventoryType>(index)))) inventoryType = static_cast<eInventoryType>(index); @@ -1988,7 +2008,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } auto* triggerComponent = closest->GetComponent<TriggerComponent>(); - if (triggerComponent){ + if (triggerComponent) { auto trigger = triggerComponent->GetTrigger(); if (trigger) { ChatPackets::SendSystemMessage(sysAddr, u"Trigger: " + (GeneralUtils::to_u16string(trigger->id))); diff --git a/docs/Commands.md b/docs/Commands.md index 7dc11ff1..a9cd3e7c 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -92,7 +92,7 @@ These commands are primarily for development and testing. The usage of many of t |setcontrolscheme|`/setcontrolscheme <scheme number>`|Sets the character control scheme to the specified number.|8| |setcurrency|`/setcurrency <coins>`|Sets your coins.|8| |setflag|`/setflag (value) <flag id>`|Sets the given inventory or health flag to the given value, where value can be one of "on" or "off". If no value is given, by default this adds the flag to your character (equivalent of calling `/setflag on <flag id>`).|8| -|setinventorysize|`/setinventorysize <size>`|Sets your inventory size to the given size. Alias: `/setinvsize`|8| +|setinventorysize|`/setinventorysize <size> (inventory)`|Sets your inventory size to the given size. If `inventory` is provided, the number or string will be used to set that inventory to the requested size. Alias: `/setinvsize`|8| |setuistate|`/setuistate <ui state>`|Changes UI state.|8| |spawn|`/spawn <id>`|Spawns an object at your location by id.|8| |speedboost|`/speedboost <amount>`|Sets the speed multiplier to the given amount. `/speedboost 1.5` will set the speed multiplier to 1.5x the normal speed.|8| From bd79e9433c27e4c51721e62278efd30de25fb55f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 17 Mar 2023 02:48:47 -0700 Subject: [PATCH 146/166] Increase Battle of Nimbus Station end of match timer to 60 seconds (#1018) as per the live script This is now the third time this has been updated lol --- dScripts/02_server/Map/NS/Waves/ZoneNsWaves.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.cpp b/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.cpp index 6f78acb6..184132fe 100644 --- a/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.cpp +++ b/dScripts/02_server/Map/NS/Waves/ZoneNsWaves.cpp @@ -439,7 +439,7 @@ std::vector<Wave> ZoneNsWaves::GetWaves() { 5.0f, (uint32_t)-1, true, - 30, + 60, }, }; } From 7671cc6865222cd8d191a50dc8856b7166d42fde Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 17 Mar 2023 07:36:21 -0700 Subject: [PATCH 147/166] CDClient cleanup and optimization (#1023) * CDClient cleanup and optimization - Use static function to get table name - Remove unused GetName function - Replace above function with a static GetTableName function - Remove verbose comments - Remove verbose initializers - Remove need to specify table name when getting a table by name - Remove unused typedef for mac and linux * Re-add unused table Convert tables to singletons - Convert all CDClient tables to singletons - Move Singleton.h to dCommon - Reduce header clutter in CDClientManager --- {dPhysics => dCommon}/Singleton.h | 0 dCommon/dEnums/dCommonVars.h | 5 - dDatabase/CDClientManager.cpp | 120 +++++++++++------- dDatabase/CDClientManager.h | 96 ++------------ dDatabase/Tables/CDActivitiesTable.cpp | 11 -- dDatabase/Tables/CDActivitiesTable.h | 34 +---- dDatabase/Tables/CDActivityRewardsTable.cpp | 11 -- dDatabase/Tables/CDActivityRewardsTable.h | 33 +---- dDatabase/Tables/CDAnimationsTable.cpp | 11 -- dDatabase/Tables/CDAnimationsTable.h | 33 +---- dDatabase/Tables/CDBehaviorParameterTable.cpp | 9 -- dDatabase/Tables/CDBehaviorParameterTable.h | 23 +--- dDatabase/Tables/CDBehaviorTemplateTable.cpp | 11 -- dDatabase/Tables/CDBehaviorTemplateTable.h | 32 +---- dDatabase/Tables/CDBrickIDTableTable.cpp | 11 -- dDatabase/Tables/CDBrickIDTableTable.h | 26 +--- .../Tables/CDComponentsRegistryTable.cpp | 37 ------ dDatabase/Tables/CDComponentsRegistryTable.h | 23 +--- dDatabase/Tables/CDCurrencyTableTable.cpp | 10 -- dDatabase/Tables/CDCurrencyTableTable.h | 26 +--- .../Tables/CDDestructibleComponentTable.cpp | 10 -- .../Tables/CDDestructibleComponentTable.h | 33 +---- dDatabase/Tables/CDEmoteTable.cpp | 5 - dDatabase/Tables/CDEmoteTable.h | 26 +--- dDatabase/Tables/CDFeatureGatingTable.cpp | 10 -- dDatabase/Tables/CDFeatureGatingTable.h | 32 +---- .../Tables/CDInventoryComponentTable.cpp | 10 -- dDatabase/Tables/CDInventoryComponentTable.h | 33 +---- dDatabase/Tables/CDItemComponentTable.cpp | 8 -- dDatabase/Tables/CDItemComponentTable.h | 25 +--- dDatabase/Tables/CDItemSetSkillsTable.cpp | 11 -- dDatabase/Tables/CDItemSetSkillsTable.h | 34 +---- dDatabase/Tables/CDItemSetsTable.cpp | 10 -- dDatabase/Tables/CDItemSetsTable.h | 33 +---- .../Tables/CDLevelProgressionLookupTable.cpp | 8 -- .../Tables/CDLevelProgressionLookupTable.h | 34 +---- dDatabase/Tables/CDLootMatrixTable.cpp | 10 -- dDatabase/Tables/CDLootMatrixTable.h | 33 +---- dDatabase/Tables/CDLootTableTable.cpp | 8 -- dDatabase/Tables/CDLootTableTable.h | 33 +---- dDatabase/Tables/CDMissionEmailTable.cpp | 8 -- dDatabase/Tables/CDMissionEmailTable.h | 33 +---- .../Tables/CDMissionNPCComponentTable.cpp | 8 -- dDatabase/Tables/CDMissionNPCComponentTable.h | 33 +---- dDatabase/Tables/CDMissionTasksTable.cpp | 10 -- dDatabase/Tables/CDMissionTasksTable.h | 32 +---- dDatabase/Tables/CDMissionsTable.cpp | 10 -- dDatabase/Tables/CDMissionsTable.h | 33 +---- .../Tables/CDMovementAIComponentTable.cpp | 8 -- dDatabase/Tables/CDMovementAIComponentTable.h | 35 +---- dDatabase/Tables/CDObjectSkillsTable.cpp | 9 -- dDatabase/Tables/CDObjectSkillsTable.h | 33 +---- dDatabase/Tables/CDObjectsTable.cpp | 8 -- dDatabase/Tables/CDObjectsTable.h | 27 +--- dDatabase/Tables/CDPackageComponentTable.cpp | 8 -- dDatabase/Tables/CDPackageComponentTable.h | 32 +---- dDatabase/Tables/CDPhysicsComponentTable.cpp | 6 +- dDatabase/Tables/CDPhysicsComponentTable.h | 8 +- .../CDPropertyEntranceComponentTable.cpp | 6 - .../Tables/CDPropertyEntranceComponentTable.h | 24 +--- dDatabase/Tables/CDPropertyTemplateTable.cpp | 6 - dDatabase/Tables/CDPropertyTemplateTable.h | 5 +- .../CDProximityMonitorComponentTable.cpp | 8 -- .../Tables/CDProximityMonitorComponentTable.h | 30 +---- dDatabase/Tables/CDRailActivatorComponent.cpp | 6 - dDatabase/Tables/CDRailActivatorComponent.h | 6 +- dDatabase/Tables/CDRarityTableTable.cpp | 8 -- dDatabase/Tables/CDRarityTableTable.h | 36 +----- dDatabase/Tables/CDRebuildComponentTable.cpp | 8 -- dDatabase/Tables/CDRebuildComponentTable.h | 35 +---- dDatabase/Tables/CDRewardsTable.cpp | 4 - dDatabase/Tables/CDRewardsTable.h | 8 +- dDatabase/Tables/CDScriptComponentTable.cpp | 8 -- dDatabase/Tables/CDScriptComponentTable.h | 30 +---- dDatabase/Tables/CDSkillBehaviorTable.cpp | 16 --- dDatabase/Tables/CDSkillBehaviorTable.h | 30 +---- dDatabase/Tables/CDTable.h | 28 +--- dDatabase/Tables/CDVendorComponentTable.cpp | 8 -- dDatabase/Tables/CDVendorComponentTable.h | 33 +---- dDatabase/Tables/CDZoneTableTable.cpp | 8 -- dDatabase/Tables/CDZoneTableTable.h | 27 +--- dGame/Entity.cpp | 34 +++-- dGame/LeaderboardManager.cpp | 6 +- dGame/dBehaviors/Behavior.cpp | 11 +- dGame/dBehaviors/OverTimeBehavior.cpp | 4 +- dGame/dComponents/BaseCombatAIComponent.cpp | 6 +- dGame/dComponents/BuffComponent.cpp | 3 +- dGame/dComponents/DestroyableComponent.cpp | 6 +- dGame/dComponents/InventoryComponent.cpp | 24 ++-- .../dComponents/LevelProgressionComponent.cpp | 4 +- dGame/dComponents/MissionComponent.cpp | 10 +- dGame/dComponents/MissionOfferComponent.cpp | 6 +- dGame/dComponents/MovementAIComponent.cpp | 7 +- dGame/dComponents/PhantomPhysicsComponent.cpp | 8 +- .../dComponents/PropertyEntranceComponent.cpp | 2 +- dGame/dComponents/RailActivatorComponent.cpp | 3 +- dGame/dComponents/RenderComponent.cpp | 2 +- .../dComponents/ScriptedActivityComponent.cpp | 14 +- dGame/dComponents/ScriptedActivityComponent.h | 2 + dGame/dComponents/SkillComponent.cpp | 4 +- dGame/dComponents/TriggerComponent.cpp | 2 +- dGame/dComponents/VendorComponent.cpp | 13 +- dGame/dGameMessages/GameMessageHandler.cpp | 2 +- dGame/dGameMessages/GameMessages.cpp | 19 +-- dGame/dGameMessages/PropertyDataMessage.cpp | 5 +- dGame/dInventory/Inventory.cpp | 8 +- dGame/dInventory/Inventory.h | 2 +- dGame/dInventory/Item.cpp | 15 ++- dGame/dInventory/ItemSet.cpp | 6 +- dGame/dMission/Mission.cpp | 12 +- dGame/dMission/MissionPrerequisites.cpp | 2 +- dGame/dUtilities/Loot.cpp | 20 +-- dGame/dUtilities/SlashCommandHandler.cpp | 7 +- dMasterServer/InstanceManager.cpp | 4 +- dMasterServer/MasterServer.cpp | 2 +- .../02_server/Map/General/QbEnemyStunner.cpp | 7 +- .../FireFirstSkillonStartup.cpp | 5 +- dWorldServer/WorldServer.cpp | 2 +- dZoneManager/Level.cpp | 2 +- dZoneManager/Zone.cpp | 2 +- dZoneManager/dZoneManager.cpp | 3 +- 121 files changed, 399 insertions(+), 1584 deletions(-) rename {dPhysics => dCommon}/Singleton.h (100%) diff --git a/dPhysics/Singleton.h b/dCommon/Singleton.h similarity index 100% rename from dPhysics/Singleton.h rename to dCommon/Singleton.h diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index da8a2e18..2b7f63dc 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -64,11 +64,6 @@ typedef std::set<LWOOBJID> TSetObjID; const float PI = 3.14159f; -#if defined(__unix) || defined(__APPLE__) -//For Linux: -typedef __int64_t __int64; -#endif - //============ STRUCTS ============== struct LWOSCENEID { diff --git a/dDatabase/CDClientManager.cpp b/dDatabase/CDClientManager.cpp index 4b32e749..eeea686f 100644 --- a/dDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientManager.cpp @@ -1,46 +1,80 @@ #include "CDClientManager.h" +#include "CDActivityRewardsTable.h" +#include "CDAnimationsTable.h" +#include "CDBehaviorParameterTable.h" +#include "CDBehaviorTemplateTable.h" +#include "CDComponentsRegistryTable.h" +#include "CDCurrencyTableTable.h" +#include "CDDestructibleComponentTable.h" +#include "CDEmoteTable.h" +#include "CDInventoryComponentTable.h" +#include "CDItemComponentTable.h" +#include "CDItemSetsTable.h" +#include "CDItemSetSkillsTable.h" +#include "CDLevelProgressionLookupTable.h" +#include "CDLootMatrixTable.h" +#include "CDLootTableTable.h" +#include "CDMissionNPCComponentTable.h" +#include "CDMissionTasksTable.h" +#include "CDMissionsTable.h" +#include "CDObjectSkillsTable.h" +#include "CDObjectsTable.h" +#include "CDPhysicsComponentTable.h" +#include "CDRebuildComponentTable.h" +#include "CDScriptComponentTable.h" +#include "CDSkillBehaviorTable.h" +#include "CDZoneTableTable.h" +#include "CDVendorComponentTable.h" +#include "CDActivitiesTable.h" +#include "CDPackageComponentTable.h" +#include "CDProximityMonitorComponentTable.h" +#include "CDMovementAIComponentTable.h" +#include "CDBrickIDTableTable.h" +#include "CDRarityTableTable.h" +#include "CDMissionEmailTable.h" +#include "CDRewardsTable.h" +#include "CDPropertyEntranceComponentTable.h" +#include "CDPropertyTemplateTable.h" +#include "CDFeatureGatingTable.h" +#include "CDRailActivatorComponent.h" -// Static Variables -CDClientManager* CDClientManager::m_Address = nullptr; - -//! Initializes the manager -void CDClientManager::Initialize(void) { - tables.insert(std::make_pair("ActivityRewards", new CDActivityRewardsTable())); - UNUSED(tables.insert(std::make_pair("Animations", new CDAnimationsTable()))); - tables.insert(std::make_pair("BehaviorParameter", new CDBehaviorParameterTable())); - tables.insert(std::make_pair("BehaviorTemplate", new CDBehaviorTemplateTable())); - tables.insert(std::make_pair("ComponentsRegistry", new CDComponentsRegistryTable())); - tables.insert(std::make_pair("CurrencyTable", new CDCurrencyTableTable())); - tables.insert(std::make_pair("DestructibleComponent", new CDDestructibleComponentTable())); - tables.insert(std::make_pair("EmoteTable", new CDEmoteTableTable())); - tables.insert(std::make_pair("InventoryComponent", new CDInventoryComponentTable())); - tables.insert(std::make_pair("ItemComponent", new CDItemComponentTable())); - tables.insert(std::make_pair("ItemSets", new CDItemSetsTable())); - tables.insert(std::make_pair("ItemSetSkills", new CDItemSetSkillsTable())); - tables.insert(std::make_pair("LevelProgressionLookup", new CDLevelProgressionLookupTable())); - tables.insert(std::make_pair("LootMatrix", new CDLootMatrixTable())); - tables.insert(std::make_pair("LootTable", new CDLootTableTable())); - tables.insert(std::make_pair("MissionNPCComponent", new CDMissionNPCComponentTable())); - tables.insert(std::make_pair("MissionTasks", new CDMissionTasksTable())); - tables.insert(std::make_pair("Missions", new CDMissionsTable())); - tables.insert(std::make_pair("ObjectSkills", new CDObjectSkillsTable())); - tables.insert(std::make_pair("Objects", new CDObjectsTable())); - tables.insert(std::make_pair("PhysicsComponent", new CDPhysicsComponentTable())); - tables.insert(std::make_pair("RebuildComponent", new CDRebuildComponentTable())); - tables.insert(std::make_pair("ScriptComponent", new CDScriptComponentTable())); - tables.insert(std::make_pair("SkillBehavior", new CDSkillBehaviorTable())); - tables.insert(std::make_pair("ZoneTable", new CDZoneTableTable())); - tables.insert(std::make_pair("VendorComponent", new CDVendorComponentTable())); - tables.insert(std::make_pair("Activities", new CDActivitiesTable())); - tables.insert(std::make_pair("PackageComponent", new CDPackageComponentTable())); - tables.insert(std::make_pair("ProximityMonitorComponent", new CDProximityMonitorComponentTable())); - tables.insert(std::make_pair("MovementAIComponent", new CDMovementAIComponentTable())); - tables.insert(std::make_pair("BrickIDTable", new CDBrickIDTableTable())); - tables.insert(std::make_pair("RarityTable", new CDRarityTableTable())); - tables.insert(std::make_pair("MissionEmail", new CDMissionEmailTable())); - tables.insert(std::make_pair("Rewards", new CDRewardsTable())); - tables.insert(std::make_pair("PropertyEntranceComponent", new CDPropertyEntranceComponentTable())); - tables.insert(std::make_pair("PropertyTemplate", new CDPropertyTemplateTable())); - tables.insert(std::make_pair("FeatureGating", new CDFeatureGatingTable())); - tables.insert(std::make_pair("RailActivatorComponent", new CDRailActivatorComponentTable())); +CDClientManager::CDClientManager() { + CDActivityRewardsTable::Instance(); + UNUSED(CDAnimationsTable::Instance()); + CDBehaviorParameterTable::Instance(); + CDBehaviorTemplateTable::Instance(); + CDComponentsRegistryTable::Instance(); + CDCurrencyTableTable::Instance(); + CDDestructibleComponentTable::Instance(); + CDEmoteTableTable::Instance(); + CDInventoryComponentTable::Instance(); + CDItemComponentTable::Instance(); + CDItemSetsTable::Instance(); + CDItemSetSkillsTable::Instance(); + CDLevelProgressionLookupTable::Instance(); + CDLootMatrixTable::Instance(); + CDLootTableTable::Instance(); + CDMissionNPCComponentTable::Instance(); + CDMissionTasksTable::Instance(); + CDMissionsTable::Instance(); + CDObjectSkillsTable::Instance(); + CDObjectsTable::Instance(); + CDPhysicsComponentTable::Instance(); + CDRebuildComponentTable::Instance(); + CDScriptComponentTable::Instance(); + CDSkillBehaviorTable::Instance(); + CDZoneTableTable::Instance(); + CDVendorComponentTable::Instance(); + CDActivitiesTable::Instance(); + CDPackageComponentTable::Instance(); + CDProximityMonitorComponentTable::Instance(); + CDMovementAIComponentTable::Instance(); + CDBrickIDTableTable::Instance(); + CDRarityTableTable::Instance(); + CDMissionEmailTable::Instance(); + CDRewardsTable::Instance(); + CDPropertyEntranceComponentTable::Instance(); + CDPropertyTemplateTable::Instance(); + CDFeatureGatingTable::Instance(); + CDRailActivatorComponentTable::Instance(); } diff --git a/dDatabase/CDClientManager.h b/dDatabase/CDClientManager.h index ea24a373..1754fe99 100644 --- a/dDatabase/CDClientManager.h +++ b/dDatabase/CDClientManager.h @@ -1,96 +1,24 @@ #pragma once -// Custom Classes #include "CDTable.h" -// Tables -#include "CDActivityRewardsTable.h" -#include "CDAnimationsTable.h" -#include "CDBehaviorParameterTable.h" -#include "CDBehaviorTemplateTable.h" -#include "CDComponentsRegistryTable.h" -#include "CDCurrencyTableTable.h" -#include "CDDestructibleComponentTable.h" -#include "CDEmoteTable.h" -#include "CDInventoryComponentTable.h" -#include "CDItemComponentTable.h" -#include "CDItemSetsTable.h" -#include "CDItemSetSkillsTable.h" -#include "CDLevelProgressionLookupTable.h" -#include "CDLootMatrixTable.h" -#include "CDLootTableTable.h" -#include "CDMissionNPCComponentTable.h" -#include "CDMissionTasksTable.h" -#include "CDMissionsTable.h" -#include "CDObjectSkillsTable.h" -#include "CDObjectsTable.h" -#include "CDPhysicsComponentTable.h" -#include "CDRebuildComponentTable.h" -#include "CDScriptComponentTable.h" -#include "CDSkillBehaviorTable.h" -#include "CDZoneTableTable.h" -#include "CDVendorComponentTable.h" -#include "CDActivitiesTable.h" -#include "CDPackageComponentTable.h" -#include "CDProximityMonitorComponentTable.h" -#include "CDMovementAIComponentTable.h" -#include "CDBrickIDTableTable.h" -#include "CDRarityTableTable.h" -#include "CDMissionEmailTable.h" -#include "CDRewardsTable.h" -#include "CDPropertyEntranceComponentTable.h" -#include "CDPropertyTemplateTable.h" -#include "CDFeatureGatingTable.h" -#include "CDRailActivatorComponent.h" +#include "Singleton.h" -// C++ -#include <type_traits> -#include <unordered_map> - -/*! - \file CDClientManager.hpp - \brief A manager for the CDClient tables +/** + * Initialize the CDClient tables so they are all loaded into memory. */ - - //! Manages all data from the CDClient -class CDClientManager { -private: - static CDClientManager* m_Address; //!< The singleton address - - std::unordered_map<std::string, CDTable*> tables; //!< The tables - +class CDClientManager : public Singleton<CDClientManager> { public: + CDClientManager(); - //! The singleton method - static CDClientManager* Instance() { - if (m_Address == 0) { - m_Address = new CDClientManager; - } - - return m_Address; - } - - //! Initializes the manager - void Initialize(void); - - //! Fetches a CDClient table - /*! - This function uses typename T which must be a subclass of CDTable. - It returns the class that conforms to the class name - - \param tableName The table name - \return The class or nullptr + /** + * Fetch a table from CDClient + * + * @tparam Table type to fetch + * @return A pointer to the requested table. */ template<typename T> - T* GetTable(const std::string& tableName) { - static_assert(std::is_base_of<CDTable, T>::value, "T should inherit from CDTable!"); - - for (auto itr = this->tables.begin(); itr != this->tables.end(); ++itr) { - if (itr->first == tableName) { - return dynamic_cast<T*>(itr->second); - } - } - - return nullptr; + T* GetTable() { + return &T::Instance(); } }; diff --git a/dDatabase/Tables/CDActivitiesTable.cpp b/dDatabase/Tables/CDActivitiesTable.cpp index d6fa354e..e1660d66 100644 --- a/dDatabase/Tables/CDActivitiesTable.cpp +++ b/dDatabase/Tables/CDActivitiesTable.cpp @@ -1,6 +1,5 @@ #include "CDActivitiesTable.h" -//! Constructor CDActivitiesTable::CDActivitiesTable(void) { // First, get the size of the table @@ -48,15 +47,6 @@ CDActivitiesTable::CDActivitiesTable(void) { tableData.finalize(); } -//! Destructor -CDActivitiesTable::~CDActivitiesTable(void) {} - -//! Returns the table's name -std::string CDActivitiesTable::GetName(void) const { - return "Activities"; -} - -//! Queries the table with a custom "where" clause std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActivities)> predicate) { std::vector<CDActivities> data = cpplinq::from(this->entries) @@ -66,7 +56,6 @@ std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActiviti return data; } -//! Gets all the entries in the table std::vector<CDActivities> CDActivitiesTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDActivitiesTable.h b/dDatabase/Tables/CDActivitiesTable.h index 51c560cf..4b60afbd 100644 --- a/dDatabase/Tables/CDActivitiesTable.h +++ b/dDatabase/Tables/CDActivitiesTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDActivitiesTable.hpp - \brief Contains data for the Activities table - */ - - //! Activities Entry Struct struct CDActivities { unsigned int ActivityID; unsigned int locStatus; @@ -31,36 +25,14 @@ struct CDActivities { float optionalPercentage; }; - -//! Activities table -class CDActivitiesTable : public CDTable { +class CDActivitiesTable : public CDTable<CDActivitiesTable> { private: std::vector<CDActivities> entries; public: - - //! Constructor - CDActivitiesTable(void); - - //! Destructor - ~CDActivitiesTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDActivitiesTable(); + // Queries the table with a custom "where" clause std::vector<CDActivities> Query(std::function<bool(CDActivities)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDActivities> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDActivityRewardsTable.cpp b/dDatabase/Tables/CDActivityRewardsTable.cpp index 3922d9fb..65ef1101 100644 --- a/dDatabase/Tables/CDActivityRewardsTable.cpp +++ b/dDatabase/Tables/CDActivityRewardsTable.cpp @@ -1,6 +1,5 @@ #include "CDActivityRewardsTable.h" -//! Constructor CDActivityRewardsTable::CDActivityRewardsTable(void) { // First, get the size of the table @@ -36,15 +35,6 @@ CDActivityRewardsTable::CDActivityRewardsTable(void) { tableData.finalize(); } -//! Destructor -CDActivityRewardsTable::~CDActivityRewardsTable(void) {} - -//! Returns the table's name -std::string CDActivityRewardsTable::GetName(void) const { - return "ActivityRewards"; -} - -//! Queries the table with a custom "where" clause std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool(CDActivityRewards)> predicate) { std::vector<CDActivityRewards> data = cpplinq::from(this->entries) @@ -54,7 +44,6 @@ std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool( return data; } -//! Gets all the entries in the table std::vector<CDActivityRewards> CDActivityRewardsTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDActivityRewardsTable.h b/dDatabase/Tables/CDActivityRewardsTable.h index 7f1e81a0..b5503fb6 100644 --- a/dDatabase/Tables/CDActivityRewardsTable.h +++ b/dDatabase/Tables/CDActivityRewardsTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDActivityRewardsTable.hpp - \brief Contains data for the ActivityRewards table - */ - - //! ActivityRewards Entry Struct struct CDActivityRewards { unsigned int objectTemplate; //!< The object template (?) unsigned int ActivityRewardIndex; //!< The activity reward index @@ -19,36 +13,15 @@ struct CDActivityRewards { std::string description; //!< The description }; - -//! ActivityRewards table -class CDActivityRewardsTable : public CDTable { +class CDActivityRewardsTable : public CDTable<CDActivityRewardsTable> { private: std::vector<CDActivityRewards> entries; public: - - //! Constructor - CDActivityRewardsTable(void); - - //! Destructor - ~CDActivityRewardsTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDActivityRewardsTable(); + // Queries the table with a custom "where" clause std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDActivityRewards> GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDAnimationsTable.cpp b/dDatabase/Tables/CDAnimationsTable.cpp index e21d44c5..e1227f39 100644 --- a/dDatabase/Tables/CDAnimationsTable.cpp +++ b/dDatabase/Tables/CDAnimationsTable.cpp @@ -1,6 +1,5 @@ #include "CDAnimationsTable.h" -//! Constructor CDAnimationsTable::CDAnimationsTable(void) { // First, get the size of the table @@ -42,15 +41,6 @@ CDAnimationsTable::CDAnimationsTable(void) { tableData.finalize(); } -//! Destructor -CDAnimationsTable::~CDAnimationsTable(void) {} - -//! Returns the table's name -std::string CDAnimationsTable::GetName(void) const { - return "Animations"; -} - -//! Queries the table with a custom "where" clause std::vector<CDAnimations> CDAnimationsTable::Query(std::function<bool(CDAnimations)> predicate) { std::vector<CDAnimations> data = cpplinq::from(this->entries) @@ -60,7 +50,6 @@ std::vector<CDAnimations> CDAnimationsTable::Query(std::function<bool(CDAnimatio return data; } -//! Gets all the entries in the table std::vector<CDAnimations> CDAnimationsTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDAnimationsTable.h b/dDatabase/Tables/CDAnimationsTable.h index 24112985..43400abf 100644 --- a/dDatabase/Tables/CDAnimationsTable.h +++ b/dDatabase/Tables/CDAnimationsTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDAnimationsTable.hpp - \brief Contains data for the Animations table - */ - - //! Animations Entry Struct struct CDAnimations { unsigned int animationGroupID; //!< The animation group ID std::string animation_type; //!< The animation type @@ -26,35 +20,14 @@ struct CDAnimations { }; -//! Animations table -class CDAnimationsTable : public CDTable { +class CDAnimationsTable : public CDTable<CDAnimationsTable> { private: std::vector<CDAnimations> entries; public: - - //! Constructor - CDAnimationsTable(void); - - //! Destructor - ~CDAnimationsTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDAnimationsTable(); + // Queries the table with a custom "where" clause std::vector<CDAnimations> Query(std::function<bool(CDAnimations)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDAnimations> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index b894688b..0713e740 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -1,7 +1,6 @@ #include "CDBehaviorParameterTable.h" #include "GeneralUtils.h" -//! Constructor CDBehaviorParameterTable::CDBehaviorParameterTable(void) { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); uint32_t uniqueParameterId = 0; @@ -28,14 +27,6 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { tableData.finalize(); } -//! Destructor -CDBehaviorParameterTable::~CDBehaviorParameterTable(void) {} - -//! Returns the table's name -std::string CDBehaviorParameterTable::GetName(void) const { - return "BehaviorParameter"; -} - float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) { auto parameterID = this->m_ParametersList.find(name); if (parameterID == this->m_ParametersList.end()) return defaultValue; diff --git a/dDatabase/Tables/CDBehaviorParameterTable.h b/dDatabase/Tables/CDBehaviorParameterTable.h index 5d0d8b72..b0715684 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.h +++ b/dDatabase/Tables/CDBehaviorParameterTable.h @@ -5,37 +5,18 @@ #include <unordered_map> #include <unordered_set> -/*! - \file CDBehaviorParameterTable.hpp - \brief Contains data for the BehaviorParameter table - */ - - //! BehaviorParameter Entry Struct struct CDBehaviorParameter { unsigned int behaviorID; //!< The Behavior ID std::unordered_map<std::string, uint32_t>::iterator parameterID; //!< The Parameter ID float value; //!< The value of the behavior template }; -//! BehaviorParameter table -class CDBehaviorParameterTable : public CDTable { +class CDBehaviorParameterTable : public CDTable<CDBehaviorParameterTable> { private: std::unordered_map<uint64_t, CDBehaviorParameter> m_Entries; std::unordered_map<std::string, uint32_t> m_ParametersList; public: - - //! Constructor - CDBehaviorParameterTable(void); - - //! Destructor - ~CDBehaviorParameterTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - + CDBehaviorParameterTable(); float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0); std::map<std::string, float> GetParametersByBehaviorID(uint32_t behaviorID); diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.cpp b/dDatabase/Tables/CDBehaviorTemplateTable.cpp index 4adb9bce..08bc86d1 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.cpp +++ b/dDatabase/Tables/CDBehaviorTemplateTable.cpp @@ -1,6 +1,5 @@ #include "CDBehaviorTemplateTable.h" -//! Constructor CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) { // First, get the size of the table @@ -40,15 +39,6 @@ CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) { tableData.finalize(); } -//! Destructor -CDBehaviorTemplateTable::~CDBehaviorTemplateTable(void) {} - -//! Returns the table's name -std::string CDBehaviorTemplateTable::GetName(void) const { - return "BehaviorTemplate"; -} - -//! Queries the table with a custom "where" clause std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::Query(std::function<bool(CDBehaviorTemplate)> predicate) { std::vector<CDBehaviorTemplate> data = cpplinq::from(this->entries) @@ -58,7 +48,6 @@ std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::Query(std::function<boo return data; } -//! Gets all the entries in the table std::vector<CDBehaviorTemplate> CDBehaviorTemplateTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDBehaviorTemplateTable.h b/dDatabase/Tables/CDBehaviorTemplateTable.h index b2bd2521..f9ac9a09 100644 --- a/dDatabase/Tables/CDBehaviorTemplateTable.h +++ b/dDatabase/Tables/CDBehaviorTemplateTable.h @@ -5,12 +5,6 @@ #include <unordered_map> #include <unordered_set> -/*! - \file CDBehaviorTemplateTable.hpp - \brief Contains data for the BehaviorTemplate table - */ - - //! BehaviorTemplate Entry Struct struct CDBehaviorTemplate { unsigned int behaviorID; //!< The Behavior ID unsigned int templateID; //!< The Template ID (LOT) @@ -19,36 +13,16 @@ struct CDBehaviorTemplate { }; -//! BehaviorTemplate table -class CDBehaviorTemplateTable : public CDTable { +class CDBehaviorTemplateTable : public CDTable<CDBehaviorTemplateTable> { private: std::vector<CDBehaviorTemplate> entries; std::unordered_map<uint32_t, CDBehaviorTemplate> entriesMappedByBehaviorID; std::unordered_set<std::string> m_EffectHandles; public: - - //! Constructor - CDBehaviorTemplateTable(void); - - //! Destructor - ~CDBehaviorTemplateTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDBehaviorTemplateTable(); + // Queries the table with a custom "where" clause std::vector<CDBehaviorTemplate> Query(std::function<bool(CDBehaviorTemplate)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDBehaviorTemplate> GetEntries(void) const; const CDBehaviorTemplate GetByBehaviorID(uint32_t behaviorID); diff --git a/dDatabase/Tables/CDBrickIDTableTable.cpp b/dDatabase/Tables/CDBrickIDTableTable.cpp index 7cd3e86f..9ad24d39 100644 --- a/dDatabase/Tables/CDBrickIDTableTable.cpp +++ b/dDatabase/Tables/CDBrickIDTableTable.cpp @@ -1,6 +1,5 @@ #include "CDBrickIDTableTable.h" -//! Constructor CDBrickIDTableTable::CDBrickIDTableTable(void) { // First, get the size of the table @@ -31,15 +30,6 @@ CDBrickIDTableTable::CDBrickIDTableTable(void) { tableData.finalize(); } -//! Destructor -CDBrickIDTableTable::~CDBrickIDTableTable(void) {} - -//! Returns the table's name -std::string CDBrickIDTableTable::GetName(void) const { - return "BrickIDTable"; -} - -//! Queries the table with a custom "where" clause std::vector<CDBrickIDTable> CDBrickIDTableTable::Query(std::function<bool(CDBrickIDTable)> predicate) { std::vector<CDBrickIDTable> data = cpplinq::from(this->entries) @@ -49,7 +39,6 @@ std::vector<CDBrickIDTable> CDBrickIDTableTable::Query(std::function<bool(CDBric return data; } -//! Gets all the entries in the table std::vector<CDBrickIDTable> CDBrickIDTableTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDBrickIDTableTable.h b/dDatabase/Tables/CDBrickIDTableTable.h index aefe332c..e2084caf 100644 --- a/dDatabase/Tables/CDBrickIDTableTable.h +++ b/dDatabase/Tables/CDBrickIDTableTable.h @@ -16,34 +16,14 @@ struct CDBrickIDTable { //! BrickIDTable table -class CDBrickIDTableTable : public CDTable { +class CDBrickIDTableTable : public CDTable<CDBrickIDTableTable> { private: std::vector<CDBrickIDTable> entries; public: - - //! Constructor - CDBrickIDTableTable(void); - - //! Destructor - ~CDBrickIDTableTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDBrickIDTableTable(); + // Queries the table with a custom "where" clause std::vector<CDBrickIDTable> Query(std::function<bool(CDBrickIDTable)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDBrickIDTable> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDComponentsRegistryTable.cpp b/dDatabase/Tables/CDComponentsRegistryTable.cpp index 88bb04cc..32012f6c 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.cpp +++ b/dDatabase/Tables/CDComponentsRegistryTable.cpp @@ -3,7 +3,6 @@ #define CDCLIENT_CACHE_ALL -//! Constructor CDComponentsRegistryTable::CDComponentsRegistryTable(void) { #ifdef CDCLIENT_CACHE_ALL @@ -31,24 +30,6 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) { this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id); - //this->entries.push_back(entry); - - /* - //Darwin's stuff: - const auto& it = this->mappedEntries.find(entry.id); - if (it != mappedEntries.end()) { - const auto& iter = it->second.find(entry.component_type); - if (iter == it->second.end()) { - it->second.insert(std::make_pair(entry.component_type, entry.component_id)); - } - } - else { - std::map<unsigned int, unsigned int> map; - map.insert(std::make_pair(entry.component_type, entry.component_id)); - this->mappedEntries.insert(std::make_pair(entry.id, map)); - } - */ - tableData.nextRow(); } @@ -56,14 +37,6 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) { #endif } -//! Destructor -CDComponentsRegistryTable::~CDComponentsRegistryTable(void) {} - -//! Returns the table's name -std::string CDComponentsRegistryTable::GetName(void) const { - return "ComponentsRegistry"; -} - int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) { const auto& iter = this->mappedEntries.find(((uint64_t)componentType) << 32 | ((uint64_t)id)); @@ -73,16 +46,6 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponent return iter->second; - /* - const auto& it = this->mappedEntries.find(id); - if (it != mappedEntries.end()) { - const auto& iter = it->second.find(componentType); - if (iter != it->second.end()) { - return iter->second; - } - } - */ - #ifndef CDCLIENT_CACHE_ALL // Now get the data std::stringstream query; diff --git a/dDatabase/Tables/CDComponentsRegistryTable.h b/dDatabase/Tables/CDComponentsRegistryTable.h index 91e3800c..990072c9 100644 --- a/dDatabase/Tables/CDComponentsRegistryTable.h +++ b/dDatabase/Tables/CDComponentsRegistryTable.h @@ -3,12 +3,7 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDComponentsRegistryTable.hpp - \brief Contains data for the ComponentsRegistry table - */ enum class eReplicaComponentType : uint32_t; - //! ComponentsRegistry Entry Struct struct CDComponentsRegistry { unsigned int id; //!< The LOT is used as the ID eReplicaComponentType component_type; //!< See ComponentTypes enum for values @@ -16,25 +11,11 @@ struct CDComponentsRegistry { }; -//! ComponentsRegistry table -class CDComponentsRegistryTable : public CDTable { +class CDComponentsRegistryTable : public CDTable<CDComponentsRegistryTable> { private: - //std::vector<CDComponentsRegistry> entries; std::map<uint64_t, uint32_t> mappedEntries; //id, component_type, component_id public: - - //! Constructor - CDComponentsRegistryTable(void); - - //! Destructor - ~CDComponentsRegistryTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - + CDComponentsRegistryTable(); int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0); }; diff --git a/dDatabase/Tables/CDCurrencyTableTable.cpp b/dDatabase/Tables/CDCurrencyTableTable.cpp index 21870f00..78a716f9 100644 --- a/dDatabase/Tables/CDCurrencyTableTable.cpp +++ b/dDatabase/Tables/CDCurrencyTableTable.cpp @@ -34,15 +34,6 @@ CDCurrencyTableTable::CDCurrencyTableTable(void) { tableData.finalize(); } -//! Destructor -CDCurrencyTableTable::~CDCurrencyTableTable(void) {} - -//! Returns the table's name -std::string CDCurrencyTableTable::GetName(void) const { - return "CurrencyTable"; -} - -//! Queries the table with a custom "where" clause std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCurrencyTable)> predicate) { std::vector<CDCurrencyTable> data = cpplinq::from(this->entries) @@ -52,7 +43,6 @@ std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCu return data; } -//! Gets all the entries in the table std::vector<CDCurrencyTable> CDCurrencyTableTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDCurrencyTableTable.h b/dDatabase/Tables/CDCurrencyTableTable.h index 5a856395..ec700320 100644 --- a/dDatabase/Tables/CDCurrencyTableTable.h +++ b/dDatabase/Tables/CDCurrencyTableTable.h @@ -18,34 +18,14 @@ struct CDCurrencyTable { }; //! CurrencyTable table -class CDCurrencyTableTable : public CDTable { +class CDCurrencyTableTable : public CDTable<CDCurrencyTableTable> { private: std::vector<CDCurrencyTable> entries; public: - - //! Constructor - CDCurrencyTableTable(void); - - //! Destructor - ~CDCurrencyTableTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDCurrencyTableTable(); + // Queries the table with a custom "where" clause std::vector<CDCurrencyTable> Query(std::function<bool(CDCurrencyTable)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDCurrencyTable> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDDestructibleComponentTable.cpp b/dDatabase/Tables/CDDestructibleComponentTable.cpp index 2480fc24..4bbc8242 100644 --- a/dDatabase/Tables/CDDestructibleComponentTable.cpp +++ b/dDatabase/Tables/CDDestructibleComponentTable.cpp @@ -43,15 +43,6 @@ CDDestructibleComponentTable::CDDestructibleComponentTable(void) { tableData.finalize(); } -//! Destructor -CDDestructibleComponentTable::~CDDestructibleComponentTable(void) {} - -//! Returns the table's name -std::string CDDestructibleComponentTable::GetName(void) const { - return "DestructibleComponent"; -} - -//! Queries the table with a custom "where" clause std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::function<bool(CDDestructibleComponent)> predicate) { std::vector<CDDestructibleComponent> data = cpplinq::from(this->entries) @@ -61,7 +52,6 @@ std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::fu return data; } -//! Gets all the entries in the table std::vector<CDDestructibleComponent> CDDestructibleComponentTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDDestructibleComponentTable.h b/dDatabase/Tables/CDDestructibleComponentTable.h index e89bbff8..e42cf486 100644 --- a/dDatabase/Tables/CDDestructibleComponentTable.h +++ b/dDatabase/Tables/CDDestructibleComponentTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDDestructibleComponentTable.hpp - \brief Contains data for the DestructibleComponent table - */ - - //! ItemComponent Struct struct CDDestructibleComponent { unsigned int id; //!< The component ID from the ComponentsRegistry Table int faction; //!< The Faction ID of the object @@ -26,35 +20,14 @@ struct CDDestructibleComponent { int difficultyLevel; //!< ??? }; -//! ItemComponent table -class CDDestructibleComponentTable : public CDTable { +class CDDestructibleComponentTable : public CDTable<CDDestructibleComponentTable> { private: std::vector<CDDestructibleComponent> entries; public: - - //! Constructor - CDDestructibleComponentTable(void); - - //! Destructor - ~CDDestructibleComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDDestructibleComponentTable(); + // Queries the table with a custom "where" clause std::vector<CDDestructibleComponent> Query(std::function<bool(CDDestructibleComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDDestructibleComponent> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDEmoteTable.cpp b/dDatabase/Tables/CDEmoteTable.cpp index b97e02e8..aacbdd55 100644 --- a/dDatabase/Tables/CDEmoteTable.cpp +++ b/dDatabase/Tables/CDEmoteTable.cpp @@ -30,11 +30,6 @@ CDEmoteTableTable::~CDEmoteTableTable(void) { entries.clear(); } -//! Returns the table's name -std::string CDEmoteTableTable::GetName(void) const { - return "Emotes"; -} - CDEmoteTable* CDEmoteTableTable::GetEmote(int id) { for (auto e : entries) { if (e.first == id) return e.second; diff --git a/dDatabase/Tables/CDEmoteTable.h b/dDatabase/Tables/CDEmoteTable.h index 1f4fb246..be40c86f 100644 --- a/dDatabase/Tables/CDEmoteTable.h +++ b/dDatabase/Tables/CDEmoteTable.h @@ -4,12 +4,6 @@ #include "CDTable.h" #include <map> -/*! - \file CDEmoteTable.hpp - \brief Contains data for the CDEmoteTable table - */ - - //! CDEmoteEntry Struct struct CDEmoteTable { CDEmoteTable() { ID = -1; @@ -32,25 +26,13 @@ struct CDEmoteTable { std::string gateVersion; }; -//! CDEmoteTable table -class CDEmoteTableTable : public CDTable { +class CDEmoteTableTable : public CDTable<CDEmoteTableTable> { private: std::map<int, CDEmoteTable*> entries; public: - - //! Constructor - CDEmoteTableTable(void); - - //! Destructor - ~CDEmoteTableTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Returns an emote by ID + CDEmoteTableTable(); + ~CDEmoteTableTable(); + // Returns an emote by ID CDEmoteTable* GetEmote(int id); }; diff --git a/dDatabase/Tables/CDFeatureGatingTable.cpp b/dDatabase/Tables/CDFeatureGatingTable.cpp index 0abcdb25..05fe69bf 100644 --- a/dDatabase/Tables/CDFeatureGatingTable.cpp +++ b/dDatabase/Tables/CDFeatureGatingTable.cpp @@ -34,15 +34,6 @@ CDFeatureGatingTable::CDFeatureGatingTable(void) { tableData.finalize(); } -//! Destructor -CDFeatureGatingTable::~CDFeatureGatingTable(void) {} - -//! Returns the table's name -std::string CDFeatureGatingTable::GetName(void) const { - return "FeatureGating"; -} - -//! Queries the table with a custom "where" clause std::vector<CDFeatureGating> CDFeatureGatingTable::Query(std::function<bool(CDFeatureGating)> predicate) { std::vector<CDFeatureGating> data = cpplinq::from(this->entries) @@ -62,7 +53,6 @@ bool CDFeatureGatingTable::FeatureUnlocked(const std::string& feature) const { return false; } -//! Gets all the entries in the table std::vector<CDFeatureGating> CDFeatureGatingTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDFeatureGatingTable.h b/dDatabase/Tables/CDFeatureGatingTable.h index 54e6d21b..7f536db5 100644 --- a/dDatabase/Tables/CDFeatureGatingTable.h +++ b/dDatabase/Tables/CDFeatureGatingTable.h @@ -3,11 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDFeatureGatingTable.hpp - */ - - //! ItemComponent Struct struct CDFeatureGating { std::string featureName; int32_t major; @@ -16,37 +11,16 @@ struct CDFeatureGating { std::string description; }; -//! ItemComponent table -class CDFeatureGatingTable : public CDTable { +class CDFeatureGatingTable : public CDTable<CDFeatureGatingTable> { private: std::vector<CDFeatureGating> entries; public: - - //! Constructor - CDFeatureGatingTable(void); - - //! Destructor - ~CDFeatureGatingTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDFeatureGatingTable(); + // Queries the table with a custom "where" clause std::vector<CDFeatureGating> Query(std::function<bool(CDFeatureGating)> predicate); bool FeatureUnlocked(const std::string& feature) const; - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDFeatureGating> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDInventoryComponentTable.cpp b/dDatabase/Tables/CDInventoryComponentTable.cpp index cf956775..2dc375ab 100644 --- a/dDatabase/Tables/CDInventoryComponentTable.cpp +++ b/dDatabase/Tables/CDInventoryComponentTable.cpp @@ -33,15 +33,6 @@ CDInventoryComponentTable::CDInventoryComponentTable(void) { tableData.finalize(); } -//! Destructor -CDInventoryComponentTable::~CDInventoryComponentTable(void) {} - -//! Returns the table's name -std::string CDInventoryComponentTable::GetName(void) const { - return "InventoryComponent"; -} - -//! Queries the table with a custom "where" clause std::vector<CDInventoryComponent> CDInventoryComponentTable::Query(std::function<bool(CDInventoryComponent)> predicate) { std::vector<CDInventoryComponent> data = cpplinq::from(this->entries) @@ -51,7 +42,6 @@ std::vector<CDInventoryComponent> CDInventoryComponentTable::Query(std::function return data; } -//! Gets all the entries in the table std::vector<CDInventoryComponent> CDInventoryComponentTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDInventoryComponentTable.h b/dDatabase/Tables/CDInventoryComponentTable.h index c6117907..cbc04d99 100644 --- a/dDatabase/Tables/CDInventoryComponentTable.h +++ b/dDatabase/Tables/CDInventoryComponentTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDInventoryComponentTable.hpp - \brief Contains data for the InventoryComponent table - */ - - //! ItemComponent Struct struct CDInventoryComponent { unsigned int id; //!< The component ID for this object unsigned int itemid; //!< The LOT of the object @@ -16,35 +10,14 @@ struct CDInventoryComponent { bool equip; //!< Whether or not to equip the item }; -//! ItemComponent table -class CDInventoryComponentTable : public CDTable { +class CDInventoryComponentTable : public CDTable<CDInventoryComponentTable> { private: std::vector<CDInventoryComponent> entries; public: - - //! Constructor - CDInventoryComponentTable(void); - - //! Destructor - ~CDInventoryComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDInventoryComponentTable(); + // Queries the table with a custom "where" clause std::vector<CDInventoryComponent> Query(std::function<bool(CDInventoryComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDInventoryComponent> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDItemComponentTable.cpp b/dDatabase/Tables/CDItemComponentTable.cpp index a3cb4159..54afc417 100644 --- a/dDatabase/Tables/CDItemComponentTable.cpp +++ b/dDatabase/Tables/CDItemComponentTable.cpp @@ -74,14 +74,6 @@ CDItemComponentTable::CDItemComponentTable(void) { #endif } -//! Destructor -CDItemComponentTable::~CDItemComponentTable(void) {} - -//! Returns the table's name -std::string CDItemComponentTable::GetName(void) const { - return "ItemComponent"; -} - const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int skillID) { const auto& it = this->entries.find(skillID); if (it != this->entries.end()) { diff --git a/dDatabase/Tables/CDItemComponentTable.h b/dDatabase/Tables/CDItemComponentTable.h index b3a2a5f4..11c34dd6 100644 --- a/dDatabase/Tables/CDItemComponentTable.h +++ b/dDatabase/Tables/CDItemComponentTable.h @@ -4,12 +4,6 @@ #include "CDTable.h" #include "dCommonVars.h" -/*! - \file CDItemComponentTable.hpp - \brief Contains data for the ItemComponent table - */ - - //! ItemComponent Struct struct CDItemComponent { unsigned int id; //!< The Component ID std::string equipLocation; //!< The equip location @@ -55,28 +49,15 @@ struct CDItemComponent { float SellMultiplier; //!< Something to do with early vendors perhaps (but replaced) }; -//! ItemComponent table -class CDItemComponentTable : public CDTable { +class CDItemComponentTable : public CDTable<CDItemComponentTable> { private: std::map<unsigned int, CDItemComponent> entries; public: - - //! Constructor - CDItemComponentTable(void); - - //! Destructor - ~CDItemComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - + CDItemComponentTable(); static std::map<LOT, uint32_t> ParseCraftingCurrencies(const CDItemComponent& itemComponent); - //! Gets an entry by ID + // Gets an entry by ID const CDItemComponent& GetItemComponentByID(unsigned int skillID); static CDItemComponent Default; diff --git a/dDatabase/Tables/CDItemSetSkillsTable.cpp b/dDatabase/Tables/CDItemSetSkillsTable.cpp index 107e25d9..f6b412ff 100644 --- a/dDatabase/Tables/CDItemSetSkillsTable.cpp +++ b/dDatabase/Tables/CDItemSetSkillsTable.cpp @@ -32,15 +32,6 @@ CDItemSetSkillsTable::CDItemSetSkillsTable(void) { tableData.finalize(); } -//! Destructor -CDItemSetSkillsTable::~CDItemSetSkillsTable(void) {} - -//! Returns the table's name -std::string CDItemSetSkillsTable::GetName(void) const { - return "ItemSetSkills"; -} - -//! Queries the table with a custom "where" clause std::vector<CDItemSetSkills> CDItemSetSkillsTable::Query(std::function<bool(CDItemSetSkills)> predicate) { std::vector<CDItemSetSkills> data = cpplinq::from(this->entries) @@ -50,7 +41,6 @@ std::vector<CDItemSetSkills> CDItemSetSkillsTable::Query(std::function<bool(CDIt return data; } -//! Gets all the entries in the table std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetEntries(void) const { return this->entries; } @@ -65,4 +55,3 @@ std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetBySkillID(unsigned int Ski return toReturn; } - diff --git a/dDatabase/Tables/CDItemSetSkillsTable.h b/dDatabase/Tables/CDItemSetSkillsTable.h index bf05eea9..8328c66b 100644 --- a/dDatabase/Tables/CDItemSetSkillsTable.h +++ b/dDatabase/Tables/CDItemSetSkillsTable.h @@ -3,50 +3,22 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDItemSetSkillsTable.hpp - \brief Contains data for the ItemSetSkills table - */ - - //! ZoneTable Struct struct CDItemSetSkills { unsigned int SkillSetID; //!< The skill set ID unsigned int SkillID; //!< The skill ID unsigned int SkillCastType; //!< The skill cast type }; -//! ItemSets table -class CDItemSetSkillsTable : public CDTable { +class CDItemSetSkillsTable : public CDTable<CDItemSetSkillsTable> { private: std::vector<CDItemSetSkills> entries; public: - - //! Constructor - CDItemSetSkillsTable(void); - - //! Destructor - ~CDItemSetSkillsTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDItemSetSkillsTable(); + // Queries the table with a custom "where" clause std::vector<CDItemSetSkills> Query(std::function<bool(CDItemSetSkills)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDItemSetSkills> GetEntries(void) const; std::vector<CDItemSetSkills> GetBySkillID(unsigned int SkillSetID); - }; - diff --git a/dDatabase/Tables/CDItemSetsTable.cpp b/dDatabase/Tables/CDItemSetsTable.cpp index 1f9d7409..0632ef13 100644 --- a/dDatabase/Tables/CDItemSetsTable.cpp +++ b/dDatabase/Tables/CDItemSetsTable.cpp @@ -44,15 +44,6 @@ CDItemSetsTable::CDItemSetsTable(void) { tableData.finalize(); } -//! Destructor -CDItemSetsTable::~CDItemSetsTable(void) {} - -//! Returns the table's name -std::string CDItemSetsTable::GetName(void) const { - return "ItemSets"; -} - -//! Queries the table with a custom "where" clause std::vector<CDItemSets> CDItemSetsTable::Query(std::function<bool(CDItemSets)> predicate) { std::vector<CDItemSets> data = cpplinq::from(this->entries) @@ -62,7 +53,6 @@ std::vector<CDItemSets> CDItemSetsTable::Query(std::function<bool(CDItemSets)> p return data; } -//! Gets all the entries in the table std::vector<CDItemSets> CDItemSetsTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDItemSetsTable.h b/dDatabase/Tables/CDItemSetsTable.h index ef12c7b4..6756e7fa 100644 --- a/dDatabase/Tables/CDItemSetsTable.h +++ b/dDatabase/Tables/CDItemSetsTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDItemSetsTable.hpp - \brief Contains data for the ItemSets table - */ - - //! ZoneTable Struct struct CDItemSets { unsigned int setID; //!< The item set ID unsigned int locStatus; //!< The loc status @@ -27,36 +21,15 @@ struct CDItemSets { float priority; //!< The priority }; -//! ItemSets table -class CDItemSetsTable : public CDTable { +class CDItemSetsTable : public CDTable<CDItemSetsTable> { private: std::vector<CDItemSets> entries; public: - - //! Constructor - CDItemSetsTable(void); - - //! Destructor - ~CDItemSetsTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDItemSetsTable(); + // Queries the table with a custom "where" clause std::vector<CDItemSets> Query(std::function<bool(CDItemSets)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDItemSets> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDLevelProgressionLookupTable.cpp b/dDatabase/Tables/CDLevelProgressionLookupTable.cpp index b3231308..47a8fc0e 100644 --- a/dDatabase/Tables/CDLevelProgressionLookupTable.cpp +++ b/dDatabase/Tables/CDLevelProgressionLookupTable.cpp @@ -32,14 +32,6 @@ CDLevelProgressionLookupTable::CDLevelProgressionLookupTable(void) { tableData.finalize(); } -//! Destructor -CDLevelProgressionLookupTable::~CDLevelProgressionLookupTable(void) {} - -//! Returns the table's name -std::string CDLevelProgressionLookupTable::GetName(void) const { - return "LevelProgressionLookup"; -} - //! Queries the table with a custom "where" clause std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std::function<bool(CDLevelProgressionLookup)> predicate) { diff --git a/dDatabase/Tables/CDLevelProgressionLookupTable.h b/dDatabase/Tables/CDLevelProgressionLookupTable.h index 391c9b37..070b2e0c 100644 --- a/dDatabase/Tables/CDLevelProgressionLookupTable.h +++ b/dDatabase/Tables/CDLevelProgressionLookupTable.h @@ -3,47 +3,21 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDLevelProgressionLookupTable.hpp - \brief Contains data for the LevelProgressionLookup table - */ - - //! LevelProgressionLookup Entry Struct struct CDLevelProgressionLookup { unsigned int id; //!< The Level ID unsigned int requiredUScore; //!< The required LEGO Score std::string BehaviorEffect; //!< The behavior effect attached to this }; -//! LevelProgressionLookup table -class CDLevelProgressionLookupTable : public CDTable { +class CDLevelProgressionLookupTable : public CDTable<CDLevelProgressionLookupTable> { private: std::vector<CDLevelProgressionLookup> entries; public: - - //! Constructor - CDLevelProgressionLookupTable(void); - - //! Destructor - ~CDLevelProgressionLookupTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDLevelProgressionLookupTable(); + // Queries the table with a custom "where" clause std::vector<CDLevelProgressionLookup> Query(std::function<bool(CDLevelProgressionLookup)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ + // Gets all the entries in the table std::vector<CDLevelProgressionLookup> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDLootMatrixTable.cpp b/dDatabase/Tables/CDLootMatrixTable.cpp index 93a2fda1..8f25e8a3 100644 --- a/dDatabase/Tables/CDLootMatrixTable.cpp +++ b/dDatabase/Tables/CDLootMatrixTable.cpp @@ -38,15 +38,6 @@ CDLootMatrixTable::CDLootMatrixTable(void) { tableData.finalize(); } -//! Destructor -CDLootMatrixTable::~CDLootMatrixTable(void) {} - -//! Returns the table's name -std::string CDLootMatrixTable::GetName(void) const { - return "LootMatrix"; -} - -//! Queries the table with a custom "where" clause std::vector<CDLootMatrix> CDLootMatrixTable::Query(std::function<bool(CDLootMatrix)> predicate) { std::vector<CDLootMatrix> data = cpplinq::from(this->entries) @@ -56,7 +47,6 @@ std::vector<CDLootMatrix> CDLootMatrixTable::Query(std::function<bool(CDLootMatr return data; } -//! Gets all the entries in the table const std::vector<CDLootMatrix>& CDLootMatrixTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDLootMatrixTable.h b/dDatabase/Tables/CDLootMatrixTable.h index 7d311b3b..c6035841 100644 --- a/dDatabase/Tables/CDLootMatrixTable.h +++ b/dDatabase/Tables/CDLootMatrixTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDLootMatrixTable.hpp - \brief Contains data for the ObjectSkills table - */ - - //! LootMatrix Struct struct CDLootMatrix { unsigned int LootMatrixIndex; //!< The Loot Matrix Index unsigned int LootTableIndex; //!< The Loot Table Index @@ -21,36 +15,15 @@ struct CDLootMatrix { UNUSED(std::string gate_version); //!< The Gate Version }; -//! MissionNPCComponent table -class CDLootMatrixTable : public CDTable { +class CDLootMatrixTable : public CDTable<CDLootMatrixTable> { private: std::vector<CDLootMatrix> entries; public: - - //! Constructor - CDLootMatrixTable(void); - - //! Destructor - ~CDLootMatrixTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDLootMatrixTable(); + // Queries the table with a custom "where" clause std::vector<CDLootMatrix> Query(std::function<bool(CDLootMatrix)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ const std::vector<CDLootMatrix>& GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDLootTableTable.cpp b/dDatabase/Tables/CDLootTableTable.cpp index 91cced47..0a46784a 100644 --- a/dDatabase/Tables/CDLootTableTable.cpp +++ b/dDatabase/Tables/CDLootTableTable.cpp @@ -35,14 +35,6 @@ CDLootTableTable::CDLootTableTable(void) { tableData.finalize(); } -//! Destructor -CDLootTableTable::~CDLootTableTable(void) {} - -//! Returns the table's name -std::string CDLootTableTable::GetName(void) const { - return "LootTable"; -} - //! Queries the table with a custom "where" clause std::vector<CDLootTable> CDLootTableTable::Query(std::function<bool(CDLootTable)> predicate) { diff --git a/dDatabase/Tables/CDLootTableTable.h b/dDatabase/Tables/CDLootTableTable.h index 3f1baf60..ba6f207e 100644 --- a/dDatabase/Tables/CDLootTableTable.h +++ b/dDatabase/Tables/CDLootTableTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDLootTableTable.hpp - \brief Contains data for the LootTable table - */ - - //! LootTable Struct struct CDLootTable { unsigned int itemid; //!< The LOT of the item unsigned int LootTableIndex; //!< The Loot Table Index @@ -17,36 +11,15 @@ struct CDLootTable { unsigned int sortPriority; //!< The sorting priority }; -//! LootTable table -class CDLootTableTable : public CDTable { +class CDLootTableTable : public CDTable<CDLootTableTable> { private: std::vector<CDLootTable> entries; public: - - //! Constructor - CDLootTableTable(void); - - //! Destructor - ~CDLootTableTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDLootTableTable(); + // Queries the table with a custom "where" clause std::vector<CDLootTable> Query(std::function<bool(CDLootTable)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ const std::vector<CDLootTable>& GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDMissionEmailTable.cpp b/dDatabase/Tables/CDMissionEmailTable.cpp index 4fac7be2..ed855d8a 100644 --- a/dDatabase/Tables/CDMissionEmailTable.cpp +++ b/dDatabase/Tables/CDMissionEmailTable.cpp @@ -37,14 +37,6 @@ CDMissionEmailTable::CDMissionEmailTable(void) { tableData.finalize(); } -//! Destructor -CDMissionEmailTable::~CDMissionEmailTable(void) {} - -//! Returns the table's name -std::string CDMissionEmailTable::GetName(void) const { - return "MissionEmail"; -} - //! Queries the table with a custom "where" clause std::vector<CDMissionEmail> CDMissionEmailTable::Query(std::function<bool(CDMissionEmail)> predicate) { diff --git a/dDatabase/Tables/CDMissionEmailTable.h b/dDatabase/Tables/CDMissionEmailTable.h index 81a7a793..db2310d4 100644 --- a/dDatabase/Tables/CDMissionEmailTable.h +++ b/dDatabase/Tables/CDMissionEmailTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDMissionEmailTable.hpp - \brief Contains data for the MissionEmail table - */ - - //! MissionEmail Entry Struct struct CDMissionEmail { unsigned int ID; unsigned int messageType; @@ -21,35 +15,14 @@ struct CDMissionEmail { }; -//! MissionEmail table -class CDMissionEmailTable : public CDTable { +class CDMissionEmailTable : public CDTable<CDMissionEmailTable> { private: std::vector<CDMissionEmail> entries; public: - - //! Constructor - CDMissionEmailTable(void); - - //! Destructor - ~CDMissionEmailTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDMissionEmailTable(); + // Queries the table with a custom "where" clause std::vector<CDMissionEmail> Query(std::function<bool(CDMissionEmail)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDMissionEmail> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDMissionNPCComponentTable.cpp b/dDatabase/Tables/CDMissionNPCComponentTable.cpp index 461cc909..5672ed67 100644 --- a/dDatabase/Tables/CDMissionNPCComponentTable.cpp +++ b/dDatabase/Tables/CDMissionNPCComponentTable.cpp @@ -34,14 +34,6 @@ CDMissionNPCComponentTable::CDMissionNPCComponentTable(void) { tableData.finalize(); } -//! Destructor -CDMissionNPCComponentTable::~CDMissionNPCComponentTable(void) {} - -//! Returns the table's name -std::string CDMissionNPCComponentTable::GetName(void) const { - return "MissionNPCComponent"; -} - //! Queries the table with a custom "where" clause std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::Query(std::function<bool(CDMissionNPCComponent)> predicate) { diff --git a/dDatabase/Tables/CDMissionNPCComponentTable.h b/dDatabase/Tables/CDMissionNPCComponentTable.h index 68c94ef0..a7aeb145 100644 --- a/dDatabase/Tables/CDMissionNPCComponentTable.h +++ b/dDatabase/Tables/CDMissionNPCComponentTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDMissionNPCComponentTable.hpp - \brief Contains data for the ObjectSkills table - */ - - //! MissionNPCComponent Struct struct CDMissionNPCComponent { unsigned int id; //!< The ID unsigned int missionID; //!< The Mission ID @@ -17,35 +11,16 @@ struct CDMissionNPCComponent { std::string gate_version; //!< The gate version }; -//! MissionNPCComponent table -class CDMissionNPCComponentTable : public CDTable { +class CDMissionNPCComponentTable : public CDTable<CDMissionNPCComponentTable> { private: std::vector<CDMissionNPCComponent> entries; public: - - //! Constructor - CDMissionNPCComponentTable(void); - - //! Destructor - ~CDMissionNPCComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDMissionNPCComponentTable(); + // Queries the table with a custom "where" clause std::vector<CDMissionNPCComponent> Query(std::function<bool(CDMissionNPCComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ + // Gets all the entries in the table std::vector<CDMissionNPCComponent> GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDMissionTasksTable.cpp b/dDatabase/Tables/CDMissionTasksTable.cpp index c22da1ef..f32dca1b 100644 --- a/dDatabase/Tables/CDMissionTasksTable.cpp +++ b/dDatabase/Tables/CDMissionTasksTable.cpp @@ -42,15 +42,6 @@ CDMissionTasksTable::CDMissionTasksTable(void) { tableData.finalize(); } -//! Destructor -CDMissionTasksTable::~CDMissionTasksTable(void) {} - -//! Returns the table's name -std::string CDMissionTasksTable::GetName(void) const { - return "MissionTasks"; -} - -//! Queries the table with a custom "where" clause std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMissionTasks)> predicate) { std::vector<CDMissionTasks> data = cpplinq::from(this->entries) @@ -74,7 +65,6 @@ std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missio return tasks; } -//! Gets all the entries in the table const std::vector<CDMissionTasks>& CDMissionTasksTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDMissionTasksTable.h b/dDatabase/Tables/CDMissionTasksTable.h index 1a4bd361..fa213faf 100644 --- a/dDatabase/Tables/CDMissionTasksTable.h +++ b/dDatabase/Tables/CDMissionTasksTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDMissionTasksTable.hpp - \brief Contains data for the MissionTasks table - */ - - //! ObjectSkills Struct struct CDMissionTasks { unsigned int id; //!< The Mission ID that the task belongs to UNUSED(unsigned int locStatus); //!< ??? @@ -25,37 +19,17 @@ struct CDMissionTasks { UNUSED(std::string gate_version); //!< ??? }; -//! ObjectSkills table -class CDMissionTasksTable : public CDTable { +class CDMissionTasksTable : public CDTable<CDMissionTasksTable> { private: std::vector<CDMissionTasks> entries; public: - - //! Constructor - CDMissionTasksTable(void); - - //! Destructor - ~CDMissionTasksTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDMissionTasksTable(); + // Queries the table with a custom "where" clause std::vector<CDMissionTasks> Query(std::function<bool(CDMissionTasks)> predicate); std::vector<CDMissionTasks*> GetByMissionID(uint32_t missionID); - //! Gets all the entries in the table - /*! - \return The entries - */ const std::vector<CDMissionTasks>& GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDMissionsTable.cpp b/dDatabase/Tables/CDMissionsTable.cpp index a87b4327..d4ee40ae 100644 --- a/dDatabase/Tables/CDMissionsTable.cpp +++ b/dDatabase/Tables/CDMissionsTable.cpp @@ -85,15 +85,6 @@ CDMissionsTable::CDMissionsTable(void) { Default.id = -1; } -//! Destructor -CDMissionsTable::~CDMissionsTable(void) {} - -//! Returns the table's name -std::string CDMissionsTable::GetName(void) const { - return "Missions"; -} - -//! Queries the table with a custom "where" clause std::vector<CDMissions> CDMissionsTable::Query(std::function<bool(CDMissions)> predicate) { std::vector<CDMissions> data = cpplinq::from(this->entries) @@ -103,7 +94,6 @@ std::vector<CDMissions> CDMissionsTable::Query(std::function<bool(CDMissions)> p return data; } -//! Gets all the entries in the table const std::vector<CDMissions>& CDMissionsTable::GetEntries(void) const { return this->entries; } diff --git a/dDatabase/Tables/CDMissionsTable.h b/dDatabase/Tables/CDMissionsTable.h index 6d1c4a8f..e6a44b02 100644 --- a/dDatabase/Tables/CDMissionsTable.h +++ b/dDatabase/Tables/CDMissionsTable.h @@ -5,12 +5,6 @@ #include <map> #include <cstdint> -/*! - \file CDMissionsTable.hpp - \brief Contains data for the Missions table - */ - - //! Missions Struct struct CDMissions { int id; //!< The Mission ID std::string defined_type; //!< The type of mission @@ -66,35 +60,16 @@ struct CDMissions { int reward_bankinventory; //!< The amount of bank space this mission rewards }; -//! Missions table -class CDMissionsTable : public CDTable { +class CDMissionsTable : public CDTable<CDMissionsTable> { private: std::vector<CDMissions> entries; public: - - //! Constructor - CDMissionsTable(void); - - //! Destructor - ~CDMissionsTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDMissionsTable(); + // Queries the table with a custom "where" clause std::vector<CDMissions> Query(std::function<bool(CDMissions)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ + // Gets all the entries in the table const std::vector<CDMissions>& GetEntries(void) const; const CDMissions* GetPtrByMissionID(uint32_t missionID) const; diff --git a/dDatabase/Tables/CDMovementAIComponentTable.cpp b/dDatabase/Tables/CDMovementAIComponentTable.cpp index 333ec202..3b9cc4f4 100644 --- a/dDatabase/Tables/CDMovementAIComponentTable.cpp +++ b/dDatabase/Tables/CDMovementAIComponentTable.cpp @@ -37,14 +37,6 @@ CDMovementAIComponentTable::CDMovementAIComponentTable(void) { tableData.finalize(); } -//! Destructor -CDMovementAIComponentTable::~CDMovementAIComponentTable(void) {} - -//! Returns the table's name -std::string CDMovementAIComponentTable::GetName(void) const { - return "MovementAIComponent"; -} - //! Queries the table with a custom "where" clause std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::function<bool(CDMovementAIComponent)> predicate) { diff --git a/dDatabase/Tables/CDMovementAIComponentTable.h b/dDatabase/Tables/CDMovementAIComponentTable.h index 0064a98b..84896e2c 100644 --- a/dDatabase/Tables/CDMovementAIComponentTable.h +++ b/dDatabase/Tables/CDMovementAIComponentTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDMovementAIComponentTable.hpp - \brief Contains data for the MovementAIComponent table - */ - - //! MovementAIComponent Struct struct CDMovementAIComponent { unsigned int id; std::string MovementType; @@ -20,36 +14,15 @@ struct CDMovementAIComponent { std::string attachedPath; }; -//! MovementAIComponent table -class CDMovementAIComponentTable : public CDTable { +class CDMovementAIComponentTable : public CDTable<CDMovementAIComponentTable> { private: std::vector<CDMovementAIComponent> entries; public: - - //! Constructor - CDMovementAIComponentTable(void); - - //! Destructor - ~CDMovementAIComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDMovementAIComponentTable(); + // Queries the table with a custom "where" clause std::vector<CDMovementAIComponent> Query(std::function<bool(CDMovementAIComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ + // Gets all the entries in the table std::vector<CDMovementAIComponent> GetEntries(void) const; - }; - diff --git a/dDatabase/Tables/CDObjectSkillsTable.cpp b/dDatabase/Tables/CDObjectSkillsTable.cpp index dc797529..2e8b3fb2 100644 --- a/dDatabase/Tables/CDObjectSkillsTable.cpp +++ b/dDatabase/Tables/CDObjectSkillsTable.cpp @@ -33,14 +33,6 @@ CDObjectSkillsTable::CDObjectSkillsTable(void) { tableData.finalize(); } -//! Destructor -CDObjectSkillsTable::~CDObjectSkillsTable(void) {} - -//! Returns the table's name -std::string CDObjectSkillsTable::GetName(void) const { - return "ObjectSkills"; -} - //! Queries the table with a custom "where" clause std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObjectSkills)> predicate) { @@ -55,4 +47,3 @@ std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObje std::vector<CDObjectSkills> CDObjectSkillsTable::GetEntries(void) const { return this->entries; } - diff --git a/dDatabase/Tables/CDObjectSkillsTable.h b/dDatabase/Tables/CDObjectSkillsTable.h index c2caf71b..4ceaa447 100644 --- a/dDatabase/Tables/CDObjectSkillsTable.h +++ b/dDatabase/Tables/CDObjectSkillsTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDObjectSkillsTable.hpp - \brief Contains data for the ObjectSkills table - */ - - //! ObjectSkills Struct struct CDObjectSkills { unsigned int objectTemplate; //!< The LOT of the item unsigned int skillID; //!< The Skill ID of the object @@ -16,35 +10,16 @@ struct CDObjectSkills { unsigned int AICombatWeight; //!< ??? }; -//! ObjectSkills table -class CDObjectSkillsTable : public CDTable { +class CDObjectSkillsTable : public CDTable<CDObjectSkillsTable> { private: std::vector<CDObjectSkills> entries; public: - - //! Constructor - CDObjectSkillsTable(void); - - //! Destructor - ~CDObjectSkillsTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDObjectSkillsTable(); + // Queries the table with a custom "where" clause std::vector<CDObjectSkills> Query(std::function<bool(CDObjectSkills)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ + // Gets all the entries in the table std::vector<CDObjectSkills> GetEntries(void) const; }; diff --git a/dDatabase/Tables/CDObjectsTable.cpp b/dDatabase/Tables/CDObjectsTable.cpp index 5133becc..c68c3e6a 100644 --- a/dDatabase/Tables/CDObjectsTable.cpp +++ b/dDatabase/Tables/CDObjectsTable.cpp @@ -43,14 +43,6 @@ CDObjectsTable::CDObjectsTable(void) { m_default.id = 0; } -//! Destructor -CDObjectsTable::~CDObjectsTable(void) {} - -//! Returns the table's name -std::string CDObjectsTable::GetName(void) const { - return "Objects"; -} - const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) { const auto& it = this->entries.find(LOT); if (it != this->entries.end()) { diff --git a/dDatabase/Tables/CDObjectsTable.h b/dDatabase/Tables/CDObjectsTable.h index 333477bd..171eddef 100644 --- a/dDatabase/Tables/CDObjectsTable.h +++ b/dDatabase/Tables/CDObjectsTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDObjectsTable.hpp - \brief Contains data for the Objects table - */ - - //! RebuildComponent Struct struct CDObjects { unsigned int id; //!< The LOT of the object std::string name; //!< The internal name of the object @@ -26,29 +20,14 @@ struct CDObjects { UNUSED(unsigned int HQ_valid); //!< Probably used for the Nexus HQ database on LEGOUniverse.com }; -//! ObjectSkills table -class CDObjectsTable : public CDTable { +class CDObjectsTable : public CDTable<CDObjectsTable> { private: - //std::vector<CDObjects> entries; std::map<unsigned int, CDObjects> entries; CDObjects m_default; public: - - //! Constructor - CDObjectsTable(void); - - //! Destructor - ~CDObjectsTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Gets an entry by ID + CDObjectsTable(); + // Gets an entry by ID const CDObjects& GetByID(unsigned int LOT); - }; diff --git a/dDatabase/Tables/CDPackageComponentTable.cpp b/dDatabase/Tables/CDPackageComponentTable.cpp index eabe68da..efb85eeb 100644 --- a/dDatabase/Tables/CDPackageComponentTable.cpp +++ b/dDatabase/Tables/CDPackageComponentTable.cpp @@ -32,14 +32,6 @@ CDPackageComponentTable::CDPackageComponentTable(void) { tableData.finalize(); } -//! Destructor -CDPackageComponentTable::~CDPackageComponentTable(void) {} - -//! Returns the table's name -std::string CDPackageComponentTable::GetName(void) const { - return "PackageComponent"; -} - //! Queries the table with a custom "where" clause std::vector<CDPackageComponent> CDPackageComponentTable::Query(std::function<bool(CDPackageComponent)> predicate) { diff --git a/dDatabase/Tables/CDPackageComponentTable.h b/dDatabase/Tables/CDPackageComponentTable.h index 763acf8c..6c11ab39 100644 --- a/dDatabase/Tables/CDPackageComponentTable.h +++ b/dDatabase/Tables/CDPackageComponentTable.h @@ -3,48 +3,20 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDPackageComponentTable.hpp - \brief Contains data for the PackageComponent table - */ - - //! PackageComponent Entry Struct struct CDPackageComponent { unsigned int id; unsigned int LootMatrixIndex; unsigned int packageType; }; - -//! PackageComponent table -class CDPackageComponentTable : public CDTable { +class CDPackageComponentTable : public CDTable<CDPackageComponentTable> { private: std::vector<CDPackageComponent> entries; public: - - //! Constructor CDPackageComponentTable(void); - - //! Destructor - ~CDPackageComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + // Queries the table with a custom "where" clause std::vector<CDPackageComponent> Query(std::function<bool(CDPackageComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDPackageComponent> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDPhysicsComponentTable.cpp b/dDatabase/Tables/CDPhysicsComponentTable.cpp index f85d83c4..bb21ed7f 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.cpp +++ b/dDatabase/Tables/CDPhysicsComponentTable.cpp @@ -28,7 +28,7 @@ CDPhysicsComponentTable::CDPhysicsComponentTable(void) { tableData.finalize(); } -CDPhysicsComponentTable::~CDPhysicsComponentTable(void) { +CDPhysicsComponentTable::~CDPhysicsComponentTable() { for (auto e : m_entries) { if (e.second) delete e.second; } @@ -36,10 +36,6 @@ CDPhysicsComponentTable::~CDPhysicsComponentTable(void) { m_entries.clear(); } -std::string CDPhysicsComponentTable::GetName(void) const { - return "PhysicsComponent"; -} - CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) { for (auto e : m_entries) { if (e.first == componentID) return e.second; diff --git a/dDatabase/Tables/CDPhysicsComponentTable.h b/dDatabase/Tables/CDPhysicsComponentTable.h index c5805da3..e63d337d 100644 --- a/dDatabase/Tables/CDPhysicsComponentTable.h +++ b/dDatabase/Tables/CDPhysicsComponentTable.h @@ -21,12 +21,12 @@ struct CDPhysicsComponent { UNUSED(std::string gravityVolumeAsset); }; -class CDPhysicsComponentTable : public CDTable { +class CDPhysicsComponentTable : public CDTable<CDPhysicsComponentTable> { public: - CDPhysicsComponentTable(void); - ~CDPhysicsComponentTable(void); + CDPhysicsComponentTable(); + ~CDPhysicsComponentTable(); - std::string GetName(void) const override; + static const std::string GetTableName() { return "PhysicsComponent"; }; CDPhysicsComponent* GetByID(unsigned int componentID); private: diff --git a/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp b/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp index 127ebc9d..1fead45e 100644 --- a/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp +++ b/dDatabase/Tables/CDPropertyEntranceComponentTable.cpp @@ -32,12 +32,6 @@ CDPropertyEntranceComponentTable::CDPropertyEntranceComponentTable() { tableData.finalize(); } -CDPropertyEntranceComponentTable::~CDPropertyEntranceComponentTable(void) = default; - -std::string CDPropertyEntranceComponentTable::GetName() const { - return "PropertyEntranceComponent"; -} - CDPropertyEntranceComponent CDPropertyEntranceComponentTable::GetByID(uint32_t id) { for (const auto& entry : entries) { if (entry.id == id) diff --git a/dDatabase/Tables/CDPropertyEntranceComponentTable.h b/dDatabase/Tables/CDPropertyEntranceComponentTable.h index fa0603c0..925fd1be 100644 --- a/dDatabase/Tables/CDPropertyEntranceComponentTable.h +++ b/dDatabase/Tables/CDPropertyEntranceComponentTable.h @@ -9,31 +9,13 @@ struct CDPropertyEntranceComponent { std::string groupType; }; -class CDPropertyEntranceComponentTable : public CDTable { +class CDPropertyEntranceComponentTable : public CDTable<CDPropertyEntranceComponentTable> { public: - //! Constructor CDPropertyEntranceComponentTable(); - - //! Destructor - ~CDPropertyEntranceComponentTable(); - - //! Returns the table's name - /*! - \return The table name - */ - [[nodiscard]] std::string GetName() const override; - - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + // Queries the table with a custom "where" clause CDPropertyEntranceComponent GetByID(uint32_t id); - //! Gets all the entries in the table - /*! - \return The entries - */ + // Gets all the entries in the table [[nodiscard]] std::vector<CDPropertyEntranceComponent> GetEntries() const { return entries; } private: std::vector<CDPropertyEntranceComponent> entries{}; diff --git a/dDatabase/Tables/CDPropertyTemplateTable.cpp b/dDatabase/Tables/CDPropertyTemplateTable.cpp index bf56da7b..4caa6dc5 100644 --- a/dDatabase/Tables/CDPropertyTemplateTable.cpp +++ b/dDatabase/Tables/CDPropertyTemplateTable.cpp @@ -30,12 +30,6 @@ CDPropertyTemplateTable::CDPropertyTemplateTable() { tableData.finalize(); } -CDPropertyTemplateTable::~CDPropertyTemplateTable() = default; - -std::string CDPropertyTemplateTable::GetName() const { - return "PropertyTemplate"; -} - CDPropertyTemplate CDPropertyTemplateTable::GetByMapID(uint32_t mapID) { for (const auto& entry : entries) { if (entry.mapID == mapID) diff --git a/dDatabase/Tables/CDPropertyTemplateTable.h b/dDatabase/Tables/CDPropertyTemplateTable.h index a266932b..cb075dbf 100644 --- a/dDatabase/Tables/CDPropertyTemplateTable.h +++ b/dDatabase/Tables/CDPropertyTemplateTable.h @@ -8,12 +8,11 @@ struct CDPropertyTemplate { std::string spawnName; }; -class CDPropertyTemplateTable : public CDTable { +class CDPropertyTemplateTable : public CDTable<CDPropertyTemplateTable> { public: CDPropertyTemplateTable(); - ~CDPropertyTemplateTable(); - [[nodiscard]] std::string GetName() const override; + static const std::string GetTableName() { return "PropertyTemplate"; }; CDPropertyTemplate GetByMapID(uint32_t mapID); private: std::vector<CDPropertyTemplate> entries{}; diff --git a/dDatabase/Tables/CDProximityMonitorComponentTable.cpp b/dDatabase/Tables/CDProximityMonitorComponentTable.cpp index 98cde098..688de056 100644 --- a/dDatabase/Tables/CDProximityMonitorComponentTable.cpp +++ b/dDatabase/Tables/CDProximityMonitorComponentTable.cpp @@ -33,14 +33,6 @@ CDProximityMonitorComponentTable::CDProximityMonitorComponentTable(void) { tableData.finalize(); } -//! Destructor -CDProximityMonitorComponentTable::~CDProximityMonitorComponentTable(void) {} - -//! Returns the table's name -std::string CDProximityMonitorComponentTable::GetName(void) const { - return "ProximityMonitorComponent"; -} - //! Queries the table with a custom "where" clause std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::Query(std::function<bool(CDProximityMonitorComponent)> predicate) { diff --git a/dDatabase/Tables/CDProximityMonitorComponentTable.h b/dDatabase/Tables/CDProximityMonitorComponentTable.h index 007bb916..38b7d43b 100644 --- a/dDatabase/Tables/CDProximityMonitorComponentTable.h +++ b/dDatabase/Tables/CDProximityMonitorComponentTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDProximityMonitorComponentTable.hpp - \brief Contains data for the ProximityMonitorComponent table - */ - - //! ProximityMonitorComponent Entry Struct struct CDProximityMonitorComponent { unsigned int id; std::string Proximities; @@ -16,36 +10,14 @@ struct CDProximityMonitorComponent { bool LoadOnServer; }; - -//! ProximityMonitorComponent table -class CDProximityMonitorComponentTable : public CDTable { +class CDProximityMonitorComponentTable : public CDTable<CDProximityMonitorComponentTable> { private: std::vector<CDProximityMonitorComponent> entries; public: - - //! Constructor CDProximityMonitorComponentTable(void); - - //! Destructor - ~CDProximityMonitorComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ std::vector<CDProximityMonitorComponent> Query(std::function<bool(CDProximityMonitorComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDProximityMonitorComponent> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDRailActivatorComponent.cpp b/dDatabase/Tables/CDRailActivatorComponent.cpp index 4d1b5e7e..2ff8990d 100644 --- a/dDatabase/Tables/CDRailActivatorComponent.cpp +++ b/dDatabase/Tables/CDRailActivatorComponent.cpp @@ -43,12 +43,6 @@ CDRailActivatorComponentTable::CDRailActivatorComponentTable() { tableData.finalize(); } -CDRailActivatorComponentTable::~CDRailActivatorComponentTable() = default; - -std::string CDRailActivatorComponentTable::GetName() const { - return "RailActivatorComponent"; -} - CDRailActivatorComponent CDRailActivatorComponentTable::GetEntryByID(int32_t id) const { for (const auto& entry : m_Entries) { if (entry.id == id) diff --git a/dDatabase/Tables/CDRailActivatorComponent.h b/dDatabase/Tables/CDRailActivatorComponent.h index b8313e96..03dd0525 100644 --- a/dDatabase/Tables/CDRailActivatorComponent.h +++ b/dDatabase/Tables/CDRailActivatorComponent.h @@ -20,12 +20,10 @@ struct CDRailActivatorComponent { bool showNameBillboard; }; -class CDRailActivatorComponentTable : public CDTable { +class CDRailActivatorComponentTable : public CDTable<CDRailActivatorComponentTable> { public: CDRailActivatorComponentTable(); - ~CDRailActivatorComponentTable(); - - std::string GetName() const override; + static const std::string GetTableName() { return "RailActivatorComponent"; }; [[nodiscard]] CDRailActivatorComponent GetEntryByID(int32_t id) const; [[nodiscard]] std::vector<CDRailActivatorComponent> GetEntries() const; private: diff --git a/dDatabase/Tables/CDRarityTableTable.cpp b/dDatabase/Tables/CDRarityTableTable.cpp index cfa8d01c..0b1212c0 100644 --- a/dDatabase/Tables/CDRarityTableTable.cpp +++ b/dDatabase/Tables/CDRarityTableTable.cpp @@ -33,14 +33,6 @@ CDRarityTableTable::CDRarityTableTable(void) { tableData.finalize(); } -//! Destructor -CDRarityTableTable::~CDRarityTableTable(void) {} - -//! Returns the table's name -std::string CDRarityTableTable::GetName(void) const { - return "RarityTable"; -} - //! Queries the table with a custom "where" clause std::vector<CDRarityTable> CDRarityTableTable::Query(std::function<bool(CDRarityTable)> predicate) { diff --git a/dDatabase/Tables/CDRarityTableTable.h b/dDatabase/Tables/CDRarityTableTable.h index 55cfec4b..592346ed 100644 --- a/dDatabase/Tables/CDRarityTableTable.h +++ b/dDatabase/Tables/CDRarityTableTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDRarityTableTable.hpp - \brief Contains data for the RarityTable table - */ - - //! RarityTable Entry Struct struct CDRarityTable { unsigned int id; float randmax; @@ -32,37 +26,15 @@ struct CDRarityTable { } }; - -//! RarityTable table -class CDRarityTableTable : public CDTable { +class CDRarityTableTable : public CDTable<CDRarityTableTable> { private: std::vector<CDRarityTable> entries; public: - - //! Constructor - CDRarityTableTable(void); - - //! Destructor - ~CDRarityTableTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDRarityTableTable(); + // Queries the table with a custom "where" clause std::vector<CDRarityTable> Query(std::function<bool(CDRarityTable)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ - const std::vector<CDRarityTable>& GetEntries(void) const; - + const std::vector<CDRarityTable>& GetEntries() const; }; diff --git a/dDatabase/Tables/CDRebuildComponentTable.cpp b/dDatabase/Tables/CDRebuildComponentTable.cpp index 111592d4..d5c386d1 100644 --- a/dDatabase/Tables/CDRebuildComponentTable.cpp +++ b/dDatabase/Tables/CDRebuildComponentTable.cpp @@ -39,14 +39,6 @@ CDRebuildComponentTable::CDRebuildComponentTable(void) { tableData.finalize(); } -//! Destructor -CDRebuildComponentTable::~CDRebuildComponentTable(void) {} - -//! Returns the table's name -std::string CDRebuildComponentTable::GetName(void) const { - return "RebuildComponent"; -} - //! Queries the table with a custom "where" clause std::vector<CDRebuildComponent> CDRebuildComponentTable::Query(std::function<bool(CDRebuildComponent)> predicate) { diff --git a/dDatabase/Tables/CDRebuildComponentTable.h b/dDatabase/Tables/CDRebuildComponentTable.h index bdc2da8a..db70a47d 100644 --- a/dDatabase/Tables/CDRebuildComponentTable.h +++ b/dDatabase/Tables/CDRebuildComponentTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDRebuildComponentTable.hpp - \brief Contains data for the RebuildComponent table - */ - - //! RebuildComponent Struct struct CDRebuildComponent { unsigned int id; //!< The component Id float reset_time; //!< The reset time @@ -22,36 +16,15 @@ struct CDRebuildComponent { float time_before_smash; //!< The time before smash }; -//! ObjectSkills table -class CDRebuildComponentTable : public CDTable { +class CDRebuildComponentTable : public CDTable<CDRebuildComponentTable> { private: std::vector<CDRebuildComponent> entries; public: - - //! Constructor - CDRebuildComponentTable(void); - - //! Destructor - ~CDRebuildComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDRebuildComponentTable(); + // Queries the table with a custom "where" clause std::vector<CDRebuildComponent> Query(std::function<bool(CDRebuildComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ - std::vector<CDRebuildComponent> GetEntries(void) const; - + std::vector<CDRebuildComponent> GetEntries() const; }; diff --git a/dDatabase/Tables/CDRewardsTable.cpp b/dDatabase/Tables/CDRewardsTable.cpp index a53e02b5..55672add 100644 --- a/dDatabase/Tables/CDRewardsTable.cpp +++ b/dDatabase/Tables/CDRewardsTable.cpp @@ -26,10 +26,6 @@ CDRewardsTable::~CDRewardsTable(void) { m_entries.clear(); } -std::string CDRewardsTable::GetName(void) const { - return "Rewards"; -} - std::vector<CDRewards*> CDRewardsTable::GetByLevelID(uint32_t levelID) { std::vector<CDRewards*> result{}; for (const auto& e : m_entries) { diff --git a/dDatabase/Tables/CDRewardsTable.h b/dDatabase/Tables/CDRewardsTable.h index 2edfd2b3..2e079a83 100644 --- a/dDatabase/Tables/CDRewardsTable.h +++ b/dDatabase/Tables/CDRewardsTable.h @@ -11,12 +11,12 @@ struct CDRewards { int32_t count; }; -class CDRewardsTable : public CDTable { +class CDRewardsTable : public CDTable<CDRewardsTable> { public: - CDRewardsTable(void); - ~CDRewardsTable(void); + CDRewardsTable(); + ~CDRewardsTable(); - std::string GetName(void) const override; + static const std::string GetTableName() { return "Rewards"; }; std::vector<CDRewards*> GetByLevelID(uint32_t levelID); private: diff --git a/dDatabase/Tables/CDScriptComponentTable.cpp b/dDatabase/Tables/CDScriptComponentTable.cpp index d91dcee9..8050c139 100644 --- a/dDatabase/Tables/CDScriptComponentTable.cpp +++ b/dDatabase/Tables/CDScriptComponentTable.cpp @@ -29,14 +29,6 @@ CDScriptComponentTable::CDScriptComponentTable(void) { tableData.finalize(); } -//! Destructor -CDScriptComponentTable::~CDScriptComponentTable(void) {} - -//! Returns the table's name -std::string CDScriptComponentTable::GetName(void) const { - return "ScriptComponent"; -} - const CDScriptComponent& CDScriptComponentTable::GetByID(unsigned int id) { std::map<unsigned int, CDScriptComponent>::iterator it = this->entries.find(id); if (it != this->entries.end()) { diff --git a/dDatabase/Tables/CDScriptComponentTable.h b/dDatabase/Tables/CDScriptComponentTable.h index 92534cc0..77453939 100644 --- a/dDatabase/Tables/CDScriptComponentTable.h +++ b/dDatabase/Tables/CDScriptComponentTable.h @@ -3,44 +3,20 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDScriptComponentTable.hpp - \brief Contains data for the ScriptComponent table - */ - - //! ScriptComponent Struct struct CDScriptComponent { unsigned int id; //!< The component ID std::string script_name; //!< The script name std::string client_script_name; //!< The client script name }; -//! ObjectSkills table -class CDScriptComponentTable : public CDTable { +class CDScriptComponentTable : public CDTable<CDScriptComponentTable> { private: std::map<unsigned int, CDScriptComponent> entries; CDScriptComponent m_ToReturnWhenNoneFound; public: - //! Gets an entry by ID + CDScriptComponentTable(); + // Gets an entry by scriptID const CDScriptComponent& GetByID(unsigned int id); - - //! Constructor - CDScriptComponentTable(void); - - //! Destructor - ~CDScriptComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ - }; diff --git a/dDatabase/Tables/CDSkillBehaviorTable.cpp b/dDatabase/Tables/CDSkillBehaviorTable.cpp index b6b601a1..c5df78ef 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.cpp +++ b/dDatabase/Tables/CDSkillBehaviorTable.cpp @@ -51,24 +51,8 @@ CDSkillBehaviorTable::CDSkillBehaviorTable(void) { tableData.finalize(); } -//! Destructor -CDSkillBehaviorTable::~CDSkillBehaviorTable(void) {} - -//! Returns the table's name -std::string CDSkillBehaviorTable::GetName(void) const { - return "SkillBehavior"; -} - //! Queries the table with a custom "where" clause std::vector<CDSkillBehavior> CDSkillBehaviorTable::Query(std::function<bool(CDSkillBehavior)> predicate) { - - /*std::vector<CDSkillBehavior> data = cpplinq::from(this->entries) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data;*/ - - //Logger::LogDebug("CDSkillBehaviorTable", "The 'Query' function is no longer working! Please use GetSkillByID instead!"); std::vector<CDSkillBehavior> data; //So MSVC shuts up return data; } diff --git a/dDatabase/Tables/CDSkillBehaviorTable.h b/dDatabase/Tables/CDSkillBehaviorTable.h index da8676db..eb3094e0 100644 --- a/dDatabase/Tables/CDSkillBehaviorTable.h +++ b/dDatabase/Tables/CDSkillBehaviorTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDSkillBehaviorTable.hpp - \brief Contains data for the SkillBehavior table - */ - - //! ZoneTable Struct struct CDSkillBehavior { unsigned int skillID; //!< The Skill ID of the skill UNUSED(unsigned int locStatus); //!< ?? @@ -31,33 +25,17 @@ struct CDSkillBehavior { UNUSED(unsigned int cancelType); //!< The cancel type (?) }; -//! SkillBehavior table -class CDSkillBehaviorTable : public CDTable { +class CDSkillBehaviorTable : public CDTable<CDSkillBehaviorTable> { private: std::map<unsigned int, CDSkillBehavior> entries; CDSkillBehavior m_empty; public: - - //! Constructor - CDSkillBehaviorTable(void); - - //! Destructor - ~CDSkillBehaviorTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDSkillBehaviorTable(); + // Queries the table with a custom "where" clause std::vector<CDSkillBehavior> Query(std::function<bool(CDSkillBehavior)> predicate); - //! Gets an entry by ID + // Gets an entry by skillID const CDSkillBehavior& GetSkillByID(unsigned int skillID); }; diff --git a/dDatabase/Tables/CDTable.h b/dDatabase/Tables/CDTable.h index cd05782d..fca16eb8 100644 --- a/dDatabase/Tables/CDTable.h +++ b/dDatabase/Tables/CDTable.h @@ -1,9 +1,8 @@ #pragma once -// Custom Classes -#include "../CDClientDatabase.h" +#include "CDClientDatabase.h" +#include "Singleton.h" -// C++ #include <functional> #include <string> #include <vector> @@ -19,23 +18,8 @@ #pragma warning (disable : 4244) //Disable double to float conversion warnings #pragma warning (disable : 4715) //Disable "not all control paths return a value" -#if defined(__unix) || defined(__APPLE__) -//For Linux: -typedef __int64_t __int64; -#endif - -/*! - \file CDTable.hpp - \brief A virtual class for CDClient Tables - */ - - //! The base class for all CD tables -class CDTable { -public: - - //! Returns the table's name - /*! - \return The table name - */ - virtual std::string GetName() const = 0; +template<class Table> +class CDTable : public Singleton<Table> { +protected: + virtual ~CDTable() = default; }; diff --git a/dDatabase/Tables/CDVendorComponentTable.cpp b/dDatabase/Tables/CDVendorComponentTable.cpp index 86d87d4b..dfff2e20 100644 --- a/dDatabase/Tables/CDVendorComponentTable.cpp +++ b/dDatabase/Tables/CDVendorComponentTable.cpp @@ -34,14 +34,6 @@ CDVendorComponentTable::CDVendorComponentTable(void) { tableData.finalize(); } -//! Destructor -CDVendorComponentTable::~CDVendorComponentTable(void) {} - -//! Returns the table's name -std::string CDVendorComponentTable::GetName(void) const { - return "VendorComponent"; -} - //! Queries the table with a custom "where" clause std::vector<CDVendorComponent> CDVendorComponentTable::Query(std::function<bool(CDVendorComponent)> predicate) { diff --git a/dDatabase/Tables/CDVendorComponentTable.h b/dDatabase/Tables/CDVendorComponentTable.h index 2e0fb9e4..f2666d7e 100644 --- a/dDatabase/Tables/CDVendorComponentTable.h +++ b/dDatabase/Tables/CDVendorComponentTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDVendorComponentTable.hpp - \brief Contains data for the VendorComponent table - */ - - //! VendorComponent Struct struct CDVendorComponent { unsigned int id; //!< The Component ID float buyScalar; //!< Buy Scalar (what does that mean?) @@ -17,36 +11,15 @@ struct CDVendorComponent { unsigned int LootMatrixIndex; //!< LootMatrixIndex of the vendor's items }; -//! VendorComponent table -class CDVendorComponentTable : public CDTable { +class CDVendorComponentTable : public CDTable<CDVendorComponentTable> { private: std::vector<CDVendorComponent> entries; public: - - //! Constructor - CDVendorComponentTable(void); - - //! Destructor - ~CDVendorComponentTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a custom "where" clause - /*! - \param predicate The predicate - */ + CDVendorComponentTable(); + // Queries the table with a custom "where" clause std::vector<CDVendorComponent> Query(std::function<bool(CDVendorComponent)> predicate); - //! Gets all the entries in the table - /*! - \return The entries - */ std::vector<CDVendorComponent> GetEntries(void) const; - }; diff --git a/dDatabase/Tables/CDZoneTableTable.cpp b/dDatabase/Tables/CDZoneTableTable.cpp index 04f7d102..bafbf8fe 100644 --- a/dDatabase/Tables/CDZoneTableTable.cpp +++ b/dDatabase/Tables/CDZoneTableTable.cpp @@ -53,14 +53,6 @@ CDZoneTableTable::CDZoneTableTable(void) { tableData.finalize(); } -//! Destructor -CDZoneTableTable::~CDZoneTableTable(void) {} - -//! Returns the table's name -std::string CDZoneTableTable::GetName(void) const { - return "ZoneTable"; -} - //! Queries the table with a zoneID to find. const CDZoneTable* CDZoneTableTable::Query(unsigned int zoneID) { const auto& iter = m_Entries.find(zoneID); diff --git a/dDatabase/Tables/CDZoneTableTable.h b/dDatabase/Tables/CDZoneTableTable.h index c115a38a..f844fd25 100644 --- a/dDatabase/Tables/CDZoneTableTable.h +++ b/dDatabase/Tables/CDZoneTableTable.h @@ -3,12 +3,6 @@ // Custom Classes #include "CDTable.h" -/*! - \file CDZoneTableTable.hpp - \brief Contains data for the ZoneTable table - */ - - //! ZoneTable Struct struct CDZoneTable { unsigned int zoneID; //!< The Zone ID of the object unsigned int locStatus; //!< The Locale Status(?) @@ -39,28 +33,13 @@ struct CDZoneTable { UNUSED(bool mountsAllowed); //!< Whether or not mounts are allowed }; -//! ZoneTable table -class CDZoneTableTable : public CDTable { +class CDZoneTableTable : public CDTable<CDZoneTableTable> { private: std::map<unsigned int, CDZoneTable> m_Entries; public: + CDZoneTableTable(); - //! Constructor - CDZoneTableTable(void); - - //! Destructor - ~CDZoneTableTable(void); - - //! Returns the table's name - /*! - \return The table name - */ - std::string GetName(void) const override; - - //! Queries the table with a zoneID to find. - /*! - \param id The zoneID - */ + // Queries the table with a zoneID to find. const CDZoneTable* Query(unsigned int zoneID); }; diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 77692966..13507527 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -72,6 +72,18 @@ #include "TriggerComponent.h" #include "eReplicaComponentType.h" +// Table includes +#include "CDComponentsRegistryTable.h" +#include "CDCurrencyTableTable.h" +#include "CDMovementAIComponentTable.h" +#include "CDProximityMonitorComponentTable.h" +#include "CDRebuildComponentTable.h" +#include "CDObjectSkillsTable.h" +#include "CDObjectsTable.h" +#include "CDScriptComponentTable.h" +#include "CDSkillBehaviorTable.h" +#include "CDZoneTableTable.h" + Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) { m_ObjectID = objectID; m_TemplateID = info.lot; @@ -158,7 +170,7 @@ void Entity::Initialize() { } // Get the registry table - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); /** * Special case for BBB models. They have components not corresponding to the registry. @@ -330,7 +342,7 @@ void Entity::Initialize() { if (rebuildComponentID > 0) componentID = rebuildComponentID; if (buffComponentID > 0) componentID = buffComponentID; - CDDestructibleComponentTable* destCompTable = CDClientManager::Instance()->GetTable<CDDestructibleComponentTable>("DestructibleComponent"); + CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable<CDDestructibleComponentTable>(); std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); if (buffComponentID > 0 || collectibleComponentID > 0) { @@ -362,7 +374,7 @@ void Entity::Initialize() { uint32_t npcMinLevel = destCompData[0].level; uint32_t currencyIndex = destCompData[0].CurrencyIndex; - CDCurrencyTableTable* currencyTable = CDClientManager::Instance()->GetTable<CDCurrencyTableTable>("CurrencyTable"); + CDCurrencyTableTable* currencyTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>(); std::vector<CDCurrencyTable> currencyValues = currencyTable->Query([=](CDCurrencyTable entry) { return (entry.currencyIndex == currencyIndex && entry.npcminlevel == npcMinLevel); }); if (currencyValues.size() > 0) { @@ -440,7 +452,7 @@ void Entity::Initialize() { * This is a bit of a mess */ - CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent"); + CDScriptComponentTable* scriptCompTable = CDClientManager::Instance().GetTable<CDScriptComponentTable>(); int32_t scriptComponentID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SCRIPT, -1); std::string scriptName = ""; @@ -489,7 +501,7 @@ void Entity::Initialize() { // ZoneControl script if (m_TemplateID == 2365) { - CDZoneTableTable* zoneTable = CDClientManager::Instance()->GetTable<CDZoneTableTable>("ZoneTable"); + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>(); const auto zoneID = dZoneManager::Instance()->GetZoneID(); const CDZoneTable* zoneData = zoneTable->Query(zoneID.GetMapID()); @@ -517,7 +529,7 @@ void Entity::Initialize() { RebuildComponent* comp = new RebuildComponent(this); m_Components.insert(std::make_pair(eReplicaComponentType::QUICK_BUILD, comp)); - CDRebuildComponentTable* rebCompTable = CDClientManager::Instance()->GetTable<CDRebuildComponentTable>("RebuildComponent"); + CDRebuildComponentTable* rebCompTable = CDClientManager::Instance().GetTable<CDRebuildComponentTable>(); std::vector<CDRebuildComponent> rebCompData = rebCompTable->Query([=](CDRebuildComponent entry) { return (entry.id == rebuildComponentID); }); if (rebCompData.size() > 0) { @@ -637,7 +649,7 @@ void Entity::Initialize() { int movementAIID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVEMENT_AI); if (movementAIID > 0) { - CDMovementAIComponentTable* moveAITable = CDClientManager::Instance()->GetTable<CDMovementAIComponentTable>("MovementAIComponent"); + CDMovementAIComponentTable* moveAITable = CDClientManager::Instance().GetTable<CDMovementAIComponentTable>(); std::vector<CDMovementAIComponent> moveAIComp = moveAITable->Query([=](CDMovementAIComponent entry) {return (entry.id == movementAIID); }); if (moveAIComp.size() > 0) { @@ -696,7 +708,7 @@ void Entity::Initialize() { int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR); if (proximityMonitorID > 0) { - CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance()->GetTable<CDProximityMonitorComponentTable>("ProximityMonitorComponent"); + CDProximityMonitorComponentTable* proxCompTable = CDClientManager::Instance().GetTable<CDProximityMonitorComponentTable>(); std::vector<CDProximityMonitorComponent> proxCompData = proxCompTable->Query([=](CDProximityMonitorComponent entry) { return (entry.id == proximityMonitorID); }); if (proxCompData.size() > 0) { std::vector<std::string> proximityStr = GeneralUtils::SplitString(proxCompData[0].Proximities, ','); @@ -1576,7 +1588,7 @@ void Entity::PickupItem(const LWOOBJID& objectID) { InventoryComponent* inv = GetComponent<InventoryComponent>(); if (!inv) return; - CDObjectsTable* objectsTable = CDClientManager::Instance()->GetTable<CDObjectsTable>("Objects"); + CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>(); auto& droppedLoot = static_cast<Player*>(this)->GetDroppedLoot(); @@ -1589,10 +1601,10 @@ void Entity::PickupItem(const LWOOBJID& objectID) { const CDObjects& object = objectsTable->GetByID(p.second.lot); if (object.id != 0 && object.type == "Powerup") { - CDObjectSkillsTable* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); + CDObjectSkillsTable* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>(); std::vector<CDObjectSkills> skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == p.second.lot); }); for (CDObjectSkills skill : skills) { - CDSkillBehaviorTable* skillBehTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + CDSkillBehaviorTable* skillBehTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); CDSkillBehavior behaviorData = skillBehTable->GetSkillByID(skill.skillID); SkillComponent::HandleUnmanaged(behaviorData.behaviorID, GetObjectID()); diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index a0df940f..d85a95d4 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -8,6 +8,10 @@ #include "dLogger.h" #include "dConfig.h" #include "CDClientManager.h" +#include "GeneralUtils.h" +#include "Entity.h" + +#include "CDActivitiesTable.h" Leaderboard::Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector<LeaderboardEntry> entries, LWOOBJID relatedPlayer, LeaderboardType leaderboardType) { @@ -273,7 +277,7 @@ void LeaderboardManager::SendLeaderboard(uint32_t gameID, InfoType infoType, boo } LeaderboardType LeaderboardManager::GetLeaderboardType(uint32_t gameID) { - auto* activitiesTable = CDClientManager::Instance()->GetTable<CDActivitiesTable>("Activities"); + auto* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>(); std::vector<CDActivities> activities = activitiesTable->Query([=](const CDActivities& entry) { return (entry.ActivityID == gameID); }); diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index c8c1a1de..2a269ddc 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -73,13 +73,14 @@ #include "EntityManager.h" #include "RenderComponent.h" #include "DestroyableComponent.h" +#include "CDBehaviorTemplateTable.h" std::unordered_map<uint32_t, Behavior*> Behavior::Cache = {}; CDBehaviorParameterTable* Behavior::BehaviorParameterTable = nullptr; Behavior* Behavior::GetBehavior(const uint32_t behaviorId) { if (BehaviorParameterTable == nullptr) { - BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter"); + BehaviorParameterTable = CDClientManager::Instance().GetTable<CDBehaviorParameterTable>(); } const auto pair = Cache.find(behaviorId); @@ -290,7 +291,7 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { } BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { - auto behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDBehaviorTemplateTable>("BehaviorTemplate"); + auto behaviorTemplateTable = CDClientManager::Instance().GetTable<CDBehaviorTemplateTable>(); BehaviorTemplates templateID = BehaviorTemplates::BEHAVIOR_EMPTY; // Find behavior template by its behavior id. Default to 0. @@ -398,7 +399,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID } Behavior::Behavior(const uint32_t behaviorId) { - auto behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDBehaviorTemplateTable>("BehaviorTemplate"); + auto behaviorTemplateTable = CDClientManager::Instance().GetTable<CDBehaviorTemplateTable>(); CDBehaviorTemplate templateInDatabase{}; @@ -441,7 +442,7 @@ Behavior::Behavior(const uint32_t behaviorId) { float Behavior::GetFloat(const std::string& name, const float defaultValue) const { // Get the behavior parameter entry and return its value. - if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter"); + if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance().GetTable<CDBehaviorParameterTable>(); return BehaviorParameterTable->GetValue(this->m_behaviorId, name, defaultValue); } @@ -469,7 +470,7 @@ Behavior* Behavior::GetAction(float value) const { std::map<std::string, float> Behavior::GetParameterNames() const { std::map<std::string, float> templatesInDatabase; // Find behavior template by its behavior id. - if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter"); + if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance().GetTable<CDBehaviorParameterTable>(); if (BehaviorParameterTable) { templatesInDatabase = BehaviorParameterTable->GetParametersByBehaviorID(this->m_behaviorId); } diff --git a/dGame/dBehaviors/OverTimeBehavior.cpp b/dGame/dBehaviors/OverTimeBehavior.cpp index 20dd89af..5afbbd26 100644 --- a/dGame/dBehaviors/OverTimeBehavior.cpp +++ b/dGame/dBehaviors/OverTimeBehavior.cpp @@ -9,6 +9,8 @@ #include "CDClientDatabase.h" #include "CDClientManager.h" +#include "CDSkillBehaviorTable.h" + void OverTimeBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto originator = context->originator; @@ -39,7 +41,7 @@ void OverTimeBehavior::Load() { m_Action = GetInt("action"); // Since m_Action is a skillID and not a behavior, get is correlated behaviorID. - CDSkillBehaviorTable* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + CDSkillBehaviorTable* skillTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); m_ActionBehaviorId = skillTable->GetSkillByID(m_Action).behaviorID; m_Delay = GetFloat("delay"); diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index a5255b07..64c739f5 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -23,6 +23,8 @@ #include "RebuildComponent.h" #include "DestroyableComponent.h" #include "Metrics.hpp" +#include "CDComponentsRegistryTable.h" +#include "CDPhysicsComponentTable.h" BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): Component(parent) { m_Target = LWOOBJID_EMPTY; @@ -105,10 +107,10 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): int32_t collisionGroup = (COLLISION_GROUP_DYNAMIC | COLLISION_GROUP_ENEMY); - CDComponentsRegistryTable* componentRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + CDComponentsRegistryTable* componentRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); auto componentID = componentRegistryTable->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::CONTROLLABLE_PHYSICS); - CDPhysicsComponentTable* physicsComponentTable = CDClientManager::Instance()->GetTable<CDPhysicsComponentTable>("PhysicsComponent"); + CDPhysicsComponentTable* physicsComponentTable = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>(); if (physicsComponentTable != nullptr) { auto* info = physicsComponentTable->GetByID(componentID); diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index 974d0bd2..68b5182c 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -10,6 +10,7 @@ #include "ControllablePhysicsComponent.h" #include "EntityManager.h" #include "CDClientManager.h" +#include "CDSkillBehaviorTable.h" std::unordered_map<int32_t, std::vector<BuffParameter>> BuffComponent::m_Cache{}; @@ -101,7 +102,7 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO const auto& parameters = GetBuffParameters(id); for (const auto& parameter : parameters) { if (parameter.name == "overtime") { - auto* behaviorTemplateTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + auto* behaviorTemplateTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); behaviorID = behaviorTemplateTable->GetSkillByID(parameter.values[0]).behaviorID; stacks = static_cast<int32_t>(parameter.values[1]); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 51d68a12..c2d72941 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -34,6 +34,8 @@ #include "WorldConfig.h" #include "eMissionTaskType.h" +#include "CDComponentsRegistryTable.h" + DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_iArmor = 0; m_fMaxArmor = 0.0f; @@ -74,7 +76,7 @@ DestroyableComponent::~DestroyableComponent() { } void DestroyableComponent::Reinitialize(LOT templateID) { - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); int32_t buffComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::BUFF); int32_t collectibleComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::COLLECTIBLE); @@ -85,7 +87,7 @@ void DestroyableComponent::Reinitialize(LOT templateID) { if (rebuildComponentID > 0) componentID = rebuildComponentID; if (buffComponentID > 0) componentID = buffComponentID; - CDDestructibleComponentTable* destCompTable = CDClientManager::Instance()->GetTable<CDDestructibleComponentTable>("DestructibleComponent"); + CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable<CDDestructibleComponentTable>(); std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); }); if (componentID > 0) { diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index df292e2a..dc8fdbdc 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -30,6 +30,12 @@ #include "CppScripts.h" #include "eMissionTaskType.h" +#include "CDComponentsRegistryTable.h" +#include "CDInventoryComponentTable.h" +#include "CDScriptComponentTable.h" +#include "CDObjectSkillsTable.h" +#include "CDSkillBehaviorTable.h" + InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) { this->m_Dirty = true; this->m_Equipped = {}; @@ -47,10 +53,10 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do return; } - auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); const auto componentId = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::INVENTORY); - auto* inventoryComponentTable = CDClientManager::Instance()->GetTable<CDInventoryComponentTable>("InventoryComponent"); + auto* inventoryComponentTable = CDClientManager::Instance().GetTable<CDInventoryComponentTable>(); auto items = inventoryComponentTable->Query([=](const CDInventoryComponent entry) { return entry.id == componentId; }); auto slot = 0u; @@ -912,11 +918,11 @@ void InventoryComponent::UnEquipItem(Item* item) { void InventoryComponent::EquipScripts(Item* equippedItem) { - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); if (!compRegistryTable) return; int32_t scriptComponentID = compRegistryTable->GetByIDAndType(equippedItem->GetLot(), eReplicaComponentType::SCRIPT, -1); if (scriptComponentID > -1) { - CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent"); + CDScriptComponentTable* scriptCompTable = CDClientManager::Instance().GetTable<CDScriptComponentTable>(); CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID); auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name); if (!itemScript) { @@ -927,11 +933,11 @@ void InventoryComponent::EquipScripts(Item* equippedItem) { } void InventoryComponent::UnequipScripts(Item* unequippedItem) { - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); if (!compRegistryTable) return; int32_t scriptComponentID = compRegistryTable->GetByIDAndType(unequippedItem->GetLot(), eReplicaComponentType::SCRIPT, -1); if (scriptComponentID > -1) { - CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent"); + CDScriptComponentTable* scriptCompTable = CDClientManager::Instance().GetTable<CDScriptComponentTable>(); CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID); auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name); if (!itemScript) { @@ -1306,7 +1312,7 @@ bool InventoryComponent::IsTransferInventory(eInventoryType type) { } uint32_t InventoryComponent::FindSkill(const LOT lot) { - auto* table = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); + auto* table = CDClientManager::Instance().GetTable<CDObjectSkillsTable>(); const auto results = table->Query([=](const CDObjectSkills& entry) { return entry.objectTemplate == static_cast<unsigned int>(lot); @@ -1324,8 +1330,8 @@ uint32_t InventoryComponent::FindSkill(const LOT lot) { std::vector<uint32_t> InventoryComponent::FindBuffs(Item* item, bool castOnEquip) const { std::vector<uint32_t> buffs; if (item == nullptr) return buffs; - auto* table = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); - auto* behaviors = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + auto* table = CDClientManager::Instance().GetTable<CDObjectSkillsTable>(); + auto* behaviors = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); const auto results = table->Query([=](const CDObjectSkills& entry) { return entry.objectTemplate == static_cast<unsigned int>(item->GetLot()); diff --git a/dGame/dComponents/LevelProgressionComponent.cpp b/dGame/dComponents/LevelProgressionComponent.cpp index 6e6b823e..814a7a86 100644 --- a/dGame/dComponents/LevelProgressionComponent.cpp +++ b/dGame/dComponents/LevelProgressionComponent.cpp @@ -4,6 +4,8 @@ #include "CharacterComponent.h" #include "tinyxml2.h" +#include "CDRewardsTable.h" + LevelProgressionComponent::LevelProgressionComponent(Entity* parent) : Component(parent) { m_Parent = parent; m_Level = 1; @@ -42,7 +44,7 @@ void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool } void LevelProgressionComponent::HandleLevelUp() { - auto* rewardsTable = CDClientManager::Instance()->GetTable<CDRewardsTable>("Rewards"); + auto* rewardsTable = CDClientManager::Instance().GetTable<CDRewardsTable>(); const auto& rewards = rewardsTable->GetByLevelID(m_Level); bool rewardingItem = rewards.size() > 0; diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index cbae7f9f..0ae0f07e 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -265,7 +265,7 @@ void MissionComponent::ForceProgressValue(uint32_t missionId, uint32_t taskType, } bool MissionComponent::GetMissionInfo(uint32_t missionId, CDMissions& result) { - auto* missionsTable = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); + auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>(); const auto missions = missionsTable->Query([=](const CDMissions& entry) { return entry.id == static_cast<int>(missionId); @@ -319,8 +319,8 @@ bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, return any; #else - auto* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); - auto* missionsTable = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); + auto* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>(); + auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>(); auto tasks = missionTasksTable->Query([=](const CDMissionTasks& entry) { return entry.taskType == static_cast<unsigned>(type); @@ -406,8 +406,8 @@ const std::vector<uint32_t>& MissionComponent::QueryAchievements(eMissionTaskTyp } // Find relevent tables - auto* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); - auto* missionsTable = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); + auto* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>(); + auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>(); std::vector<uint32_t> result; diff --git a/dGame/dComponents/MissionOfferComponent.cpp b/dGame/dComponents/MissionOfferComponent.cpp index ad315314..e4c94ebd 100644 --- a/dGame/dComponents/MissionOfferComponent.cpp +++ b/dGame/dComponents/MissionOfferComponent.cpp @@ -16,6 +16,8 @@ #include "MissionPrerequisites.h" #include "eMissionState.h" +#include "CDComponentsRegistryTable.h" + OfferedMission::OfferedMission(const uint32_t missionId, const bool offersMission, const bool acceptsMission) { this->missionId = missionId; this->offersMission = offersMission; @@ -38,7 +40,7 @@ bool OfferedMission::GetAcceptMission() const { //------------------------ MissionOfferComponent below ------------------------ MissionOfferComponent::MissionOfferComponent(Entity* parent, const LOT parentLot) : Component(parent) { - auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); auto value = compRegistryTable->GetByIDAndType(parentLot, eReplicaComponentType::MISSION_OFFER, -1); @@ -46,7 +48,7 @@ MissionOfferComponent::MissionOfferComponent(Entity* parent, const LOT parentLot const uint32_t componentId = value; // Now lookup the missions in the MissionNPCComponent table - auto* missionNpcComponentTable = CDClientManager::Instance()->GetTable<CDMissionNPCComponentTable>("MissionNPCComponent"); + auto* missionNpcComponentTable = CDClientManager::Instance().GetTable<CDMissionNPCComponentTable>(); auto missions = missionNpcComponentTable->Query([=](const CDMissionNPCComponent& entry) { return entry.id == static_cast<unsigned>(componentId); diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 1f774690..278e9106 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -11,6 +11,9 @@ #include "SimplePhysicsComponent.h" #include "CDClientManager.h" +#include "CDComponentsRegistryTable.h" +#include "CDPhysicsComponentTable.h" + std::map<LOT, float> MovementAIComponent::m_PhysicsSpeedCache = {}; MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : Component(parent) { @@ -280,8 +283,8 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) { return it->second; } - CDComponentsRegistryTable* componentRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - CDPhysicsComponentTable* physicsComponentTable = CDClientManager::Instance()->GetTable<CDPhysicsComponentTable>("PhysicsComponent"); + CDComponentsRegistryTable* componentRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); + CDPhysicsComponentTable* physicsComponentTable = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>(); int32_t componentID; CDPhysicsComponent* physicsComponent = nullptr; diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index b95b7cdd..75cef4fb 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -143,10 +143,10 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : Component(par */ if (!m_HasCreatedPhysics) { - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS); - CDPhysicsComponentTable* physComp = CDClientManager::Instance()->GetTable<CDPhysicsComponentTable>("PhysicsComponent"); + CDPhysicsComponentTable* physComp = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>(); if (physComp == nullptr) return; @@ -253,10 +253,10 @@ void PhantomPhysicsComponent::CreatePhysics() { y = m_Parent->GetVar<float>(u"primitiveModelValueY"); z = m_Parent->GetVar<float>(u"primitiveModelValueZ"); } else { - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS); - CDPhysicsComponentTable* physComp = CDClientManager::Instance()->GetTable<CDPhysicsComponentTable>("PhysicsComponent"); + CDPhysicsComponentTable* physComp = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>(); if (physComp == nullptr) return; diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index 9498a903..fa838ed7 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -16,7 +16,7 @@ PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) { this->propertyQueries = {}; - auto table = CDClientManager::Instance()->GetTable<CDPropertyEntranceComponentTable>("PropertyEntranceComponent"); + auto table = CDClientManager::Instance().GetTable<CDPropertyEntranceComponentTable>(); const auto& entry = table->GetByID(componentID); this->m_MapID = entry.mapID; diff --git a/dGame/dComponents/RailActivatorComponent.cpp b/dGame/dComponents/RailActivatorComponent.cpp index 25fad26e..49fc105d 100644 --- a/dGame/dComponents/RailActivatorComponent.cpp +++ b/dGame/dComponents/RailActivatorComponent.cpp @@ -10,8 +10,7 @@ RailActivatorComponent::RailActivatorComponent(Entity* parent, int32_t componentID) : Component(parent) { m_ComponentID = componentID; - const auto tableData = CDClientManager::Instance() - ->GetTable<CDRailActivatorComponentTable>("RailActivatorComponent")->GetEntryByID(componentID); + const auto tableData = CDClientManager::Instance().GetTable<CDRailActivatorComponentTable>()->GetEntryByID(componentID);; m_Path = parent->GetVar<std::u16string>(u"rail_path"); m_PathDirection = parent->GetVar<bool>(u"rail_path_direction"); diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index f188859d..ee42acba 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -20,7 +20,7 @@ RenderComponent::RenderComponent(Entity* parent) : Component(parent) { return; /* - auto* table = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* table = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); const auto entry = table->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::RENDER); diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 4a034187..bafa1faa 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -22,9 +22,13 @@ #include "Loot.h" #include "eMissionTaskType.h" +#include "CDCurrencyTableTable.h" +#include "CDActivityRewardsTable.h" +#include "CDActivitiesTable.h" + ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { m_ActivityID = activityID; - CDActivitiesTable* activitiesTable = CDClientManager::Instance()->GetTable<CDActivitiesTable>("Activities"); + CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>(); std::vector<CDActivities> activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); for (CDActivities activity : activities) { @@ -53,7 +57,7 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit if (destroyableComponent) { // check for LMIs and set the loot LMIs - CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance()->GetTable<CDActivityRewardsTable>("ActivityRewards"); + CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>(); std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) {return (entry.LootMatrixIndex == destroyableComponent->GetLootMatrixID()); }); uint32_t startingLMI = 0; @@ -94,7 +98,7 @@ void ScriptedActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool } void ScriptedActivityComponent::ReloadConfig() { - CDActivitiesTable* activitiesTable = CDClientManager::Instance()->GetTable<CDActivitiesTable>("Activities"); + CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>(); std::vector<CDActivities> activities = activitiesTable->Query([=](CDActivities entry) {return (entry.ActivityID == m_ActivityID); }); for (auto activity : activities) { auto mapID = m_ActivityInfo.instanceMapID; @@ -557,14 +561,14 @@ void ActivityInstance::RewardParticipant(Entity* participant) { } // First, get the activity data - auto* activityRewardsTable = CDClientManager::Instance()->GetTable<CDActivityRewardsTable>("ActivityRewards"); + auto* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>(); std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) { return (entry.objectTemplate == m_ActivityInfo.ActivityID); }); if (!activityRewards.empty()) { uint32_t minCoins = 0; uint32_t maxCoins = 0; - auto* currencyTableTable = CDClientManager::Instance()->GetTable<CDCurrencyTableTable>("CurrencyTable"); + auto* currencyTableTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>(); std::vector<CDCurrencyTable> currencyTable = currencyTableTable->Query([=](CDCurrencyTable entry) { return (entry.currencyIndex == activityRewards[0].CurrencyIndex && entry.npcminlevel == 1); }); if (!currencyTable.empty()) { diff --git a/dGame/dComponents/ScriptedActivityComponent.h b/dGame/dComponents/ScriptedActivityComponent.h index a4aad048..1d49a62d 100644 --- a/dGame/dComponents/ScriptedActivityComponent.h +++ b/dGame/dComponents/ScriptedActivityComponent.h @@ -13,6 +13,8 @@ #include "Component.h" #include "eReplicaComponentType.h" +#include "CDActivitiesTable.h" + /** * Represents an instance of an activity, having participants and score */ diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 625f1f30..23ef1bee 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -24,6 +24,8 @@ #include "DoClientProjectileImpact.h" #include "CDClientManager.h" +#include "CDSkillBehaviorTable.h" + ProjectileSyncEntry::ProjectileSyncEntry() { } @@ -220,7 +222,7 @@ bool SkillComponent::CastSkill(const uint32_t skillId, LWOOBJID target, const LW // if it's not in the cache look it up and cache it if (pair == m_skillBehaviorCache.end()) { - auto skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + auto skillTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); behaviorId = skillTable->GetSkillByID(skillId).behaviorID; m_skillBehaviorCache.insert_or_assign(skillId, behaviorId); } else { diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index fe3c7792..d98b2eea 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -161,7 +161,7 @@ void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector< } void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) { - CDMissionTasksTable* missionTasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); + CDMissionTasksTable* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>(); std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { return (entry.targetGroup == argArray.at(4)); }); diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index e9599b71..c9178785 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -5,6 +5,11 @@ #include "Game.h" #include "dServer.h" +#include "CDComponentsRegistryTable.h" +#include "CDVendorComponentTable.h" +#include "CDLootMatrixTable.h" +#include "CDLootTableTable.h" + VendorComponent::VendorComponent(Entity* parent) : Component(parent) { SetupConstants(); RefreshInventory(true); @@ -59,13 +64,13 @@ void VendorComponent::RefreshInventory(bool isCreation) { return; } m_Inventory.clear(); - auto* lootMatrixTable = CDClientManager::Instance()->GetTable<CDLootMatrixTable>("LootMatrix"); + auto* lootMatrixTable = CDClientManager::Instance().GetTable<CDLootMatrixTable>(); std::vector<CDLootMatrix> lootMatrices = lootMatrixTable->Query([=](CDLootMatrix entry) { return (entry.LootMatrixIndex == m_LootMatrixID); }); if (lootMatrices.empty()) return; // Done with lootMatrix table - auto* lootTableTable = CDClientManager::Instance()->GetTable<CDLootTableTable>("LootTable"); + auto* lootTableTable = CDClientManager::Instance().GetTable<CDLootTableTable>(); for (const auto& lootMatrix : lootMatrices) { int lootTableID = lootMatrix.LootTableIndex; @@ -118,10 +123,10 @@ void VendorComponent::RefreshInventory(bool isCreation) { } void VendorComponent::SetupConstants() { - auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); int componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::VENDOR); - auto* vendorComponentTable = CDClientManager::Instance()->GetTable<CDVendorComponentTable>("VendorComponent"); + auto* vendorComponentTable = CDClientManager::Instance().GetTable<CDVendorComponentTable>(); std::vector<CDVendorComponent> vendorComps = vendorComponentTable->Query([=](CDVendorComponent entry) { return (entry.id == componentID); }); if (vendorComps.empty()) return; m_BuyScalar = vendorComps[0].buyScalar; diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index b63f1c6d..5c05c28d 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -286,7 +286,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System comp->Progress(eMissionTaskType::USE_SKILL, startSkill.skillID); } - CDSkillBehaviorTable* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + CDSkillBehaviorTable* skillTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); unsigned int behaviorId = skillTable->GetSkillByID(startSkill.skillID).behaviorID; bool success = false; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 8da37bf5..33a7f104 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -82,6 +82,9 @@ #include "AMFFormat_BitStream.h" #include "eReplicaComponentType.h" +#include "CDComponentsRegistryTable.h" +#include "CDObjectsTable.h" + void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) { CBITSTREAM; CMSGHEADER; @@ -1077,7 +1080,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, // Currency and powerups should not sync if (team != nullptr && currency == 0) { - CDObjectsTable* objectsTable = CDClientManager::Instance()->GetTable<CDObjectsTable>("Objects"); + CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>(); const CDObjects& object = objectsTable->GetByID(item); @@ -4720,8 +4723,8 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti InventoryComponent* inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); + CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>(); int itemCompID = compRegistryTable->GetByIDAndType(item, eReplicaComponentType::ITEM); CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); @@ -4812,8 +4815,8 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit Item* item = inv->FindItemById(iObjID); if (!item) return; - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); + CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>(); int itemCompID = compRegistryTable->GetByIDAndType(item->GetLot(), eReplicaComponentType::ITEM); CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); @@ -4862,8 +4865,8 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* Item* item = inv->FindItemById(iObjID); if (!item) return; - CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); + CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>(); int itemCompID = compRegistryTable->GetByIDAndType(item->GetLot(), eReplicaComponentType::ITEM); CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); @@ -5101,7 +5104,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) } } - CDEmoteTableTable* emotes = CDClientManager::Instance()->GetTable<CDEmoteTableTable>("EmoteTable"); + CDEmoteTableTable* emotes = CDClientManager::Instance().GetTable<CDEmoteTableTable>(); if (emotes) { CDEmoteTable* emote = emotes->GetEmote(emoteID); if (emote) sAnimationName = emote->animationName; diff --git a/dGame/dGameMessages/PropertyDataMessage.cpp b/dGame/dGameMessages/PropertyDataMessage.cpp index e0b792ad..c3443f31 100644 --- a/dGame/dGameMessages/PropertyDataMessage.cpp +++ b/dGame/dGameMessages/PropertyDataMessage.cpp @@ -6,6 +6,8 @@ #include "dLogger.h" #include "CDClientManager.h" +#include "CDPropertyTemplateTable.h" + void GameMessages::PropertyDataMessage::Serialize(RakNet::BitStream& stream) const { stream.Write<int64_t>(0); // - property id @@ -101,8 +103,7 @@ void GameMessages::PropertyDataMessage::Serialize(RakNet::BitStream& stream) con } GameMessages::PropertyDataMessage::PropertyDataMessage(uint32_t mapID) { - const auto propertyTemplate = CDClientManager::Instance()-> - GetTable<CDPropertyTemplateTable>("PropertyTemplate")->GetByMapID(mapID); + const auto propertyTemplate = CDClientManager::Instance().GetTable<CDPropertyTemplateTable>()->GetByMapID(mapID); TemplateID = propertyTemplate.id; ZoneId = propertyTemplate.mapID; diff --git a/dGame/dInventory/Inventory.cpp b/dGame/dInventory/Inventory.cpp index b35281eb..d752f87d 100644 --- a/dGame/dInventory/Inventory.cpp +++ b/dGame/dInventory/Inventory.cpp @@ -6,6 +6,8 @@ #include "eItemType.h" #include "eReplicaComponentType.h" +#include "CDComponentsRegistryTable.h" + std::vector<LOT> Inventory::m_GameMasterRestrictedItems = { 1727, // GM Only - JetPack 2243, // GM Only - Hammer of Doom @@ -274,9 +276,9 @@ eInventoryType Inventory::FindInventoryTypeForLot(const LOT lot) { } const CDItemComponent& Inventory::FindItemComponent(const LOT lot) { - auto* registry = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* registry = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); - auto* itemComponents = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); + auto* itemComponents = CDClientManager::Instance().GetTable<CDItemComponentTable>(); const auto componentId = registry->GetByIDAndType(lot, eReplicaComponentType::ITEM); @@ -292,7 +294,7 @@ const CDItemComponent& Inventory::FindItemComponent(const LOT lot) { } bool Inventory::IsValidItem(const LOT lot) { - auto* registry = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* registry = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); const auto componentId = registry->GetByIDAndType(lot, eReplicaComponentType::ITEM); diff --git a/dGame/dInventory/Inventory.h b/dGame/dInventory/Inventory.h index cd381db3..5e0ac8d6 100644 --- a/dGame/dInventory/Inventory.h +++ b/dGame/dInventory/Inventory.h @@ -6,7 +6,7 @@ #include <map> #include <vector> - +#include "CDItemComponentTable.h" #include "CDClientManager.h" #include "dCommonVars.h" diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 0df1723d..acaecbf7 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -18,6 +18,11 @@ #include "Loot.h" #include "eReplicaComponentType.h" +#include "CDBrickIDTableTable.h" +#include "CDObjectSkillsTable.h" +#include "CDComponentsRegistryTable.h" +#include "CDPackageComponentTable.h" + Item::Item(const LWOOBJID id, const LOT lot, Inventory* inventory, const uint32_t slot, const uint32_t count, const bool bound, const std::vector<LDFBaseData*>& config, const LWOOBJID parent, LWOOBJID subKey, eLootSourceType lootSourceType) { if (!Inventory::IsValidItem(lot)) { return; @@ -238,7 +243,7 @@ bool Item::IsEquipped() const { } bool Item::Consume() { - auto* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); + auto* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>(); auto skills = skillsTable->Query([=](const CDObjectSkills entry) { return entry.objectTemplate == static_cast<uint32_t>(lot); @@ -297,12 +302,12 @@ void Item::UseNonEquip(Item* item) { bool success = false; auto inventory = item->GetInventory(); if (inventory && inventory->GetType() == eInventoryType::ITEMS) { - auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::PACKAGE); if (packageComponentId == 0) return; - auto* packCompTable = CDClientManager::Instance()->GetTable<CDPackageComponentTable>("PackageComponent"); + auto* packCompTable = CDClientManager::Instance().GetTable<CDPackageComponentTable>(); auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast<uint32_t>(packageComponentId); }); auto success = !packages.empty(); @@ -380,7 +385,7 @@ void Item::Disassemble(const eInventoryType inventoryType) { } void Item::DisassembleModel() { - auto* table = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); + auto* table = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); const auto componentId = table->GetByIDAndType(GetLot(), eReplicaComponentType::RENDER); @@ -457,7 +462,7 @@ void Item::DisassembleModel() { currentBrick = currentBrick->NextSiblingElement(searchTerm.c_str()); } - auto* brickIDTable = CDClientManager::Instance()->GetTable<CDBrickIDTableTable>("BrickIDTable"); + auto* brickIDTable = CDClientManager::Instance().GetTable<CDBrickIDTableTable>(); for (unsigned int part : parts) { const auto brickID = brickIDTable->Query([=](const CDBrickIDTable& entry) { diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index e246f9f7..a8e58739 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -9,6 +9,8 @@ #include "eMissionTaskType.h" #include <algorithm> +#include "CDSkillBehaviorTable.h" + ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) { this->m_ID = id; this->m_InventoryComponent = inventoryComponent; @@ -127,7 +129,7 @@ void ItemSet::OnEquip(const LOT lot) { auto* missionComponent = m_InventoryComponent->GetParent()->GetComponent<MissionComponent>(); for (const auto skill : skillSet) { - auto* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + auto* skillTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID; @@ -159,7 +161,7 @@ void ItemSet::OnUnEquip(const LOT lot) { const auto& skillComponent = m_InventoryComponent->GetParent()->GetComponent<SkillComponent>(); for (const auto skill : skillSet) { - auto* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + auto* skillTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID; diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 68384652..9cfdaaa7 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -25,6 +25,8 @@ #include "eMissionLockState.h" #include "eReplicaComponentType.h" +#include "CDMissionEmailTable.h" + Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_MissionComponent = missionComponent; @@ -38,7 +40,7 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_State = eMissionState::UNKNOWN; - auto* missionsTable = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); + auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>(); info = missionsTable->GetPtrByMissionID(missionId); @@ -48,7 +50,7 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { return; } - auto* tasksTable = CDClientManager::Instance()->GetTable<CDMissionTasksTable>("MissionTasks"); + auto* tasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>(); auto tasks = tasksTable->GetByMissionID(missionId); @@ -176,7 +178,7 @@ void Mission::UpdateXml(tinyxml2::XMLElement* element) { } bool Mission::IsValidMission(const uint32_t missionId) { - auto* table = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); + auto* table = CDClientManager::Instance().GetTable<CDMissionsTable>(); const auto missions = table->Query([=](const CDMissions& entry) { return entry.id == static_cast<int>(missionId); @@ -186,7 +188,7 @@ bool Mission::IsValidMission(const uint32_t missionId) { } bool Mission::IsValidMission(const uint32_t missionId, CDMissions& info) { - auto* table = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); + auto* table = CDClientManager::Instance().GetTable<CDMissionsTable>(); const auto missions = table->Query([=](const CDMissions& entry) { return entry.id == static_cast<int>(missionId); @@ -330,7 +332,7 @@ void Mission::Complete(const bool yieldRewards) { missionComponent->Progress(eMissionTaskType::RACING, info->id, (LWOOBJID)eRacingTaskParam::COMPLETE_TRACK_TASKS); - auto* missionEmailTable = CDClientManager::Instance()->GetTable<CDMissionEmailTable>("MissionEmail"); + auto* missionEmailTable = CDClientManager::Instance().GetTable<CDMissionEmailTable>(); const auto missionId = GetMissionId(); diff --git a/dGame/dMission/MissionPrerequisites.cpp b/dGame/dMission/MissionPrerequisites.cpp index 6b55151c..ec4522b9 100644 --- a/dGame/dMission/MissionPrerequisites.cpp +++ b/dGame/dMission/MissionPrerequisites.cpp @@ -163,7 +163,7 @@ bool MissionPrerequisites::CheckPrerequisites(uint32_t missionId, const std::uno return index->second->Execute(missions); } - auto* missionsTable = CDClientManager::Instance()->GetTable<CDMissionsTable>("Missions"); + auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>(); const auto missionEntries = missionsTable->Query([=](const CDMissions& entry) { return entry.id == static_cast<int>(missionId); }); diff --git a/dGame/dUtilities/Loot.cpp b/dGame/dUtilities/Loot.cpp index 415c976c..da0f2487 100644 --- a/dGame/dUtilities/Loot.cpp +++ b/dGame/dUtilities/Loot.cpp @@ -7,6 +7,8 @@ #include "CDLootMatrixTable.h" #include "CDLootTableTable.h" #include "CDRarityTableTable.h" +#include "CDActivityRewardsTable.h" +#include "CDCurrencyTableTable.h" #include "Character.h" #include "Entity.h" #include "GameMessages.h" @@ -17,11 +19,11 @@ #include "eReplicaComponentType.h" LootGenerator::LootGenerator() { - CDLootTableTable* lootTableTable = CDClientManager::Instance()->GetTable<CDLootTableTable>("LootTable"); - CDComponentsRegistryTable* componentsRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry"); - CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent"); - CDLootMatrixTable* lootMatrixTable = CDClientManager::Instance()->GetTable<CDLootMatrixTable>("LootMatrix"); - CDRarityTableTable* rarityTableTable = CDClientManager::Instance()->GetTable<CDRarityTableTable>("RarityTable"); + CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable<CDLootTableTable>(); + CDComponentsRegistryTable* componentsRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>(); + CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>(); + CDLootMatrixTable* lootMatrixTable = CDClientManager::Instance().GetTable<CDLootMatrixTable>(); + CDRarityTableTable* rarityTableTable = CDClientManager::Instance().GetTable<CDRarityTableTable>(); // ============================== // Cache Item Rarities @@ -292,7 +294,7 @@ void LootGenerator::GiveLoot(Entity* player, std::unordered_map<LOT, int32_t>& r } void LootGenerator::GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) { - CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance()->GetTable<CDActivityRewardsTable>("ActivityRewards"); + CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>(); std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); }); const CDActivityRewards* selectedReward = nullptr; @@ -308,7 +310,7 @@ void LootGenerator::GiveActivityLoot(Entity* player, Entity* source, uint32_t ac uint32_t minCoins = 0; uint32_t maxCoins = 0; - CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance()->GetTable<CDCurrencyTableTable>("CurrencyTable"); + CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>(); std::vector<CDCurrencyTable> currencyTable = currencyTableTable->Query([selectedReward](CDCurrencyTable entry) { return (entry.currencyIndex == selectedReward->CurrencyIndex && entry.npcminlevel == 1); }); if (currencyTable.size() > 0) { @@ -362,7 +364,7 @@ void LootGenerator::DropLoot(Entity* player, Entity* killedObject, std::unordere } void LootGenerator::DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) { - CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance()->GetTable<CDActivityRewardsTable>("ActivityRewards"); + CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>(); std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); }); const CDActivityRewards* selectedReward = nullptr; @@ -379,7 +381,7 @@ void LootGenerator::DropActivityLoot(Entity* player, Entity* source, uint32_t ac uint32_t minCoins = 0; uint32_t maxCoins = 0; - CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance()->GetTable<CDCurrencyTableTable>("CurrencyTable"); + CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>(); std::vector<CDCurrencyTable> currencyTable = currencyTableTable->Query([selectedReward](CDCurrencyTable entry) { return (entry.currencyIndex == selectedReward->CurrencyIndex && entry.npcminlevel == 1); }); if (currencyTable.size() > 0) { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index fb9485b8..0278136b 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -77,6 +77,9 @@ #include "eServerDisconnectIdentifiers.h" #include "eReplicaComponentType.h" +#include "CDObjectsTable.h" +#include "CDZoneTableTable.h" + void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { std::string chatCommand; std::vector<std::string> args; @@ -1912,7 +1915,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(closest); - auto* table = CDClientManager::Instance()->GetTable<CDObjectsTable>("Objects"); + auto* table = CDClientManager::Instance().GetTable<CDObjectsTable>(); const auto& info = table->GetByID(closest->GetLOT()); @@ -2021,7 +2024,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) { //We're gonna go ahead and presume we've got the db loaded already: - CDZoneTableTable* zoneTable = CDClientManager::Instance()->GetTable<CDZoneTableTable>("ZoneTable"); + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>(); const CDZoneTable* zone = zoneTable->Query(zoneID); if (zone != nullptr) { return Game::assetManager->HasFile(("maps/" + zone->zoneName).c_str()); diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index b277adbf..fe62a5e5 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -369,7 +369,7 @@ Instance* InstanceManager::FindPrivateInstance(const std::string& password) { } int InstanceManager::GetSoftCap(LWOMAPID mapID) { - CDZoneTableTable* zoneTable = CDClientManager::Instance()->GetTable<CDZoneTableTable>("ZoneTable"); + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>(); if (zoneTable) { const CDZoneTable* zone = zoneTable->Query(mapID); @@ -382,7 +382,7 @@ int InstanceManager::GetSoftCap(LWOMAPID mapID) { } int InstanceManager::GetHardCap(LWOMAPID mapID) { - CDZoneTableTable* zoneTable = CDClientManager::Instance()->GetTable<CDZoneTableTable>("ZoneTable"); + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>(); if (zoneTable) { const CDZoneTable* zone = zoneTable->Query(mapID); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index bcf1a540..cc2bdd90 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -193,7 +193,7 @@ int main(int argc, char** argv) { //Get CDClient initial information try { - CDClientManager::Instance()->Initialize(); + CDClientManager::Instance(); } catch (CppSQLite3Exception& e) { Game::logger->Log("WorldServer", "Failed to initialize CDServer SQLite Database"); Game::logger->Log("WorldServer", "May be caused by corrupted file: %s", (Game::assetManager->GetResPath() / "CDServer.sqlite").string().c_str()); diff --git a/dScripts/02_server/Map/General/QbEnemyStunner.cpp b/dScripts/02_server/Map/General/QbEnemyStunner.cpp index 2b15a056..441d743c 100644 --- a/dScripts/02_server/Map/General/QbEnemyStunner.cpp +++ b/dScripts/02_server/Map/General/QbEnemyStunner.cpp @@ -3,6 +3,9 @@ #include "CDClientManager.h" #include "DestroyableComponent.h" +#include "CDObjectSkillsTable.h" +#include "CDSkillBehaviorTable.h" + void QbEnemyStunner::OnRebuildComplete(Entity* self, Entity* target) { auto* destroyable = self->GetComponent<DestroyableComponent>(); @@ -14,12 +17,12 @@ void QbEnemyStunner::OnRebuildComplete(Entity* self, Entity* target) { if (!skillComponent) return; // Get the skill IDs of this object. - CDObjectSkillsTable* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); + CDObjectSkillsTable* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>(); auto skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == self->GetLOT()); }); std::map<uint32_t, uint32_t> skillBehaviorMap; // For each skill, cast it with the associated behavior ID. for (auto skill : skills) { - CDSkillBehaviorTable* skillBehaviorTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + CDSkillBehaviorTable* skillBehaviorTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); CDSkillBehavior behaviorData = skillBehaviorTable->GetSkillByID(skill.skillID); skillBehaviorMap.insert(std::make_pair(skill.skillID, behaviorData.behaviorID)); diff --git a/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp b/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp index dcccc337..389f3621 100644 --- a/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp +++ b/dScripts/EquipmentScripts/FireFirstSkillonStartup.cpp @@ -3,6 +3,7 @@ #include "SkillComponent.h" #include "CDClientDatabase.h" #include "CDObjectSkillsTable.h" +#include "CDSkillBehaviorTable.h" #include "CDClientManager.h" void FireFirstSkillonStartup::OnStartup(Entity* self) { @@ -10,12 +11,12 @@ void FireFirstSkillonStartup::OnStartup(Entity* self) { if (!skillComponent) return; // Get the skill IDs of this object. - CDObjectSkillsTable* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills"); + CDObjectSkillsTable* skillsTable = CDClientManager::Instance().GetTable<CDObjectSkillsTable>(); std::vector<CDObjectSkills> skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == self->GetLOT()); }); // For each skill, cast it with the associated behavior ID. for (auto skill : skills) { - CDSkillBehaviorTable* skillBehaviorTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior"); + CDSkillBehaviorTable* skillBehaviorTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>(); CDSkillBehavior behaviorData = skillBehaviorTable->GetSkillByID(skill.skillID); // Should parent entity be null, make the originator self. diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index f8d50f5b..8a603878 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -168,7 +168,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - CDClientManager::Instance()->Initialize(); + CDClientManager::Instance(); //Connect to the MySQL Database std::string mysql_host = Game::config->GetValue("mysql_host"); diff --git a/dZoneManager/Level.cpp b/dZoneManager/Level.cpp index dd38d208..55790592 100644 --- a/dZoneManager/Level.cpp +++ b/dZoneManager/Level.cpp @@ -162,7 +162,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { uint32_t objectsCount = 0; BinaryIO::BinaryRead(file, objectsCount); - CDFeatureGatingTable* featureGatingTable = CDClientManager::Instance()->GetTable<CDFeatureGatingTable>("FeatureGating"); + CDFeatureGatingTable* featureGatingTable = CDClientManager::Instance().GetTable<CDFeatureGatingTable>(); for (uint32_t i = 0; i < objectsCount; ++i) { SceneObject obj; diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index c32f8447..28d3f0c8 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -164,7 +164,7 @@ void Zone::LoadZoneIntoMemory() { std::string Zone::GetFilePathForZoneID() { //We're gonna go ahead and presume we've got the db loaded already: - CDZoneTableTable* zoneTable = CDClientManager::Instance()->GetTable<CDZoneTableTable>("ZoneTable"); + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>(); const CDZoneTable* zone = zoneTable->Query(this->GetZoneID().GetMapID()); if (zone != nullptr) { std::string toReturn = "maps/" + zone->zoneName; diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 0b7844a3..52008b5d 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -9,6 +9,7 @@ #include "GameMessages.h" #include "VanityUtilities.h" #include "WorldConfig.h" +#include "CDZoneTableTable.h" #include <chrono> #include "../dWorldServer/ObjectIDManager.h" @@ -27,7 +28,7 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { LOT zoneControlTemplate = 2365; - CDZoneTableTable* zoneTable = CDClientManager::Instance()->GetTable<CDZoneTableTable>("ZoneTable"); + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>(); if (zoneTable != nullptr) { const CDZoneTable* zone = zoneTable->Query(zoneID.GetMapID()); From b967cc57d17c47bc35374a004bbcdb133e55399c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 23 Mar 2023 07:49:31 -0700 Subject: [PATCH 148/166] Allow name billboards to be toggled (#1026) * Allow name billboards to be toggled * Allow name billboards to be toggled * Add comments * Move logic to Character * Use Entity in Character instead --- dCommon/dEnums/dMessageIdentifiers.h | 2 ++ dGame/Character.cpp | 18 +++++++++++++++ dGame/Character.h | 9 ++++++++ dGame/dGameMessages/GameMessages.cpp | 29 ++++++++++++++++++++++++ dGame/dGameMessages/GameMessages.h | 2 ++ dGame/dUtilities/SlashCommandHandler.cpp | 13 +++++++++++ docs/Commands.md | 1 + resources/worldconfig.ini | 3 +++ 8 files changed, 77 insertions(+) diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index e11f9e7f..63d7044e 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -484,6 +484,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_LOCK_NODE_ROTATION = 1260, GAME_MSG_VEHICLE_SET_WHEEL_LOCK_STATE = 1273, GAME_MSG_NOTIFY_VEHICLE_OF_RACING_OBJECT = 1276, + GAME_MSG_SET_NAME_BILLBOARD_STATE = 1284, GAME_MSG_PLAYER_REACHED_RESPAWN_CHECKPOINT = 1296, GAME_MSG_HANDLE_UGC_EQUIP_POST_DELETE_BASED_ON_EDIT_MODE = 1300, GAME_MSG_HANDLE_UGC_EQUIP_PRE_CREATE_BASED_ON_EDIT_MODE = 1301, @@ -494,6 +495,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_MATCH_UPDATE = 1310, GAME_MSG_MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131, GAME_MSG_MODULE_ASSEMBLY_QUERY_DATA = 1132, + GAME_MSG_SHOW_BILLBOARD_INTERACT_ICON = 1337, GAME_MSG_CHANGE_IDLE_FLAGS = 1338, GAME_MSG_VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340, GAME_MSG_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341, diff --git a/dGame/Character.cpp b/dGame/Character.cpp index 572a3e9e..16497fc3 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -621,3 +621,21 @@ void Character::SendMuteNotice() const { ChatPackets::SendSystemMessage(GetEntity()->GetSystemAddress(), u"You are muted until " + timeStr); } + +void Character::SetBillboardVisible(bool visible) { + if (m_BillboardVisible == visible) return; + m_BillboardVisible = visible; + + GameMessages::SendSetNamebillboardState(UNASSIGNED_SYSTEM_ADDRESS, m_OurEntity->GetObjectID()); + + if (!visible) return; + + // The GameMessage we send for turning the nameplate off just deletes the BillboardSubcomponent from the parent component. + // Because that same message does not allow for custom parameters, we need to create the BillboardSubcomponent a different way + // This workaround involves sending an unrelated GameMessage that does not apply to player entites, + // but forces the client to create the necessary SubComponent that controls the billboard. + GameMessages::SendShowBillboardInteractIcon(UNASSIGNED_SYSTEM_ADDRESS, m_OurEntity->GetObjectID()); + + // Now turn off the billboard for the owner. + GameMessages::SendSetNamebillboardState(m_OurEntity->GetSystemAddress(), m_OurEntity->GetObjectID()); +} diff --git a/dGame/Character.h b/dGame/Character.h index abded1b3..d77dd022 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -451,6 +451,10 @@ public: */ void SetIsFlying(bool isFlying) { m_IsFlying = isFlying; } + bool GetBillboardVisible() { return m_BillboardVisible; } + + void SetBillboardVisible(bool visible); + private: /** * The ID of this character. First 32 bits of the ObjectID. @@ -652,6 +656,11 @@ private: */ bool m_IsFlying = false; + /** + * True if billboard (referred to as nameplate for end users) is visible, false otherwise + */ + bool m_BillboardVisible = true; + /** * Queries the character XML and updates all the fields of this object * NOTE: quick as there's no DB lookups diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 33a7f104..8604d136 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -6154,3 +6154,32 @@ void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const S if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; } + +void GameMessages::SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_SET_NAME_BILLBOARD_STATE); + + // Technically these bits would be written, however the client does not + // contain a deserialize method to actually deserialize, so we are leaving it out. + // As such this GM only turns the billboard off. + + // bitStream.Write(overrideDefault); + // bitStream.Write(state); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST + else SEND_PACKET +} + +void GameMessages::SendShowBillboardInteractIcon(const SystemAddress& sysAddr, LWOOBJID objectId) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_SHOW_BILLBOARD_INTERACT_ICON); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST + else SEND_PACKET +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 5d199995..7305e429 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -574,6 +574,8 @@ namespace GameMessages { void HandleToggleGhostReferenceOverride(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleSetGhostReferencePosition(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); + void SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId); + void SendShowBillboardInteractIcon(const SystemAddress& sysAddr, LWOOBJID objectId); void HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleSellToVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 0278136b..1f3da6c7 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -171,6 +171,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } #endif + if (chatCommand == "togglenameplate" && (Game::config->GetValue("allownameplateoff") == "1" || entity->GetGMLevel() > GAME_MASTER_LEVEL_DEVELOPER)) { + auto* character = entity->GetCharacter(); + + if (character && character->GetBillboardVisible()) { + character->SetBillboardVisible(false); + ChatPackets::SendSystemMessage(sysAddr, u"Your nameplate has been turned off and is not visible to players currently in this zone."); + } else { + character->SetBillboardVisible(true); + ChatPackets::SendSystemMessage(sysAddr, u"Your nameplate is now on and visible to all players."); + } + return; + } + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //HANDLE ALL NON GM SLASH COMMANDS RIGHT HERE! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/docs/Commands.md b/docs/Commands.md index a9cd3e7c..725a03a0 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -48,6 +48,7 @@ These commands are primarily for development and testing. The usage of many of t |Command|Usage|Description|Admin Level Requirement| |--- |--- |--- |--- | +|togglenameplate|`/togglenameplate`|Turns the nameplate above your head that is visible to other players off and on.|8 or if `allow_nameplate_off` is set to exactly `1` in the settings| |fix-stats|`/fix-stats`|Resets skills, buffs, and destroyables.|| |join|`/join <password>`|Joins a private zone with given password.|| |leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station.|| diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index 64b4fb40..b05614b4 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -58,3 +58,6 @@ hardcore_uscore_enemies_multiplier=2 # Percentage of u-score to lose on player death hardcore_lose_uscore_on_death_percent=10 + +# Allow civilian players the ability to turn the nameplate above their head off. Must be exactly 1 to be enabled for civilians. +allow_nameplate_off=0 From 72ca0f13ff0f09137a05784ea1fe062d19e4e58f Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Fri, 24 Mar 2023 18:16:45 -0500 Subject: [PATCH 149/166] breakout gmlevel into a scoped enum (#996) * breakout gmlevel enum and make it a class tested that things still work slash command, chat restrictions, packets and serializations * fix GM level for some slash commands * fix new use of this enum --- dChatFilter/dChatFilter.cpp | 5 +- dChatFilter/dChatFilter.h | 3 +- dCommon/dEnums/dCommonVars.h | 15 -- dCommon/dEnums/eGameMasterLevel.h | 20 ++ dGame/Character.cpp | 9 +- dGame/Character.h | 7 +- dGame/Entity.cpp | 7 +- dGame/Entity.h | 7 +- dGame/EntityManager.cpp | 3 +- dGame/User.cpp | 5 +- dGame/User.h | 5 +- dGame/UserManager.cpp | 3 +- dGame/dComponents/CharacterComponent.cpp | 7 +- dGame/dComponents/CharacterComponent.h | 6 +- dGame/dComponents/PetComponent.cpp | 6 +- .../dComponents/PropertyEntranceComponent.cpp | 3 +- .../dComponents/ScriptedActivityComponent.cpp | 2 +- dGame/dGameMessages/GameMessages.cpp | 4 +- dGame/dGameMessages/GameMessages.h | 7 +- dGame/dUtilities/SlashCommandHandler.cpp | 176 +++++++++--------- dNet/ClientPackets.cpp | 3 +- dNet/WorldPackets.cpp | 15 +- dNet/WorldPackets.h | 5 +- docs/Commands.md | 20 +- 24 files changed, 184 insertions(+), 159 deletions(-) create mode 100644 dCommon/dEnums/eGameMasterLevel.h diff --git a/dChatFilter/dChatFilter.cpp b/dChatFilter/dChatFilter.cpp index ea38f8cd..92da9556 100644 --- a/dChatFilter/dChatFilter.cpp +++ b/dChatFilter/dChatFilter.cpp @@ -12,6 +12,7 @@ #include "dConfig.h" #include "Database.h" #include "Game.h" +#include "eGameMasterLevel.h" using namespace dChatFilterDCF; @@ -108,8 +109,8 @@ void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool whiteLis } } -std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList) { - if (gmLevel > GAME_MASTER_LEVEL_FORUM_MODERATOR) return { }; //If anything but a forum mod, return true. +std::vector<std::pair<uint8_t, uint8_t>> dChatFilter::IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList) { + if (gmLevel > eGameMasterLevel::FORUM_MODERATOR) return { }; //If anything but a forum mod, return true. if (message.empty()) return { }; if (!whiteList && m_DeniedWords.empty()) return { { 0, message.length() } }; diff --git a/dChatFilter/dChatFilter.h b/dChatFilter/dChatFilter.h index 7e7dd859..d00525ce 100644 --- a/dChatFilter/dChatFilter.h +++ b/dChatFilter/dChatFilter.h @@ -4,6 +4,7 @@ #include "dCommonVars.h" +enum class eGameMasterLevel : uint8_t; namespace dChatFilterDCF { static const uint32_t header = ('D' + ('C' << 8) + ('F' << 16) + ('B' << 24)); static const uint32_t formatVersion = 2; @@ -23,7 +24,7 @@ public: void ReadWordlistPlaintext(const std::string& filepath, bool whiteList); bool ReadWordlistDCF(const std::string& filepath, bool whiteList); void ExportWordlistToDCF(const std::string& filepath, bool whiteList); - std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList = true); + std::vector<std::pair<uint8_t, uint8_t>> IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList = true); private: bool m_DontGenerateDCF; diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 2b7f63dc..16cae3c9 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -175,21 +175,6 @@ union suchar { char svalue; }; -//=========== DLU ENUMS ============ - -enum eGameMasterLevel : int32_t { - GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player. - GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers. - GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs. - GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items. - GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban. - GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties. - GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live. - GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions. - GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live. - GAME_MASTER_LEVEL_OPERATOR = 9 // Can shutdown server for restarts & updates. -}; - //=========== LU ENUMS ============ //! An enum for object ID bits diff --git a/dCommon/dEnums/eGameMasterLevel.h b/dCommon/dEnums/eGameMasterLevel.h new file mode 100644 index 00000000..a63c1caf --- /dev/null +++ b/dCommon/dEnums/eGameMasterLevel.h @@ -0,0 +1,20 @@ +#ifndef __EGAMEMASTERLEVEL__H__ +#define __EGAMEMASTERLEVEL__H__ + +#include <cstdint> + +enum class eGameMasterLevel : uint8_t { + CIVILIAN = 0, // Normal player. + FORUM_MODERATOR = 1, // No permissions on live servers. + JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs. + MODERATOR = 3, // Can return lost items. + SENIOR_MODERATOR = 4, // Can ban. + LEAD_MODERATOR = 5, // Can approve properties. + JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live. + INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions. + DEVELOPER = 8, // Active developer, full permissions on live. + OPERATOR = 9 // Can shutdown server for restarts & updates. +}; + + +#endif //!__EGAMEMASTERLEVEL__H__ diff --git a/dGame/Character.cpp b/dGame/Character.cpp index 16497fc3..b8d08854 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -18,6 +18,7 @@ #include "InventoryComponent.h" #include "eMissionTaskType.h" #include "eMissionState.h" +#include "eGameMasterLevel.h" Character::Character(uint32_t id, User* parentUser) { //First load the name, etc: @@ -204,7 +205,9 @@ void Character::DoQuickXMLDataParse() { tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char"); if (character) { character->QueryAttribute("cc", &m_Coins); - character->QueryAttribute("gm", &m_GMLevel); + int32_t gm_level = 0; + character->QueryAttribute("gm", &gm_level); + m_GMLevel = static_cast<eGameMasterLevel>(gm_level); uint64_t lzidConcat = 0; if (character->FindAttribute("lzid")) { @@ -304,7 +307,7 @@ void Character::SaveXMLToDatabase() { tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char"); if (character) { - character->SetAttribute("gm", m_GMLevel); + character->SetAttribute("gm", static_cast<uint32_t>(m_GMLevel)); character->SetAttribute("cc", m_Coins); auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID(); @@ -545,7 +548,7 @@ void Character::OnZoneLoad() { const auto maxGMLevel = m_ParentUser->GetMaxGMLevel(); // This does not apply to the GMs - if (maxGMLevel > GAME_MASTER_LEVEL_CIVILIAN) { + if (maxGMLevel > eGameMasterLevel::CIVILIAN) { return; } diff --git a/dGame/Character.h b/dGame/Character.h index d77dd022..2f0abba5 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -15,6 +15,7 @@ class User; struct Packet; class Entity; enum class ePermissionMap : uint64_t; +enum class eGameMasterLevel : uint8_t; /** * Meta information about a character, like their name and style @@ -308,13 +309,13 @@ public: * Gets the GM level of the character * @return the GM level */ - int32_t GetGMLevel() const { return m_GMLevel; } + eGameMasterLevel GetGMLevel() const { return m_GMLevel; } /** * Sets the GM level of the character * @param value the GM level to set */ - void SetGMLevel(uint8_t value) { m_GMLevel = value; } + void SetGMLevel(eGameMasterLevel value) { m_GMLevel = value; } /** * Gets the current amount of coins of the character @@ -481,7 +482,7 @@ private: * * @see eGameMasterLevel */ - int32_t m_GMLevel; + eGameMasterLevel m_GMLevel; /** * Bitmap of permission attributes this character has. diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 13507527..c33a7247 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -70,6 +70,7 @@ #include "RailActivatorComponent.h" #include "LUPExhibitComponent.h" #include "TriggerComponent.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" // Table includes @@ -89,7 +90,7 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) m_TemplateID = info.lot; m_ParentEntity = parentEntity; m_Character = nullptr; - m_GMLevel = 0; + m_GMLevel = eGameMasterLevel::CIVILIAN; m_CollectibleID = 0; m_NetworkID = 0; m_Groups = {}; @@ -857,7 +858,7 @@ void Entity::SetProximityRadius(dpEntity* entity, std::string name) { proxMon->SetProximityRadius(entity, name); } -void Entity::SetGMLevel(uint8_t value) { +void Entity::SetGMLevel(eGameMasterLevel value) { m_GMLevel = value; if (GetParentUser()) { Character* character = GetParentUser()->GetLastUsedChar(); @@ -969,7 +970,7 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke outBitStream->Write0(); //ObjectWorldState - if (m_GMLevel != 0) { + if (m_GMLevel != eGameMasterLevel::CIVILIAN) { outBitStream->Write1(); outBitStream->Write(m_GMLevel); } else outBitStream->Write0(); //No GM Level diff --git a/dGame/Entity.h b/dGame/Entity.h index ae16fb82..f8abff31 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -31,6 +31,7 @@ class Item; class Character; class EntityCallbackTimer; enum class eTriggerEventType; +enum class eGameMasterLevel : uint8_t; enum class eReplicaComponentType : uint32_t; namespace CppScripts { @@ -60,7 +61,7 @@ public: Character* GetCharacter() const { return m_Character; } - uint8_t GetGMLevel() const { return m_GMLevel; } + eGameMasterLevel GetGMLevel() const { return m_GMLevel; } uint8_t GetCollectibleID() const { return uint8_t(m_CollectibleID); } @@ -108,7 +109,7 @@ public: void SetCharacter(Character* value) { m_Character = value; } - void SetGMLevel(uint8_t value); + void SetGMLevel(eGameMasterLevel value); void SetOwnerOverride(LWOOBJID value); @@ -308,7 +309,7 @@ protected: Entity* m_ParentEntity; //For spawners and the like std::vector<Entity*> m_ChildEntities; - uint8_t m_GMLevel; + eGameMasterLevel m_GMLevel; uint16_t m_CollectibleID; std::vector<std::string> m_Groups; uint16_t m_NetworkID; diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index e79ada25..31b755fe 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -20,6 +20,7 @@ #include "MessageIdentifiers.h" #include "dConfig.h" #include "eTriggerEventType.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" EntityManager* EntityManager::m_Address = nullptr; @@ -370,7 +371,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr // PacketUtils::SavePacket("[24]_"+std::to_string(entity->GetObjectID()) + "_" + std::to_string(m_SerializationCounter) + ".bin", (char*)stream.GetData(), stream.GetNumberOfBytesUsed()); if (entity->IsPlayer()) { - if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { + if (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, sysAddr); } } diff --git a/dGame/User.cpp b/dGame/User.cpp index dc607cd0..55bbcc09 100644 --- a/dGame/User.cpp +++ b/dGame/User.cpp @@ -6,13 +6,14 @@ #include "Game.h" #include "dZoneManager.h" #include "eServerDisconnectIdentifiers.h" +#include "eGameMasterLevel.h" User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) { m_AccountID = 0; m_Username = ""; m_SessionKey = ""; - m_MaxGMLevel = 0; //The max GM level this account can assign to it's characters + m_MaxGMLevel = eGameMasterLevel::CIVILIAN; //The max GM level this account can assign to it's characters m_LastCharID = 0; m_SessionKey = sessionKey; @@ -33,7 +34,7 @@ User::User(const SystemAddress& sysAddr, const std::string& username, const std: sql::ResultSet* res = stmt->executeQuery(); while (res->next()) { m_AccountID = res->getUInt(1); - m_MaxGMLevel = res->getInt(2); + m_MaxGMLevel = static_cast<eGameMasterLevel>(res->getInt(2)); m_MuteExpire = 0; //res->getUInt64(3); } diff --git a/dGame/User.h b/dGame/User.h index 59416c4c..3201538e 100644 --- a/dGame/User.h +++ b/dGame/User.h @@ -9,6 +9,7 @@ #include <unordered_map> class Character; +enum class eGameMasterLevel : uint8_t; struct BehaviorParams { uint32_t behavior; @@ -29,7 +30,7 @@ public: std::string& GetSessionKey() { return m_SessionKey; } SystemAddress& GetSystemAddress() { return m_SystemAddress; } - uint32_t GetMaxGMLevel() { return m_MaxGMLevel; } + eGameMasterLevel GetMaxGMLevel() { return m_MaxGMLevel; } uint32_t GetLastCharID() { return m_LastCharID; } void SetLastCharID(uint32_t newCharID) { m_LastCharID = newCharID; } @@ -61,7 +62,7 @@ private: std::string m_SessionKey; SystemAddress m_SystemAddress; - uint32_t m_MaxGMLevel; //The max GM level this account can assign to it's characters + eGameMasterLevel m_MaxGMLevel; //The max GM level this account can assign to it's characters uint32_t m_LastCharID; std::vector<Character*> m_Characters; LWOOBJID m_LoggedInCharID; diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 93469daa..4f0c456d 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -23,6 +23,7 @@ #include "AssetManager.h" #include "CDClientDatabase.h" #include "dMessageIdentifiers.h" +#include "eGameMasterLevel.h" UserManager* UserManager::m_Address = nullptr; @@ -330,7 +331,7 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) //Check to see if our name was pre-approved: bool nameOk = IsNamePreapproved(name); - if (!nameOk && u->GetMaxGMLevel() > 1) nameOk = true; + if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true; if (name != "") { sql::PreparedStatement* stmt = Database::CreatePreppedStmt("INSERT INTO `charinfo`(`id`, `account_id`, `name`, `pending_name`, `needs_rename`, `last_login`) VALUES (?,?,?,?,?,?)"); diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 98540bd0..6394cc32 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -14,6 +14,7 @@ #include "GameMessages.h" #include "Item.h" #include "AMFFormat.h" +#include "eGameMasterLevel.h" CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) { m_Character = character; @@ -165,9 +166,9 @@ void CharacterComponent::SetPvpEnabled(const bool value) { m_PvpEnabled = value; } -void CharacterComponent::SetGMLevel(int gmlevel) { +void CharacterComponent::SetGMLevel(eGameMasterLevel gmlevel) { m_DirtyGMInfo = true; - if (gmlevel > 0) m_IsGM = true; + if (gmlevel > eGameMasterLevel::CIVILIAN) m_IsGM = true; else m_IsGM = false; m_GMLevel = gmlevel; } @@ -239,7 +240,7 @@ void CharacterComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { // End custom attributes // - if (m_GMLevel > 0) { + if (m_GMLevel > eGameMasterLevel::CIVILIAN) { m_IsGM = true; m_DirtyGMInfo = true; m_EditorLevel = m_GMLevel; diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index 613f2322..0e047494 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -178,7 +178,7 @@ public: * Sets the GM level of the character, should be called in the entity. Here it's set for serialization * @param gmlevel the gm level to set */ - void SetGMLevel(int gmlevel); + void SetGMLevel(eGameMasterLevel gmlevel); /** * Initializes the player statistics from the string stored in the XML @@ -333,7 +333,7 @@ private: /** * The current GM level of this character (anything > 0 counts as a GM) */ - unsigned char m_GMLevel; + eGameMasterLevel m_GMLevel; /** * Whether the character has HF enabled @@ -343,7 +343,7 @@ private: /** * The level of the character in HF */ - unsigned char m_EditorLevel; + eGameMasterLevel m_EditorLevel; /** * Whether the currently active activity has been changed diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 5549f952..090e5791 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -22,7 +22,7 @@ #include "Database.h" #include "EntityInfo.h" #include "eMissionTaskType.h" - +#include "eGameMasterLevel.h" std::unordered_map<LOT, PetComponent::PetPuzzleData> PetComponent::buildCache{}; std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::currentActivities{}; @@ -988,7 +988,7 @@ void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandTy // TODO: Go to player } - if (owner->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (owner->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(owner->GetSystemAddress(), u"Commmand Type: " + (GeneralUtils::to_u16string(commandType)) + u" - Type Id: " + (GeneralUtils::to_u16string(typeId))); } } @@ -1080,7 +1080,7 @@ void PetComponent::SetPetNameForModeration(const std::string& petName) { int approved = 1; //default, in mod //Make sure that the name isn't already auto-approved: - if (Game::chatFilter->IsSentenceOkay(petName, 0).empty()) { + if (Game::chatFilter->IsSentenceOkay(petName, eGameMasterLevel::CIVILIAN).empty()) { approved = 2; //approved } diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index fa838ed7..c251dc96 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -12,6 +12,7 @@ #include "UserManager.h" #include "dLogger.h" #include "AMFFormat.h" +#include "eGameMasterLevel.h" PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) { this->propertyQueries = {}; @@ -271,7 +272,7 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl bool isModeratorApproved = propertyEntry->getBoolean(10); - if (!isModeratorApproved && entity->GetGMLevel() >= GAME_MASTER_LEVEL_LEAD_MODERATOR) { + if (!isModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) { propertyName = "[AWAITING APPROVAL]"; propertyDescription = "[AWAITING APPROVAL]"; isModeratorApproved = true; diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index bafa1faa..1bc8c01f 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -303,7 +303,7 @@ bool ScriptedActivityComponent::HasLobby() const { bool ScriptedActivityComponent::IsValidActivity(Entity* player) { // Makes it so that scripted activities with an unimplemented map cannot be joined - /*if (player->GetGMLevel() < GAME_MASTER_LEVEL_DEVELOPER && (m_ActivityInfo.instanceMapID == 1302 || m_ActivityInfo.instanceMapID == 1301)) { + /*if (player->GetGMLevel() < eGameMasterLevel::DEVELOPER && (m_ActivityInfo.instanceMapID == 1302 || m_ActivityInfo.instanceMapID == 1301)) { if (m_Parent->GetLOT() == 4860) { auto* missionComponent = player->GetComponent<MissionComponent>(); missionComponent->CompleteMission(229); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 8604d136..2941a0f9 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -409,7 +409,7 @@ void GameMessages::SendServerDoneLoadingAllObjects(Entity* entity, const SystemA SEND_PACKET; } -void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level) { +void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, eGameMasterLevel level) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); @@ -418,7 +418,7 @@ void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level) { SEND_PACKET_BROADCAST; } -void GameMessages::SendGMLevelBroadcast(const LWOOBJID& objectID, uint8_t level) { +void GameMessages::SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLevel level) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 7305e429..1372003e 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -21,6 +21,7 @@ enum class eAnimationFlags : uint32_t; enum class eUnequippableActiveType; enum eInventoryType : uint32_t; +enum class eGameMasterLevel : uint8_t; namespace GameMessages { class PropertyDataMessage; @@ -61,8 +62,8 @@ namespace GameMessages { void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr); void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr); - void SendGMLevelBroadcast(const LWOOBJID& objectID, uint8_t level); - void SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level); + void SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLevel level); + void SendChatModeUpdate(const LWOOBJID& objectID, eGameMasterLevel level); void SendAddItemToInventoryClientSync(Entity* entity, const SystemAddress& sysAddr, Item* item, const LWOOBJID& objectID, bool showFlyingLoot, int itemCount, LWOOBJID subKey = LWOOBJID_EMPTY, eLootSourceType lootSourceType = eLootSourceType::LOOT_SOURCE_NONE); void SendNotifyClientFlagChange(const LWOOBJID& objectID, int iFlagID, bool bFlag, const SystemAddress& sysAddr); @@ -623,7 +624,7 @@ namespace GameMessages { void HandleReportBug(RakNet::BitStream* inStream, Entity* entity); void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId); - + // bubble void HandleDeactivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 1f3da6c7..f9bf4884 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -75,6 +75,7 @@ #include "eMissionState.h" #include "TriggerComponent.h" #include "eServerDisconnectIdentifiers.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" #include "CDObjectsTable.h" @@ -121,19 +122,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"", GeneralUtils::UTF16ToWTF8(command).c_str()); User* user = UserManager::Instance()->GetUser(sysAddr); - if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { + if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > eGameMasterLevel::CIVILIAN) { if (args.size() != 1) return; - uint32_t level; + uint32_t level_intermed = 0; - if (!GeneralUtils::TryParse(args[0], level)) { + if (!GeneralUtils::TryParse(args[0], level_intermed)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid gm level."); return; } + eGameMasterLevel level = static_cast<eGameMasterLevel>(level_intermed); #ifndef DEVELOPER_SERVER - if (user->GetMaxGMLevel() == GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { - level = GAME_MASTER_LEVEL_CIVILIAN; + if (user->GetMaxGMLevel() == eGameMasterLevel::JUNIOR_DEVELOPER) { + level = eGameMasterLevel::CIVILIAN; } #endif @@ -146,9 +148,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (success) { - if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && level == GAME_MASTER_LEVEL_CIVILIAN) { + if (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN && level == eGameMasterLevel::CIVILIAN) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); - } else if (entity->GetGMLevel() == GAME_MASTER_LEVEL_CIVILIAN && level > GAME_MASTER_LEVEL_CIVILIAN) { + } else if (entity->GetGMLevel() == eGameMasterLevel::CIVILIAN && level > eGameMasterLevel::CIVILIAN) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); } @@ -160,10 +162,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } #ifndef DEVELOPER_SERVER - if ((entity->GetGMLevel() > user->GetMaxGMLevel()) || (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && user->GetMaxGMLevel() == GAME_MASTER_LEVEL_JUNIOR_DEVELOPER)) { - WorldPackets::SendGMLevelChange(sysAddr, true, user->GetMaxGMLevel(), entity->GetGMLevel(), GAME_MASTER_LEVEL_CIVILIAN); - GameMessages::SendChatModeUpdate(entity->GetObjectID(), GAME_MASTER_LEVEL_CIVILIAN); - entity->SetGMLevel(GAME_MASTER_LEVEL_CIVILIAN); + if ((entity->GetGMLevel() > user->GetMaxGMLevel()) || (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN && user->GetMaxGMLevel() == eGameMasterLevel::JUNIOR_DEVELOPER)) { + WorldPackets::SendGMLevelChange(sysAddr, true, user->GetMaxGMLevel(), entity->GetGMLevel(), eGameMasterLevel::CIVILIAN); + GameMessages::SendChatModeUpdate(entity->GetObjectID(), eGameMasterLevel::CIVILIAN); + entity->SetGMLevel(eGameMasterLevel::CIVILIAN); GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); @@ -171,7 +173,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } #endif - if (chatCommand == "togglenameplate" && (Game::config->GetValue("allownameplateoff") == "1" || entity->GetGMLevel() > GAME_MASTER_LEVEL_DEVELOPER)) { + if (chatCommand == "togglenameplate" && (Game::config->GetValue("allownameplateoff") == "1" || entity->GetGMLevel() > eGameMasterLevel::DEVELOPER)) { auto* character = entity->GetCharacter(); if (character && character->GetBillboardVisible()) { @@ -349,7 +351,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit }); } - if (user->GetMaxGMLevel() == 0 || entity->GetGMLevel() >= 0) { + if (user->GetMaxGMLevel() == eGameMasterLevel::CIVILIAN || entity->GetGMLevel() >= eGameMasterLevel::CIVILIAN) { if (chatCommand == "die") { entity->Smash(entity->GetObjectID()); } @@ -375,7 +377,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Map: " + (GeneralUtils::to_u16string(zoneId.GetMapID())) + u"\nClone: " + (GeneralUtils::to_u16string(zoneId.GetCloneID())) + u"\nInstance: " + (GeneralUtils::to_u16string(zoneId.GetInstanceID()))); } - if (entity->GetGMLevel() == 0) return; + if (entity->GetGMLevel() == eGameMasterLevel::CIVILIAN) return; } // Log command to database @@ -385,7 +387,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit stmt->execute(); delete stmt; - if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0 + if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) { // could break characters so only allow if GM > 0 int32_t minifigItemId; if (!GeneralUtils::TryParse(args[1], minifigItemId)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID."); @@ -429,7 +431,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character } - if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { std::u16string anim = GeneralUtils::ASCIIToUTF16(args[0], args[0].size()); GameMessages::SendPlayAnimation(entity, anim); auto* possessorComponent = entity->GetComponent<PossessorComponent>(); @@ -439,7 +441,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "list-spawns" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "list-spawns" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) { ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first)); } @@ -449,7 +451,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { int32_t emoteID; if (!GeneralUtils::TryParse(args[0], emoteID)) { @@ -460,11 +462,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->UnlockEmote(emoteID); } - if (chatCommand == "force-save" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "force-save" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { entity->GetCharacter()->SaveXMLToDatabase(); } - if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Brutally murdering that player, if online on this server."); auto* user = UserManager::Instance()->GetUser(args[0]); @@ -479,7 +481,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { float boost; if (!GeneralUtils::TryParse(args[0], boost)) { @@ -510,7 +512,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "freecam" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "freecam" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto state = !entity->GetVar<bool>(u"freecam"); entity->SetVar<bool>(u"freecam", state); @@ -520,7 +522,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setcontrolscheme" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setcontrolscheme" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { uint32_t scheme; if (!GeneralUtils::TryParse(args[0], scheme)) { @@ -534,7 +536,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "approveproperty" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_LEAD_MODERATOR) { + if (chatCommand == "approveproperty" && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) { if (PropertyManagementComponent::Instance() != nullptr) { PropertyManagementComponent::Instance()->UpdateApprovedStatus(true); @@ -543,7 +545,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { AMFStringValue* value = new AMFStringValue(); value->SetStringValue(args[0]); @@ -556,7 +558,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { AMFTrueValue* value = new AMFTrueValue(); AMFArrayValue amfArgs; @@ -568,7 +570,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { uint32_t size; if (!GeneralUtils::TryParse(args.at(0), size)) { @@ -609,7 +611,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "runmacro" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "runmacro" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() != 1) return; // Only process if input does not contain separator charaters @@ -639,7 +641,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "addmission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "addmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; uint32_t missionID; @@ -654,7 +656,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "completemission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "completemission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; uint32_t missionID; @@ -669,7 +671,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { uint32_t flagId; if (!GeneralUtils::TryParse(args[0], flagId)) { @@ -680,7 +682,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->SetPlayerFlag(flagId, true); } - if (chatCommand == "setflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 2) { + if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 2) { uint32_t flagId; std::string onOffFlag = args[0]; if (!GeneralUtils::TryParse(args[1], flagId)) { @@ -693,7 +695,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } entity->GetCharacter()->SetPlayerFlag(flagId, onOffFlag == "on"); } - if (chatCommand == "clearflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "clearflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { uint32_t flagId; if (!GeneralUtils::TryParse(args[0], flagId)) { @@ -704,7 +706,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->SetPlayerFlag(flagId, false); } - if (chatCommand == "resetmission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; uint32_t missionID; @@ -731,7 +733,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "playeffect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { + if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { int32_t effectID = 0; if (!GeneralUtils::TryParse(args[0], effectID)) { @@ -742,11 +744,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendPlayFXEffect(entity->GetObjectID(), effectID, GeneralUtils::ASCIIToUTF16(args[1]), args[2]); } - if (chatCommand == "stopeffect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "stopeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { GameMessages::SendStopFXEffect(entity, true, args[0]); } - if (chatCommand == "setanntitle" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setanntitle" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() < 0) return; std::stringstream ss; @@ -757,7 +759,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setannmsg" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setannmsg" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() < 0) return; std::stringstream ss; @@ -768,7 +770,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "announce" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "announce" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (entity->GetCharacter()->GetAnnouncementTitle().size() == 0 || entity->GetCharacter()->GetAnnouncementMessage().size() == 0) { ChatPackets::SendSystemMessage(sysAddr, u"Use /setanntitle <title> & /setannmsg <msg> first!"); return; @@ -778,7 +780,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == GAME_MASTER_LEVEL_OPERATOR) { + if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == eGameMasterLevel::OPERATOR) { //Tell the master server that we're going to be shutting down whole "universe": CBITSTREAM; PacketUtils::WriteHeader(bitStream, MASTER, MSG_MASTER_SHUTDOWN_UNIVERSE); @@ -790,7 +792,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "getnavmeshheight" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "getnavmeshheight" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto control = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!control) return; @@ -799,7 +801,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, msg); } - if (chatCommand == "gmadditem" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "gmadditem" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 1) { uint32_t itemLOT; @@ -834,7 +836,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "mailitem" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_MODERATOR && args.size() >= 2) { + if (chatCommand == "mailitem" && entity->GetGMLevel() >= eGameMasterLevel::MODERATOR && args.size() >= 2) { const auto& playerName = args[0]; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT id from charinfo WHERE name=? LIMIT 1;"); @@ -883,7 +885,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setname" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setname" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { std::string name = ""; for (const auto& arg : args) { @@ -893,7 +895,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); } - if (chatCommand == "title" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "title" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { std::string name = entity->GetCharacter()->GetName() + " - "; for (const auto& arg : args) { @@ -903,7 +905,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); } - if ((chatCommand == "teleport" || chatCommand == "tele") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_MODERATOR) { + if ((chatCommand == "teleport" || chatCommand == "tele") && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_MODERATOR) { NiPoint3 pos{}; if (args.size() == 3) { @@ -969,7 +971,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "tpall" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "tpall" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto pos = entity->GetPosition(); const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); @@ -981,7 +983,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "dismount" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "dismount" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* possessorComponent = entity->GetComponent<PossessorComponent>(); if (possessorComponent) { auto possessableId = possessorComponent->GetPossessable(); @@ -992,7 +994,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "fly" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { + if (chatCommand == "fly" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { auto* character = entity->GetCharacter(); if (character) { @@ -1028,7 +1030,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //------- GM COMMANDS TO ACTUALLY MODERATE -------- - if (chatCommand == "mute" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { + if (chatCommand == "mute" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { if (args.size() >= 1) { auto* player = Player::GetPlayer(args[0]); @@ -1123,7 +1125,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "kick" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_MODERATOR) { + if (chatCommand == "kick" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_MODERATOR) { if (args.size() == 1) { auto* player = Player::GetPlayer(args[0]); @@ -1141,7 +1143,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "ban" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_SENIOR_MODERATOR) { + if (chatCommand == "ban" && entity->GetGMLevel() >= eGameMasterLevel::SENIOR_MODERATOR) { if (args.size() == 1) { auto* player = Player::GetPlayer(args[0]); @@ -1190,7 +1192,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //------------------------------------------------- - if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buffme" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth(999); @@ -1203,7 +1205,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "startcelebration" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "startcelebration" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { int32_t celebration; if (!GeneralUtils::TryParse(args[0], celebration)) { @@ -1214,7 +1216,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration); } - if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buffmed" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth(9); @@ -1227,7 +1229,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "refillstats" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { @@ -1239,7 +1241,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "lookup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto query = CDClientDatabase::CreatePreppedStmt( "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); // Concatenate all of the arguments into a single query so a multi word query can be used properly. @@ -1261,7 +1263,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "spawn" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!comp) return; @@ -1302,7 +1304,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->ConstructEntity(newEntity); } - if (chatCommand == "spawngroup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { + if (chatCommand == "spawngroup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>(); if (!controllablePhysicsComponent) return; @@ -1353,7 +1355,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { int32_t uscore; if (!GeneralUtils::TryParse(args[0], uscore)) { @@ -1375,7 +1377,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType); } - if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { // We may be trying to set a specific players level to a level. If so override the entity with the requested players. std::string requestedPlayerToSetLevelOf = ""; if (args.size() > 1) { @@ -1443,7 +1445,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "pos" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "pos" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto position = entity->GetPosition(); ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(position.x)) + u", " + (GeneralUtils::to_u16string(position.y)) + u", " + (GeneralUtils::to_u16string(position.z)) + u">"); @@ -1451,7 +1453,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit std::cout << position.x << ", " << position.y << ", " << position.z << std::endl; } - if (chatCommand == "rot" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "rot" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto rotation = entity->GetRotation(); ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(rotation.w)) + u", " + (GeneralUtils::to_u16string(rotation.x)) + u", " + (GeneralUtils::to_u16string(rotation.y)) + u", " + (GeneralUtils::to_u16string(rotation.z)) + u">"); @@ -1459,22 +1461,22 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit std::cout << rotation.w << ", " << rotation.x << ", " << rotation.y << ", " << rotation.z << std::endl; } - if (chatCommand == "locrow" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "locrow" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto position = entity->GetPosition(); const auto rotation = entity->GetRotation(); std::cout << "<location x=\"" << position.x << "\" y=\"" << position.y << "\" z=\"" << position.z << "\" rw=\"" << rotation.w << "\" rx=\"" << rotation.x << "\" ry=\"" << rotation.y << "\" rz=\"" << rotation.z << "\" />" << std::endl; } - if (chatCommand == "playlvlfx" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "playlvlfx" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { GameMessages::SendPlayFXEffect(entity, 7074, u"create", "7074", LWOOBJID_EMPTY, 1.0f, 1.0f, true); } - if (chatCommand == "playrebuildfx" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "playrebuildfx" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { GameMessages::SendPlayFXEffect(entity, 230, u"rebuild", "230", LWOOBJID_EMPTY, 1.0f, 1.0f, true); } - if ((chatCommand == "freemoney" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) && args.size() == 1) { + if ((chatCommand == "freemoney" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) && args.size() == 1) { int32_t money; if (!GeneralUtils::TryParse(args[0], money)) { @@ -1486,7 +1488,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ch->SetCoins(ch->GetCoins() + money, eLootSourceType::LOOT_SOURCE_MODERATION); } - if ((chatCommand == "setcurrency") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "setcurrency") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { int32_t money; if (!GeneralUtils::TryParse(args[0], money)) { @@ -1499,13 +1501,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } // Allow for this on even while not a GM, as it sometimes toggles incorrrectly. - if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= eGameMasterLevel::DEVELOPER) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); return; } - if (chatCommand == "gmimmune" && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "gmimmune" && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* destroyableComponent = entity->GetComponent<DestroyableComponent>(); int32_t state = false; @@ -1522,7 +1524,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "buff" && args.size() >= 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buff" && args.size() >= 2 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* buffComponent = entity->GetComponent<BuffComponent>(); int32_t id = 0; @@ -1545,7 +1547,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "testmap" && args.size() >= 1) && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { + if ((chatCommand == "testmap" && args.size() >= 1) && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) { ChatPackets::SendSystemMessage(sysAddr, u"Requesting map change..."); uint32_t reqZone; LWOCLONEID cloneId = 0; @@ -1604,7 +1606,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "createprivate" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { + if (chatCommand == "createprivate" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { uint32_t zone; if (!GeneralUtils::TryParse(args[0], zone)) { @@ -1628,13 +1630,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "debugui") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "debugui") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Opening UIDebugger..."); AMFArrayValue args; GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", nullptr); } - if ((chatCommand == "boost") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "boost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* possessorComponent = entity->GetComponent<PossessorComponent>(); if (possessorComponent == nullptr) { @@ -1666,7 +1668,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } - if ((chatCommand == "unboost") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "unboost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* possessorComponent = entity->GetComponent<PossessorComponent>(); if (possessorComponent == nullptr) return; @@ -1676,7 +1678,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendVehicleRemovePassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); } - if (chatCommand == "activatespawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "activatespawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); for (auto* spawner : spawners) { @@ -1690,7 +1692,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= 6) { + if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { //Go tell physics to spawn all the vertices: auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS); for (auto en : entities) { @@ -1700,7 +1702,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= 6) { + if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR); for (auto en : entities) { auto phys = static_cast<ProximityMonitorComponent*>(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR)); @@ -1716,7 +1718,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); for (auto* spawner : spawners) { @@ -1730,7 +1732,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "reforge" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 2) { + if (chatCommand == "reforge" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 2) { LOT baseItem; LOT reforgedItem; @@ -1747,7 +1749,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit inventoryComponent->AddItem(baseItem, 1, eLootSourceType::LOOT_SOURCE_MODERATION, eInventoryType::INVALID, data); } - if (chatCommand == "crash" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR) { + if (chatCommand == "crash" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR) { ChatPackets::SendSystemMessage(sysAddr, u"Crashing..."); int* badPtr = nullptr; @@ -1756,7 +1758,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "metrics" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "metrics" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { for (const auto variable : Metrics::GetAllMetrics()) { auto* metric = Metrics::GetMetric(variable); @@ -1793,7 +1795,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { Game::config->ReloadConfig(); VanityUtilities::SpawnVanity(); dpWorld::Instance().Reload(); @@ -1809,7 +1811,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!"); } - if (chatCommand == "rollloot" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR && args.size() >= 3) { + if (chatCommand == "rollloot" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR && args.size() >= 3) { uint32_t lootMatrixIndex = 0; uint32_t targetLot = 0; uint32_t loops = 1; @@ -1846,7 +1848,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, message); } - if (chatCommand == "deleteinven" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "deleteinven" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { eInventoryType inventoryType = eInventoryType::INVALID; if (!GeneralUtils::TryParse(args[0], inventoryType)) { // In this case, we treat the input as a string and try to find it in the reflection list @@ -1873,7 +1875,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Deleted inventory " + GeneralUtils::UTF8ToUTF16(args[0])); } - if (chatCommand == "inspect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "inspect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { Entity* closest = nullptr; eReplicaComponentType component; diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 100efac5..a1c08938 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -32,6 +32,7 @@ #include "CharacterComponent.h" #include "Database.h" #include "dMessageIdentifiers.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) { @@ -66,7 +67,7 @@ void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* pack } std::string playerName = user->GetLastUsedChar()->GetName(); - bool isMythran = user->GetLastUsedChar()->GetGMLevel() > 0; + bool isMythran = user->GetLastUsedChar()->GetGMLevel() > eGameMasterLevel::CIVILIAN; if (!user->GetLastChatMessageApproved() && !isMythran) return; diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index f6a8f558..febb6bc1 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -15,6 +15,7 @@ #include "CharacterComponent.h" #include "ZCompression.h" + void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) { RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_LOAD_STATIC_ZONE); @@ -127,7 +128,7 @@ void WorldPackets::SendServerState(const SystemAddress& sysAddr) { SEND_PACKET; } -void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm) { +void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) { RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_CREATE_CHARACTER); @@ -144,8 +145,8 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent LDFData<LOT>* lot = new LDFData<LOT>(u"template", 1); LDFData<std::string>* xmlConfigData = new LDFData<std::string>(u"xmlData", xmlData); LDFData<std::u16string>* name = new LDFData<std::u16string>(u"name", username); - LDFData<int32_t>* gmlevel = new LDFData<int32_t>(u"gmlevel", gm); - LDFData<int32_t>* chatmode = new LDFData<int32_t>(u"chatmode", gm); + LDFData<int32_t>* gmlevel = new LDFData<int32_t>(u"gmlevel", static_cast<int32_t>(gm)); + LDFData<int32_t>* chatmode = new LDFData<int32_t>(u"chatmode", static_cast<int32_t>(gm)); LDFData<int64_t>* reputation = new LDFData<int64_t>(u"reputation", character->GetReputation()); objid->WriteToPacket(&data); @@ -220,14 +221,14 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool SEND_PACKET; } -void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, uint8_t highestLevel, uint8_t prevLevel, uint8_t newLevel) { +void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel) { CBITSTREAM; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAKE_GM_RESPONSE); bitStream.Write<uint8_t>(success); - bitStream.Write<uint16_t>(highestLevel); - bitStream.Write<uint16_t>(prevLevel); - bitStream.Write<uint16_t>(newLevel); + bitStream.Write(static_cast<uint16_t>(highestLevel)); + bitStream.Write(static_cast<uint16_t>(prevLevel)); + bitStream.Write(static_cast<uint16_t>(newLevel)); SEND_PACKET; } diff --git a/dNet/WorldPackets.h b/dNet/WorldPackets.h index d9951941..ec20ac22 100644 --- a/dNet/WorldPackets.h +++ b/dNet/WorldPackets.h @@ -8,6 +8,7 @@ class User; struct SystemAddress; +enum class eGameMasterLevel : uint8_t; namespace WorldPackets { void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum); @@ -17,9 +18,9 @@ namespace WorldPackets { void SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response); void SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift); void SendServerState(const SystemAddress& sysAddr); - void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm); + void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm); void SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems); - void SendGMLevelChange(const SystemAddress& sysAddr, bool success, uint8_t highestLevel, uint8_t prevLevel, uint8_t newLevel); + void SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel); } #endif // WORLDPACKETS_H diff --git a/docs/Commands.md b/docs/Commands.md index 725a03a0..c997c3c4 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -128,13 +128,13 @@ There are 9 Game master levels |Level|Variable Name|Description| |--- |--- |--- | -|0|GAME_MASTER_LEVEL_CIVILIAN|Normal player| -|1|GAME_MASTER_LEVEL_FORUM_MODERATOR|Forum moderator. No permissions on live servers.| -|2|GAME_MASTER_LEVEL_JUNIOR_MODERATOR|Can kick/mute and pull chat logs| -|3|GAME_MASTER_LEVEL_MODERATOR|Can return lost items| -|4|GAME_MASTER_LEVEL_SENIOR_MODERATOR|Can ban| -|5|GAME_MASTER_LEVEL_LEAD_MODERATOR|Can approve properties| -|6|GAME_MASTER_LEVEL_JUNIOR_DEVELOPER|Junior developer & future content team. Civilan on live.| -|7|GAME_MASTER_LEVEL_INACTIVE_DEVELOPER|Inactive developer, limited permissions.| -|8|GAME_MASTER_LEVEL_DEVELOPER|Active developer, full permissions on live.| -|9|GAME_MASTER_LEVEL_OPERATOR|Can shutdown server for restarts & updates.| +|0|CIVILIAN|Normal player| +|1|FORUM_MODERATOR|Forum moderator. No permissions on live servers.| +|2|JUNIOR_MODERATOR|Can kick/mute and pull chat logs| +|3|MODERATOR|Can return lost items| +|4|SENIOR_MODERATOR|Can ban| +|5|LEAD_MODERATOR|Can approve properties| +|6|JUNIOR_DEVELOPER|Junior developer & future content team. Civilan on live.| +|7|INACTIVE_DEVELOPER|Inactive developer, limited permissions.| +|8|DEVELOPER|Active developer, full permissions on live.| +|9|OPERATOR|Can shutdown server for restarts & updates.| From c415d0520afe442827046ce53ae538703e58f0e0 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sat, 25 Mar 2023 05:26:39 -0500 Subject: [PATCH 150/166] Implement some more trigger event calls and command handlers (#989) * Implement some trigger event calls and command handlers * add zone summary dimissed GM * break and remove log * some cleanup in Gather Targets and blocking out * fix default value of unlock for play cinematic * Log on errors add enum for physics effect type simplify nipoint3 logic check arg count add enum for End behavior * tryparse for nipoint3 * totally didn't forget to include it * bleh c++ is blah * ??? * address feedback * Fix for #1028 --- dCommon/GeneralUtils.cpp | 4 + dCommon/GeneralUtils.h | 3 + dCommon/NiPoint3.cpp | 6 + dCommon/NiPoint3.h | 3 + dCommon/dEnums/dMessageIdentifiers.h | 1 + dCommon/dEnums/eEndBehavior.h | 11 + dCommon/dEnums/ePhysicsEffectType.h | 15 + dCommon/dEnums/eTriggerEventType.h | 2 +- dGame/Entity.cpp | 5 +- dGame/EntityManager.cpp | 4 +- dGame/dComponents/BouncerComponent.cpp | 3 + dGame/dComponents/PhantomPhysicsComponent.cpp | 5 +- dGame/dComponents/PhantomPhysicsComponent.h | 7 +- dGame/dComponents/RebuildComponent.cpp | 3 + dGame/dComponents/SwitchComponent.cpp | 4 +- dGame/dComponents/TriggerComponent.cpp | 409 ++++++++++++++---- dGame/dComponents/TriggerComponent.h | 31 +- dGame/dGameMessages/GameMessageHandler.cpp | 3 + dGame/dGameMessages/GameMessages.cpp | 14 +- dGame/dGameMessages/GameMessages.h | 5 +- dGame/dUtilities/SlashCommandHandler.cpp | 2 +- .../02_server/Map/AG/AgLaserSensorServer.cpp | 3 +- dScripts/02_server/Map/GF/MastTeleport.cpp | 3 +- .../Map/General/ForceVolumeServer.cpp | 3 +- .../02_server/Map/NT/NtAssemblyTubeServer.cpp | 3 +- .../Map/NT/NtSentinelWalkwayServer.cpp | 3 +- .../Map/NT/NtVentureCannonServer.cpp | 3 +- dScripts/BasePropertyServer.cpp | 14 +- dScripts/ai/FV/ActParadoxPipeFix.cpp | 3 +- dZoneManager/Spawner.cpp | 25 +- dZoneManager/Spawner.h | 1 + dZoneManager/dZoneManager.cpp | 12 +- 32 files changed, 461 insertions(+), 152 deletions(-) create mode 100644 dCommon/dEnums/eEndBehavior.h create mode 100644 dCommon/dEnums/ePhysicsEffectType.h diff --git a/dCommon/GeneralUtils.cpp b/dCommon/GeneralUtils.cpp index 54ef5661..df641a1b 100644 --- a/dCommon/GeneralUtils.cpp +++ b/dCommon/GeneralUtils.cpp @@ -319,3 +319,7 @@ std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::stri return sortedFiles; } + +bool GeneralUtils::TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst) { + return TryParse<float>(x.c_str(), dst.x) && TryParse<float>(y.c_str(), dst.y) && TryParse<float>(z.c_str(), dst.z); +} diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index a2a52b45..25aac783 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -10,6 +10,7 @@ #include <type_traits> #include <stdexcept> #include <BitStream.h> +#include "NiPoint3.h" #include "Game.h" #include "dLogger.h" @@ -208,6 +209,8 @@ namespace GeneralUtils { return TryParse<T>(value.c_str(), dst); } + bool TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst); + template<typename T> std::u16string to_u16string(T value) { return GeneralUtils::ASCIIToUTF16(std::to_string(value)); diff --git a/dCommon/NiPoint3.cpp b/dCommon/NiPoint3.cpp index a539c4df..b2ffa0d1 100644 --- a/dCommon/NiPoint3.cpp +++ b/dCommon/NiPoint3.cpp @@ -128,6 +128,12 @@ NiPoint3 NiPoint3::operator+(const NiPoint3& point) const { return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z); } +//! Operator for addition of vectors +NiPoint3 NiPoint3::operator+=(const NiPoint3& point) const { + return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z); +} + + //! Operator for subtraction of vectors NiPoint3 NiPoint3::operator-(const NiPoint3& point) const { return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z); diff --git a/dCommon/NiPoint3.h b/dCommon/NiPoint3.h index 6c0b9d3d..f76b9269 100644 --- a/dCommon/NiPoint3.h +++ b/dCommon/NiPoint3.h @@ -135,6 +135,9 @@ public: //! Operator for addition of vectors NiPoint3 operator+(const NiPoint3& point) const; + //! Operator for addition of vectors + NiPoint3 operator+=(const NiPoint3& point) const; + //! Operator for subtraction of vectors NiPoint3 operator-(const NiPoint3& point) const; diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index 63d7044e..7c810a2d 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -445,6 +445,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_BBB_SAVE_RESPONSE = 1006, GAME_MSG_NOTIFY_CLIENT_OBJECT = 1042, GAME_MSG_DISPLAY_ZONE_SUMMARY = 1043, + GAME_MSG_ZONE_SUMMARY_DISMISSED = 1044, GAME_MSG_ACTIVITY_STATE_CHANGE_REQUEST = 1053, GAME_MSG_MODIFY_PLAYER_ZONE_STATISTIC = 1046, GAME_MSG_START_BUILDING_WITH_ITEM = 1057, diff --git a/dCommon/dEnums/eEndBehavior.h b/dCommon/dEnums/eEndBehavior.h new file mode 100644 index 00000000..77afaab4 --- /dev/null +++ b/dCommon/dEnums/eEndBehavior.h @@ -0,0 +1,11 @@ +#ifndef __EENDBEHAVIOR__H__ +#define __EENDBEHAVIOR__H__ + +#include <cstdint> + +enum class eEndBehavior : uint32_t { + RETURN, + WAIT +}; + +#endif //!__EENDBEHAVIOR__H__ diff --git a/dCommon/dEnums/ePhysicsEffectType.h b/dCommon/dEnums/ePhysicsEffectType.h new file mode 100644 index 00000000..1aa68b34 --- /dev/null +++ b/dCommon/dEnums/ePhysicsEffectType.h @@ -0,0 +1,15 @@ +#ifndef __EPHYSICSEFFECTTYPE__H__ +#define __EPHYSICSEFFECTTYPE__H__ + + +#include <cstdint> + +enum class ePhysicsEffectType : uint32_t { + PUSH, + ATTRACT, + REPULSE, + GRAVITY_SCALE, + FRICTION +}; + +#endif //!__EPHYSICSEFFECTTYPE__H__ diff --git a/dCommon/dEnums/eTriggerEventType.h b/dCommon/dEnums/eTriggerEventType.h index 1705ce22..a2daa256 100644 --- a/dCommon/dEnums/eTriggerEventType.h +++ b/dCommon/dEnums/eTriggerEventType.h @@ -35,7 +35,7 @@ public: {"OnTimerDone", eTriggerEventType::TIMER_DONE}, {"OnRebuildComplete", eTriggerEventType::REBUILD_COMPLETE}, {"OnActivated", eTriggerEventType::ACTIVATED}, - {"OnDeactivated", eTriggerEventType::DEACTIVATED}, + {"OnDectivated", eTriggerEventType::DEACTIVATED}, // Dectivated vs Deactivated {"OnArrived", eTriggerEventType::ARRIVED}, {"OnArrivedAtEndOfPath", eTriggerEventType::ARRIVED_AT_END_OF_PATH}, {"OnZoneSummaryDismissed", eTriggerEventType::ZONE_SUMMARY_DISMISSED}, diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index c33a7247..95a550a6 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -763,7 +763,7 @@ void Entity::Initialize() { no_ghosting: - TriggerEvent(eTriggerEventType::CREATE); + TriggerEvent(eTriggerEventType::CREATE, this); if (m_Character) { auto* controllablePhysicsComponent = GetComponent<ControllablePhysicsComponent>(); @@ -1390,7 +1390,7 @@ void Entity::OnEmoteReceived(const int32_t emote, Entity* target) { } void Entity::OnUse(Entity* originator) { - TriggerEvent(eTriggerEventType::INTERACT); + TriggerEvent(eTriggerEventType::INTERACT, originator); for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { script->OnUse(this, originator); @@ -1412,6 +1412,7 @@ void Entity::OnHitOrHealResult(Entity* attacker, int32_t damage) { } void Entity::OnHit(Entity* attacker) { + TriggerEvent(eTriggerEventType::HIT, attacker); for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { script->OnHit(this, attacker); } diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 31b755fe..d547cdb1 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -163,6 +163,8 @@ void EntityManager::DestroyEntity(Entity* entity) { return; } + entity->TriggerEvent(eTriggerEventType::DESTROY, entity); + const auto id = entity->GetObjectID(); if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), id)) { @@ -588,7 +590,7 @@ void EntityManager::ScheduleForKill(Entity* entity) { SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>(); if (switchComp) { - entity->TriggerEvent(eTriggerEventType::DEACTIVATED); + entity->TriggerEvent(eTriggerEventType::DEACTIVATED, entity); } const auto objectId = entity->GetObjectID(); diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index 1f32d6e5..f6a53261 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -7,6 +7,7 @@ #include "dLogger.h" #include "GameMessages.h" #include <BitStream.h> +#include "eTriggerEventType.h" BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) { m_PetEnabled = false; @@ -46,8 +47,10 @@ void BouncerComponent::SetPetBouncerEnabled(bool value) { EntityManager::Instance()->SerializeEntity(m_Parent); if (value) { + m_Parent->TriggerEvent(eTriggerEventType::PET_ON_SWITCH, m_Parent); GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 1513, u"create", "PetOnSwitch", LWOOBJID_EMPTY, 1, 1, true); } else { + m_Parent->TriggerEvent(eTriggerEventType::PET_OFF_SWITCH, m_Parent); GameMessages::SendStopFXEffect(m_Parent, true, "PetOnSwitch"); } diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index 75cef4fb..ce205826 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -14,6 +14,7 @@ #include "EntityManager.h" #include "ControllablePhysicsComponent.h" #include "GameMessages.h" +#include "ePhysicsEffectType.h" #include "CDClientManager.h" #include "CDComponentsRegistryTable.h" @@ -36,7 +37,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : Component(par m_PositionInfoDirty = false; m_IsPhysicsEffectActive = false; - m_EffectType = 0; + m_EffectType = ePhysicsEffectType::PUSH; m_DirectionalMultiplier = 0.0f; m_MinMax = false; @@ -405,7 +406,7 @@ void PhantomPhysicsComponent::SetDirectionalMultiplier(float mul) { m_EffectInfoDirty = true; } -void PhantomPhysicsComponent::SetEffectType(uint32_t type) { +void PhantomPhysicsComponent::SetEffectType(ePhysicsEffectType type) { m_EffectType = type; m_EffectInfoDirty = true; } diff --git a/dGame/dComponents/PhantomPhysicsComponent.h b/dGame/dComponents/PhantomPhysicsComponent.h index 0b27db05..cc0d1844 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.h +++ b/dGame/dComponents/PhantomPhysicsComponent.h @@ -17,6 +17,7 @@ class LDFBaseData; class Entity; class dpEntity; +enum class ePhysicsEffectType : uint32_t ; /** * Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be @@ -103,13 +104,13 @@ public: * Returns the effect that's currently active, defaults to 0 * @return the effect that's currently active */ - uint32_t GetEffectType() const { return m_EffectType; } + ePhysicsEffectType GetEffectType() const { return m_EffectType; } /** * Sets the effect that's currently active * @param type the effect to set */ - void SetEffectType(uint32_t type); + void SetEffectType(ePhysicsEffectType type); /** * Returns the Physics entity for the component @@ -168,7 +169,7 @@ private: /** * The physics effect that's currently active, defaults to 0 */ - uint32_t m_EffectType; + ePhysicsEffectType m_EffectType; /** * A scaling multiplier to add to the directional vector diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index abd21873..2562b313 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -8,6 +8,7 @@ #include "CharacterComponent.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "eTriggerEventType.h" #include "dServer.h" #include "PacketUtils.h" @@ -495,6 +496,8 @@ void RebuildComponent::CompleteRebuild(Entity* user) { for (const auto& callback : m_RebuildCompleteCallbacks) callback(user); + m_Parent->TriggerEvent(eTriggerEventType::REBUILD_COMPLETE, user); + auto* movingPlatform = m_Parent->GetComponent<MovingPlatformComponent>(); if (movingPlatform != nullptr) { movingPlatform->OnCompleteRebuild(); diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index dbdf37a9..392d885a 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -43,7 +43,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { } m_Active = true; if (!m_Parent) return; - m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED); + m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED, entity); const auto grpName = m_Parent->GetVarAsString(u"grp_name"); @@ -79,7 +79,7 @@ void SwitchComponent::Update(float deltaTime) { if (m_Timer <= 0.0f) { m_Active = false; if (!m_Parent) return; - m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED); + m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED, m_Parent); const auto grpName = m_Parent->GetVarAsString(u"grp_name"); diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index d98b2eea..0f241116 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -1,10 +1,19 @@ #include "TriggerComponent.h" #include "dZoneManager.h" -#include "LUTriggers.h" +#include "TeamManager.h" #include "eTriggerCommandType.h" +#include "eMissionTaskType.h" +#include "ePhysicsEffectType.h" + +#include "CharacterComponent.h" +#include "ControllablePhysicsComponent.h" #include "MissionComponent.h" #include "PhantomPhysicsComponent.h" -#include "CDMissionTasksTable.h" +#include "Player.h" +#include "RebuildComponent.h" +#include "SkillComponent.h" +#include "eEndBehavior.h" + TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) { m_Parent = parent; @@ -51,19 +60,37 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity case eTriggerCommandType::FIRE_EVENT: HandleFireEvent(targetEntity, command->args); break; - case eTriggerCommandType::DESTROY_OBJ: break; - case eTriggerCommandType::TOGGLE_TRIGGER: break; - case eTriggerCommandType::RESET_REBUILD: break; + case eTriggerCommandType::DESTROY_OBJ: + HandleDestroyObject(targetEntity, command->args); + break; + case eTriggerCommandType::TOGGLE_TRIGGER: + HandleToggleTrigger(targetEntity, command->args); + break; + case eTriggerCommandType::RESET_REBUILD: + HandleResetRebuild(targetEntity, command->args); + break; case eTriggerCommandType::SET_PATH: break; case eTriggerCommandType::SET_PICK_TYPE: break; - case eTriggerCommandType::MOVE_OBJECT: break; - case eTriggerCommandType::ROTATE_OBJECT: break; - case eTriggerCommandType::PUSH_OBJECT: break; - case eTriggerCommandType::REPEL_OBJECT: break; + case eTriggerCommandType::MOVE_OBJECT: + HandleMoveObject(targetEntity, argArray); + break; + case eTriggerCommandType::ROTATE_OBJECT: + HandleRotateObject(targetEntity, argArray); + break; + case eTriggerCommandType::PUSH_OBJECT: + HandlePushObject(targetEntity, argArray); + break; + case eTriggerCommandType::REPEL_OBJECT: + HandleRepelObject(targetEntity, command->args); + break; case eTriggerCommandType::SET_TIMER: break; case eTriggerCommandType::CANCEL_TIMER: break; - case eTriggerCommandType::PLAY_CINEMATIC: break; - case eTriggerCommandType::TOGGLE_BBB: break; + case eTriggerCommandType::PLAY_CINEMATIC: + HandlePlayCinematic(targetEntity, argArray); + break; + case eTriggerCommandType::TOGGLE_BBB: + HandleToggleBBB(targetEntity, command->args); + break; case eTriggerCommandType::UPDATE_MISSION: HandleUpdateMission(targetEntity, argArray); break; @@ -75,8 +102,43 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity case eTriggerCommandType::STOP_PATHING: break; case eTriggerCommandType::START_PATHING: break; case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break; - case eTriggerCommandType::PLAY_EFFECT: break; - case eTriggerCommandType::STOP_EFFECT: break; + case eTriggerCommandType::PLAY_EFFECT: + HandlePlayEffect(targetEntity, argArray); + break; + case eTriggerCommandType::STOP_EFFECT: + GameMessages::SendStopFXEffect(targetEntity, true, command->args); + break; + case eTriggerCommandType::CAST_SKILL: + HandleCastSkill(targetEntity, command->args); + break; + case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: + GameMessages::SendDisplayZoneSummary(targetEntity->GetObjectID(), targetEntity->GetSystemAddress(), false, command->args == "1", m_Parent->GetObjectID()); + break; + case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT: + HandleSetPhysicsVolumeEffect(targetEntity, argArray); + break; + case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: + HandleSetPhysicsVolumeStatus(targetEntity, command->args); + break; + case eTriggerCommandType::SET_MODEL_TO_BUILD: break; + case eTriggerCommandType::SPAWN_MODEL_BRICKS: break; + case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: + HandleActivateSpawnerNetwork(command->args); + break; + case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: + HandleDeactivateSpawnerNetwork(command->args); + break; + case eTriggerCommandType::RESET_SPAWNER_NETWORK: + HandleResetSpawnerNetwork(command->args); + break; + case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: + HandleDestroySpawnerNetworkObjects(command->args); + break; + case eTriggerCommandType::GO_TO_WAYPOINT: break; + case eTriggerCommandType::ACTIVATE_PHYSICS: + HandleActivatePhysics(targetEntity, command->args); + break; + // DEPRECATED BLOCK START case eTriggerCommandType::ACTIVATE_MUSIC_CUE: break; case eTriggerCommandType::DEACTIVATE_MUSIC_CUE: break; case eTriggerCommandType::FLASH_MUSIC_CUE: break; @@ -87,20 +149,7 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break; case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break; case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break; - case eTriggerCommandType::CAST_SKILL: break; - case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: break; - case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT: - HandleSetPhysicsVolume(targetEntity, argArray, command->target); - break; - case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: break; - case eTriggerCommandType::SET_MODEL_TO_BUILD: break; - case eTriggerCommandType::SPAWN_MODEL_BRICKS: break; - case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: break; - case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: break; - case eTriggerCommandType::RESET_SPAWNER_NETWORK: break; - case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: break; - case eTriggerCommandType::GO_TO_WAYPOINT: break; - case eTriggerCommandType::ACTIVATE_PHYSICS: break; + // DEPRECATED BLOCK END default: Game::logger->LogDebug("TriggerComponent", "Event %i was not handled!", command->id); break; @@ -113,70 +162,262 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman if (command->target == "self") entities.push_back(m_Parent); else if (command->target == "zone") { /*TODO*/ } - else if (command->target == "target") { /*TODO*/ } - else if (command->target == "targetTeam") { /*TODO*/ } - else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); - else if (command->target == "allPlayers") { /*TODO*/ } - else if (command->target == "allNPCs") { /*TODO*/ } - - if (optionalTarget) entities.push_back(optionalTarget); + else if (command->target == "target" && optionalTarget) entities.push_back(optionalTarget); + else if (command->target == "targetTeam" && optionalTarget) { + auto* team = TeamManager::Instance()->GetTeam(optionalTarget->GetObjectID()); + for (const auto memberId : team->members) { + auto* member = EntityManager::Instance()->GetEntity(memberId); + if (member) entities.push_back(member); + } + } else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); + else if (command->target == "allPlayers") { + for (auto* player : Player::GetAllPlayers()) { + entities.push_back(player); + } + } else if (command->target == "allNPCs") { /*UNUSED*/ } return entities; } -void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target) { - PhantomPhysicsComponent* phanPhys = m_Parent->GetComponent<PhantomPhysicsComponent>(); - if (!phanPhys) return; - - phanPhys->SetPhysicsEffectActive(true); - uint32_t effectType = 0; - std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase - if (argArray.at(0) == "push") effectType = 0; - else if (argArray.at(0) == "attract") effectType = 1; - else if (argArray.at(0) == "repulse") effectType = 2; - else if (argArray.at(0) == "gravity") effectType = 3; - else if (argArray.at(0) == "friction") effectType = 4; - - phanPhys->SetEffectType(effectType); - phanPhys->SetDirectionalMultiplier(std::stof(argArray.at(1))); - if (argArray.size() > 4) { - NiPoint3 direction = NiPoint3::ZERO; - GeneralUtils::TryParse<float>(argArray.at(2), direction.x); - GeneralUtils::TryParse<float>(argArray.at(3), direction.y); - GeneralUtils::TryParse<float>(argArray.at(4), direction.z); - phanPhys->SetDirection(direction); - } - if (argArray.size() > 5) { - uint32_t min; - GeneralUtils::TryParse<uint32_t>(argArray.at(6), min); - phanPhys->SetMin(min); - - uint32_t max; - GeneralUtils::TryParse<uint32_t>(argArray.at(7), max); - phanPhys->SetMax(max); - } - - // TODO: why is this contruct and not serialize? - if (target == "self") EntityManager::Instance()->ConstructEntity(m_Parent); -} - -void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) { - CDMissionTasksTable* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>(); - std::vector<CDMissionTasks> missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { - return (entry.targetGroup == argArray.at(4)); - }); - - for (const CDMissionTasks& task : missionTasks) { - MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>(); - if (!missionComponent) continue; - - missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray.at(2))); - } -} - void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0); } } +void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){ + uint32_t killType; + GeneralUtils::TryParse<uint32_t>(args, killType); + targetEntity->Smash(m_Parent->GetObjectID(), static_cast<eKillType>(killType)); +} + +void TriggerComponent::HandleToggleTrigger(Entity* targetEntity, std::string args){ + auto* triggerComponent = targetEntity->GetComponent<TriggerComponent>(); + if (!triggerComponent) { + Game::logger->Log("TriggerComponent::HandleToggleTrigger", "Trigger component not found!"); + return; + } + triggerComponent->SetTriggerEnabled(args == "1"); +} + +void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args){ + auto* rebuildComponent = targetEntity->GetComponent<RebuildComponent>(); + if (!rebuildComponent) { + Game::logger->Log("TriggerComponent::HandleResetRebuild", "Rebuild component not found!"); + return; + } + rebuildComponent->ResetRebuild(args == "1"); +} + +void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray){ + if (argArray.size() <= 2) return; + + auto position = targetEntity->GetPosition(); + NiPoint3 offset = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), offset); + + position += offset; + targetEntity->SetPosition(position); +} + +void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray){ + if (argArray.size() <= 2) return; + + NiPoint3 vector = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), vector); + + NiQuaternion rotation = NiQuaternion::FromEulerAngles(vector); + targetEntity->SetRotation(rotation); +} + +void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray){ + auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandlePushObject", "Phantom Physics component not found!"); + return; + } + phantomPhysicsComponent->SetPhysicsEffectActive(true); + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH); + phantomPhysicsComponent->SetDirectionalMultiplier(1); + NiPoint3 direction = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), direction); + phantomPhysicsComponent->SetDirection(direction); + + EntityManager::Instance()->SerializeEntity(m_Parent); +} + + +void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args){ + auto* phantomPhysicsComponent = m_Parent->GetComponent<PhantomPhysicsComponent>(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandleRepelObject", "Phantom Physics component not found!"); + return; + } + float forceMultiplier; + GeneralUtils::TryParse<float>(args, forceMultiplier); + phantomPhysicsComponent->SetPhysicsEffectActive(true); + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE); + phantomPhysicsComponent->SetDirectionalMultiplier(forceMultiplier); + + auto triggerPos = m_Parent->GetPosition(); + auto targetPos = targetEntity->GetPosition(); + + // normalize the vectors to get the direction + auto delta = targetPos - triggerPos; + auto length = delta.Length(); + NiPoint3 direction = delta / length; + phantomPhysicsComponent->SetDirection(direction); + + EntityManager::Instance()->SerializeEntity(m_Parent); +} + +void TriggerComponent::HandlePlayCinematic(Entity* targetEntity, std::vector<std::string> argArray) { + float leadIn = -1.0; + auto wait = eEndBehavior::RETURN; + bool unlock = true; + bool leaveLocked = false; + bool hidePlayer = false; + + if (argArray.size() >= 2) { + GeneralUtils::TryParse<float>(argArray.at(1), leadIn); + if (argArray.size() >= 3 && argArray.at(2) == "wait") { + wait = eEndBehavior::WAIT; + if (argArray.size() >= 4 && argArray.at(3) == "unlock") { + unlock = false; + if (argArray.size() >= 5 && argArray.at(4) == "leavelocked") { + leaveLocked = true; + if (argArray.size() >= 6 && argArray.at(5) == "hideplayer") { + hidePlayer = true; + } + } + } + } + } + + GameMessages::SendPlayCinematic(targetEntity->GetObjectID(), GeneralUtils::UTF8ToUTF16(argArray.at(0)), targetEntity->GetSystemAddress(), true, true, false, false, wait, hidePlayer, leadIn, leaveLocked, unlock); +} + +void TriggerComponent::HandleToggleBBB(Entity* targetEntity, std::string args) { + auto* character = targetEntity->GetCharacter(); + if (!character) { + Game::logger->Log("TriggerComponent::HandleToggleBBB", "Character was not found!"); + return; + } + bool buildMode = !(character->GetBuildMode()); + if (args == "enter") buildMode = true; + else if (args == "exit") buildMode = false; + character->SetBuildMode(buildMode); +} + +void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray) { + // there are only explore tasks used + // If others need to be implemented for modding + // then we need a good way to convert this from a string to that enum + if (argArray.at(0) != "exploretask") return; + MissionComponent* missionComponent = targetEntity->GetComponent<MissionComponent>(); + if (!missionComponent){ + Game::logger->Log("TriggerComponent::HandleUpdateMission", "Mission component not found!"); + return; + } + missionComponent->Progress(eMissionTaskType::EXPLORE, 0, 0, argArray.at(4)); +} + +void TriggerComponent::HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray) { + if (argArray.size() < 3) return; + int32_t effectID = 0; + if (!GeneralUtils::TryParse<int32_t>(argArray.at(1), effectID)) return; + std::u16string effectType = GeneralUtils::UTF8ToUTF16(argArray.at(2)); + float priority = 1; + if (argArray.size() == 4) GeneralUtils::TryParse<float>(argArray.at(3), priority); + GameMessages::SendPlayFXEffect(targetEntity, effectID, effectType, argArray.at(0), LWOOBJID_EMPTY, priority); +} + +void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){ + auto* skillComponent = targetEntity->GetComponent<SkillComponent>(); + if (!skillComponent) { + Game::logger->Log("TriggerComponent::HandleCastSkill", "Skill component not found!"); + return; + } + uint32_t skillId; + GeneralUtils::TryParse<uint32_t>(args, skillId); + skillComponent->CastSkill(skillId, targetEntity->GetObjectID()); +} + +void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray) { + auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!"); + return; + } + phantomPhysicsComponent->SetPhysicsEffectActive(true); + ePhysicsEffectType effectType = ePhysicsEffectType::PUSH; + std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase + if (argArray.at(0) == "push") effectType = ePhysicsEffectType::PUSH; + else if (argArray.at(0) == "attract") effectType = ePhysicsEffectType::ATTRACT; + else if (argArray.at(0) == "repulse") effectType = ePhysicsEffectType::REPULSE; + else if (argArray.at(0) == "gravity") effectType = ePhysicsEffectType::GRAVITY_SCALE; + else if (argArray.at(0) == "friction") effectType = ePhysicsEffectType::FRICTION; + + phantomPhysicsComponent->SetEffectType(effectType); + phantomPhysicsComponent->SetDirectionalMultiplier(std::stof(argArray.at(1))); + if (argArray.size() > 4) { + NiPoint3 direction = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4), direction); + phantomPhysicsComponent->SetDirection(direction); + } + if (argArray.size() > 5) { + uint32_t min; + GeneralUtils::TryParse<uint32_t>(argArray.at(6), min); + phantomPhysicsComponent->SetMin(min); + + uint32_t max; + GeneralUtils::TryParse<uint32_t>(argArray.at(7), max); + phantomPhysicsComponent->SetMax(max); + } + + EntityManager::Instance()->SerializeEntity(targetEntity); +} + +void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) { + auto* phantomPhysicsComponent = targetEntity->GetComponent<PhantomPhysicsComponent>(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!"); + return; + } + phantomPhysicsComponent->SetPhysicsEffectActive(args == "On"); + EntityManager::Instance()->SerializeEntity(targetEntity); +} + +void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->Activate(); + } +} + +void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->Deactivate(); + } +} + +void TriggerComponent::HandleResetSpawnerNetwork(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->Reset(); + } +} + +void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->DestroyAllEntities(); + } +} + +void TriggerComponent::HandleActivatePhysics(Entity* targetEntity, std::string args) { + if (args == "true") { + // TODO add physics entity if there isn't one + } else if (args == "false"){ + // TODO remove Phsyics entity if there is one + } else { + Game::logger->LogDebug("TriggerComponent", "Invalid argument for ActivatePhysics Trigger: %s", args.c_str()); + } +} diff --git a/dGame/dComponents/TriggerComponent.h b/dGame/dComponents/TriggerComponent.h index 492b0449..317da00e 100644 --- a/dGame/dComponents/TriggerComponent.h +++ b/dGame/dComponents/TriggerComponent.h @@ -2,13 +2,9 @@ #define __TRIGGERCOMPONENT__H__ #include "Component.h" +#include "LUTriggers.h" #include "eReplicaComponentType.h" -namespace LUTriggers { - struct Trigger; - struct Command; -}; - class TriggerComponent : public Component { public: static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER; @@ -17,18 +13,35 @@ public: void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); LUTriggers::Trigger* GetTrigger() const { return m_Trigger; } + void SetTriggerEnabled(bool enabled){ m_Trigger->enabled = enabled; }; + private: void HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget); - std::vector<std::string> ParseArgs(std::string args); std::vector<Entity*> GatherTargets(LUTriggers::Command* command, Entity* optionalTarget); // Trigger Event Handlers - void HandleSetPhysicsVolume(Entity* targetEntity, std::vector<std::string> argArray, std::string target); - void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray); void HandleFireEvent(Entity* targetEntity, std::string args); - void HandleCastSkill(Entity* targetEntity, uint32_t skillID); + void HandleDestroyObject(Entity* targetEntity, std::string args); + void HandleToggleTrigger(Entity* targetEntity, std::string args); + void HandleResetRebuild(Entity* targetEntity, std::string args); + void HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray); + void HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray); + void HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray); + void HandleRepelObject(Entity* targetEntity, std::string args); + void HandlePlayCinematic(Entity* targetEntity, std::vector<std::string> argArray); + void HandleToggleBBB(Entity* targetEntity, std::string args); + void HandleUpdateMission(Entity* targetEntity, std::vector<std::string> argArray); + void HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray); + void HandleCastSkill(Entity* targetEntity, std::string args); + void HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector<std::string> argArray); + void HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args); + void HandleActivateSpawnerNetwork(std::string args); + void HandleDeactivateSpawnerNetwork(std::string args); + void HandleResetSpawnerNetwork(std::string args); + void HandleDestroySpawnerNetworkObjects(std::string args); + void HandleActivatePhysics(Entity* targetEntity, std::string args); LUTriggers::Trigger* m_Trigger; }; diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 5c05c28d..c0893a09 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -673,6 +673,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case GAME_MSG_ACTIVATE_BUBBLE_BUFF: GameMessages::HandleActivateBubbleBuff(inStream, entity); break; + case GAME_MSG_ZONE_SUMMARY_DISMISSED: + GameMessages::HandleZoneSummaryDismissed(inStream, entity); + break; default: // Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID); break; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 2941a0f9..bf7476e9 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -34,6 +34,7 @@ #include "eRacingTaskParam.h" #include "eMissionTaskType.h" #include "eMissionState.h" +#include "eTriggerEventType.h" #include <sstream> #include <future> @@ -2813,7 +2814,7 @@ void GameMessages::HandleSetConsumableItem(RakNet::BitStream* inStream, Entity* void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, bool allowGhostUpdates, bool bCloseMultiInteract, bool bSendServerNotify, bool bUseControlledObjectForAudioListener, - int endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished, + eEndBehavior endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished, bool lockPlayer, bool result, bool skipIfSamePath, float startTimeAdvance) { CBITSTREAM; CMSGHEADER; @@ -2826,8 +2827,8 @@ void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, bitStream.Write(bSendServerNotify); bitStream.Write(bUseControlledObjectForAudioListener); - bitStream.Write(endBehavior != 0); - if (endBehavior != 0) bitStream.Write(endBehavior); + bitStream.Write(endBehavior != eEndBehavior::RETURN); + if (endBehavior != eEndBehavior::RETURN) bitStream.Write(endBehavior); bitStream.Write(hidePlayerDuringCine); @@ -6155,6 +6156,13 @@ void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const S SEND_PACKET; } +void GameMessages::HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity) { + LWOOBJID player_id; + inStream->Read<LWOOBJID>(player_id); + auto target = EntityManager::Instance()->GetEntity(player_id); + entity->TriggerEvent(eTriggerEventType::ZONE_SUMMARY_DISMISSED, target); +}; + void GameMessages::SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId) { CBITSTREAM; CMSGHEADER; diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 1372003e..68f4542f 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -7,6 +7,7 @@ #include <vector> #include "eMovementPlatformState.h" #include "NiPoint3.h" +#include "eEndBehavior.h" class AMFValue; class Entity; @@ -266,7 +267,7 @@ namespace GameMessages { void SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, bool allowGhostUpdates = true, bool bCloseMultiInteract = true, bool bSendServerNotify = false, bool bUseControlledObjectForAudioListener = false, - int endBehavior = 0, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false, + eEndBehavior endBehavior = eEndBehavior::RETURN, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false, bool lockPlayer = true, bool result = false, bool skipIfSamePath = false, float startTimeAdvance = 0); void SendEndCinematic(LWOOBJID objectID, std::u16string pathName, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS, @@ -633,6 +634,8 @@ namespace GameMessages { void SendActivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); + + void HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity); }; #endif // GAMEMESSAGES_H diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index f9bf4884..7383d51c 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -2018,7 +2018,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto* phantomPhysicsComponent = closest->GetComponent<PhantomPhysicsComponent>(); if (phantomPhysicsComponent != nullptr) { - ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetEffectType()))); + ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(static_cast<uint32_t>(phantomPhysicsComponent->GetEffectType())))); const auto dir = phantomPhysicsComponent->GetDirection(); ChatPackets::SendSystemMessage(sysAddr, u"Direction: <" + (GeneralUtils::to_u16string(dir.x)) + u", " + (GeneralUtils::to_u16string(dir.y)) + u", " + (GeneralUtils::to_u16string(dir.z)) + u">"); ChatPackets::SendSystemMessage(sysAddr, u"Multiplier: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetDirectionalMultiplier()))); diff --git a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp index c09000be..703625d2 100644 --- a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp +++ b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp @@ -5,13 +5,14 @@ #include "EntityManager.h" #include "AgMonumentLaserServer.h" #include "EntityManager.h" +#include "ePhysicsEffectType.h" #include "eReplicaComponentType.h" void AgLaserSensorServer::OnStartup(Entity* self) { PhantomPhysicsComponent* physComp = static_cast<PhantomPhysicsComponent*>(self->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); physComp->SetPhysicsEffectActive(true); - physComp->SetEffectType(2); // repulse (prolly should make definitions of these are in Entity.cpp) + physComp->SetEffectType(ePhysicsEffectType::REPULSE); physComp->SetDirectionalMultiplier(static_cast<float>(m_RepelForce)); physComp->SetDirection(NiPoint3::UNIT_Y); diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index 6e50c6ec..8b8453b9 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -2,6 +2,7 @@ #include "EntityManager.h" #include "GameMessages.h" #include "Preconditions.h" +#include "eEndBehavior.h" #include "DestroyableComponent.h" #ifdef _WIN32 @@ -52,7 +53,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { if (!cinematic.empty()) { GameMessages::SendPlayCinematic(playerId, GeneralUtils::ASCIIToUTF16(cinematic), player->GetSystemAddress(), - true, true, false, false, 0, false, leanIn + true, true, false, false, eEndBehavior::RETURN, false, leanIn ); } diff --git a/dScripts/02_server/Map/General/ForceVolumeServer.cpp b/dScripts/02_server/Map/General/ForceVolumeServer.cpp index fbaad6ee..ed9024c1 100644 --- a/dScripts/02_server/Map/General/ForceVolumeServer.cpp +++ b/dScripts/02_server/Map/General/ForceVolumeServer.cpp @@ -1,6 +1,7 @@ #include "ForceVolumeServer.h" #include "PhantomPhysicsComponent.h" #include "EntityManager.h" +#include "ePhysicsEffectType.h" void ForceVolumeServer::OnStartup(Entity* self) { auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); @@ -12,7 +13,7 @@ void ForceVolumeServer::OnStartup(Entity* self) { const auto forceY = self->GetVar<float>(u"ForceY"); const auto forceZ = self->GetVar<float>(u"ForceZ"); - phantomPhysicsComponent->SetEffectType(0); // PUSH + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH); phantomPhysicsComponent->SetDirectionalMultiplier(forceAmount); phantomPhysicsComponent->SetDirection({ forceX, forceY, forceZ }); phantomPhysicsComponent->SetPhysicsEffectActive(true); diff --git a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp index b4d75296..74f9bd16 100644 --- a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp +++ b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp @@ -4,6 +4,7 @@ #include "MissionComponent.h" #include "eMissionTaskType.h" #include "eMissionState.h" +#include "eEndBehavior.h" void NtAssemblyTubeServer::OnStartup(Entity* self) { self->SetProximityRadius(5, "teleport"); @@ -45,7 +46,7 @@ void NtAssemblyTubeServer::RunAssemblyTube(Entity* self, Entity* player) { if (!teleCinematic.empty()) { const auto teleCinematicUname = teleCinematic; GameMessages::SendPlayCinematic(player->GetObjectID(), teleCinematicUname, player->GetSystemAddress(), - true, true, true, false, 0, false, -1, false, true + true, true, true, false, eEndBehavior::RETURN, false, -1, false, true ); } diff --git a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp index 66bfe46f..257bf6da 100644 --- a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp +++ b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "ePhysicsEffectType.h" void NtSentinelWalkwayServer::OnStartup(Entity* self) { auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); @@ -19,7 +20,7 @@ void NtSentinelWalkwayServer::OnStartup(Entity* self) { const auto forward = self->GetRotation().GetRightVector() * -1; - phantomPhysicsComponent->SetEffectType(0); // PUSH + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH); phantomPhysicsComponent->SetDirectionalMultiplier(force); phantomPhysicsComponent->SetDirection(forward); phantomPhysicsComponent->SetPhysicsEffectActive(true); diff --git a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp index e6cd2df6..874d8aa1 100644 --- a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp +++ b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp @@ -1,6 +1,7 @@ #include "NtVentureCannonServer.h" #include "GameMessages.h" #include "EntityManager.h" +#include "eEndBehavior.h" void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { auto* player = user; @@ -73,7 +74,7 @@ void NtVentureCannonServer::EnterCannonEnded(Entity* self, Entity* player) { const auto exitCinematicUname = exitCinematic; GameMessages::SendPlayCinematic(player->GetObjectID(), exitCinematicUname, player->GetSystemAddress(), - true, true, true, false, 0, false, 0, false, false + true, true, true, false, eEndBehavior::RETURN, false, 0, false, false ); self->AddCallbackTimer(1.5f, [this, self, playerID]() { diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index 7552eeca..a9f35e25 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -303,18 +303,8 @@ void BasePropertyServer::ResetSpawner(const std::string& spawnerName) { void BasePropertyServer::DestroySpawner(const std::string& spawnerName) { for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { - for (auto* node : spawner->m_Info.nodes) { - for (const auto& element : node->entities) { - auto* entity = EntityManager::Instance()->GetEntity(element); - if (entity == nullptr) - continue; - - entity->Kill(); - } - - node->entities.clear(); - } - + if (!spawner) return; + spawner->DestroyAllEntities(); spawner->Deactivate(); } } diff --git a/dScripts/ai/FV/ActParadoxPipeFix.cpp b/dScripts/ai/FV/ActParadoxPipeFix.cpp index 1dddde64..517474a9 100644 --- a/dScripts/ai/FV/ActParadoxPipeFix.cpp +++ b/dScripts/ai/FV/ActParadoxPipeFix.cpp @@ -3,6 +3,7 @@ #include "RebuildComponent.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eEndBehavior.h" void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { const auto myGroup = "AllPipes"; @@ -42,7 +43,7 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { missionComponent->ForceProgressTaskType(769, 1, 1, false); } - GameMessages::SendPlayCinematic(player->GetObjectID(), u"ParadoxPipeFinish", player->GetSystemAddress(), true, true, false, false, 0, false, 2.0f); + GameMessages::SendPlayCinematic(player->GetObjectID(), u"ParadoxPipeFinish", player->GetSystemAddress(), true, true, false, false, eEndBehavior::RETURN, false, 2.0f); } object->SetVar(u"PlayerID", LWOOBJID_EMPTY); diff --git a/dZoneManager/Spawner.cpp b/dZoneManager/Spawner.cpp index 57b4e988..28f77fea 100644 --- a/dZoneManager/Spawner.cpp +++ b/dZoneManager/Spawner.cpp @@ -134,24 +134,23 @@ void Spawner::AddEntitySpawnedCallback(std::function<void(Entity*)> callback) { void Spawner::Reset() { m_Start = true; - - for (auto* node : m_Info.nodes) { - for (const auto& spawned : node->entities) { - auto* entity = EntityManager::Instance()->GetEntity(spawned); - - if (entity == nullptr) continue; - - entity->Kill(); - } - - node->entities.clear(); - } - + DestroyAllEntities(); m_Entities.clear(); m_AmountSpawned = 0; m_NeedsUpdate = true; } +void Spawner::DestroyAllEntities(){ + for (auto* node : m_Info.nodes) { + for (const auto& element : node->entities) { + auto* entity = EntityManager::Instance()->GetEntity(element); + if (entity == nullptr) continue; + entity->Kill(); + } + node->entities.clear(); + } +} + void Spawner::SoftReset() { m_Start = true; m_AmountSpawned = 0; diff --git a/dZoneManager/Spawner.h b/dZoneManager/Spawner.h index a42c8a65..1f610b71 100644 --- a/dZoneManager/Spawner.h +++ b/dZoneManager/Spawner.h @@ -61,6 +61,7 @@ public: void AddEntitySpawnedCallback(std::function<void(Entity*)> callback); void SetSpawnLot(LOT lot); void Reset(); + void DestroyAllEntities(); void SoftReset(); void SetRespawnTime(float time); void SetNumToMaintain(int32_t value); diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 52008b5d..ac3a7008 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -182,17 +182,7 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id) { Game::logger->Log("dZoneManager", "Failed to find spawner entity (%llu)", id); } - for (auto* node : spawner->m_Info.nodes) { - for (const auto& element : node->entities) { - auto* nodeEntity = EntityManager::Instance()->GetEntity(element); - - if (nodeEntity == nullptr) continue; - - nodeEntity->Kill(); - } - - node->entities.clear(); - } + spawner->DestroyAllEntities(); spawner->Deactivate(); From cbef4a140efaac328b46cff65598983cf78dc42b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 30 Mar 2023 06:01:15 -0700 Subject: [PATCH 151/166] Fix Spider Queen boss battle crash (#1034) --- .../Enemy/AG/BossSpiderQueenEnemyServer.cpp | 139 ++++-------------- 1 file changed, 30 insertions(+), 109 deletions(-) diff --git a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp index c584f05b..a3b9cc3f 100644 --- a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp @@ -48,8 +48,6 @@ void BossSpiderQueenEnemyServer::OnStartup(Entity* self) { m_CurrentBossStage = 1; // Obtain faction and collision group to save for subsequent resets - //self : SetVar("SBFactionList", self:GetFaction().factionList) - //self : SetVar("SBCollisionGroup", self:GetCollisionGroup().colGroup) } void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { @@ -61,8 +59,6 @@ void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { missionComponent->CompleteMission(instanceMissionID); } - Game::logger->Log("BossSpiderQueenEnemyServer", "Starting timer..."); - // There is suppose to be a 0.1 second delay here but that may be admitted? auto* controller = EntityManager::Instance()->GetZoneControlEntity(); @@ -165,9 +161,6 @@ void BossSpiderQueenEnemyServer::SpawnSpiderWave(Entity* self, int spiderCount) // The Spider Queen Boss is withdrawing and requesting the spawn // of a hatchling wave - /*auto SpiderEggNetworkID = self->GetI64(u"SpiderEggNetworkID"); - if (SpiderEggNetworkID == 0) return;*/ - // Clamp invalid Spiderling number requests to the maximum amount of eggs available if ((spiderCount > maxSpiderEggCnt) || (spiderCount < 0)) spiderCount = maxSpiderEggCnt; @@ -176,44 +169,13 @@ void BossSpiderQueenEnemyServer::SpawnSpiderWave(Entity* self, int spiderCount) hatchCounter = spiderCount; hatchList = {}; - Game::logger->Log("SpiderQueen", "Trying to spawn %i spiders", hatchCounter); - - // Run the wave manager SpiderWaveManager(self); - } void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { auto SpiderEggNetworkID = self->GetI64(u"SpiderEggNetworkID"); - // Reset the spider egg spawner network to ensure a maximum number of eggs - //SpiderEggNetworkID:SpawnerReset() - - // Obtain a list of all the eggs on the egg spawner network - - //auto spiderEggList = SpiderEggNetworkID:SpawnerGetAllObjectIDsSpawned().objects; - - //if (table.maxn(spiderEggList) <= 0) { - // self->AddTimer("PollSpiderWaveManager", 1.0f); - // return; - //} - // - //// A check for (wave mangement across multiple spawn iterations - //if(hatchCounter < spiderWaveCnt) { - // // We have already prepped some objects for (hatching, - // // remove them from our list for (random egg pulls - // for (i, sVal in ipairs(spiderEggList) { - // if(hatchList[sVal:GetID()]) { - // // We have found a prepped egg, remove it from the spiderEggList - // spiderEggList[i] = nil - // } - // } - - //} - - - std::vector<LWOOBJID> spiderEggs{}; auto spooders = EntityManager::Instance()->GetEntitiesInGroup("EGG"); @@ -223,44 +185,43 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { // Select a number of random spider eggs from the list equal to the // current number needed to complete the current wave - for (int i = 0; i < hatchCounter; i++) { - // Select a random spider egg - auto randomEggLoc = GeneralUtils::GenerateRandomNumber<int>(0, spiderEggs.size() - 1); - auto randomEgg = spiderEggs[randomEggLoc]; + if (!spiderEggs.empty()) { + for (int i = 0; i < hatchCounter; i++) { + // Select a random spider egg + auto randomEggLoc = GeneralUtils::GenerateRandomNumber<int>(0, spiderEggs.size() - 1); + auto randomEgg = spiderEggs[randomEggLoc]; - //Just a quick check to try and prevent dupes: - for (auto en : hatchList) { - if (en == randomEgg) { - randomEggLoc++; - randomEgg = spiderEggs[randomEggLoc]; - } - } - - if (randomEgg) { - auto* eggEntity = EntityManager::Instance()->GetEntity(randomEgg); - - if (eggEntity == nullptr) { - continue; + //Just a quick check to try and prevent dupes: + for (auto en : hatchList) { + if (en == randomEgg) { + randomEggLoc++; + randomEgg = spiderEggs[randomEggLoc]; + } } - // Prep the selected spider egg - //randomEgg:FireEvent{s}erID=self, args="prepEgg"} - eggEntity->OnFireEventServerSide(self, "prepEgg"); - Game::logger->Log("SpiderQueen", "Prepping egg %llu", eggEntity->GetObjectID()); + if (randomEgg) { + auto* eggEntity = EntityManager::Instance()->GetEntity(randomEgg); - // Add the prepped egg to our hatchList - hatchList.push_back(eggEntity->GetObjectID()); + if (eggEntity == nullptr) { + continue; + } - // Decrement the hatchCounter - hatchCounter = hatchCounter - 1; - } + // Prep the selected spider egg + eggEntity->OnFireEventServerSide(self, "prepEgg"); - // Remove it from our spider egg list - //table.remove(spiderEggList, randomEggLoc); - spiderEggs[randomEggLoc] = LWOOBJID_EMPTY; + // Add the prepped egg to our hatchList + hatchList.push_back(eggEntity->GetObjectID()); - if (spiderEggs.size() <= 0 || (hatchCounter <= 0)) { - break; + // Decrement the hatchCounter + hatchCounter = hatchCounter - 1; + } + + // Remove it from our spider egg list + spiderEggs[randomEggLoc] = LWOOBJID_EMPTY; + + if (spiderEggs.size() <= 0 || (hatchCounter <= 0)) { + break; + } } } @@ -279,14 +240,12 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { } eggEntity->OnFireEventServerSide(self, "hatchEgg"); - Game::logger->Log("SpiderQueen", "hatching egg %llu", eggEntity->GetObjectID()); auto time = PlayAnimAndReturnTime(self, spiderWithdrawIdle); combat->SetStunImmune(false); combat->Stun(time += 6.0f); combat->SetStunImmune(true); - //self->AddTimer("disableWaitForIdle", defaultAnimPause); self->AddTimer("checkForSpiders", 6.0f); } @@ -397,10 +356,6 @@ void BossSpiderQueenEnemyServer::RapidFireShooterManager(Entity* self) { } void BossSpiderQueenEnemyServer::RunRapidFireShooter(Entity* self) { - /* - const auto targets = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); - */ - const auto targets = self->GetTargetsInPhantom(); if (self->GetBoolean(u"stoppedFlag")) { @@ -433,8 +388,6 @@ void BossSpiderQueenEnemyServer::RunRapidFireShooter(Entity* self) { PlayAnimAndReturnTime(self, spiderSingleShot); - Game::logger->Log("BossSpiderQueenEnemyServer", "Ran RFS"); - self->AddTimer("RFS", GeneralUtils::GenerateRandomNumber<float>(10, 15)); } @@ -556,26 +509,6 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim GameMessages::SendPlayEmbeddedEffectOnAllClientsNearObject(self, u"camshake-bridge", self->GetObjectID(), 100.0f); } else if (timerName == "AdvanceComplete") { - //Reset faction and collision - /*local SBFactionList = self:GetVar("SBFactionList") - local SBCollisionGroup = self:GetVar("SBCollisionGroup") - - for i, fVal in ipairs(SBFactionList) { - if(i == 1) { - //Our first faction - flush and add - self:SetFaction{faction = fVal} - else - //Add - self:ModifyFaction{factionID = fVal, bAddFaction = true} - } - }*/ - - /* - auto SBCollisionGroup = self->GetI32(u"SBCollisionGroup"); - - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SetColGroup", SBCollisionGroup, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); - */ - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SetColGroup", 11, 0, 0, "", UNASSIGNED_SYSTEM_ADDRESS); //Wind up, telegraphing next round @@ -625,7 +558,6 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim //Did we queue a spcial attack? if (self->GetBoolean(u"bSpecialQueued")) { self->SetBoolean(u"bSpecialQueued", false); - //SpiderSkillManager(self, true); } } } @@ -673,17 +605,6 @@ void BossSpiderQueenEnemyServer::OnUpdate(Entity* self) { controllable->SetStatic(true); EntityManager::Instance()->SerializeEntity(self); - - //if (waitForIdle) return; - - ////Play the Spider Boss' mountain idle anim - //PlayAnimAndReturnTime(self, spiderWithdrawIdle); - - ////If there are still baby spiders, don't do anyhting either - //auto spooders = EntityManager::Instance()->GetEntitiesInGroup("BabySpider"); - //if (spooders.size() > 0) return; - //else - // WithdrawSpider(self, false); } //---------------------------------------------- From 152c8ea71218b2d210005684bd45843df71defe5 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 31 Mar 2023 14:50:17 -0700 Subject: [PATCH 152/166] Add npc (#1038) --- vanity/NPC.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/vanity/NPC.xml b/vanity/NPC.xml index 3bb5ae9f..dfe324c3 100644 --- a/vanity/NPC.xml +++ b/vanity/NPC.xml @@ -17,6 +17,18 @@ </locations> </zone> </npc> + <npc name="EmosewaMC - Quickbuilder" lot="6738"> + <equipment>12947, 12949, 12962, 12963</equipment> + <phrases> + <phrase>I hope quickbulds are still working!</phrase> + <phrase>Be careful crossing the gap!</phrase> + </phrases> + <zone id="1800"> + <locations> + <location x="745.756" y="75.262" z="-207.989" rw="0.838565" rx="0.0" ry="0.544801" rz="0.0" /> + </locations> + </zone> + </npc> <npc name="Neal - Paradox Scout" lot="6738"> <equipment>9950, 9944, 14102, 14092</equipment> <phrases> From 49d695a153aeb6537458dd642ca9bde17765612b Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 1 Apr 2023 02:45:29 -0700 Subject: [PATCH 153/166] Remove extra bit in BasicAttackBehavior write (#1039) --- dGame/dBehaviors/BasicAttackBehavior.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dBehaviors/BasicAttackBehavior.cpp b/dGame/dBehaviors/BasicAttackBehavior.cpp index 97068d91..f8693795 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.cpp +++ b/dGame/dBehaviors/BasicAttackBehavior.cpp @@ -147,7 +147,7 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* DoBehaviorCalculation(context, bitStream, branch); const auto endAddress = bitStream->GetWriteOffset(); - const uint16_t allocate = endAddress - startAddress + 1; + const uint16_t allocate = endAddress - startAddress; bitStream->SetWriteOffset(allocatedAddress); bitStream->Write(allocate); From 801ca69778c9a073f70ded93cee13382a2a72e16 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 1 Apr 2023 18:30:08 -0700 Subject: [PATCH 154/166] Fix nameplate command (#1040) --- dGame/dUtilities/SlashCommandHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 7383d51c..6f346d88 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -173,7 +173,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } #endif - if (chatCommand == "togglenameplate" && (Game::config->GetValue("allownameplateoff") == "1" || entity->GetGMLevel() > eGameMasterLevel::DEVELOPER)) { + if (chatCommand == "togglenameplate" && (Game::config->GetValue("allow_nameplate_off") == "1" || entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER)) { auto* character = entity->GetCharacter(); if (character && character->GetBillboardVisible()) { From 54d8c45b52e1506e21ee8bb2825f66b978cbd239 Mon Sep 17 00:00:00 2001 From: David Markowitz <EmosewaMC@gmail.com> Date: Sun, 2 Apr 2023 11:54:34 -0700 Subject: [PATCH 155/166] Don't interrupt players --- dGame/dBehaviors/InterruptBehavior.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dGame/dBehaviors/InterruptBehavior.cpp b/dGame/dBehaviors/InterruptBehavior.cpp index 9035c092..96cba1b1 100644 --- a/dGame/dBehaviors/InterruptBehavior.cpp +++ b/dGame/dBehaviors/InterruptBehavior.cpp @@ -46,6 +46,8 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (target == nullptr) return; + if (target->GetLOT() == 1) return; + auto* skillComponent = target->GetComponent<SkillComponent>(); if (skillComponent == nullptr) return; @@ -71,6 +73,8 @@ void InterruptBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* b if (target == nullptr) return; + if (target->GetLOT() == 1) return; + auto* skillComponent = target->GetComponent<SkillComponent>(); if (skillComponent == nullptr) return; From 595afe42e5a0764672d5473396a48790a0be2201 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Sun, 2 Apr 2023 22:37:24 -0500 Subject: [PATCH 156/166] fix the lookat --- dGame/dBehaviors/ChangeOrientationBehavior.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.cpp b/dGame/dBehaviors/ChangeOrientationBehavior.cpp index a60be62f..d07e7429 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.cpp +++ b/dGame/dBehaviors/ChangeOrientationBehavior.cpp @@ -16,7 +16,7 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS if (self == nullptr || other == nullptr) return; const auto source = self->GetPosition(); - const auto destination = self->GetPosition(); + const auto destination = other->GetPosition(); if (m_OrientCaster) { auto* baseCombatAIComponent = self->GetComponent<BaseCombatAIComponent>(); From a26f29baf696735112fc6b7ac4c7e319d9138d37 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 2 Apr 2023 23:26:44 -0700 Subject: [PATCH 157/166] Fix some models not disassembling into bricks (#1041) --- dGame/dInventory/Item.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index acaecbf7..5795ab12 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -390,19 +390,22 @@ void Item::DisassembleModel() { const auto componentId = table->GetByIDAndType(GetLot(), eReplicaComponentType::RENDER); auto query = CDClientDatabase::CreatePreppedStmt( - "SELECT render_asset FROM RenderComponent WHERE id = ?;"); + "SELECT render_asset, LXFMLFolder FROM RenderComponent WHERE id = ?;"); query.bind(1, (int)componentId); auto result = query.execQuery(); - if (result.eof()) { + if (result.eof() || result.fieldIsNull(0)) { return; } - std::string renderAsset = result.fieldIsNull(0) ? "" : std::string(result.getStringField(0)); - std::vector<std::string> renderAssetSplit = GeneralUtils::SplitString(renderAsset, '\\'); + std::string renderAsset = std::string(result.getStringField(0)); + std::string lxfmlFolderName = std::string(result.getStringField(1)); - std::string lxfmlPath = "BrickModels/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.').at(0) + ".lxfml"; + std::vector<std::string> renderAssetSplit = GeneralUtils::SplitString(renderAsset, '\\'); + if (renderAssetSplit.size() == 0) return; + + std::string lxfmlPath = "BrickModels/" + lxfmlFolderName + "/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.').at(0) + ".lxfml"; auto buffer = Game::assetManager->GetFileAsBuffer(lxfmlPath.c_str()); if (!buffer.m_Success) { From b8251c06b8dbdbc215b86d64c3ac6a8293fdc86f Mon Sep 17 00:00:00 2001 From: David Markowitz <EmosewaMC@gmail.com> Date: Mon, 3 Apr 2023 04:11:02 -0700 Subject: [PATCH 158/166] Fix incorrect SwitchMultiple handling --- dGame/dBehaviors/SwitchMultipleBehavior.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dGame/dBehaviors/SwitchMultipleBehavior.cpp b/dGame/dBehaviors/SwitchMultipleBehavior.cpp index 078464bb..23411429 100644 --- a/dGame/dBehaviors/SwitchMultipleBehavior.cpp +++ b/dGame/dBehaviors/SwitchMultipleBehavior.cpp @@ -22,13 +22,9 @@ void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* for (unsigned int i = 0; i < this->m_behaviors.size(); i++) { const double data = this->m_behaviors.at(i).first; + trigger = i; - if (value <= data) { - - trigger = i; - - break; - } + if (value <= data) break; } auto* behavior = this->m_behaviors.at(trigger).second; From 1fb086ccbdb146caa4423191fc9e1d57dd996684 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Mon, 3 Apr 2023 08:21:23 -0500 Subject: [PATCH 159/166] Fully implement Change orientation fix bug where you would always look at self added to_angle handline --- .../dBehaviors/ChangeOrientationBehavior.cpp | 57 +++++++++---------- dGame/dBehaviors/ChangeOrientationBehavior.h | 24 +++----- 2 files changed, 35 insertions(+), 46 deletions(-) diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.cpp b/dGame/dBehaviors/ChangeOrientationBehavior.cpp index d07e7429..a7dc838f 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.cpp +++ b/dGame/dBehaviors/ChangeOrientationBehavior.cpp @@ -2,43 +2,40 @@ #include "BehaviorBranchContext.h" #include "BehaviorContext.h" #include "EntityManager.h" -#include "BaseCombatAIComponent.h" - -void ChangeOrientationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { -} void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - if (!m_ToTarget) return; // TODO: Add the other arguments to this behavior + Entity* sourceEntity; + if (this->m_orientCaster) sourceEntity = EntityManager::Instance()->GetEntity(context->originator); + else sourceEntity = EntityManager::Instance()->GetEntity(branch.target); + if (!sourceEntity) return; - auto* self = EntityManager::Instance()->GetEntity(context->originator); - auto* other = EntityManager::Instance()->GetEntity(branch.target); - if (self == nullptr || other == nullptr) return; + if (this->m_toTarget) { + Entity* destinationEntity; + if (this->m_orientCaster) destinationEntity = EntityManager::Instance()->GetEntity(branch.target); + else destinationEntity = EntityManager::Instance()->GetEntity(context->originator); + if (!destinationEntity) return; - const auto source = self->GetPosition(); - const auto destination = other->GetPosition(); - - if (m_OrientCaster) { - auto* baseCombatAIComponent = self->GetComponent<BaseCombatAIComponent>(); - - /*if (baseCombatAIComponent != nullptr) - { - baseCombatAIComponent->LookAt(destination); + const auto source = sourceEntity->GetPosition(); + const auto destination = destinationEntity->GetPosition(); + sourceEntity->SetRotation(NiQuaternion::LookAt(source, destination)); + } else if (this->m_toAngle){ + auto baseAngle = NiPoint3(this->m_angle, 0, 0); + if (this->m_relative){ + auto sourceAngle = sourceEntity->GetRotation().GetEulerAngles(); + baseAngle += sourceAngle; } - else*/ - { - self->SetRotation(NiQuaternion::LookAt(source, destination)); - } - - EntityManager::Instance()->SerializeEntity(self); - } else { - other->SetRotation(NiQuaternion::LookAt(destination, source)); - - EntityManager::Instance()->SerializeEntity(other); - } + auto newRotation = NiQuaternion::FromEulerAngles(baseAngle); + sourceEntity->SetRotation(newRotation); + } else return; + EntityManager::Instance()->SerializeEntity(sourceEntity); + return; } void ChangeOrientationBehavior::Load() { - m_OrientCaster = GetBoolean("orient_caster"); - m_ToTarget = GetBoolean("to_target"); + this->m_orientCaster = GetBoolean("orient_caster", true); + this->m_toTarget = GetBoolean("to_target", false); + this->m_toAngle = GetBoolean("to_angle", false); + this->m_angle = GetFloat("angle", 0.0f); + this->m_relative = GetBoolean("relative", false); } diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.h b/dGame/dBehaviors/ChangeOrientationBehavior.h index eb038ffb..46d471ad 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.h +++ b/dGame/dBehaviors/ChangeOrientationBehavior.h @@ -1,25 +1,17 @@ #pragma once #include "Behavior.h" - #include <vector> -class ChangeOrientationBehavior final : public Behavior -{ +class ChangeOrientationBehavior final : public Behavior { public: - bool m_OrientCaster; - bool m_ToTarget; - - /* - * Inherited - */ - - explicit ChangeOrientationBehavior(const uint32_t behaviorId) : Behavior(behaviorId) { - } - - void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; - + explicit ChangeOrientationBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {} void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; - void Load() override; +private: + bool m_orientCaster; + bool m_toTarget; + bool m_toAngle; + float m_angle; + bool m_relative; }; From a5ff93351dea4e19c0c4121db0c532f22719690a Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Mon, 3 Apr 2023 08:25:47 -0500 Subject: [PATCH 160/166] remove empty line remove undeeded header --- dGame/dBehaviors/ChangeOrientationBehavior.cpp | 1 - dGame/dBehaviors/ChangeOrientationBehavior.h | 1 - 2 files changed, 2 deletions(-) diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.cpp b/dGame/dBehaviors/ChangeOrientationBehavior.cpp index a7dc838f..398e9e33 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.cpp +++ b/dGame/dBehaviors/ChangeOrientationBehavior.cpp @@ -9,7 +9,6 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS else sourceEntity = EntityManager::Instance()->GetEntity(branch.target); if (!sourceEntity) return; - if (this->m_toTarget) { Entity* destinationEntity; if (this->m_orientCaster) destinationEntity = EntityManager::Instance()->GetEntity(branch.target); diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.h b/dGame/dBehaviors/ChangeOrientationBehavior.h index 46d471ad..22c92bb8 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.h +++ b/dGame/dBehaviors/ChangeOrientationBehavior.h @@ -1,7 +1,6 @@ #pragma once #include "Behavior.h" -#include <vector> class ChangeOrientationBehavior final : public Behavior { public: From dffcbcd4d4970927a3137dd4ad85c830df9aeb8a Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Mon, 3 Apr 2023 08:29:39 -0500 Subject: [PATCH 161/166] cleanup --- dGame/dBehaviors/ChangeOrientationBehavior.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.cpp b/dGame/dBehaviors/ChangeOrientationBehavior.cpp index 398e9e33..ee9e2009 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.cpp +++ b/dGame/dBehaviors/ChangeOrientationBehavior.cpp @@ -15,17 +15,13 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS else destinationEntity = EntityManager::Instance()->GetEntity(context->originator); if (!destinationEntity) return; - const auto source = sourceEntity->GetPosition(); - const auto destination = destinationEntity->GetPosition(); - sourceEntity->SetRotation(NiQuaternion::LookAt(source, destination)); + sourceEntity->SetRotation( + NiQuaternion::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition()) + ); } else if (this->m_toAngle){ auto baseAngle = NiPoint3(this->m_angle, 0, 0); - if (this->m_relative){ - auto sourceAngle = sourceEntity->GetRotation().GetEulerAngles(); - baseAngle += sourceAngle; - } - auto newRotation = NiQuaternion::FromEulerAngles(baseAngle); - sourceEntity->SetRotation(newRotation); + if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetEulerAngles(); + sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle)); } else return; EntityManager::Instance()->SerializeEntity(sourceEntity); return; From 426a84daf98e2edf4657b8b9c43536a65ff91795 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 3 Apr 2023 09:37:29 -0700 Subject: [PATCH 162/166] Update InterruptBehavior.cpp --- dGame/dBehaviors/InterruptBehavior.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dGame/dBehaviors/InterruptBehavior.cpp b/dGame/dBehaviors/InterruptBehavior.cpp index 96cba1b1..9035c092 100644 --- a/dGame/dBehaviors/InterruptBehavior.cpp +++ b/dGame/dBehaviors/InterruptBehavior.cpp @@ -46,8 +46,6 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (target == nullptr) return; - if (target->GetLOT() == 1) return; - auto* skillComponent = target->GetComponent<SkillComponent>(); if (skillComponent == nullptr) return; @@ -73,8 +71,6 @@ void InterruptBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* b if (target == nullptr) return; - if (target->GetLOT() == 1) return; - auto* skillComponent = target->GetComponent<SkillComponent>(); if (skillComponent == nullptr) return; From 930735860b05a23bee25eb7f78946546359ad7be Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Mon, 3 Apr 2023 13:10:51 -0500 Subject: [PATCH 163/166] use z axis --- dGame/dBehaviors/ChangeOrientationBehavior.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.cpp b/dGame/dBehaviors/ChangeOrientationBehavior.cpp index ee9e2009..36a2e6a8 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.cpp +++ b/dGame/dBehaviors/ChangeOrientationBehavior.cpp @@ -19,8 +19,8 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS NiQuaternion::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition()) ); } else if (this->m_toAngle){ - auto baseAngle = NiPoint3(this->m_angle, 0, 0); - if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetEulerAngles(); + auto baseAngle = NiPoint3(0, 0, this->m_angle); + if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector(); sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle)); } else return; EntityManager::Instance()->SerializeEntity(sourceEntity); From 541250176c8c5d203480e53de4e58ea598740656 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 5 Apr 2023 06:57:47 -0700 Subject: [PATCH 164/166] Resolve many issues with invisible enemies and End Behavior nodes not firing (#1044) * Finall fix invisible enemies * Add garbage collection * Add comment * Add constexpr for lagFrames --- dGame/dBehaviors/AirMovementBehavior.cpp | 3 ++- dGame/dBehaviors/AirMovementBehavior.h | 10 +++------- dGame/dBehaviors/AttackDelayBehavior.cpp | 2 +- dGame/dBehaviors/BehaviorContext.cpp | 20 +++++++++++++++++++- dGame/dBehaviors/BehaviorContext.h | 4 +++- dGame/dBehaviors/ChargeUpBehavior.cpp | 3 ++- dGame/dBehaviors/ChargeUpBehavior.h | 12 ++++-------- dGame/dBehaviors/ForceMovementBehavior.cpp | 2 +- dGame/dComponents/SkillComponent.cpp | 18 +++++++++++++++--- vanity/NPC.xml | 1 + 10 files changed, 51 insertions(+), 24 deletions(-) diff --git a/dGame/dBehaviors/AirMovementBehavior.cpp b/dGame/dBehaviors/AirMovementBehavior.cpp index 932297b9..dbfde465 100644 --- a/dGame/dBehaviors/AirMovementBehavior.cpp +++ b/dGame/dBehaviors/AirMovementBehavior.cpp @@ -13,7 +13,7 @@ void AirMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi return; } - context->RegisterSyncBehavior(handle, this, branch); + context->RegisterSyncBehavior(handle, this, branch, this->m_Timeout); } void AirMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { @@ -47,4 +47,5 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitS } void AirMovementBehavior::Load() { + this->m_Timeout = (GetFloat("timeout_ms") / 1000.0f); } diff --git a/dGame/dBehaviors/AirMovementBehavior.h b/dGame/dBehaviors/AirMovementBehavior.h index 89dc1e05..9d51ef03 100644 --- a/dGame/dBehaviors/AirMovementBehavior.h +++ b/dGame/dBehaviors/AirMovementBehavior.h @@ -4,13 +4,7 @@ class AirMovementBehavior final : public Behavior { public: - - /* - * Inherited - */ - - explicit AirMovementBehavior(const uint32_t behavior_id) : Behavior(behavior_id) { - } + explicit AirMovementBehavior(const uint32_t behavior_id) : Behavior(behavior_id) {} void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; @@ -19,4 +13,6 @@ public: void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; void Load() override; +private: + float m_Timeout; }; diff --git a/dGame/dBehaviors/AttackDelayBehavior.cpp b/dGame/dBehaviors/AttackDelayBehavior.cpp index ccea5fd9..af33aadd 100644 --- a/dGame/dBehaviors/AttackDelayBehavior.cpp +++ b/dGame/dBehaviors/AttackDelayBehavior.cpp @@ -13,7 +13,7 @@ void AttackDelayBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi }; for (auto i = 0u; i < this->m_numIntervals; ++i) { - context->RegisterSyncBehavior(handle, this, branch, m_ignoreInterrupts); + context->RegisterSyncBehavior(handle, this, branch, m_ignoreInterrupts, this->m_delay * i); } } diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index 397e0c72..d0cb68e4 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -47,7 +47,7 @@ uint32_t BehaviorContext::GetUniqueSkillId() const { } -void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, bool ignoreInterrupts) { +void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, const float duration, bool ignoreInterrupts) { auto entry = BehaviorSyncEntry(); entry.handle = syncId; @@ -55,6 +55,9 @@ void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* beha entry.branchContext = branchContext; entry.branchContext.isSync = true; entry.ignoreInterrupts = ignoreInterrupts; + // Add 10 seconds + duration time to account for lag and give clients time to send their syncs to the server. + constexpr float lagTime = 10.0f; + entry.time = lagTime + duration; this->syncEntries.push_back(entry); } @@ -183,6 +186,21 @@ void BehaviorContext::SyncCalculation(const uint32_t syncId, const float time, B this->syncEntries.push_back(entry); } +void BehaviorContext::UpdatePlayerSyncs(float deltaTime) { + uint32_t i = 0; + while (i < this->syncEntries.size()) { + auto& entry = this->syncEntries.at(i); + + entry.time -= deltaTime; + + if (entry.time >= 0.0f) { + i++; + continue; + } + this->syncEntries.erase(this->syncEntries.begin() + i); + } +} + void BehaviorContext::InvokeEnd(const uint32_t id) { std::vector<BehaviorEndEntry> entries; diff --git a/dGame/dBehaviors/BehaviorContext.h b/dGame/dBehaviors/BehaviorContext.h index dbba4d91..117f328d 100644 --- a/dGame/dBehaviors/BehaviorContext.h +++ b/dGame/dBehaviors/BehaviorContext.h @@ -80,7 +80,9 @@ struct BehaviorContext uint32_t GetUniqueSkillId() const; - void RegisterSyncBehavior(uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, bool ignoreInterrupts = false); + void UpdatePlayerSyncs(float deltaTime); + + void RegisterSyncBehavior(uint32_t syncId, Behavior* behavior, const BehaviorBranchContext& branchContext, const float duration, bool ignoreInterrupts = false); void RegisterTimerBehavior(Behavior* behavior, const BehaviorBranchContext& branchContext, LWOOBJID second = LWOOBJID_EMPTY); diff --git a/dGame/dBehaviors/ChargeUpBehavior.cpp b/dGame/dBehaviors/ChargeUpBehavior.cpp index 1b9ba433..4c7c3dac 100644 --- a/dGame/dBehaviors/ChargeUpBehavior.cpp +++ b/dGame/dBehaviors/ChargeUpBehavior.cpp @@ -12,7 +12,7 @@ void ChargeUpBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitSt return; }; - context->RegisterSyncBehavior(handle, this, branch); + context->RegisterSyncBehavior(handle, this, branch, this->m_MaxDuration); } void ChargeUpBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { @@ -24,4 +24,5 @@ void ChargeUpBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStre void ChargeUpBehavior::Load() { this->m_action = GetAction("action"); + this->m_MaxDuration = GetFloat("max_duration"); } diff --git a/dGame/dBehaviors/ChargeUpBehavior.h b/dGame/dBehaviors/ChargeUpBehavior.h index d753895e..ceb40f6c 100644 --- a/dGame/dBehaviors/ChargeUpBehavior.h +++ b/dGame/dBehaviors/ChargeUpBehavior.h @@ -4,14 +4,7 @@ class ChargeUpBehavior final : public Behavior { public: - Behavior* m_action; - - /* - * Inherited - */ - - explicit ChargeUpBehavior(const uint32_t behaviorId) : Behavior(behaviorId) { - } + explicit ChargeUpBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {} void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; @@ -20,4 +13,7 @@ public: void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; void Load() override; +private: + Behavior* m_action; + float m_MaxDuration; }; diff --git a/dGame/dBehaviors/ForceMovementBehavior.cpp b/dGame/dBehaviors/ForceMovementBehavior.cpp index e095447c..52359cf7 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.cpp +++ b/dGame/dBehaviors/ForceMovementBehavior.cpp @@ -16,7 +16,7 @@ void ForceMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* Game::logger->Log("ForceMovementBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); return; } - context->RegisterSyncBehavior(handle, this, branch); + context->RegisterSyncBehavior(handle, this, branch, this->m_Duration); } void ForceMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 23ef1bee..ae0e82f0 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -134,6 +134,10 @@ void SkillComponent::Update(const float deltaTime) { CalculateUpdate(deltaTime); } + if (m_Parent->IsPlayer()) { + for (const auto& pair : this->m_managedBehaviors) pair.second->UpdatePlayerSyncs(deltaTime); + } + std::map<uint32_t, BehaviorContext*> keep{}; for (const auto& pair : this->m_managedBehaviors) { @@ -192,7 +196,15 @@ void SkillComponent::Interrupt() { auto* combat = m_Parent->GetComponent<BaseCombatAIComponent>(); if (combat != nullptr && combat->GetStunImmune()) return; - for (const auto& behavior : this->m_managedBehaviors) behavior.second->Interrupt(); + for (const auto& behavior : this->m_managedBehaviors) { + for (const auto& behaviorEndEntry : behavior.second->endEntries) { + behaviorEndEntry.behavior->End(behavior.second, behaviorEndEntry.branchContext, behaviorEndEntry.second); + } + behavior.second->endEntries.clear(); + if (m_Parent->IsPlayer()) continue; + behavior.second->Interrupt(); + } + } void SkillComponent::RegisterCalculatedProjectile(const LWOOBJID projectileId, BehaviorContext* context, const BehaviorBranchContext& branch, const LOT lot, const float maxTime, @@ -215,7 +227,7 @@ void SkillComponent::RegisterCalculatedProjectile(const LWOOBJID projectileId, B this->m_managedProjectiles.push_back(entry); } -bool SkillComponent::CastSkill(const uint32_t skillId, LWOOBJID target, const LWOOBJID optionalOriginatorID){ +bool SkillComponent::CastSkill(const uint32_t skillId, LWOOBJID target, const LWOOBJID optionalOriginatorID) { uint32_t behaviorId = -1; // try to find it via the cache const auto& pair = m_skillBehaviorCache.find(skillId); @@ -463,7 +475,7 @@ void SkillComponent::HandleUnCast(const uint32_t behaviorId, const LWOOBJID targ delete context; } -SkillComponent::SkillComponent(Entity* parent) : Component(parent) { +SkillComponent::SkillComponent(Entity* parent): Component(parent) { this->m_skillUid = 0; } diff --git a/vanity/NPC.xml b/vanity/NPC.xml index dfe324c3..2311ab46 100644 --- a/vanity/NPC.xml +++ b/vanity/NPC.xml @@ -22,6 +22,7 @@ <phrases> <phrase>I hope quickbulds are still working!</phrase> <phrase>Be careful crossing the gap!</phrase> + <phrase>Have The Maelstrom stopped going invisible?</phrase> </phrases> <zone id="1800"> <locations> From 33f9e9c8cb687cb5a278c1f29d2572fe908689a0 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 8 Apr 2023 13:45:45 -0700 Subject: [PATCH 165/166] Allow case insensitive commands (#1047) --- dCommon/GeneralUtils.cpp | 2 +- dCommon/GeneralUtils.h | 2 +- dGame/dUtilities/SlashCommandHandler.cpp | 48 +++++++----------------- 3 files changed, 16 insertions(+), 36 deletions(-) diff --git a/dCommon/GeneralUtils.cpp b/dCommon/GeneralUtils.cpp index df641a1b..99ca687a 100644 --- a/dCommon/GeneralUtils.cpp +++ b/dCommon/GeneralUtils.cpp @@ -241,7 +241,7 @@ std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t d return vector; } -std::vector<std::u16string> GeneralUtils::SplitString(std::u16string& str, char16_t delimiter) { +std::vector<std::u16string> GeneralUtils::SplitString(const std::u16string& str, char16_t delimiter) { std::vector<std::u16string> vector = std::vector<std::u16string>(); std::u16string current; diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 25aac783..0555a45e 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -139,7 +139,7 @@ namespace GeneralUtils { std::vector<std::wstring> SplitString(std::wstring& str, wchar_t delimiter); - std::vector<std::u16string> SplitString(std::u16string& str, char16_t delimiter); + std::vector<std::u16string> SplitString(const std::u16string& str, char16_t delimiter); std::vector<std::string> SplitString(const std::string& str, char delimiter); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 6f346d88..8693abe9 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -82,44 +82,24 @@ #include "CDZoneTableTable.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { + auto commandCopy = command; + // Sanity check that a command was given + if (command.empty() || command.front() != u'/') return; + commandCopy.erase(commandCopy.begin()); + + // Split the command by spaces std::string chatCommand; std::vector<std::string> args; + auto wideCommand = GeneralUtils::SplitString(commandCopy, u' '); + if (wideCommand.empty()) return; - uint32_t breakIndex = 0; - for (uint32_t i = 1; i < command.size(); ++i) { - if (command[i] == L' ') { - breakIndex = i; - break; - } + // Convert the command to lowercase + chatCommand = GeneralUtils::UTF16ToWTF8(wideCommand.front()); + std::transform(chatCommand.begin(), chatCommand.end(), chatCommand.begin(), ::tolower); + wideCommand.erase(wideCommand.begin()); - chatCommand.push_back(static_cast<unsigned char>(command[i])); - breakIndex++; - } - - uint32_t index = ++breakIndex; - while (true) { - std::string arg; - - while (index < command.size()) { - if (command[index] == L' ') { - args.push_back(arg); - arg = ""; - index++; - continue; - } - - arg.push_back(static_cast<char>(command[index])); - index++; - } - - if (arg != "") { - args.push_back(arg); - } - - break; - } - - //Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"", GeneralUtils::UTF16ToWTF8(command).c_str()); + // Convert the arguements to not u16strings + for (auto wideArg : wideCommand) args.push_back(GeneralUtils::UTF16ToWTF8(wideArg)); User* user = UserManager::Instance()->GetUser(sysAddr); if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > eGameMasterLevel::CIVILIAN) { From 2cf92a16d2d4c6b9713f7d36b3d725c2cf2c5107 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell <aronwk.aaron@gmail.com> Date: Sun, 9 Apr 2023 10:17:05 -0500 Subject: [PATCH 166/166] Add scripts for a few wild creatures (#1051) ignore frog script --- dScripts/CppScripts.cpp | 17 +++++++++++++++++ dScripts/ai/WILD/CMakeLists.txt | 6 +++++- dScripts/ai/WILD/WildAmbientCrab.cpp | 27 +++++++++++++++++++++++++++ dScripts/ai/WILD/WildAmbientCrab.h | 9 +++++++++ dScripts/ai/WILD/WildAndScared.cpp | 6 ++++++ dScripts/ai/WILD/WildAndScared.h | 7 +++++++ dScripts/ai/WILD/WildGfGlowbug.cpp | 28 ++++++++++++++++++++++++++++ dScripts/ai/WILD/WildGfGlowbug.h | 9 +++++++++ dScripts/ai/WILD/WildPants.cpp | 10 ++++++++++ dScripts/ai/WILD/WildPants.h | 9 +++++++++ 10 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 dScripts/ai/WILD/WildAmbientCrab.cpp create mode 100644 dScripts/ai/WILD/WildAmbientCrab.h create mode 100644 dScripts/ai/WILD/WildAndScared.cpp create mode 100644 dScripts/ai/WILD/WildAndScared.h create mode 100644 dScripts/ai/WILD/WildGfGlowbug.cpp create mode 100644 dScripts/ai/WILD/WildGfGlowbug.h create mode 100644 dScripts/ai/WILD/WildPants.cpp create mode 100644 dScripts/ai/WILD/WildPants.h diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 24b30dee..7ed7373f 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -295,6 +295,12 @@ // WBL scripts #include "WblGenericZone.h" +// Wild Scripts +#include "WildAndScared.h" +#include "WildGfGlowbug.h" +#include "WildAmbientCrab.h" +#include "WildPants.h" + //Big bad global bc this is a namespace and not a class: InvalidScript* invalidToReturn = new InvalidScript(); std::map<std::string, CppScripts::Script*> m_Scripts; @@ -860,11 +866,22 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr else if (scriptName == "scripts\\zone\\LUPs\\WBL_generic_zone.lua") script = new WblGenericZone(); + // Wild + if (scriptName == "scripts\\ai\\WILD\\L_WILD_GF_RAT.lua" || scriptName == "scripts\\ai\\WILD\\L_WILD_GF_SNAIL.lua") + script = new WildAndScared(); + else if (scriptName == "scripts\\ai\\WILD\\L_WILD_GF_GLOWBUG.lua") + script = new WildGfGlowbug(); + else if (scriptName == "scripts\\ai\\WILD\\L_WILD_AMBIENT_CRAB.lua") + script = new WildAmbientCrab(); + else if (scriptName == "scripts\\ai\\WILD\\L_WILD_PANTS.lua") + script = new WildPants(); + // handle invalid script reporting if the path is greater than zero and it's not an ignored script // information not really needed for sys admins but is for developers else if (script == invalidToReturn) { if ((scriptName.length() > 0) && !((scriptName == "scripts\\02_server\\Enemy\\General\\L_SUSPEND_LUA_AI.lua") || (scriptName == "scripts\\02_server\\Enemy\\General\\L_BASE_ENEMY_SPIDERLING.lua") || + (scriptName == "scripts\\ai\\WILD\\L_WILD_GF_FROG.lua") || (scriptName == "scripts\\empty.lua") )) Game::logger->LogDebug("CppScripts", "LOT %i attempted to load CppScript for '%s', but returned InvalidScript.", parent->GetLOT(), scriptName.c_str()); } diff --git a/dScripts/ai/WILD/CMakeLists.txt b/dScripts/ai/WILD/CMakeLists.txt index 57470f72..d3e499db 100644 --- a/dScripts/ai/WILD/CMakeLists.txt +++ b/dScripts/ai/WILD/CMakeLists.txt @@ -1,4 +1,8 @@ -set(DSCRIPTS_SOURCES_AI_WILD +set(DSCRIPTS_SOURCES_AI_WILD "AllCrateChicken.cpp" "WildAmbients.cpp" + "WildAmbientCrab.cpp" + "WildAndScared.cpp" + "WildGfGlowbug.cpp" + "WildPants.cpp" PARENT_SCOPE) diff --git a/dScripts/ai/WILD/WildAmbientCrab.cpp b/dScripts/ai/WILD/WildAmbientCrab.cpp new file mode 100644 index 00000000..7b5b3d45 --- /dev/null +++ b/dScripts/ai/WILD/WildAmbientCrab.cpp @@ -0,0 +1,27 @@ +#include "WildAmbientCrab.h" +#include "GameMessages.h" + +void WildAmbientCrab::OnStartup(Entity* self){ + self->SetVar(u"flipped", true); + GameMessages::SendPlayAnimation(self, u"idle"); +} + +void WildAmbientCrab::OnUse(Entity* self, Entity* user) { + auto flipped = self->GetVar<bool>(u"flipped"); + if (flipped) { + self->AddTimer("Flipping", 0.6f); + GameMessages::SendPlayAnimation(self, u"flip-over"); + self->SetVar(u"flipped", false); + } else if (!flipped) { + self->AddTimer("Flipback", 0.8f); + GameMessages::SendPlayAnimation(self, u"flip-back"); + self->SetVar(u"flipped", true); + } +} + +void WildAmbientCrab::OnTimerDone(Entity* self, std::string timerName) { + if (timerName == "Flipping") GameMessages::SendPlayAnimation(self, u"over-idle"); + else if (timerName == "Flipback") GameMessages::SendPlayAnimation(self, u"idle"); +} + + diff --git a/dScripts/ai/WILD/WildAmbientCrab.h b/dScripts/ai/WILD/WildAmbientCrab.h new file mode 100644 index 00000000..0e1b3877 --- /dev/null +++ b/dScripts/ai/WILD/WildAmbientCrab.h @@ -0,0 +1,9 @@ +#pragma once +#include "CppScripts.h" + +class WildAmbientCrab final : public CppScripts::Script { +public: + void OnStartup(Entity* self) override; + void OnTimerDone(Entity* self, std::string timerName) override; + void OnUse(Entity* self, Entity* user) override; +}; diff --git a/dScripts/ai/WILD/WildAndScared.cpp b/dScripts/ai/WILD/WildAndScared.cpp new file mode 100644 index 00000000..d2e89c40 --- /dev/null +++ b/dScripts/ai/WILD/WildAndScared.cpp @@ -0,0 +1,6 @@ +#include "WildAndScared.h" +#include "GameMessages.h" + +void WildAndScared::OnUse(Entity* self, Entity* user) { + GameMessages::SendPlayAnimation(self, u"scared"); +} diff --git a/dScripts/ai/WILD/WildAndScared.h b/dScripts/ai/WILD/WildAndScared.h new file mode 100644 index 00000000..c94fb06d --- /dev/null +++ b/dScripts/ai/WILD/WildAndScared.h @@ -0,0 +1,7 @@ +#pragma once +#include "CppScripts.h" + +class WildAndScared : public CppScripts::Script { +public: + void OnUse(Entity* self, Entity* user) override; +}; diff --git a/dScripts/ai/WILD/WildGfGlowbug.cpp b/dScripts/ai/WILD/WildGfGlowbug.cpp new file mode 100644 index 00000000..d834f5b5 --- /dev/null +++ b/dScripts/ai/WILD/WildGfGlowbug.cpp @@ -0,0 +1,28 @@ +#include "WildGfGlowbug.h" +#include "GameMessages.h" + +void WildGfGlowbug::OnStartup(Entity* self){ + self->SetVar(u"switch", false); +} + +void WildGfGlowbug::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { + if (args == "physicsReady") { + auto switchState = self->GetVar<bool>(u"switch"); + if (!switchState) { + GameMessages::SendStopFXEffect(self, true, "glowlight"); + } else if (switchState) { + GameMessages::SendPlayFXEffect(self, -1, u"light", "glowlight", LWOOBJID_EMPTY); + } + } +} + +void WildGfGlowbug::OnUse(Entity* self, Entity* user) { + auto switchState = self->GetVar<bool>(u"switch"); + if (switchState) { + GameMessages::SendStopFXEffect(self, true, "glowlight"); + self->SetVar(u"switch", false); + } else if (!switchState) { + GameMessages::SendPlayFXEffect(self, -1, u"light", "glowlight", LWOOBJID_EMPTY); + self->SetVar(u"switch", true); + } +} diff --git a/dScripts/ai/WILD/WildGfGlowbug.h b/dScripts/ai/WILD/WildGfGlowbug.h new file mode 100644 index 00000000..03242372 --- /dev/null +++ b/dScripts/ai/WILD/WildGfGlowbug.h @@ -0,0 +1,9 @@ +#pragma once +#include "CppScripts.h" + +class WildGfGlowbug : public CppScripts::Script { +public: + void OnStartup(Entity* self) override; + void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override; + void OnUse(Entity* self, Entity* user) override; +}; diff --git a/dScripts/ai/WILD/WildPants.cpp b/dScripts/ai/WILD/WildPants.cpp new file mode 100644 index 00000000..7c5e1cd2 --- /dev/null +++ b/dScripts/ai/WILD/WildPants.cpp @@ -0,0 +1,10 @@ +#include "WildPants.h" +#include "GameMessages.h" + +void WildPants::OnStartup(Entity* self) { + self->SetProximityRadius(5, "scardyPants"); +} + +void WildPants::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { + if (status == "ENTER") GameMessages::SendPlayAnimation(self, u"scared"); +} diff --git a/dScripts/ai/WILD/WildPants.h b/dScripts/ai/WILD/WildPants.h new file mode 100644 index 00000000..c6968045 --- /dev/null +++ b/dScripts/ai/WILD/WildPants.h @@ -0,0 +1,9 @@ +#pragma once +#include "CppScripts.h" + +class WildPants : public CppScripts::Script +{ +public: + void OnStartup(Entity* self) override; + void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override; +};