Merge branch 'main' into moreMovementAi

This commit is contained in:
David Markowitz 2024-03-07 00:40:26 -08:00
commit 02de7ef28a
143 changed files with 1769 additions and 1288 deletions

View File

@ -4,6 +4,8 @@ include(CTest)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CXX_STANDARD_REQUIRED ON) set(CXX_STANDARD_REQUIRED ON)
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW) # Set CMAKE visibility policy to NEW on project and subprojects
set(CMAKE_CXX_VISIBILITY_PRESET hidden) # Set C++ symbol visibility to default to hidden
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# Read variables from file # Read variables from file
@ -77,6 +79,7 @@ endif()
# Our output dir # Our output dir
set(CMAKE_BINARY_DIR ${PROJECT_BINARY_DIR}) set(CMAKE_BINARY_DIR ${PROJECT_BINARY_DIR})
#set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) # unfortunately, forces all libraries to be built in series, which will slow down the build process
# TODO make this not have to override the build type directories # TODO make this not have to override the build type directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR})
@ -90,6 +93,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
find_package(MariaDB)
# Create a /resServer directory # Create a /resServer directory
make_directory(${CMAKE_BINARY_DIR}/resServer) make_directory(${CMAKE_BINARY_DIR}/resServer)
@ -179,7 +184,7 @@ file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip DESTINATION ${PRO
file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip) file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip)
# Copy vanity files on first build # Copy vanity files on first build
set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "root.xml" "dev-tribute.xml" "atm.xml") set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "root.xml" "dev-tribute.xml" "atm.xml" "demo.xml")
foreach(file ${VANITY_FILES}) foreach(file ${VANITY_FILES})
configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY) configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY)
@ -202,39 +207,19 @@ foreach(file ${SQL_FILES})
configure_file(${CMAKE_SOURCE_DIR}/migrations/cdserver/${file} ${PROJECT_BINARY_DIR}/migrations/cdserver/${file}) configure_file(${CMAKE_SOURCE_DIR}/migrations/cdserver/${file} ${PROJECT_BINARY_DIR}/migrations/cdserver/${file})
endforeach() endforeach()
# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
if (APPLE)
include_directories("/usr/local/include/")
endif()
# Load all of our third party directories
add_subdirectory(thirdparty)
# Create our list of include directories # Create our list of include directories
set(INCLUDED_DIRECTORIES set(INCLUDED_DIRECTORIES
"dCommon"
"dCommon/dClient"
"dCommon/dEnums"
"dChatFilter"
"dGame"
"dGame/dBehaviors"
"dGame/dComponents"
"dGame/dGameMessages"
"dGame/dInventory"
"dGame/dMission"
"dGame/dEntity"
"dGame/dPropertyBehaviors"
"dGame/dPropertyBehaviors/ControlBehaviorMessages"
"dGame/dUtilities"
"dPhysics" "dPhysics"
"dNavigation" "dNavigation"
"dNavigation/dTerrain"
"dZoneManager"
"dDatabase"
"dDatabase/CDClientDatabase"
"dDatabase/CDClientDatabase/CDClientTables"
"dDatabase/GameDatabase"
"dDatabase/GameDatabase/ITables"
"dDatabase/GameDatabase/MySQL"
"dDatabase/GameDatabase/MySQL/Tables"
"dNet" "dNet"
@ -254,6 +239,7 @@ set(INCLUDED_DIRECTORIES
) )
# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux) # Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
# TODO: Should probably not do this.
if(APPLE) if(APPLE)
include_directories("/usr/local/include/") include_directories("/usr/local/include/")
endif() endif()
@ -263,30 +249,10 @@ foreach(dir ${INCLUDED_DIRECTORIES})
include_directories(${PROJECT_SOURCE_DIR}/${dir}) include_directories(${PROJECT_SOURCE_DIR}/${dir})
endforeach() endforeach()
if(NOT WIN32)
include_directories("${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include/bcrypt")
endif()
include_directories("${PROJECT_SOURCE_DIR}/thirdparty/libbcrypt/include")
# Add linking directories: # Add linking directories:
link_directories(${PROJECT_BINARY_DIR})
# Load all of our third party directories
add_subdirectory(thirdparty)
if (UNIX) if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif() endif()
# Glob together all headers that need to be precompiled
file(
GLOB HEADERS_DDATABASE
LIST_DIRECTORIES false
${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/*.h
${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables/*.h
${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables/*.h
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h
)
file( file(
GLOB HEADERS_DZONEMANAGER GLOB HEADERS_DZONEMANAGER
LIST_DIRECTORIES false LIST_DIRECTORIES false
@ -321,7 +287,7 @@ add_subdirectory(dPhysics)
add_subdirectory(dServer) add_subdirectory(dServer)
# Create a list of common libraries shared between all binaries # Create a list of common libraries shared between all binaries
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum" "MD5") set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "MariaDB::ConnCpp" "magic_enum")
# Add platform specific common libraries # Add platform specific common libraries
if(UNIX) if(UNIX)
@ -343,12 +309,6 @@ target_precompile_headers(
${HEADERS_DZONEMANAGER} ${HEADERS_DZONEMANAGER}
) )
# Need to specify to use the CXX compiler language here or else we get errors including <string>.
target_precompile_headers(
dDatabase PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE}>"
)
target_precompile_headers( target_precompile_headers(
dCommon PRIVATE dCommon PRIVATE
${HEADERS_DCOMMON} ${HEADERS_DCOMMON}

View File

@ -23,8 +23,7 @@ RUN --mount=type=cache,id=build-apt-cache,target=/var/cache/apt \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
# Grab libraries and load them # Grab libraries and load them
COPY --from=build /app/build/mariadbcpp/src/mariadb_connector_cpp-build/libmariadbcpp.so /usr/local/lib/ COPY --from=build /app/build/mariadbcpp/libmariadbcpp.so /usr/local/lib/
COPY --from=build /app/build/mariadbcpp/src/mariadb_connector_cpp-build/libmariadb/libmariadb/libmariadb.so.3 /usr/local/lib
RUN ldconfig RUN ldconfig
# Server bins # Server bins

View File

@ -0,0 +1,17 @@
include(FetchContent)
message(STATUS "Fetching gtest...")
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(GoogleTest)
message(STATUS "gtest fetched and is now ready.")
set(GoogleTest_FOUND TRUE)

View File

@ -23,14 +23,14 @@ if(WIN32 AND NOT MARIADB_BUILD_SOURCE)
set(MARIADB_CONNECTOR_CPP_MSI "mariadb-connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}-win64.msi") set(MARIADB_CONNECTOR_CPP_MSI "mariadb-connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}-win64.msi")
if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" ) if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" )
message("Downloading mariadb connector/c") message(STATUS "Downloading mariadb connector/c")
file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_C_BUCKET}/Connectors/c/connector-c-${MARIADB_CONNECTOR_C_VERSION}/${MARIADB_CONNECTOR_C_MSI} file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_C_BUCKET}/Connectors/c/connector-c-${MARIADB_CONNECTOR_C_VERSION}/${MARIADB_CONNECTOR_C_MSI}
"${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}"
EXPECTED_HASH MD5=${MARIADB_CONNECTOR_C_MD5}) EXPECTED_HASH MD5=${MARIADB_CONNECTOR_C_MD5})
endif() endif()
if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" ) if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" )
message("Downloading mariadb connector/c++") message(STATUS "Downloading mariadb connector/c++")
file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_CPP_BUCKET}/Connectors/cpp/connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}/${MARIADB_CONNECTOR_CPP_MSI} file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_CPP_BUCKET}/Connectors/cpp/connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}/${MARIADB_CONNECTOR_CPP_MSI}
"${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}"
EXPECTED_HASH MD5=${MARIADB_CONNECTOR_CPP_MD5}) EXPECTED_HASH MD5=${MARIADB_CONNECTOR_CPP_MD5})
@ -43,27 +43,28 @@ if(WIN32 AND NOT MARIADB_BUILD_SOURCE)
file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" MSI_DIR) file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" MSI_DIR)
execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR})
endif() endif()
set(MARIADBC_SHARED_LIBRARY_LOCATION "${MARIADB_C_CONNECTOR_DIR}/lib/libmariadb.dll")
if(NOT EXISTS "${MARIADB_CPP_CONNECTOR_DIR}") if(NOT EXISTS "${MARIADB_CPP_CONNECTOR_DIR}")
file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" MSI_DIR) file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" MSI_DIR)
execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR})
endif() endif()
set(MARIADB_SHARED_LIBRARY_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll") set(MARIADBCPP_SHARED_LIBRARY_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll")
set(MARIADB_IMPLIB_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.lib") set(MARIADB_IMPLIB_LOCATION "${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.lib")
set(MARIADB_INCLUDE_DIR "${MARIADB_CPP_CONNECTOR_DIR}/include/mariadb") set(MARIADB_INCLUDE_DIR "${MARIADB_CPP_CONNECTOR_DIR}/include/mariadb")
add_custom_target(mariadb_connector_cpp) add_custom_target(mariadb_connector_cpp)
add_custom_command(TARGET mariadb_connector_cpp POST_BUILD add_custom_command(TARGET mariadb_connector_cpp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${MARIADB_CPP_CONNECTOR_DIR}/mariadbcpp.dll" "${MARIADBCPP_SHARED_LIBRARY_LOCATION}"
"${MARIADB_C_CONNECTOR_DIR}/lib/libmariadb.dll" "${MARIADBC_SHARED_LIBRARY_LOCATION}"
"${PROJECT_BINARY_DIR}") "${PROJECT_BINARY_DIR}")
# MariaDB uses plugins that the database needs to load, the prebuilt binaries by default will try to find the libraries in system directories, # MariaDB uses plugins that the database needs to load, the prebuilt binaries by default will try to find the libraries in system directories,
# so set this define and the servers will set the MARIADB_PLUGIN_DIR environment variable to the appropriate directory. # so set this define and the servers will set the MARIADB_PLUGIN_DIR environment variable to the appropriate directory.
# Plugin directory is determined at dll load time (this will happen before main()) so we need to delay the dll load so that we can set the environment variable # Plugin directory is determined at dll load time (this will happen before main()) so we need to delay the dll load so that we can set the environment variable
add_link_options(/DELAYLOAD:${MARIADB_SHARED_LIBRARY_LOCATION}) add_link_options(/DELAYLOAD:${MARIADBCPP_SHARED_LIBRARY_LOCATION})
add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${MARIADB_CPP_CONNECTOR_DIR}/plugin") add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${MARIADB_CPP_CONNECTOR_DIR}/plugin")
else() # Build from source else() # Build from source
@ -85,77 +86,61 @@ else() # Build from source
-DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0) -DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0)
endif() endif()
set(MARIADBCPP_INSTALL_DIR ${PROJECT_BINARY_DIR}/prefix)
set(MARIADBCPP_LIBRARY_DIR ${PROJECT_BINARY_DIR}/mariadbcpp)
set(MARIADBCPP_PLUGIN_DIR ${MARIADBCPP_LIBRARY_DIR}/plugin)
set(MARIADBCPP_SOURCE_DIR ${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp)
set(MARIADB_INCLUDE_DIR "${MARIADBCPP_SOURCE_DIR}/include")
ExternalProject_Add(mariadb_connector_cpp ExternalProject_Add(mariadb_connector_cpp
SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp PREFIX "${PROJECT_BINARY_DIR}/thirdparty/mariadb-connector-cpp"
CMAKE_ARGS -Wno-dev SOURCE_DIR ${MARIADBCPP_SOURCE_DIR}
-DCMAKE_BUILD_RPATH_USE_ORIGIN=${CMAKE_BUILD_RPATH_USE_ORIGIN} INSTALL_DIR ${MARIADBCPP_INSTALL_DIR}
-DCMAKE_INSTALL_PREFIX=./mariadbcpp # Points the connector to the correct plugin directory CMAKE_ARGS -Wno-dev
-DINSTALL_PLUGINDIR=plugin -DWITH_UNIT_TESTS=OFF
${MARIADB_EXTRA_CMAKE_ARGS} -DMARIADB_LINK_DYNAMIC=OFF
PREFIX "${PROJECT_BINARY_DIR}/mariadbcpp" -DCMAKE_BUILD_RPATH_USE_ORIGIN=${CMAKE_BUILD_RPATH_USE_ORIGIN}
BUILD_COMMAND cmake --build . --config RelWithDebInfo -j${MARIADB_CONNECTOR_COMPILE_JOBS} -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
INSTALL_COMMAND "") -DINSTALL_LIBDIR=${MARIADBCPP_LIBRARY_DIR}
-DINSTALL_PLUGINDIR=${MARIADBCPP_PLUGIN_DIR}
ExternalProject_Get_Property(mariadb_connector_cpp BINARY_DIR) ${MARIADB_EXTRA_CMAKE_ARGS}
BUILD_ALWAYS true
)
if(WIN32) if(WIN32)
set(MARIADB_SHARED_LIBRARY_NAME mariadbcpp.dll) set(MARIADB_SHARED_LIBRARY_NAME mariadbcpp.dll)
set(MARIADB_PLUGIN_SUFFIX .dll) set(MARIADB_PLUGIN_SUFFIX .dll)
set(MARIADB_IMPLIB_LOCATION "${BINARY_DIR}/RelWithDebInfo/mariadbcpp.lib") set(MARIADB_IMPLIB_LOCATION "${MARIADBCPP_LIBRARY_DIR}/mariadbcpp.lib")
# When built from source windows only seems to check same folder as exe instead specified folder, so use # When built from source windows only seems to check same folder as exe instead specified folder, so use
# environment variable to force it # environment variable to force it
add_link_options(/DELAYLOAD:mariadbcpp.dll) add_link_options(/DELAYLOAD:mariadbcpp.dll)
add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${PROJECT_BINARY_DIR}/mariadbcpp/plugin") add_compile_definitions(MARIADB_PLUGIN_DIR_OVERRIDE="${MARIADBCPP_PLUGIN_DIR}")
else() else()
set(MARIADB_SHARED_LIBRARY_NAME libmariadbcpp${CMAKE_SHARED_LIBRARY_SUFFIX}) set(MARIADB_SHARED_LIBRARY_NAME libmariadbcpp${CMAKE_SHARED_LIBRARY_SUFFIX})
set(MARIADB_PLUGIN_SUFFIX .so) set(MARIADB_PLUGIN_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
endif() endif()
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) set(MARIADBCPP_SHARED_LIBRARY_LOCATION "${MARIADBCPP_LIBRARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}")
if(isMultiConfig) if(WIN32)
set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/RelWithDebInfo/${MARIADB_SHARED_LIBRARY_NAME}") set(MARIADBC_SHARED_LIBRARY_LOCATION "${MARIADBCPP_LIBRARY_DIR}/libmariadb.lib")
set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}/$<CONFIG>")
set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb/RelWithDebInfo")
else()
set(MARIADB_SHARED_LIBRARY_LOCATION "${BINARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}")
set(MARIADB_SHARED_LIBRARY_COPY_LOCATION "${PROJECT_BINARY_DIR}")
set(MARIADB_PLUGINS_LOCATION "${BINARY_DIR}/libmariadb")
endif() endif()
set(MARIADB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include/")
add_custom_command(TARGET mariadb_connector_cpp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
${BINARY_DIR}/mariadbcpp/plugin
${MARIADB_SHARED_LIBRARY_COPY_LOCATION}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${MARIADB_SHARED_LIBRARY_LOCATION}
${MARIADB_SHARED_LIBRARY_COPY_LOCATION}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${MARIADB_PLUGINS_LOCATION}/caching_sha2_password${MARIADB_PLUGIN_SUFFIX}
${MARIADB_PLUGINS_LOCATION}/client_ed25519${MARIADB_PLUGIN_SUFFIX}
${MARIADB_PLUGINS_LOCATION}/dialog${MARIADB_PLUGIN_SUFFIX}
${MARIADB_PLUGINS_LOCATION}/mysql_clear_password${MARIADB_PLUGIN_SUFFIX}
${MARIADB_PLUGINS_LOCATION}/sha256_password${MARIADB_PLUGIN_SUFFIX}
${BINARY_DIR}/mariadbcpp/plugin)
endif()
# Remove the CMakeLists.txt file from the tests folder for the maria-db-connector so we dont compile the tests.
if(EXISTS "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt")
file(REMOVE "${CMAKE_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/test/CMakeLists.txt")
endif() endif()
# Create mariadb connector library object # Create mariadb connector library object
add_library(mariadbConnCpp SHARED IMPORTED GLOBAL) add_library(MariaDB::ConnCpp SHARED IMPORTED GLOBAL)
set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_LOCATION ${MARIADB_SHARED_LIBRARY_LOCATION}) add_dependencies(MariaDB::ConnCpp mariadb_connector_cpp)
set_target_properties(MariaDB::ConnCpp PROPERTIES
IMPORTED_LOCATION "${MARIADBCPP_SHARED_LIBRARY_LOCATION}")
if(WIN32) if(WIN32)
set_property(TARGET mariadbConnCpp PROPERTY IMPORTED_IMPLIB ${MARIADB_IMPLIB_LOCATION}) set_target_properties(MariaDB::ConnCpp PROPERTIES
IMPORTED_IMPLIB "${MARIADB_IMPLIB_LOCATION}")
elseif(APPLE)
set_target_properties(MariaDB::ConnCpp PROPERTIES
IMPORTED_SONAME "libmariadbcpp")
endif() endif()
# Add directories to include lists # Add directories to include lists
target_include_directories(mariadbConnCpp INTERFACE ${MARIADB_INCLUDE_DIR}) target_include_directories(MariaDB::ConnCpp INTERFACE ${MARIADB_INCLUDE_DIR})
add_dependencies(mariadbConnCpp mariadb_connector_cpp)
set(MariaDB_FOUND TRUE)

View File

@ -5,10 +5,12 @@ set(DCHATSERVER_SOURCES
) )
add_executable(ChatServer "ChatServer.cpp") add_executable(ChatServer "ChatServer.cpp")
add_library(dChatServer ${DCHATSERVER_SOURCES}) target_include_directories(ChatServer PRIVATE "${PROJECT_SOURCE_DIR}/dChatFilter")
target_include_directories(dChatServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer)
add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"")
add_library(dChatServer ${DCHATSERVER_SOURCES})
target_include_directories(dChatServer PRIVATE "${PROJECT_SOURCE_DIR}/dServer")
target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter) target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter)
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer) target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer)

View File

@ -101,7 +101,7 @@ int main(int argc, char** argv) {
//It's safe to pass 'localhost' here, as the IP is only used as the external IP. //It's safe to pass 'localhost' here, as the IP is only used as the external IP.
std::string ourIP = "localhost"; std::string ourIP = "localhost";
const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999); const uint32_t maxClients = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_clients")).value_or(999);
const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("chat_server_port")).value_or(1501); const uint32_t ourPort = GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("chat_server_port")).value_or(2005);
const auto externalIPString = Game::config->GetValue("external_ip"); const auto externalIPString = Game::config->GetValue("external_ip");
if (!externalIPString.empty()) ourIP = externalIPString; if (!externalIPString.empty()) ourIP = externalIPString;

View File

@ -30,11 +30,15 @@ foreach(file ${DCOMMON_DCLIENT_SOURCES})
set(DCOMMON_SOURCES ${DCOMMON_SOURCES} "dClient/${file}") set(DCOMMON_SOURCES ${DCOMMON_SOURCES} "dClient/${file}")
endforeach() endforeach()
include_directories(${PROJECT_SOURCE_DIR}/dCommon/)
add_library(dCommon STATIC ${DCOMMON_SOURCES}) add_library(dCommon STATIC ${DCOMMON_SOURCES})
target_include_directories(dCommon
target_link_libraries(dCommon bcrypt dDatabase tinyxml2) PUBLIC "." "dClient" "dEnums"
PRIVATE
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
"${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include"
)
if (UNIX) if (UNIX)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
@ -65,4 +69,6 @@ else ()
) )
endif () endif ()
target_link_libraries(dCommon ZLIB::ZLIB) target_link_libraries(dCommon
PRIVATE ZLIB::ZLIB bcrypt tinyxml2
INTERFACE dDatabase)

View File

@ -264,8 +264,8 @@ namespace GeneralUtils {
* @returns The enum entry's value in its underlying type * @returns The enum entry's value in its underlying type
*/ */
template <Enum eType> template <Enum eType>
constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) noexcept { constexpr std::underlying_type_t<eType> ToUnderlying(const eType entry) noexcept {
return static_cast<typename std::underlying_type_t<eType>>(entry); return static_cast<std::underlying_type_t<eType>>(entry);
} }
// on Windows we need to undef these or else they conflict with our numeric limits calls // on Windows we need to undef these or else they conflict with our numeric limits calls

View File

@ -6,28 +6,14 @@
struct RemoteInputInfo { struct RemoteInputInfo {
RemoteInputInfo() {
m_RemoteInputX = 0;
m_RemoteInputY = 0;
m_IsPowersliding = false;
m_IsModified = false;
}
void operator=(const RemoteInputInfo& other) {
m_RemoteInputX = other.m_RemoteInputX;
m_RemoteInputY = other.m_RemoteInputY;
m_IsPowersliding = other.m_IsPowersliding;
m_IsModified = other.m_IsModified;
}
bool operator==(const RemoteInputInfo& other) { bool operator==(const RemoteInputInfo& other) {
return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified; return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified;
} }
float m_RemoteInputX; float m_RemoteInputX = 0;
float m_RemoteInputY; float m_RemoteInputY = 0;
bool m_IsPowersliding; bool m_IsPowersliding = false;
bool m_IsModified; bool m_IsModified = false;
}; };
struct LocalSpaceInfo { struct LocalSpaceInfo {

View File

@ -58,7 +58,7 @@ void CDLootTableTable::LoadValuesFromDatabase() {
CDLootTable entry; CDLootTable entry;
uint32_t lootTableIndex = tableData.getIntField("LootTableIndex", -1); uint32_t lootTableIndex = tableData.getIntField("LootTableIndex", -1);
entries[lootTableIndex].push_back(ReadRow(tableData)); entries[lootTableIndex].emplace_back(ReadRow(tableData));
tableData.nextRow(); tableData.nextRow();
} }
for (auto& [id, table] : entries) { for (auto& [id, table] : entries) {
@ -66,7 +66,7 @@ void CDLootTableTable::LoadValuesFromDatabase() {
} }
} }
const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) { const LootTableEntries& CDLootTableTable::GetTable(const uint32_t tableId) {
auto& entries = GetEntriesMutable(); auto& entries = GetEntriesMutable();
auto itr = entries.find(tableId); auto itr = entries.find(tableId);
if (itr != entries.end()) { if (itr != entries.end()) {
@ -79,7 +79,7 @@ const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) {
while (!tableData.eof()) { while (!tableData.eof()) {
CDLootTable entry; CDLootTable entry;
entries[tableId].push_back(ReadRow(tableData)); entries[tableId].emplace_back(ReadRow(tableData));
tableData.nextRow(); tableData.nextRow();
} }
SortTable(entries[tableId]); SortTable(entries[tableId]);

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDLootTable { struct CDLootTable {
uint32_t itemid; //!< The LOT of the item uint32_t itemid; //!< The LOT of the item
uint32_t LootTableIndex; //!< The Loot Table Index uint32_t LootTableIndex; //!< The Loot Table Index
@ -20,6 +22,5 @@ private:
public: public:
void LoadValuesFromDatabase(); void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
const LootTableEntries& GetTable(uint32_t tableId); const LootTableEntries& GetTable(const uint32_t tableId);
}; };

View File

@ -20,7 +20,7 @@ void CDMissionEmailTable::LoadValuesFromDatabase() {
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionEmail"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionEmail");
while (!tableData.eof()) { while (!tableData.eof()) {
CDMissionEmail entry; auto& entry = entries.emplace_back();
entry.ID = tableData.getIntField("ID", -1); entry.ID = tableData.getIntField("ID", -1);
entry.messageType = tableData.getIntField("messageType", -1); entry.messageType = tableData.getIntField("messageType", -1);
entry.notificationGroup = tableData.getIntField("notificationGroup", -1); entry.notificationGroup = tableData.getIntField("notificationGroup", -1);
@ -30,11 +30,8 @@ void CDMissionEmailTable::LoadValuesFromDatabase() {
entry.locStatus = tableData.getIntField("locStatus", -1); entry.locStatus = tableData.getIntField("locStatus", -1);
entry.gate_version = tableData.getStringField("gate_version", ""); entry.gate_version = tableData.getStringField("gate_version", "");
entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize();
} }
//! Queries the table with a custom "where" clause //! Queries the table with a custom "where" clause

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDMissionEmail { struct CDMissionEmail {
uint32_t ID; uint32_t ID;
uint32_t messageType; uint32_t messageType;

View File

@ -20,18 +20,15 @@ void CDMissionNPCComponentTable::LoadValuesFromDatabase() {
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionNPCComponent"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionNPCComponent");
while (!tableData.eof()) { while (!tableData.eof()) {
CDMissionNPCComponent entry; auto& entry = entries.emplace_back();
entry.id = tableData.getIntField("id", -1); entry.id = tableData.getIntField("id", -1);
entry.missionID = tableData.getIntField("missionID", -1); entry.missionID = tableData.getIntField("missionID", -1);
entry.offersMission = tableData.getIntField("offersMission", -1) == 1 ? true : false; entry.offersMission = tableData.getIntField("offersMission", -1) == 1 ? true : false;
entry.acceptsMission = tableData.getIntField("acceptsMission", -1) == 1 ? true : false; entry.acceptsMission = tableData.getIntField("acceptsMission", -1) == 1 ? true : false;
entry.gate_version = tableData.getStringField("gate_version", ""); entry.gate_version = tableData.getStringField("gate_version", "");
entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize();
} }
//! Queries the table with a custom "where" clause //! Queries the table with a custom "where" clause

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDMissionNPCComponent { struct CDMissionNPCComponent {
uint32_t id; //!< The ID uint32_t id; //!< The ID
uint32_t missionID; //!< The Mission ID uint32_t missionID; //!< The Mission ID
@ -17,4 +19,3 @@ public:
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDMissionNPCComponent> Query(std::function<bool(CDMissionNPCComponent)> predicate); std::vector<CDMissionNPCComponent> Query(std::function<bool(CDMissionNPCComponent)> predicate);
}; };

View File

@ -20,7 +20,7 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionTasks"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionTasks");
while (!tableData.eof()) { while (!tableData.eof()) {
CDMissionTasks entry; auto& entry = entries.emplace_back();
entry.id = tableData.getIntField("id", -1); entry.id = tableData.getIntField("id", -1);
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
entry.taskType = tableData.getIntField("taskType", -1); entry.taskType = tableData.getIntField("taskType", -1);
@ -35,11 +35,8 @@ void CDMissionTasksTable::LoadValuesFromDatabase() {
UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false); UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false);
UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize();
} }
std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMissionTasks)> predicate) { std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMissionTasks)> predicate) {
@ -51,7 +48,7 @@ std::vector<CDMissionTasks> CDMissionTasksTable::Query(std::function<bool(CDMiss
return data; return data;
} }
std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missionID) { std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(const uint32_t missionID) {
std::vector<CDMissionTasks*> tasks; std::vector<CDMissionTasks*> tasks;
// TODO: this should not be linear(?) and also shouldnt need to be a pointer // TODO: this should not be linear(?) and also shouldnt need to be a pointer

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDMissionTasks { struct CDMissionTasks {
uint32_t id; //!< The Mission ID that the task belongs to uint32_t id; //!< The Mission ID that the task belongs to
UNUSED(uint32_t locStatus); //!< ??? UNUSED(uint32_t locStatus); //!< ???
@ -25,7 +27,7 @@ public:
// Queries the table with a custom "where" clause // Queries the table with a custom "where" clause
std::vector<CDMissionTasks> Query(std::function<bool(CDMissionTasks)> predicate); std::vector<CDMissionTasks> Query(std::function<bool(CDMissionTasks)> predicate);
std::vector<CDMissionTasks*> GetByMissionID(uint32_t missionID); std::vector<CDMissionTasks*> GetByMissionID(const uint32_t missionID);
// TODO: Remove this and replace it with a proper lookup function. // TODO: Remove this and replace it with a proper lookup function.
const CDTable::StorageType& GetEntries() const; const CDTable::StorageType& GetEntries() const;

View File

@ -22,7 +22,7 @@ void CDMissionsTable::LoadValuesFromDatabase() {
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Missions"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Missions");
while (!tableData.eof()) { while (!tableData.eof()) {
CDMissions entry; auto& entry = entries.emplace_back();
entry.id = tableData.getIntField("id", -1); entry.id = tableData.getIntField("id", -1);
entry.defined_type = tableData.getStringField("defined_type", ""); entry.defined_type = tableData.getStringField("defined_type", "");
entry.defined_subtype = tableData.getStringField("defined_subtype", ""); entry.defined_subtype = tableData.getStringField("defined_subtype", "");
@ -76,7 +76,6 @@ void CDMissionsTable::LoadValuesFromDatabase() {
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1)); UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1); entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1);
entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize(); tableData.finalize();

View File

@ -75,4 +75,3 @@ public:
static CDMissions Default; static CDMissions Default;
}; };

View File

@ -20,7 +20,7 @@ void CDMovementAIComponentTable::LoadValuesFromDatabase() {
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovementAIComponent"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovementAIComponent");
while (!tableData.eof()) { while (!tableData.eof()) {
CDMovementAIComponent entry; auto& entry = entries.emplace_back();
entry.id = tableData.getIntField("id", -1); entry.id = tableData.getIntField("id", -1);
entry.MovementType = tableData.getStringField("MovementType", ""); entry.MovementType = tableData.getStringField("MovementType", "");
entry.WanderChance = tableData.getFloatField("WanderChance", -1.0f); entry.WanderChance = tableData.getFloatField("WanderChance", -1.0f);
@ -30,11 +30,8 @@ void CDMovementAIComponentTable::LoadValuesFromDatabase() {
entry.WanderRadius = tableData.getFloatField("WanderRadius", -1.0f); entry.WanderRadius = tableData.getFloatField("WanderRadius", -1.0f);
entry.attachedPath = tableData.getStringField("attachedPath", ""); entry.attachedPath = tableData.getStringField("attachedPath", "");
entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize();
} }
std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::function<bool(CDMovementAIComponent)> predicate) { std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::function<bool(CDMovementAIComponent)> predicate) {

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDMovementAIComponent { struct CDMovementAIComponent {
uint32_t id; uint32_t id;
std::string MovementType; std::string MovementType;

View File

@ -20,17 +20,14 @@ void CDObjectSkillsTable::LoadValuesFromDatabase() {
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ObjectSkills"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ObjectSkills");
while (!tableData.eof()) { while (!tableData.eof()) {
CDObjectSkills entry; auto &entry = entries.emplace_back();
entry.objectTemplate = tableData.getIntField("objectTemplate", -1); entry.objectTemplate = tableData.getIntField("objectTemplate", -1);
entry.skillID = tableData.getIntField("skillID", -1); entry.skillID = tableData.getIntField("skillID", -1);
entry.castOnType = tableData.getIntField("castOnType", -1); entry.castOnType = tableData.getIntField("castOnType", -1);
entry.AICombatWeight = tableData.getIntField("AICombatWeight", -1); entry.AICombatWeight = tableData.getIntField("AICombatWeight", -1);
entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize();
} }
std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObjectSkills)> predicate) { std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObjectSkills)> predicate) {

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDObjectSkills { struct CDObjectSkills {
uint32_t objectTemplate; //!< The LOT of the item uint32_t objectTemplate; //!< The LOT of the item
uint32_t skillID; //!< The Skill ID of the object uint32_t skillID; //!< The Skill ID of the object

View File

@ -1,7 +1,7 @@
#include "CDObjectsTable.h" #include "CDObjectsTable.h"
namespace { namespace {
CDObjects m_default; CDObjects ObjDefault;
}; };
void CDObjectsTable::LoadValuesFromDatabase() { void CDObjectsTable::LoadValuesFromDatabase() {
@ -20,8 +20,10 @@ void CDObjectsTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Objects"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Objects");
auto& entries = GetEntriesMutable(); auto& entries = GetEntriesMutable();
while (!tableData.eof()) { while (!tableData.eof()) {
CDObjects entry; const uint32_t lot = tableData.getIntField("id", 0);
entry.id = tableData.getIntField("id", -1);
auto& entry = entries[lot];
entry.id = lot;
entry.name = tableData.getStringField("name", ""); entry.name = tableData.getStringField("name", "");
UNUSED_COLUMN(entry.placeable = tableData.getIntField("placeable", -1);) UNUSED_COLUMN(entry.placeable = tableData.getIntField("placeable", -1);)
entry.type = tableData.getStringField("type", ""); entry.type = tableData.getStringField("type", "");
@ -36,35 +38,34 @@ void CDObjectsTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "");) UNUSED_COLUMN(entry.gate_version = tableData.getStringField("gate_version", "");)
UNUSED_COLUMN(entry.HQ_valid = tableData.getIntField("HQ_valid", -1);) UNUSED_COLUMN(entry.HQ_valid = tableData.getIntField("HQ_valid", -1);)
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize(); ObjDefault.id = 0;
m_default.id = 0;
} }
const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) { const CDObjects& CDObjectsTable::GetByID(const uint32_t lot) {
auto& entries = GetEntriesMutable(); auto& entries = GetEntriesMutable();
const auto& it = entries.find(LOT); const auto& it = entries.find(lot);
if (it != entries.end()) { if (it != entries.end()) {
return it->second; return it->second;
} }
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Objects WHERE id = ?;"); auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Objects WHERE id = ?;");
query.bind(1, static_cast<int32_t>(LOT)); query.bind(1, static_cast<int32_t>(lot));
auto tableData = query.execQuery(); auto tableData = query.execQuery();
if (tableData.eof()) { if (tableData.eof()) {
entries.insert(std::make_pair(LOT, m_default)); entries.emplace(lot, ObjDefault);
return m_default; return ObjDefault;
} }
// Now get the data // Now get the data
while (!tableData.eof()) { while (!tableData.eof()) {
CDObjects entry; const uint32_t lot = tableData.getIntField("id", 0);
entry.id = tableData.getIntField("id", -1);
auto& entry = entries[lot];
entry.id = lot;
entry.name = tableData.getStringField("name", ""); entry.name = tableData.getStringField("name", "");
UNUSED(entry.placeable = tableData.getIntField("placeable", -1)); UNUSED(entry.placeable = tableData.getIntField("placeable", -1));
entry.type = tableData.getStringField("type", ""); entry.type = tableData.getStringField("type", "");
@ -79,17 +80,15 @@ const CDObjects& CDObjectsTable::GetByID(uint32_t LOT) {
UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
UNUSED(entry.HQ_valid = tableData.getIntField("HQ_valid", -1)); UNUSED(entry.HQ_valid = tableData.getIntField("HQ_valid", -1));
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize(); tableData.finalize();
const auto& it2 = entries.find(LOT); const auto& it2 = entries.find(lot);
if (it2 != entries.end()) { if (it2 != entries.end()) {
return it2->second; return it2->second;
} }
return m_default; return ObjDefault;
} }

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDObjects { struct CDObjects {
uint32_t id; //!< The LOT of the object uint32_t id; //!< The LOT of the object
std::string name; //!< The internal name of the object std::string name; //!< The internal name of the object
@ -24,6 +26,6 @@ class CDObjectsTable : public CDTable<CDObjectsTable, std::map<uint32_t, CDObjec
public: public:
void LoadValuesFromDatabase(); void LoadValuesFromDatabase();
// Gets an entry by ID // Gets an entry by ID
const CDObjects& GetByID(uint32_t LOT); const CDObjects& GetByID(const uint32_t lot);
}; };

View File

@ -19,12 +19,11 @@ void CDPackageComponentTable::LoadValuesFromDatabase() {
// Now get the data // Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PackageComponent"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PackageComponent");
while (!tableData.eof()) { while (!tableData.eof()) {
CDPackageComponent entry; auto& entry = entries.emplace_back();
entry.id = tableData.getIntField("id", -1); entry.id = tableData.getIntField("id", -1);
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
entry.packageType = tableData.getIntField("packageType", -1); entry.packageType = tableData.getIntField("packageType", -1);
entries.push_back(entry);
tableData.nextRow(); tableData.nextRow();
} }

View File

@ -3,6 +3,8 @@
// Custom Classes // Custom Classes
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
struct CDPackageComponent { struct CDPackageComponent {
uint32_t id; uint32_t id;
uint32_t LootMatrixIndex; uint32_t LootMatrixIndex;

View File

@ -4,32 +4,31 @@ void CDPhysicsComponentTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent"); auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent");
auto& entries = GetEntriesMutable(); auto& entries = GetEntriesMutable();
while (!tableData.eof()) { while (!tableData.eof()) {
CDPhysicsComponent entry; const uint32_t componentID = tableData.getIntField("id", -1);
entry.id = tableData.getIntField("id", -1);
auto& entry = entries[componentID];
entry.id = componentID;
entry.bStatic = tableData.getIntField("static", -1) != 0; entry.bStatic = tableData.getIntField("static", -1) != 0;
entry.physicsAsset = tableData.getStringField("physics_asset", ""); entry.physicsAsset = tableData.getStringField("physics_asset", "");
UNUSED(entry->jump = tableData.getIntField("jump", -1) != 0); UNUSED_COLUMN(entry.jump = tableData.getIntField("jump", -1) != 0;)
UNUSED(entry->doublejump = tableData.getIntField("doublejump", -1) != 0); UNUSED_COLUMN(entry.doubleJump = tableData.getIntField("doublejump", -1) != 0;)
entry.speed = tableData.getFloatField("speed", -1); entry.speed = static_cast<float>(tableData.getFloatField("speed", -1));
UNUSED(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1)); UNUSED_COLUMN(entry.rotSpeed = tableData.getFloatField("rotSpeed", -1);)
entry.playerHeight = tableData.getFloatField("playerHeight"); entry.playerHeight = static_cast<float>(tableData.getFloatField("playerHeight"));
entry.playerRadius = tableData.getFloatField("playerRadius"); entry.playerRadius = static_cast<float>(tableData.getFloatField("playerRadius"));
entry.pcShapeType = tableData.getIntField("pcShapeType"); entry.pcShapeType = tableData.getIntField("pcShapeType");
entry.collisionGroup = tableData.getIntField("collisionGroup"); entry.collisionGroup = tableData.getIntField("collisionGroup");
UNUSED(entry->airSpeed = tableData.getFloatField("airSpeed")); UNUSED_COLUMN(entry.airSpeed = tableData.getFloatField("airSpeed");)
UNUSED(entry->boundaryAsset = tableData.getStringField("boundaryAsset")); UNUSED_COLUMN(entry.boundaryAsset = tableData.getStringField("boundaryAsset");)
UNUSED(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed")); UNUSED_COLUMN(entry.jumpAirSpeed = tableData.getFloatField("jumpAirSpeed");)
UNUSED(entry->friction = tableData.getFloatField("friction")); UNUSED_COLUMN(entry.friction = tableData.getFloatField("friction");)
UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset")); UNUSED_COLUMN(entry.gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset");)
entries.insert(std::make_pair(entry.id, entry));
tableData.nextRow(); tableData.nextRow();
} }
tableData.finalize();
} }
CDPhysicsComponent* CDPhysicsComponentTable::GetByID(uint32_t componentID) { CDPhysicsComponent* CDPhysicsComponentTable::GetByID(const uint32_t componentID) {
auto& entries = GetEntriesMutable(); auto& entries = GetEntriesMutable();
auto itr = entries.find(componentID); auto itr = entries.find(componentID);
return itr != entries.end() ? &itr->second : nullptr; return itr != entries.end() ? &itr->second : nullptr;

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "CDTable.h" #include "CDTable.h"
#include <cstdint>
#include <string> #include <string>
struct CDPhysicsComponent { struct CDPhysicsComponent {
@ -7,7 +8,7 @@ struct CDPhysicsComponent {
bool bStatic; bool bStatic;
std::string physicsAsset; std::string physicsAsset;
UNUSED(bool jump); UNUSED(bool jump);
UNUSED(bool doublejump); UNUSED(bool doubleJump);
float speed; float speed;
UNUSED(float rotSpeed); UNUSED(float rotSpeed);
float playerHeight; float playerHeight;
@ -26,5 +27,5 @@ public:
void LoadValuesFromDatabase(); void LoadValuesFromDatabase();
static const std::string GetTableName() { return "PhysicsComponent"; }; static const std::string GetTableName() { return "PhysicsComponent"; };
CDPhysicsComponent* GetByID(uint32_t componentID); CDPhysicsComponent* GetByID(const uint32_t componentID);
}; };

View File

@ -9,4 +9,28 @@ foreach(file ${DDATABASE_CDCLIENTDATABASE_CDCLIENTTABLES_SOURCES})
set(DDATABASE_CDCLIENTDATABASE_SOURCES ${DDATABASE_CDCLIENTDATABASE_SOURCES} "CDClientTables/${file}") set(DDATABASE_CDCLIENTDATABASE_SOURCES ${DDATABASE_CDCLIENTDATABASE_SOURCES} "CDClientTables/${file}")
endforeach() endforeach()
set(DDATABASE_CDCLIENTDATABASE_SOURCES ${DDATABASE_CDCLIENTDATABASE_SOURCES} PARENT_SCOPE) add_library(dDatabaseCDClient STATIC ${DDATABASE_CDCLIENTDATABASE_SOURCES})
target_include_directories(dDatabaseCDClient PUBLIC "."
"CDClientTables"
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
)
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3)
if (${CDCLIENT_CACHE_ALL})
add_compile_definitions(dDatabaseCDClient PRIVATE CDCLIENT_CACHE_ALL=${CDCLIENT_CACHE_ALL})
endif()
file(
GLOB HEADERS_DDATABASE_CDCLIENT
LIST_DIRECTORIES false
${PROJECT_SOURCE_DIR}/thirdparty/SQLite/*.h
CDClientTables/*.h
*.h
)
# Need to specify to use the CXX compiler language here or else we get errors including <string>.
target_precompile_headers(
dDatabaseCDClient PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE_CDCLIENT}>"
)

View File

@ -1,20 +1,7 @@
set(DDATABASE_SOURCES)
add_subdirectory(CDClientDatabase) add_subdirectory(CDClientDatabase)
foreach(file ${DDATABASE_CDCLIENTDATABASE_SOURCES})
set(DDATABASE_SOURCES ${DDATABASE_SOURCES} "CDClientDatabase/${file}")
endforeach()
add_subdirectory(GameDatabase) add_subdirectory(GameDatabase)
foreach(file ${DDATABASE_GAMEDATABASE_SOURCES}) add_library(dDatabase STATIC "MigrationRunner.cpp")
set(DDATABASE_SOURCES ${DDATABASE_SOURCES} "GameDatabase/${file}") target_include_directories(dDatabase PUBLIC ".")
endforeach() target_link_libraries(dDatabase
PUBLIC dDatabaseCDClient dDatabaseGame)
add_library(dDatabase STATIC ${DDATABASE_SOURCES})
target_link_libraries(dDatabase sqlite3 mariadbConnCpp)
if (${CDCLIENT_CACHE_ALL})
add_compile_definitions(dDatabase CDCLIENT_CACHE_ALL=${CDCLIENT_CACHE_ALL})
endif()

View File

@ -1,6 +1,5 @@
set(DDATABASE_GAMEDATABASE_SOURCES set(DDATABASE_GAMEDATABASE_SOURCES
"Database.cpp" "Database.cpp"
"MigrationRunner.cpp"
) )
add_subdirectory(MySQL) add_subdirectory(MySQL)
@ -9,4 +8,25 @@ foreach(file ${DDATABSE_DATABSES_MYSQL_SOURCES})
set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "MySQL/${file}") set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} "MySQL/${file}")
endforeach() endforeach()
set(DDATABASE_GAMEDATABASE_SOURCES ${DDATABASE_GAMEDATABASE_SOURCES} PARENT_SCOPE) add_library(dDatabaseGame STATIC ${DDATABASE_GAMEDATABASE_SOURCES})
target_include_directories(dDatabaseGame PUBLIC "."
"ITables" PRIVATE "MySQL"
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
)
target_link_libraries(dDatabaseGame
PUBLIC MariaDB::ConnCpp
INTERFACE dCommon)
# Glob together all headers that need to be precompiled
file(
GLOB HEADERS_DDATABASE_GAME
LIST_DIRECTORIES false
ITables/*.h
)
# Need to specify to use the CXX compiler language here or else we get errors including <string>.
target_precompile_headers(
dDatabaseGame PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${HEADERS_DDATABASE_GAME}>"
)

View File

@ -3,6 +3,7 @@
#include <cstdint> #include <cstdint>
#include <optional> #include <optional>
#include <string>
#include <string_view> #include <string_view>
enum class eGameMasterLevel : uint8_t; enum class eGameMasterLevel : uint8_t;

View File

@ -13,11 +13,25 @@ include_directories(
${PROJECT_SOURCE_DIR}/dGame ${PROJECT_SOURCE_DIR}/dGame
) )
add_library(dGameBase ${DGAME_SOURCES}) add_library(dGameBase OBJECT ${DGAME_SOURCES})
target_precompile_headers(dGameBase PRIVATE ${HEADERS_DGAME}) target_precompile_headers(dGameBase PRIVATE ${HEADERS_DGAME})
target_link_libraries(dGameBase target_include_directories(dGameBase PUBLIC "." "dEntity"
PUBLIC dDatabase dPhysics PRIVATE "dComponents" "dGameMessages" "dBehaviors" "dMission" "dUtilities" "dInventory"
INTERFACE dComponents dEntity) $<TARGET_PROPERTY:dPropertyBehaviors,INTERFACE_INCLUDE_DIRECTORIES>
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
"${PROJECT_SOURCE_DIR}/dCommon/dClient"
# dDatabase
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
"${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include"
# dPhysics
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include"
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include"
"${PROJECT_SOURCE_DIR}/dZoneManager"
)
add_subdirectory(dBehaviors) add_subdirectory(dBehaviors)
add_subdirectory(dComponents) add_subdirectory(dComponents)
@ -28,7 +42,26 @@ add_subdirectory(dMission)
add_subdirectory(dPropertyBehaviors) add_subdirectory(dPropertyBehaviors)
add_subdirectory(dUtilities) add_subdirectory(dUtilities)
add_library(dGame INTERFACE) add_library(dGame STATIC
target_link_libraries(dGame INTERFACE $<TARGET_OBJECTS:dGameBase>
dGameBase dBehaviors dComponents dEntity dGameMessages dInventory dMission dPropertyBehaviors dUtilities dScripts $<TARGET_OBJECTS:dBehaviors>
$<TARGET_OBJECTS:dComponents>
$<TARGET_OBJECTS:dEntity>
$<TARGET_OBJECTS:dGameMessages>
$<TARGET_OBJECTS:dInventory>
$<TARGET_OBJECTS:dMission>
$<TARGET_OBJECTS:dPropertyBehaviors>
$<TARGET_OBJECTS:dUtilities>
)
target_link_libraries(dGame INTERFACE dNet)
target_include_directories(dGame INTERFACE
$<TARGET_PROPERTY:dGameBase,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dBehaviors,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dComponents,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dEntity,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dGameMessages,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dInventory,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dMission,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dPropertyBehaviors,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dUtilities,INTERFACE_INCLUDE_DIRECTORIES>
) )

View File

@ -146,17 +146,15 @@ Entity::~Entity() {
return; return;
} }
Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); auto* zoneControl = Game::entityManager->GetZoneControlEntity();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { if (zoneControl) {
script->OnPlayerExit(zoneControl, this); zoneControl->GetScript()->OnPlayerExit(zoneControl, this);
} }
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
for (Entity* scriptEntity : scriptedActs) { for (Entity* scriptEntity : scriptedActs) {
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { scriptEntity->GetScript()->OnPlayerExit(scriptEntity, this);
script->OnPlayerExit(scriptEntity, this);
}
} }
} }
} }
@ -756,9 +754,7 @@ void Entity::Initialize() {
// Hacky way to trigger these when the object has had a chance to get constructed // Hacky way to trigger these when the object has had a chance to get constructed
AddCallbackTimer(0, [this]() { AddCallbackTimer(0, [this]() {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { this->GetScript()->OnStartup(this);
script->OnStartup(this);
}
}); });
if (!m_Character && Game::entityManager->GetGhostingEnabled()) { if (!m_Character && Game::entityManager->GetGhostingEnabled()) {
@ -833,17 +829,6 @@ bool Entity::HasComponent(const eReplicaComponentType componentId) const {
return m_Components.find(componentId) != m_Components.end(); return m_Components.find(componentId) != m_Components.end();
} }
std::vector<ScriptComponent*> Entity::GetScriptComponents() {
std::vector<ScriptComponent*> comps;
for (std::pair<eReplicaComponentType, void*> p : m_Components) {
if (p.first == eReplicaComponentType::SCRIPT) {
comps.push_back(static_cast<ScriptComponent*>(p.second));
}
}
return comps;
}
void Entity::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName) { void Entity::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName) {
if (notificationName == "HitOrHealResult" || notificationName == "Hit") { if (notificationName == "HitOrHealResult" || notificationName == "Hit") {
auto* destroyableComponent = GetComponent<DestroyableComponent>(); auto* destroyableComponent = GetComponent<DestroyableComponent>();
@ -1272,9 +1257,7 @@ void Entity::Update(const float deltaTime) {
// Remove the timer from the list of timers first so that scripts and events can remove timers without causing iterator invalidation // Remove the timer from the list of timers first so that scripts and events can remove timers without causing iterator invalidation
auto timerName = timer.GetName(); auto timerName = timer.GetName();
m_Timers.erase(m_Timers.begin() + timerPosition); m_Timers.erase(m_Timers.begin() + timerPosition);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnTimerDone(this, timerName);
script->OnTimerDone(this, timerName);
}
TriggerEvent(eTriggerEventType::TIMER_DONE, this); TriggerEvent(eTriggerEventType::TIMER_DONE, this);
} else { } else {
@ -1320,9 +1303,7 @@ void Entity::Update(const float deltaTime) {
Wake(); Wake();
} }
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnUpdate(this);
script->OnUpdate(this);
}
for (const auto& pair : m_Components) { for (const auto& pair : m_Components) {
if (pair.second == nullptr) continue; if (pair.second == nullptr) continue;
@ -1339,9 +1320,7 @@ void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxN
Entity* other = Game::entityManager->GetEntity(otherEntity); Entity* other = Game::entityManager->GetEntity(otherEntity);
if (!other) return; if (!other) return;
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnProximityUpdate(this, other, proxName, status);
script->OnProximityUpdate(this, other, proxName, status);
}
RocketLaunchpadControlComponent* rocketComp = GetComponent<RocketLaunchpadControlComponent>(); RocketLaunchpadControlComponent* rocketComp = GetComponent<RocketLaunchpadControlComponent>();
if (!rocketComp) return; if (!rocketComp) return;
@ -1353,9 +1332,7 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) {
auto* other = Game::entityManager->GetEntity(otherEntity); auto* other = Game::entityManager->GetEntity(otherEntity);
if (!other) return; if (!other) return;
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnCollisionPhantom(this, other);
script->OnCollisionPhantom(this, other);
}
for (const auto& callback : m_PhantomCollisionCallbacks) { for (const auto& callback : m_PhantomCollisionCallbacks) {
callback(other); callback(other);
@ -1394,9 +1371,7 @@ void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) {
auto* other = Game::entityManager->GetEntity(otherEntity); auto* other = Game::entityManager->GetEntity(otherEntity);
if (!other) return; if (!other) return;
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnOffCollisionPhantom(this, other);
script->OnOffCollisionPhantom(this, other);
}
TriggerEvent(eTriggerEventType::EXIT, other); TriggerEvent(eTriggerEventType::EXIT, other);
@ -1413,46 +1388,32 @@ void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) {
} }
void Entity::OnFireEventServerSide(Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { void Entity::OnFireEventServerSide(Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnFireEventServerSide(this, sender, args, param1, param2, param3);
script->OnFireEventServerSide(this, sender, args, param1, param2, param3);
}
} }
void Entity::OnActivityStateChangeRequest(LWOOBJID senderID, int32_t value1, int32_t value2, const std::u16string& stringValue) { void Entity::OnActivityStateChangeRequest(LWOOBJID senderID, int32_t value1, int32_t value2, const std::u16string& stringValue) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnActivityStateChangeRequest(this, senderID, value1, value2, stringValue);
script->OnActivityStateChangeRequest(this, senderID, value1, value2, stringValue);
}
} }
void Entity::OnCinematicUpdate(Entity* self, Entity* sender, eCinematicEvent event, const std::u16string& pathName, void Entity::OnCinematicUpdate(Entity* self, Entity* sender, eCinematicEvent event, const std::u16string& pathName,
float_t pathTime, float_t totalTime, int32_t waypoint) { float_t pathTime, float_t totalTime, int32_t waypoint) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnCinematicUpdate(self, sender, event, pathName, pathTime, totalTime, waypoint);
script->OnCinematicUpdate(self, sender, event, pathName, pathTime, totalTime, waypoint);
}
} }
void Entity::NotifyObject(Entity* sender, const std::string& name, int32_t param1, int32_t param2) { void Entity::NotifyObject(Entity* sender, const std::string& name, int32_t param1, int32_t param2) {
GameMessages::SendNotifyObject(GetObjectID(), sender->GetObjectID(), GeneralUtils::ASCIIToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendNotifyObject(GetObjectID(), sender->GetObjectID(), GeneralUtils::ASCIIToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnNotifyObject(this, sender, name, param1, param2);
script->OnNotifyObject(this, sender, name, param1, param2);
}
} }
void Entity::OnEmoteReceived(const int32_t emote, Entity* target) { void Entity::OnEmoteReceived(const int32_t emote, Entity* target) {
for (auto* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnEmoteReceived(this, emote, target);
script->OnEmoteReceived(this, emote, target);
}
} }
void Entity::OnUse(Entity* originator) { void Entity::OnUse(Entity* originator) {
TriggerEvent(eTriggerEventType::INTERACT, originator); TriggerEvent(eTriggerEventType::INTERACT, originator);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnUse(this, originator);
script->OnUse(this, originator);
}
// component base class when
for (const auto& pair : m_Components) { for (const auto& pair : m_Components) {
if (pair.second == nullptr) continue; if (pair.second == nullptr) continue;
@ -1462,82 +1423,63 @@ void Entity::OnUse(Entity* originator) {
} }
void Entity::OnHitOrHealResult(Entity* attacker, int32_t damage) { void Entity::OnHitOrHealResult(Entity* attacker, int32_t damage) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnHitOrHealResult(this, attacker, damage);
script->OnHitOrHealResult(this, attacker, damage);
}
} }
void Entity::OnHit(Entity* attacker) { void Entity::OnHit(Entity* attacker) {
TriggerEvent(eTriggerEventType::HIT, attacker); TriggerEvent(eTriggerEventType::HIT, attacker);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnHit(this, attacker);
script->OnHit(this, attacker);
}
} }
void Entity::OnZonePropertyEditBegin() { void Entity::OnZonePropertyEditBegin() {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyEditBegin(this);
script->OnZonePropertyEditBegin(this);
}
} }
void Entity::OnZonePropertyEditEnd() { void Entity::OnZonePropertyEditEnd() {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyEditEnd(this);
script->OnZonePropertyEditEnd(this);
}
} }
void Entity::OnZonePropertyModelEquipped() { void Entity::OnZonePropertyModelEquipped() {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyModelEquipped(this);
script->OnZonePropertyModelEquipped(this);
}
} }
void Entity::OnZonePropertyModelPlaced(Entity* player) { void Entity::OnZonePropertyModelPlaced(Entity* player) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyModelPlaced(this, player);
script->OnZonePropertyModelPlaced(this, player);
}
} }
void Entity::OnZonePropertyModelPickedUp(Entity* player) { void Entity::OnZonePropertyModelPickedUp(Entity* player) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyModelPickedUp(this, player);
script->OnZonePropertyModelPickedUp(this, player);
}
} }
void Entity::OnZonePropertyModelRemoved(Entity* player) { void Entity::OnZonePropertyModelRemoved(Entity* player) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyModelRemoved(this, player);
script->OnZonePropertyModelRemoved(this, player);
}
} }
void Entity::OnZonePropertyModelRemovedWhileEquipped(Entity* player) { void Entity::OnZonePropertyModelRemovedWhileEquipped(Entity* player) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyModelRemovedWhileEquipped(this, player);
script->OnZonePropertyModelRemovedWhileEquipped(this, player);
}
} }
void Entity::OnZonePropertyModelRotated(Entity* player) { void Entity::OnZonePropertyModelRotated(Entity* player) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnZonePropertyModelRotated(this, player);
script->OnZonePropertyModelRotated(this, player);
}
} }
void Entity::OnMessageBoxResponse(Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) { void Entity::OnMessageBoxResponse(Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnMessageBoxResponse(this, sender, button, identifier, userData);
script->OnMessageBoxResponse(this, sender, button, identifier, userData);
}
} }
void Entity::OnChoiceBoxResponse(Entity* sender, int32_t button, const std::u16string& buttonIdentifier, const std::u16string& identifier) { void Entity::OnChoiceBoxResponse(Entity* sender, int32_t button, const std::u16string& buttonIdentifier, const std::u16string& identifier) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnChoiceBoxResponse(this, sender, button, buttonIdentifier, identifier);
script->OnChoiceBoxResponse(this, sender, button, buttonIdentifier, identifier);
}
} }
void Entity::RequestActivityExit(Entity* sender, LWOOBJID player, bool canceled) { void Entity::RequestActivityExit(Entity* sender, LWOOBJID player, bool canceled) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnRequestActivityExit(sender, player, canceled);
script->OnRequestActivityExit(sender, player, canceled); }
}
CppScripts::Script* const Entity::GetScript() {
auto* scriptComponent = GetComponent<ScriptComponent>();
auto* script = scriptComponent ? scriptComponent->GetScript() : CppScripts::GetInvalidScript();
DluAssert(script != nullptr);
return script;
} }
void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType) { void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType) {
@ -1570,9 +1512,7 @@ void Entity::Kill(Entity* murderer, const eKillType killType) {
//OMAI WA MOU, SHINDERIU //OMAI WA MOU, SHINDERIU
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { GetScript()->OnDie(this, murderer);
script->OnDie(this, murderer);
}
if (m_Spawner != nullptr) { if (m_Spawner != nullptr) {
m_Spawner->NotifyOfEntityDeath(m_ObjectID); m_Spawner->NotifyOfEntityDeath(m_ObjectID);
@ -2120,9 +2060,7 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) {
havokVehiclePhysicsComponent->SetIsOnGround(update.onGround); havokVehiclePhysicsComponent->SetIsOnGround(update.onGround);
havokVehiclePhysicsComponent->SetIsOnRail(update.onRail); havokVehiclePhysicsComponent->SetIsOnRail(update.onRail);
havokVehiclePhysicsComponent->SetVelocity(update.velocity); havokVehiclePhysicsComponent->SetVelocity(update.velocity);
havokVehiclePhysicsComponent->SetDirtyVelocity(update.velocity != NiPoint3Constant::ZERO);
havokVehiclePhysicsComponent->SetAngularVelocity(update.angularVelocity); havokVehiclePhysicsComponent->SetAngularVelocity(update.angularVelocity);
havokVehiclePhysicsComponent->SetDirtyAngularVelocity(update.angularVelocity != NiPoint3Constant::ZERO);
havokVehiclePhysicsComponent->SetRemoteInputInfo(update.remoteInputInfo); havokVehiclePhysicsComponent->SetRemoteInputInfo(update.remoteInputInfo);
} else { } else {
// Need to get the mount's controllable physics // Need to get the mount's controllable physics
@ -2187,9 +2125,3 @@ void Entity::SetRespawnRot(const NiQuaternion& rotation) {
auto* characterComponent = GetComponent<CharacterComponent>(); auto* characterComponent = GetComponent<CharacterComponent>();
if (characterComponent) characterComponent->SetRespawnRot(rotation); if (characterComponent) characterComponent->SetRespawnRot(rotation);
} }
void Entity::SetScale(const float scale) {
if (scale == m_Scale) return;
m_Scale = scale;
Game::entityManager->SerializeEntity(this);
}

View File

@ -146,7 +146,8 @@ public:
void AddComponent(eReplicaComponentType componentId, Component* component); void AddComponent(eReplicaComponentType componentId, Component* component);
std::vector<ScriptComponent*> GetScriptComponents(); // This is expceted to never return nullptr, an assert checks this.
CppScripts::Script* const GetScript();
void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName); void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName);
void Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName); void Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName);
@ -295,7 +296,8 @@ public:
void ProcessPositionUpdate(PositionUpdate& update); void ProcessPositionUpdate(PositionUpdate& update);
void SetScale(const float scale); // Scale will only be communicated to the client when the construction packet is sent
void SetScale(const float scale) { m_Scale = scale; };
protected: protected:
LWOOBJID m_ObjectID; LWOOBJID m_ObjectID;

View File

@ -418,10 +418,16 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
} }
void EntityManager::SerializeEntity(Entity* entity) { void EntityManager::SerializeEntity(Entity* entity) {
if (!entity || entity->GetNetworkId() == 0) return; if (!entity) return;
EntityManager::SerializeEntity(*entity);
}
if (std::find(m_EntitiesToSerialize.begin(), m_EntitiesToSerialize.end(), entity->GetObjectID()) == m_EntitiesToSerialize.end()) { void EntityManager::SerializeEntity(const Entity& entity) {
m_EntitiesToSerialize.push_back(entity->GetObjectID()); if (entity.GetNetworkId() == 0) return;
if (std::find(m_EntitiesToSerialize.cbegin(), m_EntitiesToSerialize.cend(), entity.GetObjectID()) == m_EntitiesToSerialize.cend()) {
m_EntitiesToSerialize.push_back(entity.GetObjectID());
} }
} }

View File

@ -45,6 +45,7 @@ public:
void ConstructEntity(Entity* entity, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS, bool skipChecks = false); void ConstructEntity(Entity* entity, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS, bool skipChecks = false);
void DestructEntity(Entity* entity, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS); void DestructEntity(Entity* entity, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
void SerializeEntity(Entity* entity); void SerializeEntity(Entity* entity);
void SerializeEntity(const Entity& entity);
void ConstructAllEntities(const SystemAddress& sysAddr); void ConstructAllEntities(const SystemAddress& sysAddr);
void DestructAllEntities(const SystemAddress& sysAddr); void DestructAllEntities(const SystemAddress& sysAddr);

View File

@ -21,7 +21,6 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp"
"DamageReductionBehavior.cpp" "DamageReductionBehavior.cpp"
"DarkInspirationBehavior.cpp" "DarkInspirationBehavior.cpp"
"DurationBehavior.cpp" "DurationBehavior.cpp"
"EmptyBehavior.cpp"
"EndBehavior.cpp" "EndBehavior.cpp"
"FallSpeedBehavior.cpp" "FallSpeedBehavior.cpp"
"ForceMovementBehavior.cpp" "ForceMovementBehavior.cpp"
@ -56,7 +55,15 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp"
"VentureVisionBehavior.cpp" "VentureVisionBehavior.cpp"
"VerifyBehavior.cpp") "VerifyBehavior.cpp")
add_library(dBehaviors STATIC ${DGAME_DBEHAVIORS_SOURCES}) add_library(dBehaviors OBJECT ${DGAME_DBEHAVIORS_SOURCES})
target_link_libraries(dBehaviors PUBLIC dPhysics) target_link_libraries(dBehaviors PUBLIC dDatabaseCDClient dPhysics)
target_include_directories(dBehaviors PUBLIC ".") target_include_directories(dBehaviors PUBLIC "."
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # via BehaviorContext.h
PRIVATE
"${PROJECT_SOURCE_DIR}/dGame/dComponents" # direct BuffComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # Preconditions.h via QuickBuildComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager.h, Spawner.h
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via CharacterComponent.h
"${PROJECT_SOURCE_DIR}/dZoneManager" # via BasicAttackBehavior.cpp
)
target_precompile_headers(dBehaviors REUSE_FROM dGameBase) target_precompile_headers(dBehaviors REUSE_FROM dGameBase)

View File

@ -1,2 +0,0 @@
#include "EmptyBehavior.h"

View File

@ -3,15 +3,14 @@
#include "BehaviorContext.h" #include "BehaviorContext.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "CppScripts.h" #include "CppScripts.h"
#include "Entity.h"
void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStream, BehaviorBranchContext branch) { void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStream, BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target); auto* target = Game::entityManager->GetEntity(branch.target);
auto* caster = Game::entityManager->GetEntity(context->originator); auto* caster = Game::entityManager->GetEntity(context->originator);
if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) { if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) { target->GetScript()->OnSkillEventFired(target, caster, *this->m_effectHandle);
script->OnSkillEventFired(target, caster, *this->m_effectHandle);
}
} }
} }
@ -21,8 +20,6 @@ SkillEventBehavior::Calculate(BehaviorContext* context, RakNet::BitStream& bitSt
auto* caster = Game::entityManager->GetEntity(context->originator); auto* caster = Game::entityManager->GetEntity(context->originator);
if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) { if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) { target->GetScript()->OnSkillEventFired(target, caster, *this->m_effectHandle);
script->OnSkillEventFired(target, caster, *this->m_effectHandle);
}
} }
} }

View File

@ -9,11 +9,15 @@
#include "UserManager.h" #include "UserManager.h"
#include "CDMissionsTable.h" #include "CDMissionsTable.h"
AchievementVendorComponent::AchievementVendorComponent(Entity* parent) : VendorComponent(parent) {
RefreshInventory(true);
};
bool AchievementVendorComponent::SellsItem(Entity* buyer, const LOT lot) { bool AchievementVendorComponent::SellsItem(Entity* buyer, const LOT lot) {
auto* missionComponent = buyer->GetComponent<MissionComponent>(); auto* missionComponent = buyer->GetComponent<MissionComponent>();
if (!missionComponent) return false; if (!missionComponent) return false;
if (m_PlayerPurchasableItems[buyer->GetObjectID()].contains(lot)){ if (m_PlayerPurchasableItems[buyer->GetObjectID()].contains(lot)) {
return true; return true;
} }
@ -35,7 +39,7 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM); int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM);
CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID);
uint32_t costLOT = itemComp.commendationLOT; uint32_t costLOT = itemComp.commendationLOT;
if (costLOT == -1 || !SellsItem(buyer, lot)) { if (costLOT == -1 || !SellsItem(buyer, lot)) {
auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress()); auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress());
CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT()); CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT());
@ -44,7 +48,7 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
} }
auto* inventoryComponent = buyer->GetComponent<InventoryComponent>(); auto* inventoryComponent = buyer->GetComponent<InventoryComponent>();
if (!inventoryComponent) { if (!inventoryComponent) {
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
return; return;
} }
@ -69,4 +73,9 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR); inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS); GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
} }
void AchievementVendorComponent::RefreshInventory(bool isCreation) {
SetHasStandardCostItems(true);
Game::entityManager->SerializeEntity(m_Parent);
}

View File

@ -11,7 +11,9 @@ class Entity;
class AchievementVendorComponent final : public VendorComponent { class AchievementVendorComponent final : public VendorComponent {
public: public:
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ACHIEVEMENT_VENDOR; static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ACHIEVEMENT_VENDOR;
AchievementVendorComponent(Entity* parent) : VendorComponent(parent) {}; AchievementVendorComponent(Entity* parent);
void RefreshInventory(bool isCreation = false) override;
bool SellsItem(Entity* buyer, const LOT lot); bool SellsItem(Entity* buyer, const LOT lot);
void Buy(Entity* buyer, LOT lot, uint32_t count); void Buy(Entity* buyer, LOT lot, uint32_t count);

View File

@ -48,11 +48,35 @@ set(DGAME_DCOMPONENTS_SOURCES
"HavokVehiclePhysicsComponent.cpp" "HavokVehiclePhysicsComponent.cpp"
"VendorComponent.cpp" "VendorComponent.cpp"
"MiniGameControlComponent.cpp" "MiniGameControlComponent.cpp"
"ScriptComponent.cpp"
) )
add_library(dComponents STATIC ${DGAME_DCOMPONENTS_SOURCES}) add_library(dComponents OBJECT ${DGAME_DCOMPONENTS_SOURCES})
target_include_directories(dComponents PRIVATE ${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/General) # PetDigServer.h target_include_directories(dComponents PUBLIC "."
"${PROJECT_SOURCE_DIR}/dGame/dPropertyBehaviors" # via ModelComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dPropertyBehaviors/ControlBehaviorMessages"
"${PROJECT_SOURCE_DIR}/dGame/dMission" # via MissionComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # via InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via InventoryComponent.h
PRIVATE
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
"${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include"
# dPhysics (via dpWorld.h)
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include"
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include"
"${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/General" # PetDigServer.h
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # direct
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # direct Loot.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h
"${PROJECT_SOURCE_DIR}/dZoneManager" # via BouncerComponent.cpp, ActivityComponent.cpp
"${PROJECT_SOURCE_DIR}/dChatFilter" # via PetComponent.cpp
)
target_precompile_headers(dComponents REUSE_FROM dGameBase) target_precompile_headers(dComponents REUSE_FROM dGameBase)
target_link_libraries(dComponents
PUBLIC dPhysics dDatabase target_link_libraries(dComponents INTERFACE dBehaviors)
INTERFACE dUtilities dCommon dBehaviors dChatFilter dMission dInventory)

View File

@ -5,7 +5,6 @@
#include "RakNetTypes.h" #include "RakNetTypes.h"
#include "Character.h" #include "Character.h"
#include "Component.h" #include "Component.h"
#include "Item.h"
#include <string> #include <string>
#include "CDMissionsTable.h" #include "CDMissionsTable.h"
#include "tinyxml2.h" #include "tinyxml2.h"
@ -15,6 +14,8 @@
enum class eGameActivity : uint32_t; enum class eGameActivity : uint32_t;
class Item;
/** /**
* The statistics that can be achieved per zone * The statistics that can be achieved per zone
*/ */

View File

@ -21,7 +21,6 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Phy
m_InJetpackMode = false; m_InJetpackMode = false;
m_IsOnGround = true; m_IsOnGround = true;
m_IsOnRail = false; m_IsOnRail = false;
m_DirtyVelocity = true;
m_dpEntity = nullptr; m_dpEntity = nullptr;
m_Static = false; m_Static = false;
m_SpeedMultiplier = 1; m_SpeedMultiplier = 1;
@ -137,21 +136,23 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
outBitStream.Write(m_IsOnGround); outBitStream.Write(m_IsOnGround);
outBitStream.Write(m_IsOnRail); outBitStream.Write(m_IsOnRail);
outBitStream.Write(isVelocityZero); bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
if (isVelocityZero) { outBitStream.Write(isNotZero);
if (isNotZero) {
outBitStream.Write(m_Velocity.x); outBitStream.Write(m_Velocity.x);
outBitStream.Write(m_Velocity.y); outBitStream.Write(m_Velocity.y);
outBitStream.Write(m_Velocity.z); outBitStream.Write(m_Velocity.z);
} }
outBitStream.Write(isAngularVelocityZero); isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
if (isAngularVelocityZero) { outBitStream.Write(isNotZero);
if (isNotZero) {
outBitStream.Write(m_AngularVelocity.x); outBitStream.Write(m_AngularVelocity.x);
outBitStream.Write(m_AngularVelocity.y); outBitStream.Write(m_AngularVelocity.y);
outBitStream.Write(m_AngularVelocity.z); outBitStream.Write(m_AngularVelocity.z);
} }
outBitStream.Write0(); // LocalSpaceInfo outBitStream.Write0();
if (!bIsInitialUpdate) { if (!bIsInitialUpdate) {
m_DirtyPosition = false; m_DirtyPosition = false;
outBitStream.Write(m_IsTeleporting); outBitStream.Write(m_IsTeleporting);
@ -213,9 +214,7 @@ void ControllablePhysicsComponent::SetRotation(const NiQuaternion& rot) {
} }
void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) { void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) {
if (m_Static || m_Velocity == vel) { if (m_Static || m_Velocity == vel) return;
return;
}
m_Velocity = vel; m_Velocity = vel;
m_DirtyPosition = true; m_DirtyPosition = true;
@ -224,22 +223,20 @@ void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) {
} }
void ControllablePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) { void ControllablePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
if (m_Static || m_AngularVelocity == vel) { if (m_Static || m_AngularVelocity == vel) return;
return;
}
m_AngularVelocity = vel; m_AngularVelocity = vel;
m_DirtyPosition = true; m_DirtyPosition = true;
} }
void ControllablePhysicsComponent::SetIsOnGround(bool val) { void ControllablePhysicsComponent::SetIsOnGround(bool val) {
if (val == m_IsOnGround) return; if (m_IsOnGround == val) return;
m_DirtyPosition = true; m_DirtyPosition = true;
m_IsOnGround = val; m_IsOnGround = val;
} }
void ControllablePhysicsComponent::SetIsOnRail(bool val) { void ControllablePhysicsComponent::SetIsOnRail(bool val) {
if (val == m_IsOnRail) return; if (m_IsOnRail == val) return;
m_DirtyPosition = true; m_DirtyPosition = true;
m_IsOnRail = val; m_IsOnRail = val;
} }

View File

@ -298,11 +298,6 @@ private:
*/ */
dpEntity* m_dpEntity; dpEntity* m_dpEntity;
/**
* Whether or not the velocity is dirty, forcing a serialization of the velocity
*/
bool m_DirtyVelocity;
/** /**
* The current velocity of the entity * The current velocity of the entity
*/ */

View File

@ -785,16 +785,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
} }
Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { if (zoneControl) zoneControl->GetScript()->OnPlayerDied(zoneControl, m_Parent);
script->OnPlayerDied(zoneControl, m_Parent);
}
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
for (Entity* scriptEntity : scriptedActs) { for (Entity* scriptEntity : scriptedActs) {
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { scriptEntity->GetScript()->OnPlayerDied(scriptEntity, m_Parent);
script->OnPlayerDied(scriptEntity, m_Parent);
}
} }
} }
} }

View File

@ -7,8 +7,6 @@ HavokVehiclePhysicsComponent::HavokVehiclePhysicsComponent(Entity* parent) : Phy
m_IsOnGround = true; m_IsOnGround = true;
m_IsOnRail = false; m_IsOnRail = false;
m_DirtyPosition = true; m_DirtyPosition = true;
m_DirtyVelocity = true;
m_DirtyAngularVelocity = true;
m_EndBehavior = GeneralUtils::GenerateRandomNumber<uint32_t>(0, 7); m_EndBehavior = GeneralUtils::GenerateRandomNumber<uint32_t>(0, 7);
} }
@ -37,17 +35,9 @@ void HavokVehiclePhysicsComponent::SetIsOnRail(bool val) {
} }
void HavokVehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) { void HavokVehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) {
if (m_RemoteInputInfo == remoteInputInfo) return; if (remoteInputInfo == m_RemoteInputInfo) return;
this->m_RemoteInputInfo = remoteInputInfo; this->m_RemoteInputInfo = remoteInputInfo;
m_DirtyRemoteInput = true; m_DirtyPosition = true;
}
void HavokVehiclePhysicsComponent::SetDirtyVelocity(bool val) {
m_DirtyVelocity = val;
}
void HavokVehiclePhysicsComponent::SetDirtyAngularVelocity(bool val) {
m_DirtyAngularVelocity = val;
} }
void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) { void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
@ -67,18 +57,17 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
outBitStream.Write(m_IsOnGround); outBitStream.Write(m_IsOnGround);
outBitStream.Write(m_IsOnRail); outBitStream.Write(m_IsOnRail);
bool isVelocityZero = m_Velocity == NiPoint3Constant::ZERO; bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
outBitStream.Write(isNotZero);
outBitStream.Write(isVelocityZero); if (isNotZero) {
if (isVelocityZero) {
outBitStream.Write(m_Velocity.x); outBitStream.Write(m_Velocity.x);
outBitStream.Write(m_Velocity.y); outBitStream.Write(m_Velocity.y);
outBitStream.Write(m_Velocity.z); outBitStream.Write(m_Velocity.z);
} }
bool isAngularVelocityZero = m_AngularVelocity == NiPoint3Constant::ZERO; isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
outBitStream.Write(isAngularVelocityZero); outBitStream.Write(isNotZero);
if (isAngularVelocityZero) { if (isNotZero) {
outBitStream.Write(m_AngularVelocity.x); outBitStream.Write(m_AngularVelocity.x);
outBitStream.Write(m_AngularVelocity.y); outBitStream.Write(m_AngularVelocity.y);
outBitStream.Write(m_AngularVelocity.z); outBitStream.Write(m_AngularVelocity.z);
@ -86,14 +75,14 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
outBitStream.Write0(); // local_space_info. TODO: Implement this outBitStream.Write0(); // local_space_info. TODO: Implement this
outBitStream.Write(m_DirtyRemoteInput || bIsInitialUpdate); // remote_input_info // This structure only has this bool flag set to false if a ptr to the peVehicle is null, which we don't have
if (m_DirtyRemoteInput || bIsInitialUpdate) { // therefore, this will always be 1, even if all the values in the structure are 0.
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputX); outBitStream.Write1(); // has remote_input_info
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputY); outBitStream.Write(m_RemoteInputInfo.m_RemoteInputX);
outBitStream.Write(m_RemoteInputInfo.m_IsPowersliding); outBitStream.Write(m_RemoteInputInfo.m_RemoteInputY);
outBitStream.Write(m_RemoteInputInfo.m_IsModified); outBitStream.Write(m_RemoteInputInfo.m_IsPowersliding);
m_DirtyRemoteInput = false; outBitStream.Write(m_RemoteInputInfo.m_IsModified);
}
outBitStream.Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race. outBitStream.Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race.
@ -109,12 +98,3 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
outBitStream.Write0(); outBitStream.Write0();
} }
void HavokVehiclePhysicsComponent::Update(float deltaTime) {
if (m_SoftUpdate > 5) {
Game::entityManager->SerializeEntity(m_Parent);
m_SoftUpdate = 0;
} else {
m_SoftUpdate += deltaTime;
}
}

View File

@ -17,8 +17,6 @@ public:
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
void Update(float deltaTime) override;
/** /**
* Sets the velocity * Sets the velocity
* @param vel the new velocity * @param vel the new velocity
@ -67,22 +65,16 @@ public:
*/ */
const bool GetIsOnRail() const { return m_IsOnRail; } const bool GetIsOnRail() const { return m_IsOnRail; }
void SetDirtyPosition(bool val);
void SetDirtyVelocity(bool val);
void SetDirtyAngularVelocity(bool val);
void SetRemoteInputInfo(const RemoteInputInfo&); void SetRemoteInputInfo(const RemoteInputInfo&);
private: private:
bool m_DirtyVelocity;
NiPoint3 m_Velocity; NiPoint3 m_Velocity;
bool m_DirtyAngularVelocity;
NiPoint3 m_AngularVelocity; NiPoint3 m_AngularVelocity;
bool m_IsOnGround; bool m_IsOnGround;
bool m_IsOnRail; bool m_IsOnRail;
float m_SoftUpdate = 0; float m_SoftUpdate = 0;
uint32_t m_EndBehavior; uint32_t m_EndBehavior;
RemoteInputInfo m_RemoteInputInfo; RemoteInputInfo m_RemoteInputInfo;
bool m_DirtyRemoteInput;
}; };

View File

@ -162,7 +162,7 @@ void MovingPlatformComponent::StartPathing() {
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
subComponent->mPosition = currentWaypoint.position; subComponent->mPosition = currentWaypoint.position;
subComponent->mSpeed = currentWaypoint.movingPlatform.speed; subComponent->mSpeed = currentWaypoint.speed;
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; subComponent->mWaitTime = currentWaypoint.movingPlatform.wait;
targetPosition = nextWaypoint.position; targetPosition = nextWaypoint.position;
@ -183,9 +183,7 @@ void MovingPlatformComponent::StartPathing() {
const auto travelNext = subComponent->mWaitTime + travelTime; const auto travelNext = subComponent->mWaitTime + travelTime;
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
}
}); });
m_Parent->AddCallbackTimer(travelNext, [this] { m_Parent->AddCallbackTimer(travelNext, [this] {
@ -213,7 +211,7 @@ void MovingPlatformComponent::ContinuePathing() {
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex]; const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
subComponent->mPosition = currentWaypoint.position; subComponent->mPosition = currentWaypoint.position;
subComponent->mSpeed = currentWaypoint.movingPlatform.speed; subComponent->mSpeed = currentWaypoint.speed;
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2; subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2;
pathSize = m_Path->pathWaypoints.size() - 1; pathSize = m_Path->pathWaypoints.size() - 1;
@ -295,9 +293,7 @@ void MovingPlatformComponent::ContinuePathing() {
const auto travelNext = subComponent->mWaitTime + travelTime; const auto travelNext = subComponent->mWaitTime + travelTime;
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] { m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
}
}); });
m_Parent->AddCallbackTimer(travelNext, [this] { m_Parent->AddCallbackTimer(travelNext, [this] {

View File

@ -306,9 +306,7 @@ void PetComponent::OnUse(Entity* originator) {
currentActivities.insert_or_assign(m_Tamer, m_Parent->GetObjectID()); currentActivities.insert_or_assign(m_Tamer, m_Parent->GetObjectID());
// Notify the start of a pet taming minigame // Notify the start of a pet taming minigame
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, originator, ePetTamingNotifyType::BEGIN);
script->OnNotifyPetTamingMinigame(m_Parent, originator, ePetTamingNotifyType::BEGIN);
}
} }
void PetComponent::Update(float deltaTime) { void PetComponent::Update(float deltaTime) {
@ -690,9 +688,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
m_Tamer = LWOOBJID_EMPTY; m_Tamer = LWOOBJID_EMPTY;
// Notify the end of a pet taming minigame // Notify the end of a pet taming minigame
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::SUCCESS);
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::SUCCESS);
}
} }
void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
@ -731,9 +727,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
Game::entityManager->SerializeEntity(m_Parent); Game::entityManager->SerializeEntity(m_Parent);
// Notify the end of a pet taming minigame // Notify the end of a pet taming minigame
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::QUIT);
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::QUIT);
}
} }
void PetComponent::StartTimer() { void PetComponent::StartTimer() {
@ -782,9 +776,7 @@ void PetComponent::ClientFailTamingMinigame() {
Game::entityManager->SerializeEntity(m_Parent); Game::entityManager->SerializeEntity(m_Parent);
// Notify the end of a pet taming minigame // Notify the end of a pet taming minigame
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::FAILED);
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::FAILED);
}
} }
void PetComponent::Wander() { void PetComponent::Wander() {

View File

@ -353,7 +353,6 @@ private:
/** /**
* Pet information loaded from the CDClientDatabase * Pet information loaded from the CDClientDatabase
* TODO: Switch to a reference when safe to do so
*/ */
CDPetComponent m_PetInfo; CDPetComponent m_PetInfo;
}; };

View File

@ -214,9 +214,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
Database::Get()->InsertNewProperty(info, templateId, worldId); Database::Get()->InsertNewProperty(info, templateId, worldId);
auto* zoneControlObject = Game::zoneManager->GetZoneControlObject(); auto* zoneControlObject = Game::zoneManager->GetZoneControlObject();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControlObject)) { if (zoneControlObject) zoneControlObject->GetScript()->OnZonePropertyRented(zoneControlObject, entity);
script->OnZonePropertyRented(zoneControlObject, entity);
}
return true; return true;
} }

View File

@ -414,13 +414,11 @@ void QuickBuildComponent::StartQuickBuild(Entity* const user) {
movingPlatform->OnQuickBuildInitilized(); movingPlatform->OnQuickBuildInitilized();
} }
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) { auto* script = m_Parent->GetScript();
script->OnQuickBuildStart(m_Parent, user); script->OnQuickBuildStart(m_Parent, user);
}
// Notify scripts and possible subscribers // Notify scripts and possible subscribers
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) script->OnQuickBuildNotifyState(m_Parent, m_State);
script->OnQuickBuildNotifyState(m_Parent, m_State);
for (const auto& cb : m_QuickBuildStateCallbacks) for (const auto& cb : m_QuickBuildStateCallbacks)
cb(m_State); cb(m_State);
} }
@ -485,10 +483,9 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* const user) {
} }
// Notify scripts // Notify scripts
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) { auto* script = m_Parent->GetScript();
script->OnQuickBuildComplete(m_Parent, user); script->OnQuickBuildComplete(m_Parent, user);
script->OnQuickBuildNotifyState(m_Parent, m_State); script->OnQuickBuildNotifyState(m_Parent, m_State);
}
// Notify subscribers // Notify subscribers
for (const auto& callback : m_QuickBuildStateCallbacks) for (const auto& callback : m_QuickBuildStateCallbacks)
@ -539,8 +536,7 @@ void QuickBuildComponent::ResetQuickBuild(const bool failed) {
Game::entityManager->SerializeEntity(m_Parent); Game::entityManager->SerializeEntity(m_Parent);
// Notify scripts and possible subscribers // Notify scripts and possible subscribers
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) m_Parent->GetScript()->OnQuickBuildNotifyState(m_Parent, m_State);
script->OnQuickBuildNotifyState(m_Parent, m_State);
for (const auto& cb : m_QuickBuildStateCallbacks) for (const auto& cb : m_QuickBuildStateCallbacks)
cb(m_State); cb(m_State);
@ -571,8 +567,7 @@ void QuickBuildComponent::CancelQuickBuild(Entity* const entity, const eQuickBui
m_StateDirty = true; m_StateDirty = true;
// Notify scripts and possible subscribers // Notify scripts and possible subscribers
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) m_Parent->GetScript()->OnQuickBuildNotifyState(m_Parent, m_State);
script->OnQuickBuildNotifyState(m_Parent, m_State);
for (const auto& cb : m_QuickBuildStateCallbacks) for (const auto& cb : m_QuickBuildStateCallbacks)
cb(m_State); cb(m_State);

View File

@ -41,7 +41,7 @@ void ScriptComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitial
} }
} }
CppScripts::Script* ScriptComponent::GetScript() { CppScripts::Script* const ScriptComponent::GetScript() {
return m_Script; return m_Script;
} }

View File

@ -30,7 +30,7 @@ public:
* Returns the script that's attached to this entity * Returns the script that's attached to this entity
* @return the script that's attached to this entity * @return the script that's attached to this entity
*/ */
CppScripts::Script* GetScript(); CppScripts::Script* const GetScript();
/** /**
* Sets whether the entity should be serialized, unused * Sets whether the entity should be serialized, unused

View File

@ -268,9 +268,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c
behavior->Calculate(context, bitStream, { target, 0 }); behavior->Calculate(context, bitStream, { target, 0 });
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) { m_Parent->GetScript()->OnSkillCast(m_Parent, skillId);
script->OnSkillCast(m_Parent, skillId);
}
if (!context->foundTarget) { if (!context->foundTarget) {
delete context; delete context;

View File

@ -14,6 +14,8 @@
#include "MovementAIComponent.h" #include "MovementAIComponent.h"
#include "eEndBehavior.h" #include "eEndBehavior.h"
#include "PlayerManager.h" #include "PlayerManager.h"
#include "Game.h"
#include "EntityManager.h"
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) { TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) {
m_Parent = parent; m_Parent = parent;
@ -194,9 +196,7 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman
} }
void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) { void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { targetEntity->GetScript()->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0);
script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0);
}
} }
void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){ void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){

View File

@ -40,9 +40,19 @@ void VendorComponent::RefreshInventory(bool isCreation) {
SetHasMultiCostItems(false); SetHasMultiCostItems(false);
m_Inventory.clear(); m_Inventory.clear();
// Custom code for Max vanity NPC and Mr.Ree cameras // Custom code for Vanity Vendor Invetory Override
if(isCreation && m_Parent->GetLOT() == 9749 && Game::server->GetZoneID() == 1201) { if(m_Parent->HasVar(u"vendorInvOverride")) {
SetupMaxCustomVendor(); std::vector<std::string> items = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"vendorInvOverride"), ',');
uint32_t sortPriority = -1;
for (auto& itemString : items) {
itemString.erase(remove_if(itemString.begin(), itemString.end(), isspace), itemString.end());
auto item = GeneralUtils::TryParse<uint32_t>(itemString);
if (!item) continue;
if (SetupItem(item.value())) {
sortPriority++;
m_Inventory.push_back(SoldItem(item.value(), sortPriority));
}
}
return; return;
} }
@ -52,24 +62,12 @@ void VendorComponent::RefreshInventory(bool isCreation) {
if (lootMatrices.empty()) return; if (lootMatrices.empty()) return;
auto* lootTableTable = CDClientManager::GetTable<CDLootTableTable>(); auto* lootTableTable = CDClientManager::GetTable<CDLootTableTable>();
auto* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
for (const auto& lootMatrix : lootMatrices) { for (const auto& lootMatrix : lootMatrices) {
auto vendorItems = lootTableTable->GetTable(lootMatrix.LootTableIndex); auto vendorItems = lootTableTable->GetTable(lootMatrix.LootTableIndex);
if (lootMatrix.maxToDrop == 0 || lootMatrix.minToDrop == 0) { if (lootMatrix.maxToDrop == 0 || lootMatrix.minToDrop == 0) {
for (const auto& item : vendorItems) { for (const auto& item : vendorItems) {
if (!m_HasStandardCostItems || !m_HasMultiCostItems) { if (SetupItem(item.itemid)) m_Inventory.push_back(SoldItem(item.itemid, item.sortPriority));
auto itemComponentID = compRegistryTable->GetByIDAndType(item.itemid, eReplicaComponentType::ITEM, -1);
if (itemComponentID == -1) {
LOG("Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
continue;
}
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
}
m_Inventory.push_back(SoldItem(item.itemid, item.sortPriority));
} }
} else { } else {
auto randomCount = GeneralUtils::GenerateRandomNumber<int32_t>(lootMatrix.minToDrop, lootMatrix.maxToDrop); auto randomCount = GeneralUtils::GenerateRandomNumber<int32_t>(lootMatrix.minToDrop, lootMatrix.maxToDrop);
@ -79,17 +77,7 @@ void VendorComponent::RefreshInventory(bool isCreation) {
auto randomItemIndex = GeneralUtils::GenerateRandomNumber<int32_t>(0, vendorItems.size() - 1); auto randomItemIndex = GeneralUtils::GenerateRandomNumber<int32_t>(0, vendorItems.size() - 1);
const auto& randomItem = vendorItems.at(randomItemIndex); const auto& randomItem = vendorItems.at(randomItemIndex);
vendorItems.erase(vendorItems.begin() + randomItemIndex); vendorItems.erase(vendorItems.begin() + randomItemIndex);
if (!m_HasStandardCostItems || !m_HasMultiCostItems) { if (SetupItem(randomItem.itemid)) m_Inventory.push_back(SoldItem(randomItem.itemid, randomItem.sortPriority));
auto itemComponentID = compRegistryTable->GetByIDAndType(randomItem.itemid, eReplicaComponentType::ITEM, -1);
if (itemComponentID == -1) {
LOG("Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
continue;
}
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
}
m_Inventory.push_back(SoldItem(randomItem.itemid, randomItem.sortPriority));
} }
} }
} }
@ -126,15 +114,6 @@ bool VendorComponent::SellsItem(const LOT item) const {
}) > 0; }) > 0;
} }
void VendorComponent::SetupMaxCustomVendor(){
SetHasStandardCostItems(true);
m_Inventory.push_back(SoldItem(11909, 0)); // Top hat w frog
m_Inventory.push_back(SoldItem(7785, 0)); // Flash bulb
m_Inventory.push_back(SoldItem(12764, 0)); // Big fountain soda
m_Inventory.push_back(SoldItem(12241, 0)); // Hot cocoa (from fb)
}
void VendorComponent::HandleMrReeCameras(){ void VendorComponent::HandleMrReeCameras(){
if (m_Parent->GetLOT() == 13569) { if (m_Parent->GetLOT() == 13569) {
SetHasStandardCostItems(true); SetHasStandardCostItems(true);
@ -211,5 +190,25 @@ void VendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR); character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR);
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR); inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS); GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
}
bool VendorComponent::SetupItem(LOT item) {
auto* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
auto itemComponentID = compRegistryTable->GetByIDAndType(item, eReplicaComponentType::ITEM, -1);
if (itemComponentID == -1) {
LOG("Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
return false;
}
if (!m_HasStandardCostItems || !m_HasMultiCostItems) {
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
}
return true;
}
}

View File

@ -26,7 +26,7 @@ public:
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
void OnUse(Entity* originator) override; void OnUse(Entity* originator) override;
void RefreshInventory(bool isCreation = false); virtual void RefreshInventory(bool isCreation = false);
void SetupConstants(); void SetupConstants();
bool SellsItem(const LOT item) const; bool SellsItem(const LOT item) const;
float GetBuyScalar() const { return m_BuyScalar; } float GetBuyScalar() const { return m_BuyScalar; }
@ -50,8 +50,8 @@ public:
void Buy(Entity* buyer, LOT lot, uint32_t count); void Buy(Entity* buyer, LOT lot, uint32_t count);
private: private:
void SetupMaxCustomVendor();
void HandleMrReeCameras(); void HandleMrReeCameras();
bool SetupItem(LOT item);
float m_BuyScalar = 0.0f; float m_BuyScalar = 0.0f;
float m_SellScalar = 0.0f; float m_SellScalar = 0.0f;
float m_RefreshTimeSeconds = 0.0f; float m_RefreshTimeSeconds = 0.0f;

View File

@ -2,6 +2,6 @@ set(DGAME_DENTITY_SOURCES
"EntityCallbackTimer.cpp" "EntityCallbackTimer.cpp"
"EntityTimer.cpp") "EntityTimer.cpp")
add_library(dEntity STATIC ${DGAME_DENTITY_SOURCES}) add_library(dEntity OBJECT ${DGAME_DENTITY_SOURCES})
target_include_directories(dEntity PUBLIC ".") target_include_directories(dEntity PUBLIC ".")
target_precompile_headers(dEntity REUSE_FROM dGameBase) target_precompile_headers(dEntity REUSE_FROM dGameBase)

View File

@ -4,6 +4,20 @@ set(DGAME_DGAMEMESSAGES_SOURCES
"PropertyDataMessage.cpp" "PropertyDataMessage.cpp"
"PropertySelectQueryProperty.cpp") "PropertySelectQueryProperty.cpp")
add_library(dGameMessages STATIC ${DGAME_DGAMEMESSAGES_SOURCES}) add_library(dGameMessages OBJECT ${DGAME_DGAMEMESSAGES_SOURCES})
target_link_libraries(dGameMessages PUBLIC dDatabase) target_link_libraries(dGameMessages
PUBLIC dDatabase
INTERFACE dGameBase # TradingManager
)
target_include_directories(dGameMessages PUBLIC "."
PRIVATE
"${PROJECT_SOURCE_DIR}/dGame/dComponents" # direct MissionComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # direct SlashCommandHandler.h
"${PROJECT_SOURCE_DIR}/dGame/dPropertyBehaviors" # direct ControlBehaviors.h
"${PROJECT_SOURCE_DIR}/dGame/dMission" # via MissionComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # via InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h
"${PROJECT_SOURCE_DIR}/dZoneManager" # via GameMessages.cpp, GameMessageHandler.cpp
)
target_precompile_headers(dGameMessages REUSE_FROM dGameBase) target_precompile_headers(dGameMessages REUSE_FROM dGameBase)

View File

@ -136,16 +136,14 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
} }
Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { if (zoneControl) {
script->OnPlayerLoaded(zoneControl, entity); zoneControl->GetScript()->OnPlayerLoaded(zoneControl, entity);
} }
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT);
for (Entity* scriptEntity : scriptedActs) { for (Entity* scriptEntity : scriptedActs) {
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { scriptEntity->GetScript()->OnPlayerLoaded(scriptEntity, entity);
script->OnPlayerLoaded(scriptEntity, entity);
}
} }
} }

View File

@ -321,9 +321,9 @@ void GameMessages::SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& s
CMSGHEADER; CMSGHEADER;
bitStream.Write(entity->GetObjectID()); bitStream.Write(entity->GetObjectID());
bitStream.Write((uint16_t)eGameMessageType::PLAY_ND_AUDIO_EMITTER); bitStream.Write(eGameMessageType::PLAY_ND_AUDIO_EMITTER);
bitStream.Write0(); // callback message data {lwoobjid} bitStream.Write0(); // callback message data {lwoobjid}
bitStream.Write0(); // audio emmitterid {uint32_t}} bitStream.Write0(); // audio emitterid {uint32_t}
uint32_t length = audioGUID.size(); uint32_t length = audioGUID.size();
bitStream.Write(length); bitStream.Write(length);
@ -331,8 +331,8 @@ void GameMessages::SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& s
bitStream.Write<char>(audioGUID[k]); bitStream.Write<char>(audioGUID[k]);
} }
bitStream.Write(uint32_t(0)); // size of NDAudioMetaEventName (then print he string like the guid) bitStream.Write<uint32_t>(0); // size of NDAudioMetaEventName (then print the string like the guid)
bitStream.Write0(); //result {bool} bitStream.Write0(); // result {bool}
bitStream.Write0(); // m_TargetObjectIDForNDAudioCallbackMessages {lwoobjid} bitStream.Write0(); // m_TargetObjectIDForNDAudioCallbackMessages {lwoobjid}
SEND_PACKET_BROADCAST; SEND_PACKET_BROADCAST;
@ -5083,9 +5083,7 @@ void GameMessages::HandleRespondToMission(RakNet::BitStream& inStream, Entity* e
return; return;
} }
for (CppScripts::Script* script : CppScripts::GetEntityScripts(offerer)) { offerer->GetScript()->OnRespondToMission(offerer, missionID, Game::entityManager->GetEntity(playerID), reward);
script->OnRespondToMission(offerer, missionID, Game::entityManager->GetEntity(playerID), reward);
}
} }
void GameMessages::HandleMissionDialogOK(RakNet::BitStream& inStream, Entity* entity) { void GameMessages::HandleMissionDialogOK(RakNet::BitStream& inStream, Entity* entity) {
@ -5101,9 +5099,7 @@ void GameMessages::HandleMissionDialogOK(RakNet::BitStream& inStream, Entity* en
inStream.Read(responder); inStream.Read(responder);
player = Game::entityManager->GetEntity(responder); player = Game::entityManager->GetEntity(responder);
for (CppScripts::Script* script : CppScripts::GetEntityScripts(entity)) { if (entity) entity->GetScript()->OnMissionDialogueOK(entity, player, missionID, iMissionState);
script->OnMissionDialogueOK(entity, player, missionID, iMissionState);
}
// Get the player's mission component // Get the player's mission component
MissionComponent* missionComponent = static_cast<MissionComponent*>(player->GetComponent(eReplicaComponentType::MISSION)); MissionComponent* missionComponent = static_cast<MissionComponent*>(player->GetComponent(eReplicaComponentType::MISSION));
@ -5556,9 +5552,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream& inStream, Entity*
ScriptComponent* script = static_cast<ScriptComponent*>(entity->GetComponent(eReplicaComponentType::SCRIPT)); ScriptComponent* script = static_cast<ScriptComponent*>(entity->GetComponent(eReplicaComponentType::SCRIPT));
for (CppScripts::Script* script : CppScripts::GetEntityScripts(entity)) { entity->GetScript()->OnModularBuildExit(entity, character, count >= 3, modList);
script->OnModularBuildExit(entity, character, count >= 3, modList);
}
// Move remaining temp models back to models // Move remaining temp models back to models
std::vector<Item*> items; std::vector<Item*> items;
@ -5734,16 +5728,14 @@ void GameMessages::HandleResurrect(RakNet::BitStream& inStream, Entity* entity)
bool immediate = inStream.ReadBit(); bool immediate = inStream.ReadBit();
Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { if (zoneControl) {
script->OnPlayerResurrected(zoneControl, entity); zoneControl->GetScript()->OnPlayerResurrected(zoneControl, entity);
} }
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
for (Entity* scriptEntity : scriptedActs) { for (Entity* scriptEntity : scriptedActs) {
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { scriptEntity->GetScript()->OnPlayerResurrected(scriptEntity, entity);
script->OnPlayerResurrected(scriptEntity, entity);
}
} }
} }
} }
@ -5977,9 +5969,7 @@ void GameMessages::HandlePlayerRailArrivedNotification(RakNet::BitStream& inStre
const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR);
for (auto* possibleRail : possibleRails) { for (auto* possibleRail : possibleRails) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(possibleRail)) { if (possibleRail) possibleRail->GetScript()->OnPlayerRailArrived(possibleRail, entity, pathName, waypointNumber);
script->OnPlayerRailArrived(possibleRail, entity, pathName, waypointNumber);
}
} }
} }

View File

@ -5,11 +5,32 @@ set(DGAME_DINVENTORY_SOURCES
"ItemSet.cpp" "ItemSet.cpp"
"ItemSetPassiveAbility.cpp") "ItemSetPassiveAbility.cpp")
add_library(dInventory OBJECT ${DGAME_DINVENTORY_SOURCES})
target_include_directories(dInventory PUBLIC "."
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # Item.h uses Preconditions.h
"${PROJECT_SOURCE_DIR}/dCommon/eEnums" # Item.h uses dCommonVars.h
PRIVATE
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
"${PROJECT_SOURCE_DIR}/dCommon/dClient" # Item.cpp uses AssetManager
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables"
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # direct
"${PROJECT_SOURCE_DIR}/dGame/dComponents" # direct InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # via InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h
"${PROJECT_SOURCE_DIR}/dGame/dMission" # via MissionComponent.h
"${PROJECT_SOURCE_DIR}/dZoneManager" # via Item.cpp
)
target_precompile_headers(dInventory REUSE_FROM dGameBase)
# Workaround for compiler bug where the optimized code could result in a memcpy of 0 bytes, even though that isnt possible. # Workaround for compiler bug where the optimized code could result in a memcpy of 0 bytes, even though that isnt possible.
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97185 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97185
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set_source_files_properties("Item.cpp" PROPERTIES COMPILE_FLAGS "-Wno-stringop-overflow") set_source_files_properties("Item.cpp" PROPERTIES COMPILE_FLAGS "-Wno-stringop-overflow")
endif() endif()
# INTERFACE link w/o dependency
add_library(dInventory STATIC ${DGAME_DINVENTORY_SOURCES}) #set_property(TARGET dInventory APPEND PROPERTY INTERFACE_LINK_LIBRARIES
target_precompile_headers(dInventory REUSE_FROM dGameBase) # dNet dDatabaseCDClient
#)

View File

@ -3,6 +3,16 @@ set(DGAME_DMISSION_SOURCES
"MissionPrerequisites.cpp" "MissionPrerequisites.cpp"
"MissionTask.cpp") "MissionTask.cpp")
add_library(dMission STATIC ${DGAME_DMISSION_SOURCES}) add_library(dMission OBJECT ${DGAME_DMISSION_SOURCES})
target_link_libraries(dMission PUBLIC dDatabase) target_link_libraries(dMission PUBLIC dDatabase)
target_include_directories(dMission PUBLIC "."
PRIVATE
"${PROJECT_SOURCE_DIR}/dGame/dComponents"
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via CharacterComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # via CharacterComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # via LevelProgressionComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # via InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dZoneManager" # via Mission.cpp, MissionTask.cpp
)
target_precompile_headers(dMission REUSE_FROM dGameBase) target_precompile_headers(dMission REUSE_FROM dGameBase)

View File

@ -12,5 +12,15 @@ foreach(file ${DGAME_DPROPERTYBEHAVIORS_CONTROLBEHAVIORMESSAGES})
set(DGAME_DPROPERTYBEHAVIORS_SOURCES ${DGAME_DPROPERTYBEHAVIORS_SOURCES} "ControlBehaviorMessages/${file}") set(DGAME_DPROPERTYBEHAVIORS_SOURCES ${DGAME_DPROPERTYBEHAVIORS_SOURCES} "ControlBehaviorMessages/${file}")
endforeach() endforeach()
add_library(dPropertyBehaviors STATIC ${DGAME_DPROPERTYBEHAVIORS_SOURCES}) add_library(dPropertyBehaviors OBJECT ${DGAME_DPROPERTYBEHAVIORS_SOURCES})
target_link_libraries(dPropertyBehaviors PRIVATE dDatabaseCDClient)
target_include_directories(dPropertyBehaviors PUBLIC "." "ControlBehaviorMessages"
PRIVATE
"${PROJECT_SOURCE_DIR}/dCommon/dClient" # ControlBehaviors.cpp uses AssetManager
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # ObjectIdManager.h
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # GameMessages.h
"${PROJECT_SOURCE_DIR}/dGame/dComponents" # ModelComponent.h
)
target_precompile_headers(dPropertyBehaviors REUSE_FROM dGameBase) target_precompile_headers(dPropertyBehaviors REUSE_FROM dGameBase)
target_link_libraries(dPropertyBehaviors INTERFACE dComponents)

View File

@ -8,8 +8,18 @@ set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp"
"SlashCommandHandler.cpp" "SlashCommandHandler.cpp"
"VanityUtilities.cpp") "VanityUtilities.cpp")
add_library(dUtilities STATIC ${DGAME_DUTILITIES_SOURCES}) add_library(dUtilities OBJECT ${DGAME_DUTILITIES_SOURCES})
target_precompile_headers(dUtilities REUSE_FROM dGameBase) target_precompile_headers(dUtilities REUSE_FROM dGameBase)
target_include_directories(dUtilities PUBLIC "."
PRIVATE
"${PROJECT_SOURCE_DIR}/dGame/dComponents"
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # transitive via PossessableComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages"
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # transitive via InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dMission" # transitive via MissionComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # transitive via dZoneManager/Spawner.h
"${PROJECT_SOURCE_DIR}/dZoneManager" # Mail.cpp
)
target_link_libraries(dUtilities target_link_libraries(dUtilities
PUBLIC dDatabase dPhysics PUBLIC dDatabase dPhysics
INTERFACE dZoneManager) INTERFACE dZoneManager)

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "dCommonVars.h" #include "dCommonVars.h"
#include "eLootSourceType.h"
#include <unordered_map> #include <unordered_map>
class Entity; class Entity;

View File

@ -22,9 +22,18 @@
#include <fstream> #include <fstream>
std::vector<VanityObject> VanityUtilities::m_Objects = {};
std::set<std::string> VanityUtilities::m_LoadedFiles = {};
namespace {
std::vector<VanityObject> objects;
std::set<std::string> loadedFiles;
}
void SetupNPCTalk(Entity* npc);
void NPCTalk(Entity* npc);
void ParseXml(const std::string& file);
LWOOBJID SpawnSpawner(const VanityObject& object, const VanityObjectLocation& location);
Entity* SpawnObject(const VanityObject& object, const VanityObjectLocation& location);
VanityObject* GetObject(const std::string& name);
void VanityUtilities::SpawnVanity() { void VanityUtilities::SpawnVanity() {
const uint32_t zoneID = Game::server->GetZoneID(); const uint32_t zoneID = Game::server->GetZoneID();
@ -36,21 +45,19 @@ void VanityUtilities::SpawnVanity() {
info.pos = { 259.5f, 246.4f, -705.2f }; info.pos = { 259.5f, 246.4f, -705.2f };
info.rot = { 0.0f, 0.0f, 1.0f, 0.0f }; info.rot = { 0.0f, 0.0f, 1.0f, 0.0f };
info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
info.settings = {
info.settings = { new LDFData<bool>(u"hasCustomText", true), new LDFData<bool>(u"hasCustomText", true),
new LDFData<std::string>(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string())) }; new LDFData<std::string>(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string()))
};
auto* entity = Game::entityManager->CreateEntity(info); auto* entity = Game::entityManager->CreateEntity(info);
Game::entityManager->ConstructEntity(entity); Game::entityManager->ConstructEntity(entity);
} }
} }
if (Game::config->GetValue("disable_vanity") == "1") { if (Game::config->GetValue("disable_vanity") == "1") return;
return;
}
for (const auto& npc : m_Objects) { for (const auto& npc : objects) {
if (npc.m_ID == LWOOBJID_EMPTY) continue; if (npc.m_ID == LWOOBJID_EMPTY) continue;
if (npc.m_LOT == 176){ if (npc.m_LOT == 176){
Game::zoneManager->RemoveSpawner(npc.m_ID); Game::zoneManager->RemoveSpawner(npc.m_ID);
@ -61,13 +68,13 @@ void VanityUtilities::SpawnVanity() {
} }
} }
m_Objects.clear(); objects.clear();
m_LoadedFiles.clear(); loadedFiles.clear();
ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/root.xml").string()); ParseXml((BinaryPathFinder::GetBinaryDir() / "vanity/root.xml").string());
// Loop through all objects // Loop through all objects
for (auto& object : m_Objects) { for (auto& object : objects) {
if (object.m_Locations.find(Game::server->GetZoneID()) == object.m_Locations.end()) continue; if (object.m_Locations.find(Game::server->GetZoneID()) == object.m_Locations.end()) continue;
const std::vector<VanityObjectLocation>& locations = object.m_Locations.at(Game::server->GetZoneID()); const std::vector<VanityObjectLocation>& locations = object.m_Locations.at(Game::server->GetZoneID());
@ -79,12 +86,6 @@ void VanityUtilities::SpawnVanity() {
float rate = GeneralUtils::GenerateRandomNumber<float>(0, 1); float rate = GeneralUtils::GenerateRandomNumber<float>(0, 1);
if (location.m_Chance < rate) continue; if (location.m_Chance < rate) continue;
if (object.m_Config.empty()) {
object.m_Config = {
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 (object.m_LOT == 176){ if (object.m_LOT == 176){
object.m_ID = SpawnSpawner(object, location); object.m_ID = SpawnSpawner(object, location);
} else { } else {
@ -94,20 +95,13 @@ void VanityUtilities::SpawnVanity() {
object.m_ID = objectEntity->GetObjectID(); object.m_ID = objectEntity->GetObjectID();
if (!object.m_Phrases.empty()){ if (!object.m_Phrases.empty()){
objectEntity->SetVar<std::vector<std::string>>(u"chats", object.m_Phrases); objectEntity->SetVar<std::vector<std::string>>(u"chats", object.m_Phrases);
auto* scriptComponent = objectEntity->GetComponent<ScriptComponent>();
if (scriptComponent && !object.m_Script.empty()) {
scriptComponent->SetScript(object.m_Script);
scriptComponent->SetSerialized(false);
}
SetupNPCTalk(objectEntity); SetupNPCTalk(objectEntity);
} }
} }
} }
} }
LWOOBJID VanityUtilities::SpawnSpawner(const VanityObject& object, const VanityObjectLocation& location) { LWOOBJID SpawnSpawner(const VanityObject& object, const VanityObjectLocation& location) {
SceneObject obj; SceneObject obj;
obj.lot = object.m_LOT; obj.lot = object.m_LOT;
// guratantee we have no collisions // guratantee we have no collisions
@ -121,7 +115,7 @@ LWOOBJID VanityUtilities::SpawnSpawner(const VanityObject& object, const VanityO
return obj.id; return obj.id;
} }
Entity* VanityUtilities::SpawnObject(const VanityObject& object, const VanityObjectLocation& location) { Entity* SpawnObject(const VanityObject& object, const VanityObjectLocation& location) {
EntityInfo info; EntityInfo info;
info.lot = object.m_LOT; info.lot = object.m_LOT;
info.pos = location.m_Position; info.pos = location.m_Position;
@ -131,18 +125,16 @@ Entity* VanityUtilities::SpawnObject(const VanityObject& object, const VanityObj
info.settings = object.m_Config; info.settings = object.m_Config;
auto* entity = Game::entityManager->CreateEntity(info); auto* entity = Game::entityManager->CreateEntity(info);
entity->SetVar(u"npcName", object.m_Name); if (!object.m_Name.empty()) entity->SetVar(u"npcName", object.m_Name);
if (entity->GetVar<bool>(u"noGhosting")) entity->SetIsGhostingCandidate(false); if (entity->GetVar<bool>(u"noGhosting")) entity->SetIsGhostingCandidate(false);
auto* inventoryComponent = entity->GetComponent<InventoryComponent>(); auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
if (inventoryComponent && !object.m_Equipment.empty()) { if (inventoryComponent && !object.m_Equipment.empty()) {
inventoryComponent->SetNPCItems(object.m_Equipment); inventoryComponent->SetNPCItems(object.m_Equipment);
} }
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>(); auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (destroyableComponent) {
if (destroyableComponent != nullptr) {
destroyableComponent->SetIsGMImmune(true); destroyableComponent->SetIsGMImmune(true);
destroyableComponent->SetMaxHealth(0); destroyableComponent->SetMaxHealth(0);
destroyableComponent->SetHealth(0); destroyableComponent->SetHealth(0);
@ -153,12 +145,12 @@ Entity* VanityUtilities::SpawnObject(const VanityObject& object, const VanityObj
return entity; return entity;
} }
void VanityUtilities::ParseXML(const std::string& file) { void ParseXml(const std::string& file) {
if (m_LoadedFiles.contains(file)){ if (loadedFiles.contains(file)){
LOG("Trying to load vanity file %s twice!!!", file.c_str()); LOG("Trying to load vanity file %s twice!!!", file.c_str());
return; return;
} }
m_LoadedFiles.insert(file); loadedFiles.insert(file);
// Read the entire file // Read the entire file
std::ifstream xmlFile(file); std::ifstream xmlFile(file);
std::string xml((std::istreambuf_iterator<char>(xmlFile)), std::istreambuf_iterator<char>()); std::string xml((std::istreambuf_iterator<char>(xmlFile)), std::istreambuf_iterator<char>());
@ -176,24 +168,26 @@ void VanityUtilities::ParseXML(const std::string& file) {
if (enabled != "1") { if (enabled != "1") {
continue; continue;
} }
ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity" / filename).string()); ParseXml((BinaryPathFinder::GetBinaryDir() / "vanity" / filename).string());
} }
} }
// Read the objects // Read the objects
auto* objects = doc.FirstChildElement("objects"); auto* objectsElement = doc.FirstChildElement("objects");
const uint32_t currentZoneID = Game::server->GetZoneID();
if (objects) { if (objectsElement) {
for (auto* object = objects->FirstChildElement("object"); object != nullptr; object = object->NextSiblingElement("object")) { for (auto* object = objectsElement->FirstChildElement("object"); object != nullptr; object = object->NextSiblingElement("object")) {
// for use later when adding to the vector of VanityObjects
bool useLocationsAsRandomSpawnPoint = false;
// Get the NPC name // Get the NPC name
auto* name = object->Attribute("name"); auto* name = object->Attribute("name");
if (!name) name = ""; if (!name) name = "";
// Get the NPC lot // Get the NPC lot
auto* lot = object->Attribute("lot"); auto lot = GeneralUtils::TryParse<LOT>(object->Attribute("lot")).value_or(LOT_NULL);
if (lot == nullptr) { if (lot == LOT_NULL) {
LOG("Failed to parse object lot"); LOG("Failed to parse object lot");
continue; continue;
} }
@ -211,17 +205,17 @@ void VanityUtilities::ParseXML(const std::string& file) {
std::vector<std::string> splitEquipment = GeneralUtils::SplitString(equipmentString, ','); std::vector<std::string> splitEquipment = GeneralUtils::SplitString(equipmentString, ',');
for (auto& item : splitEquipment) { for (auto& item : splitEquipment) {
inventory.push_back(std::stoi(item)); // remove spaces for tryParse to work
item.erase(remove_if(item.begin(), item.end(), isspace), item.end());
auto itemInt = GeneralUtils::TryParse<uint32_t>(item);
if (itemInt) inventory.push_back(itemInt.value());
} }
} }
} }
// Get the phrases // Get the phrases
auto* phrases = object->FirstChildElement("phrases"); auto* phrases = object->FirstChildElement("phrases");
std::vector<std::string> phraseList = {}; std::vector<std::string> phraseList = {};
if (phrases) { if (phrases) {
for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr; for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr;
phrase = phrase->NextSiblingElement("phrase")) { phrase = phrase->NextSiblingElement("phrase")) {
@ -235,41 +229,34 @@ void VanityUtilities::ParseXML(const std::string& file) {
} }
} }
// Get the script
auto* scriptElement = object->FirstChildElement("script");
std::string scriptName = "";
if (scriptElement != nullptr) {
auto* scriptNameAttribute = scriptElement->Attribute("name");
if (scriptNameAttribute) scriptName = scriptNameAttribute;
}
auto* configElement = object->FirstChildElement("config"); auto* configElement = object->FirstChildElement("config");
std::vector<std::u16string> keys = {}; std::vector<std::u16string> keys = {};
std::vector<LDFBaseData*> config = {}; std::vector<LDFBaseData*> config = {};
if(configElement) { if(configElement) {
for (auto* key = configElement->FirstChildElement("key"); key != nullptr; for (auto* key = configElement->FirstChildElement("key"); key != nullptr;
key = key->NextSiblingElement("key")) { key = key->NextSiblingElement("key")) {
// Get the config data // Get the config data
auto* data = key->Attribute("data"); auto* data = key->GetText();
if (!data) continue; if (!data) continue;
LDFBaseData* configData = LDFBaseData::DataFromString(data); LDFBaseData* configData = LDFBaseData::DataFromString(data);
if (configData->GetKey() == u"useLocationsAsRandomSpawnPoint" && configData->GetValueType() == eLDFType::LDF_TYPE_BOOLEAN){
useLocationsAsRandomSpawnPoint = static_cast<bool>(configData);
continue;
}
keys.push_back(configData->GetKey()); keys.push_back(configData->GetKey());
config.push_back(configData); config.push_back(configData);
} }
} }
if (!keys.empty()) config.push_back(new LDFData<std::vector<std::u16string>>(u"syncLDF", keys)); if (!keys.empty()) config.push_back(new LDFData<std::vector<std::u16string>>(u"syncLDF", keys));
VanityObject objectData; VanityObject objectData {
objectData.m_Name = name; .m_Name = name,
objectData.m_LOT = std::stoi(lot); .m_LOT = lot,
objectData.m_Equipment = inventory; .m_Equipment = inventory,
objectData.m_Phrases = phraseList; .m_Phrases = phraseList,
objectData.m_Script = scriptName; .m_Config = config
objectData.m_Config = config; };
// Get the locations // Get the locations
auto* locations = object->FirstChildElement("locations"); auto* locations = object->FirstChildElement("locations");
@ -283,64 +270,67 @@ void VanityUtilities::ParseXML(const std::string& file) {
location = location->NextSiblingElement("location")) { location = location->NextSiblingElement("location")) {
// Get the location data // Get the location data
auto* zoneID = location->Attribute("zone"); auto zoneID = GeneralUtils::TryParse<uint32_t>(location->Attribute("zone"));
auto* x = location->Attribute("x"); auto x = GeneralUtils::TryParse<float>(location->Attribute("x"));
auto* y = location->Attribute("y"); auto y = GeneralUtils::TryParse<float>(location->Attribute("y"));
auto* z = location->Attribute("z"); auto z = GeneralUtils::TryParse<float>(location->Attribute("z"));
auto* rw = location->Attribute("rw"); auto rw = GeneralUtils::TryParse<float>(location->Attribute("rw"));
auto* rx = location->Attribute("rx"); auto rx = GeneralUtils::TryParse<float>(location->Attribute("rx"));
auto* ry = location->Attribute("ry"); auto ry = GeneralUtils::TryParse<float>(location->Attribute("ry"));
auto* rz = location->Attribute("rz"); auto rz = GeneralUtils::TryParse<float>(location->Attribute("rz"));
if (zoneID == nullptr || x == nullptr || y == nullptr || z == nullptr || rw == nullptr || rx == nullptr || ry == nullptr if (!zoneID || !x || !y || !z || !rw || !rx || !ry || !rz) {
|| rz == nullptr) {
LOG("Failed to parse NPC location data"); LOG("Failed to parse NPC location data");
continue; continue;
} }
VanityObjectLocation locationData; if (zoneID.value() != currentZoneID) {
locationData.m_Position = { std::stof(x), std::stof(y), std::stof(z) }; LOG_DEBUG("Skipping (%s) %i location because it is in %i and not the current zone (%i)", name, lot, zoneID.value(), currentZoneID);
locationData.m_Rotation = { std::stof(rw), std::stof(rx), std::stof(ry), std::stof(rz) }; continue;
locationData.m_Chance = 1.0f; }
VanityObjectLocation locationData {
.m_Position = { x.value(), y.value(), z.value() },
.m_Rotation = { rw.value(), rx.value(), ry.value(), rz.value() },
};
if (location->Attribute("chance")) { if (location->Attribute("chance")) {
locationData.m_Chance = std::stof(location->Attribute("chance")); locationData.m_Chance = GeneralUtils::TryParse<float>(location->Attribute("chance")).value_or(1.0f);
} }
if (location->Attribute("scale")) { if (location->Attribute("scale")) {
locationData.m_Scale = std::stof(location->Attribute("scale")); locationData.m_Scale = GeneralUtils::TryParse<float>(location->Attribute("scale")).value_or(1.0f);
} }
const auto& it = objectData.m_Locations.find(zoneID.value());
const auto& it = objectData.m_Locations.find(std::stoi(zoneID));
if (it != objectData.m_Locations.end()) { if (it != objectData.m_Locations.end()) {
it->second.push_back(locationData); it->second.push_back(locationData);
} else { } else {
std::vector<VanityObjectLocation> locations; std::vector<VanityObjectLocation> locations;
locations.push_back(locationData); locations.push_back(locationData);
objectData.m_Locations.insert(std::make_pair(std::stoi(zoneID), locations)); objectData.m_Locations.insert(std::make_pair(zoneID.value(), locations));
} }
if (!(std::find(keys.begin(), keys.end(), u"teleport") != keys.end())) { if (!useLocationsAsRandomSpawnPoint) {
m_Objects.push_back(objectData); objects.push_back(objectData);
objectData.m_Locations.clear(); objectData.m_Locations.clear();
} }
} }
if (std::find(keys.begin(), keys.end(), u"teleport") != keys.end()) {
m_Objects.push_back(objectData); if (useLocationsAsRandomSpawnPoint && !objectData.m_Locations.empty()) {
} objects.push_back(objectData);
}
} }
} }
} }
VanityObject* VanityUtilities::GetObject(const std::string& name) { VanityObject* VanityUtilities::GetObject(const std::string& name) {
for (size_t i = 0; i < m_Objects.size(); i++) { for (size_t i = 0; i < objects.size(); i++) {
if (m_Objects[i].m_Name == name) { if (objects[i].m_Name == name) {
return &m_Objects[i]; return &objects[i];
} }
} }
return nullptr; return nullptr;
} }
@ -350,7 +340,7 @@ std::string VanityUtilities::ParseMarkdown(const std::string& file) {
// Read the file into a string // Read the file into a string
std::ifstream t(file); std::ifstream t(file);
std::stringstream output; std::stringstream output;
// If the file does not exist, return an empty string. // If the file does not exist, return a useful error.
if (!t.good()) { if (!t.good()) {
output << "File "; output << "File ";
output << file.substr(file.rfind("/") + 1); output << file.substr(file.rfind("/") + 1);
@ -408,13 +398,13 @@ std::string VanityUtilities::ParseMarkdown(const std::string& file) {
return output.str(); return output.str();
} }
void VanityUtilities::SetupNPCTalk(Entity* npc) { void SetupNPCTalk(Entity* npc) {
npc->AddCallbackTimer(15.0f, [npc]() { NPCTalk(npc); }); npc->AddCallbackTimer(15.0f, [npc]() { NPCTalk(npc); });
npc->SetProximityRadius(20.0f, "talk"); npc->SetProximityRadius(20.0f, "talk");
} }
void VanityUtilities::NPCTalk(Entity* npc) { void NPCTalk(Entity* npc) {
auto* proximityMonitorComponent = npc->GetComponent<ProximityMonitorComponent>(); auto* proximityMonitorComponent = npc->GetComponent<ProximityMonitorComponent>();
if (!proximityMonitorComponent->GetProximityObjects("talk").empty()) { if (!proximityMonitorComponent->GetProximityObjects("talk").empty()) {

View File

@ -5,58 +5,30 @@
#include <map> #include <map>
#include <set> #include <set>
struct VanityObjectLocation struct VanityObjectLocation {
{
float m_Chance = 1.0f; float m_Chance = 1.0f;
NiPoint3 m_Position; NiPoint3 m_Position;
NiQuaternion m_Rotation; NiQuaternion m_Rotation;
float m_Scale = 1.0f; float m_Scale = 1.0f;
}; };
struct VanityObject struct VanityObject {
{
LWOOBJID m_ID = LWOOBJID_EMPTY; LWOOBJID m_ID = LWOOBJID_EMPTY;
std::string m_Name; std::string m_Name;
LOT m_LOT; LOT m_LOT = LOT_NULL;
std::vector<LOT> m_Equipment; std::vector<LOT> m_Equipment;
std::vector<std::string> m_Phrases; std::vector<std::string> m_Phrases;
std::string m_Script;
std::map<uint32_t, std::vector<VanityObjectLocation>> m_Locations; std::map<uint32_t, std::vector<VanityObjectLocation>> m_Locations;
std::vector<LDFBaseData*> m_Config; std::vector<LDFBaseData*> m_Config;
}; };
class VanityUtilities namespace VanityUtilities {
{ void SpawnVanity();
public:
static void SpawnVanity();
static Entity* SpawnObject( VanityObject* GetObject(const std::string& name);
const VanityObject& object,
const VanityObjectLocation& location
);
static LWOOBJID SpawnSpawner( std::string ParseMarkdown(
const VanityObject& object,
const VanityObjectLocation& location
);
static std::string ParseMarkdown(
const std::string& file const std::string& file
); );
static void ParseXML(
const std::string& file
);
static VanityObject* GetObject(const std::string& name);
private:
static void SetupNPCTalk(Entity* npc);
static void NPCTalk(Entity* npc);
static std::vector<VanityObject> m_Objects;
static std::set<std::string> m_LoadedFiles;
}; };

View File

@ -7,10 +7,13 @@ set(DMASTERSERVER_SOURCES
add_library(dMasterServer ${DMASTERSERVER_SOURCES}) add_library(dMasterServer ${DMASTERSERVER_SOURCES})
add_executable(MasterServer "MasterServer.cpp") add_executable(MasterServer "MasterServer.cpp")
add_compile_definitions(MasterServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") add_compile_definitions(MasterServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"")
target_include_directories(dMasterServer PUBLIC "."
"${PROJECT_SOURCE_DIR}/dZoneManager" # InstanceManager.h uses dZMCommon.h
${PROJECT_SOURCE_DIR}/dServer/ # BinaryPathFinder.h
)
target_link_libraries(dMasterServer ${COMMON_LIBRARIES}) target_link_libraries(dMasterServer ${COMMON_LIBRARIES})
target_link_libraries(MasterServer ${COMMON_LIBRARIES} dMasterServer dServer) target_link_libraries(MasterServer ${COMMON_LIBRARIES} bcrypt dMasterServer dServer)
target_include_directories(dMasterServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer)
if(WIN32) if(WIN32)
add_dependencies(MasterServer WorldServer AuthServer ChatServer) add_dependencies(MasterServer WorldServer AuthServer ChatServer)

View File

@ -6,5 +6,12 @@ foreach(file ${DNAVIGATIONS_DTERRAIN_SOURCES})
set(DNAVIGATION_SOURCES ${DNAVIGATION_SOURCES} "dTerrain/${file}") set(DNAVIGATION_SOURCES ${DNAVIGATION_SOURCES} "dTerrain/${file}")
endforeach() endforeach()
add_library(dNavigation STATIC ${DNAVIGATION_SOURCES}) add_library(dNavigation OBJECT ${DNAVIGATION_SOURCES})
target_link_libraries(dNavigation Detour Recast) target_include_directories(dNavigation PUBLIC "."
PRIVATE
"${PROJECT_SOURCE_DIR}/dZoneManager"
"${PROJECT_SOURCE_DIR}/dGame"
"${PROJECT_SOURCE_DIR}/dGame/dEntity"
"${PROJECT_SOURCE_DIR}/dNavigation/dTerrain" # via dNavMesh.cpp
)
target_link_libraries(dNavigation PRIVATE Detour Recast dCommon)

View File

@ -8,7 +8,7 @@
#include "ZoneInstanceManager.h" #include "ZoneInstanceManager.h"
#include "MD5.h" #include "MD5.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "ClientVersion.h" #include "dClient/ClientVersion.h"
#include <bcrypt/BCrypt.hpp> #include <bcrypt/BCrypt.hpp>
@ -229,7 +229,7 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd
RakNet::BitStream loginResponse; RakNet::BitStream loginResponse;
BitStreamUtils::WriteHeader(loginResponse, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE); BitStreamUtils::WriteHeader(loginResponse, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE);
loginResponse.Write<uint8_t>(GeneralUtils::CastUnderlyingType(responseCode)); loginResponse.Write(responseCode);
// Event Gating // Event Gating
loginResponse.Write(LUString(Game::config->GetValue("event_1"))); loginResponse.Write(LUString(Game::config->GetValue("event_1")));

View File

@ -8,5 +8,24 @@ set(DNET_SOURCES "AuthPackets.cpp"
"ZoneInstanceManager.cpp") "ZoneInstanceManager.cpp")
add_library(dNet STATIC ${DNET_SOURCES}) add_library(dNet STATIC ${DNET_SOURCES})
target_link_libraries(dNet PRIVATE bcrypt MD5)
target_include_directories(dNet PRIVATE
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
target_link_libraries(dNet PUBLIC dCommon) "${PROJECT_SOURCE_DIR}/dZoneManager"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
"${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include"
"${PROJECT_SOURCE_DIR}/dGame" # UserManager.h
"${PROJECT_SOURCE_DIR}/dGame/dComponents"
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # GameMessages.h
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via PossessableComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # via Item.h
"${PROJECT_SOURCE_DIR}/dScripts" # transitive through components
)

View File

@ -7,6 +7,10 @@ set(DPHYSICS_SOURCES "dpCollisionChecks.cpp"
"dpWorld.cpp") "dpWorld.cpp")
add_library(dPhysics STATIC ${DPHYSICS_SOURCES}) add_library(dPhysics STATIC ${DPHYSICS_SOURCES})
target_include_directories(dPhysics PUBLIC "."
"${PROJECT_SOURCE_DIR}/dCommon"
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
)
target_link_libraries(dPhysics target_link_libraries(dPhysics
PUBLIC Recast Detour PUBLIC Recast Detour
INTERFACE dNavigation) INTERFACE dNavigation dCommon)

View File

@ -30,15 +30,28 @@ endforeach()
add_subdirectory(Pets) add_subdirectory(Pets)
add_library(dScriptsServer STATIC ${DSCRIPTS_SOURCES_02_SERVER}) add_library(dScriptsServerBase OBJECT ${DSCRIPTS_SOURCES_02_SERVER})
target_include_directories(dScriptsServer PUBLIC "." target_include_directories(dScriptsServerBase PUBLIC "."
"DLU" "DLU"
"Equipment" "Equipment"
"Minigame" "Minigame"
"Minigame/General" "Minigame/General"
"Objects" "Objects"
"Pets") )
target_precompile_headers(dScriptsServerBase REUSE_FROM dScriptsBase)
add_library(dScriptsServer INTERFACE)
target_sources(dScriptsServer INTERFACE
$<TARGET_OBJECTS:dScriptsServerBase>
$<TARGET_OBJECTS:dScriptsServerEnemy>
$<TARGET_OBJECTS:dScriptsServerPets>
)
target_link_libraries(dScriptsServer INTERFACE target_link_libraries(dScriptsServer INTERFACE
dScriptsServerEnemy dScriptsServerMap
dScriptsServerMap) )
target_precompile_headers(dScriptsServer REUSE_FROM dScriptsBase) target_include_directories(dScriptsServer INTERFACE
$<TARGET_PROPERTY:dScriptsServerBase,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerEnemy,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMap,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerPets,INTERFACE_INCLUDE_DIRECTORIES>
)

View File

@ -5,20 +5,17 @@
#include "RenderComponent.h" #include "RenderComponent.h"
void DLUVanityTeleportingObject::OnStartup(Entity* self) { void DLUVanityTeleportingObject::OnStartup(Entity* self) {
if (!self->HasVar(u"npcName") || !self->HasVar(u"teleport")) return; if (!self->HasVar(u"npcName")) return;
m_Object = VanityUtilities::GetObject(self->GetVarAsString(u"npcName"));
m_Object = VanityUtilities::GetObject(self->GetVarAsString(u"npcName"));
if (!m_Object) return; if (!m_Object) return;
if (self->HasVar(u"teleportInterval")) m_TeleportInterval = self->GetVar<float>(u"teleportInterval"); if (self->HasVar(u"teleportInterval")) m_TeleportInterval = self->GetVar<float>(u"teleportInterval");
if (self->GetVar<bool>(u"teleport")) { self->AddTimer("setupTeleport", m_TeleportInterval);
self->AddTimer("setupTeleport", m_TeleportInterval);
}
} }
void DLUVanityTeleportingObject::OnTimerDone(Entity* self, std::string timerName) { void DLUVanityTeleportingObject::OnTimerDone(Entity* self, std::string timerName) {
if (timerName == "setupTeleport") { if (timerName == "setupTeleport") {
RenderComponent::PlayAnimation(self, u"interact");
GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam");
GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportRings", "teleportRings"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportRings", "teleportRings");
@ -40,7 +37,6 @@ void DLUVanityTeleportingObject::OnTimerDone(Entity* self, std::string timerName
self->SetPosition(newLocation.m_Position); self->SetPosition(newLocation.m_Position);
self->SetRotation(newLocation.m_Rotation); self->SetRotation(newLocation.m_Rotation);
self->SetScale(newLocation.m_Scale);
GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam");
GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportRings", "teleportRings"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportRings", "teleportRings");
self->AddTimer("stopFX", 2.0f); self->AddTimer("stopFX", 2.0f);

View File

@ -42,7 +42,7 @@ foreach(file ${DSCRIPTS_SOURCES_02_SERVER_ENEMY_WAVES})
set(DSCRIPTS_SOURCES_02_SERVER_ENEMY ${DSCRIPTS_SOURCES_02_SERVER_ENEMY} "Waves/${file}") set(DSCRIPTS_SOURCES_02_SERVER_ENEMY ${DSCRIPTS_SOURCES_02_SERVER_ENEMY} "Waves/${file}")
endforeach() endforeach()
add_library(dScriptsServerEnemy STATIC ${DSCRIPTS_SOURCES_02_SERVER_ENEMY}) add_library(dScriptsServerEnemy OBJECT ${DSCRIPTS_SOURCES_02_SERVER_ENEMY})
target_link_libraries(dScriptsServerEnemy dScriptsBase) target_link_libraries(dScriptsServerEnemy dScriptsBase)
target_include_directories(dScriptsServerEnemy PUBLIC "." target_include_directories(dScriptsServerEnemy PUBLIC "."
"AG" "AG"

View File

@ -14,6 +14,6 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_AG
"NpcCowboyServer.cpp" "NpcCowboyServer.cpp"
"NpcPirateServer.cpp") "NpcPirateServer.cpp")
add_library(dScriptsServerMapAG ${DSCRIPTS_SOURCES_02_SERVER_MAP_AG}) add_library(dScriptsServerMapAG OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_AG})
target_include_directories(dScriptsServerMapAG PUBLIC ".") target_include_directories(dScriptsServerMapAG PUBLIC ".")
target_precompile_headers(dScriptsServerMapAG REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapAG REUSE_FROM dScriptsBase)

View File

@ -2,7 +2,7 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_AG_SPIDER_QUEEN
"ZoneAgSpiderQueen.cpp" "ZoneAgSpiderQueen.cpp"
"SpiderBossTreasureChestServer.cpp") "SpiderBossTreasureChestServer.cpp")
add_library(dScriptsServerMapAGSpiderQueen ${DSCRIPTS_SOURCES_02_SERVER_MAP_AG_SPIDER_QUEEN}) add_library(dScriptsServerMapAGSpiderQueen OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_AG_SPIDER_QUEEN})
target_include_directories(dScriptsServerMapAGSpiderQueen PUBLIC ".") target_include_directories(dScriptsServerMapAGSpiderQueen PUBLIC ".")
target_link_libraries(dScriptsServerMapAGSpiderQueen dScriptsServerMapProperty) target_link_libraries(dScriptsServerMapAGSpiderQueen dScriptsServerMapProperty)
target_precompile_headers(dScriptsServerMapAGSpiderQueen REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapAGSpiderQueen REUSE_FROM dScriptsBase)

View File

@ -19,6 +19,6 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_AM
"WanderingVendor.cpp" "WanderingVendor.cpp"
) )
add_library(dScriptsServerMapAM ${DSCRIPTS_SOURCES_02_SERVER_MAP_AM}) add_library(dScriptsServerMapAM OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_AM})
target_include_directories(dScriptsServerMapAM PUBLIC ".") target_include_directories(dScriptsServerMapAM PUBLIC ".")
target_precompile_headers(dScriptsServerMapAM REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapAM REUSE_FROM dScriptsBase)

View File

@ -5,7 +5,7 @@
void WanderingVendor::OnStartup(Entity* self) { void WanderingVendor::OnStartup(Entity* self) {
auto movementAIComponent = self->GetComponent<MovementAIComponent>(); auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return; if (!movementAIComponent) return;
movementAIComponent->Resume(); // movementAIComponent->Resume();
self->SetProximityRadius(10, "playermonitor"); self->SetProximityRadius(10, "playermonitor");
} }
@ -13,14 +13,12 @@ void WanderingVendor::OnProximityUpdate(Entity* self, Entity* entering, std::str
if (status == "ENTER" && entering->IsPlayer()) { if (status == "ENTER" && entering->IsPlayer()) {
auto movementAIComponent = self->GetComponent<MovementAIComponent>(); auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return; if (!movementAIComponent) return;
movementAIComponent->Pause(); // movementAIComponent->Pause();
self->CancelTimer("startWalking"); self->CancelTimer("startWalking");
} else if (status == "LEAVE") { } else if (status == "LEAVE") {
auto* proximityMonitorComponent = self->GetComponent<ProximityMonitorComponent>(); auto* proximityMonitorComponent = self->GetComponent<ProximityMonitorComponent>();
if (!proximityMonitorComponent) { if (!proximityMonitorComponent) self->AddComponent<ProximityMonitorComponent>();
LOG("Proximity monitor component not found!");
return;
}
const auto proxObjs = proximityMonitorComponent->GetProximityObjects("playermonitor"); const auto proxObjs = proximityMonitorComponent->GetProximityObjects("playermonitor");
if (proxObjs.empty()) self->AddTimer("startWalking", 1.5); if (proxObjs.empty()) self->AddTimer("startWalking", 1.5);
} }
@ -30,6 +28,6 @@ void WanderingVendor::OnTimerDone(Entity* self, std::string timerName) {
if (timerName == "startWalking") { if (timerName == "startWalking") {
auto movementAIComponent = self->GetComponent<MovementAIComponent>(); auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return; if (!movementAIComponent) return;
movementAIComponent->Resume(); // movementAIComponent->Resume();
} }
} }

View File

@ -1,4 +1,6 @@
#pragma once #ifndef __WANDERINGVENDOR__H__
#define __WANDERINGVENDOR__H__
#include "CppScripts.h" #include "CppScripts.h"
class WanderingVendor : public CppScripts::Script { class WanderingVendor : public CppScripts::Script {
@ -8,3 +10,4 @@ public:
void OnTimerDone(Entity* self, std::string timerName) override; void OnTimerDone(Entity* self, std::string timerName) override;
}; };
#endif //!__WANDERINGVENDOR__H__

View File

@ -13,17 +13,33 @@ add_subdirectory(SS)
add_subdirectory(VE) add_subdirectory(VE)
add_library(dScriptsServerMap INTERFACE) add_library(dScriptsServerMap INTERFACE)
target_link_libraries(dScriptsServerMap INTERFACE target_sources(dScriptsServerMap INTERFACE
dScriptsServerMapAG $<TARGET_OBJECTS:dScriptsServerMapAG>
dScriptsServerMapAGSpiderQueen $<TARGET_OBJECTS:dScriptsServerMapAGSpiderQueen>
dScriptsServerMapAM $<TARGET_OBJECTS:dScriptsServerMapAM>
dScriptsServerMapFV $<TARGET_OBJECTS:dScriptsServerMapFV>
dScriptsServerMapGeneral $<TARGET_OBJECTS:dScriptsServerMapGeneral>
dScriptsServerMapGF $<TARGET_OBJECTS:dScriptsServerMapGF>
dScriptsServerMapNJHub $<TARGET_OBJECTS:dScriptsServerMapNJHub>
dScriptsServerMapNS $<TARGET_OBJECTS:dScriptsServerMapNS>
dScriptsServerMapNT $<TARGET_OBJECTS:dScriptsServerMapNT>
dScriptsServerMapPR $<TARGET_OBJECTS:dScriptsServerMapPR>
dScriptsServerMapProperty $<TARGET_OBJECTS:dScriptsServerMapProperty>
dScriptsServerMapSS $<TARGET_OBJECTS:dScriptsServerMapSS>
dScriptsServerMapVE) $<TARGET_OBJECTS:dScriptsServerMapVE>
)
target_include_directories(dScriptsServerMap INTERFACE
$<TARGET_PROPERTY:dScriptsServerMapAG,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapAGSpiderQueen,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapAM,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapFV,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapGeneral,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapGF,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapNJHub,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapNS,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapNT,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapPR,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapProperty,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapSS,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServerMapVE,INTERFACE_INCLUDE_DIRECTORIES>
)

View File

@ -11,6 +11,6 @@ foreach(file ${DSCRIPTS_SOURCES_02_SERVER_MAP_FV_RACING})
set(DSCRIPTS_SOURCES_02_SERVER_MAP_FV ${DSCRIPTS_SOURCES_02_SERVER_MAP_FV} "Racing/${file}") set(DSCRIPTS_SOURCES_02_SERVER_MAP_FV ${DSCRIPTS_SOURCES_02_SERVER_MAP_FV} "Racing/${file}")
endforeach() endforeach()
add_library(dScriptsServerMapFV ${DSCRIPTS_SOURCES_02_SERVER_MAP_FV}) add_library(dScriptsServerMapFV OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_FV})
target_include_directories(dScriptsServerMapFV PUBLIC "." "Racing") target_include_directories(dScriptsServerMapFV PUBLIC "." "Racing")
target_precompile_headers(dScriptsServerMapFV REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapFV REUSE_FROM dScriptsBase)

View File

@ -4,6 +4,6 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_GF
"MastTeleport.cpp" "MastTeleport.cpp"
"SpawnLionServer.cpp") "SpawnLionServer.cpp")
add_library(dScriptsServerMapGF ${DSCRIPTS_SOURCES_02_SERVER_MAP_GF}) add_library(dScriptsServerMapGF OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_GF})
target_include_directories(dScriptsServerMapGF PUBLIC ".") target_include_directories(dScriptsServerMapGF PUBLIC ".")
target_precompile_headers(dScriptsServerMapGF REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapGF REUSE_FROM dScriptsBase)

View File

@ -27,6 +27,6 @@ foreach(file ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL_NINJAGO})
set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL} "Ninjago/${file}") set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL} "Ninjago/${file}")
endforeach() endforeach()
add_library(dScriptsServerMapGeneral ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL}) add_library(dScriptsServerMapGeneral OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL})
target_include_directories(dScriptsServerMapGeneral PUBLIC "." "Ninjago") target_include_directories(dScriptsServerMapGeneral PUBLIC "." "Ninjago")
target_precompile_headers(dScriptsServerMapGeneral REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapGeneral REUSE_FROM dScriptsBase)

View File

@ -6,7 +6,7 @@
#include "Entity.h" #include "Entity.h"
void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) {
if (self->GetVar<bool>(u"hasCustomText")) { if (self->HasVar(u"customText")) {
const auto& customText = self->GetVar<std::string>(u"customText"); const auto& customText = self->GetVar<std::string>(u"customText");
{ {
@ -29,15 +29,19 @@ void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) {
return; return;
} }
if (!self->HasVar(u"storyText") || !self->HasVar(u"altFlagID")) return;
const auto storyText = self->GetVarAsString(u"storyText"); const auto storyText = self->GetVarAsString(u"storyText");
if (storyText.length() > 2) {
auto storyValue = GeneralUtils::TryParse<uint32_t>(storyText.substr(storyText.length() - 2));
if(!storyValue) return;
int32_t boxFlag = self->GetVar<int32_t>(u"altFlagID");
if (boxFlag <= 0) {
boxFlag = (10000 + Game::server->GetZoneID() + storyValue.value());
}
int32_t boxFlag = self->GetVar<int32_t>(u"altFlagID"); if (user->GetCharacter()->GetPlayerFlag(boxFlag) == false) {
if (boxFlag <= 0) { user->GetCharacter()->SetPlayerFlag(boxFlag, true);
boxFlag = (10000 + Game::server->GetZoneID() + std::stoi(storyText.substr(storyText.length() - 2))); GameMessages::SendFireEventClientSide(self->GetObjectID(), user->GetSystemAddress(), u"achieve", LWOOBJID_EMPTY, 0, -1, LWOOBJID_EMPTY);
} }
if (user->GetCharacter()->GetPlayerFlag(boxFlag) == false) {
user->GetCharacter()->SetPlayerFlag(boxFlag, true);
GameMessages::SendFireEventClientSide(self->GetObjectID(), user->GetSystemAddress(), u"achieve", LWOOBJID_EMPTY, 0, -1, LWOOBJID_EMPTY);
} }
} }

View File

@ -10,6 +10,6 @@ foreach(file ${DSCRIPTS_SOURCES_02_SERVER_MAP_NS_WAVES})
set(DSCRIPTS_SOURCES_02_SERVER_MAP_NS ${DSCRIPTS_SOURCES_02_SERVER_MAP_NS} "Waves/${file}") set(DSCRIPTS_SOURCES_02_SERVER_MAP_NS ${DSCRIPTS_SOURCES_02_SERVER_MAP_NS} "Waves/${file}")
endforeach() endforeach()
add_library(dScriptsServerMapNS ${DSCRIPTS_SOURCES_02_SERVER_MAP_NS}) add_library(dScriptsServerMapNS OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_NS})
target_include_directories(dScriptsServerMapNS PUBLIC "." "Waves") target_include_directories(dScriptsServerMapNS PUBLIC "." "Waves")
target_precompile_headers(dScriptsServerMapNS REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapNS REUSE_FROM dScriptsBase)

View File

@ -27,6 +27,6 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_NT
"NtBcSubmitServer.cpp" "NtBcSubmitServer.cpp"
"NtNaomiBreadcrumbServer.cpp") "NtNaomiBreadcrumbServer.cpp")
add_library(dScriptsServerMapNT ${DSCRIPTS_SOURCES_02_SERVER_MAP_NT}) add_library(dScriptsServerMapNT OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_NT})
target_include_directories(dScriptsServerMapNT PUBLIC ".") target_include_directories(dScriptsServerMapNT PUBLIC ".")
target_precompile_headers(dScriptsServerMapNT REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapNT REUSE_FROM dScriptsBase)

View File

@ -1,5 +1,6 @@
#include "NtCombatChallengeDummy.h" #include "NtCombatChallengeDummy.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "Entity.h"
void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) { void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) {
const auto challengeObjectID = self->GetVar<LWOOBJID>(u"challengeObjectID"); const auto challengeObjectID = self->GetVar<LWOOBJID>(u"challengeObjectID");
@ -7,9 +8,7 @@ void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) {
auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID);
if (challengeObject != nullptr) { if (challengeObject != nullptr) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { challengeObject->GetScript()->OnDie(challengeObject, killer);
script->OnDie(challengeObject, killer);
}
} }
} }
@ -19,8 +18,6 @@ void NtCombatChallengeDummy::OnHitOrHealResult(Entity* self, Entity* attacker, i
auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID);
if (challengeObject != nullptr) { if (challengeObject != nullptr) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { challengeObject->GetScript()->OnHitOrHealResult(challengeObject, attacker, damage);
script->OnHitOrHealResult(challengeObject, attacker, damage);
}
} }
} }

View File

@ -9,9 +9,7 @@ void NtCombatChallengeExplodingDummy::OnDie(Entity* self, Entity* killer) {
auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID);
if (challengeObject != nullptr) { if (challengeObject != nullptr) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { challengeObject->GetScript()->OnDie(challengeObject, killer);
script->OnDie(challengeObject, killer);
}
} }
} }
@ -32,9 +30,7 @@ void NtCombatChallengeExplodingDummy::OnHitOrHealResult(Entity* self, Entity* at
auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID);
if (challengeObject != nullptr) { if (challengeObject != nullptr) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { challengeObject->GetScript()->OnHitOrHealResult(challengeObject, attacker, damage);
script->OnHitOrHealResult(challengeObject, attacker, damage);
}
} }
auto skillComponent = self->GetComponent<SkillComponent>(); auto skillComponent = self->GetComponent<SkillComponent>();
if (skillComponent != nullptr) { if (skillComponent != nullptr) {

View File

@ -3,6 +3,6 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_PR
"PrSeagullFly.cpp" "PrSeagullFly.cpp"
"SpawnGryphonServer.cpp") "SpawnGryphonServer.cpp")
add_library(dScriptsServerMapPR ${DSCRIPTS_SOURCES_02_SERVER_MAP_PR}) add_library(dScriptsServerMapPR OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_PR})
target_include_directories(dScriptsServerMapPR PUBLIC ".") target_include_directories(dScriptsServerMapPR PUBLIC ".")
target_precompile_headers(dScriptsServerMapPR REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapPR REUSE_FROM dScriptsBase)

View File

@ -19,7 +19,7 @@ foreach(file ${DSCRIPTS_SOURCES_02_SERVER_MAP_PROPERTY_NS_MED})
set(DSCRIPTS_SOURCES_02_SERVER_MAP_PROPERTY ${DSCRIPTS_SOURCES_02_SERVER_MAP_PROPERTY} "NS_Med/${file}") set(DSCRIPTS_SOURCES_02_SERVER_MAP_PROPERTY ${DSCRIPTS_SOURCES_02_SERVER_MAP_PROPERTY} "NS_Med/${file}")
endforeach() endforeach()
add_library(dScriptsServerMapProperty ${DSCRIPTS_SOURCES_02_SERVER_MAP_PROPERTY}) add_library(dScriptsServerMapProperty OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_PROPERTY})
target_precompile_headers(dScriptsServerMapProperty REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapProperty REUSE_FROM dScriptsBase)
target_include_directories(dScriptsServerMapProperty PUBLIC "." target_include_directories(dScriptsServerMapProperty PUBLIC "."
"AG_Med" "AG_Med"

View File

@ -1,6 +1,6 @@
set(DSCRIPTS_SOURCES_02_SERVER_MAP_SS set(DSCRIPTS_SOURCES_02_SERVER_MAP_SS
"SsModularBuildServer.cpp") "SsModularBuildServer.cpp")
add_library(dScriptsServerMapSS ${DSCRIPTS_SOURCES_02_SERVER_MAP_SS}) add_library(dScriptsServerMapSS OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_SS})
target_include_directories(dScriptsServerMapSS PUBLIC ".") target_include_directories(dScriptsServerMapSS PUBLIC ".")
target_precompile_headers(dScriptsServerMapSS REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapSS REUSE_FROM dScriptsBase)

View File

@ -3,6 +3,6 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_VE
"VeEpsilonServer.cpp" "VeEpsilonServer.cpp"
"VeBricksampleServer.cpp") "VeBricksampleServer.cpp")
add_library(dScriptsServerMapVE ${DSCRIPTS_SOURCES_02_SERVER_MAP_VE}) add_library(dScriptsServerMapVE OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_VE})
target_include_directories(dScriptsServerMapVE PUBLIC ".") target_include_directories(dScriptsServerMapVE PUBLIC ".")
target_precompile_headers(dScriptsServerMapVE REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerMapVE REUSE_FROM dScriptsBase)

Some files were not shown because too many files have changed in this diff Show More