Merge remote-tracking branch 'upstream/main' into PetFixes

This commit is contained in:
jadebenn 2024-03-05 23:02:35 -06:00
commit 9ec028b92d
105 changed files with 1679 additions and 1029 deletions

View File

@ -77,6 +77,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 +91,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 +182,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 +205,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 +237,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 +247,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 +285,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 +307,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"
SOURCE_DIR ${MARIADBCPP_SOURCE_DIR}
INSTALL_DIR ${MARIADBCPP_INSTALL_DIR}
CMAKE_ARGS -Wno-dev CMAKE_ARGS -Wno-dev
-DWITH_UNIT_TESTS=OFF
-DMARIADB_LINK_DYNAMIC=OFF
-DCMAKE_BUILD_RPATH_USE_ORIGIN=${CMAKE_BUILD_RPATH_USE_ORIGIN} -DCMAKE_BUILD_RPATH_USE_ORIGIN=${CMAKE_BUILD_RPATH_USE_ORIGIN}
-DCMAKE_INSTALL_PREFIX=./mariadbcpp # Points the connector to the correct plugin directory -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DINSTALL_PLUGINDIR=plugin -DINSTALL_LIBDIR=${MARIADBCPP_LIBRARY_DIR}
-DINSTALL_PLUGINDIR=${MARIADBCPP_PLUGIN_DIR}
${MARIADB_EXTRA_CMAKE_ARGS} ${MARIADB_EXTRA_CMAKE_ARGS}
PREFIX "${PROJECT_BINARY_DIR}/mariadbcpp" BUILD_ALWAYS true
BUILD_COMMAND cmake --build . --config RelWithDebInfo -j${MARIADB_CONNECTOR_COMPILE_JOBS} )
INSTALL_COMMAND "")
ExternalProject_Get_Property(mariadb_connector_cpp BINARY_DIR)
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

@ -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

@ -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

@ -841,11 +841,9 @@ bool Entity::HasComponent(const eReplicaComponentType componentId) const {
std::vector<ScriptComponent*> Entity::GetScriptComponents() { std::vector<ScriptComponent*> Entity::GetScriptComponents() {
std::vector<ScriptComponent*> comps; std::vector<ScriptComponent*> comps;
for (std::pair<eReplicaComponentType, void*> p : m_Components) {
if (p.first == eReplicaComponentType::SCRIPT) { auto* scriptComponent = GetComponent<ScriptComponent>();
comps.push_back(static_cast<ScriptComponent*>(p.second)); if (scriptComponent) comps.push_back(scriptComponent);
}
}
return comps; return comps;
} }
@ -2126,9 +2124,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
@ -2139,9 +2135,7 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) {
possessedControllablePhysicsComponent->SetIsOnGround(update.onGround); possessedControllablePhysicsComponent->SetIsOnGround(update.onGround);
possessedControllablePhysicsComponent->SetIsOnRail(update.onRail); possessedControllablePhysicsComponent->SetIsOnRail(update.onRail);
possessedControllablePhysicsComponent->SetVelocity(update.velocity); possessedControllablePhysicsComponent->SetVelocity(update.velocity);
possessedControllablePhysicsComponent->SetDirtyVelocity(update.velocity != NiPoint3Constant::ZERO);
possessedControllablePhysicsComponent->SetAngularVelocity(update.angularVelocity); possessedControllablePhysicsComponent->SetAngularVelocity(update.angularVelocity);
possessedControllablePhysicsComponent->SetDirtyAngularVelocity(update.angularVelocity != NiPoint3Constant::ZERO);
} }
Game::entityManager->SerializeEntity(possassableEntity); Game::entityManager->SerializeEntity(possassableEntity);
} }
@ -2163,9 +2157,7 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) {
controllablePhysicsComponent->SetIsOnGround(update.onGround); controllablePhysicsComponent->SetIsOnGround(update.onGround);
controllablePhysicsComponent->SetIsOnRail(update.onRail); controllablePhysicsComponent->SetIsOnRail(update.onRail);
controllablePhysicsComponent->SetVelocity(update.velocity); controllablePhysicsComponent->SetVelocity(update.velocity);
controllablePhysicsComponent->SetDirtyVelocity(update.velocity != NiPoint3Constant::ZERO);
controllablePhysicsComponent->SetAngularVelocity(update.angularVelocity); controllablePhysicsComponent->SetAngularVelocity(update.angularVelocity);
controllablePhysicsComponent->SetDirtyAngularVelocity(update.angularVelocity != NiPoint3Constant::ZERO);
auto* ghostComponent = GetComponent<GhostComponent>(); auto* ghostComponent = GetComponent<GhostComponent>();
if (ghostComponent) ghostComponent->SetGhostReferencePoint(update.position); if (ghostComponent) ghostComponent->SetGhostReferencePoint(update.position);
@ -2197,9 +2189,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

@ -295,7 +295,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

@ -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

@ -50,9 +50,32 @@ set(DGAME_DCOMPONENTS_SOURCES
"MiniGameControlComponent.cpp" "MiniGameControlComponent.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,8 +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_DirtyAngularVelocity = true;
m_dpEntity = nullptr; m_dpEntity = nullptr;
m_Static = false; m_Static = false;
m_SpeedMultiplier = 1; m_SpeedMultiplier = 1;
@ -135,28 +133,30 @@ 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(m_DirtyVelocity); bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
if (m_DirtyVelocity) { 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(m_DirtyAngularVelocity); isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
if (m_DirtyAngularVelocity) { 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(); outBitStream.Write0();
}
if (!bIsInitialUpdate) { if (!bIsInitialUpdate) {
m_DirtyPosition = false;
outBitStream.Write(m_IsTeleporting); outBitStream.Write(m_IsTeleporting);
m_IsTeleporting = false; m_IsTeleporting = false;
} }
} }
}
void ControllablePhysicsComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { void ControllablePhysicsComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
tinyxml2::XMLElement* character = doc->FirstChildElement("obj")->FirstChildElement("char"); tinyxml2::XMLElement* character = doc->FirstChildElement("obj")->FirstChildElement("char");
@ -211,33 +211,29 @@ void ControllablePhysicsComponent::SetRotation(const NiQuaternion& rot) {
} }
void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) { void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) {
if (m_Static) { if (m_Static || m_Velocity == vel) return;
return;
}
m_Velocity = vel; m_Velocity = vel;
m_DirtyPosition = true; m_DirtyPosition = true;
m_DirtyVelocity = true;
if (m_dpEntity) m_dpEntity->SetVelocity(vel); if (m_dpEntity) m_dpEntity->SetVelocity(vel);
} }
void ControllablePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) { void ControllablePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
if (m_Static) { if (m_Static || m_AngularVelocity == vel) return;
return;
}
m_AngularVelocity = vel; m_AngularVelocity = vel;
m_DirtyPosition = true; m_DirtyPosition = true;
m_DirtyAngularVelocity = true;
} }
void ControllablePhysicsComponent::SetIsOnGround(bool val) { void ControllablePhysicsComponent::SetIsOnGround(bool val) {
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 (m_IsOnRail == val) return;
m_DirtyPosition = true; m_DirtyPosition = true;
m_IsOnRail = val; m_IsOnRail = val;
} }
@ -245,15 +241,6 @@ void ControllablePhysicsComponent::SetIsOnRail(bool val) {
void ControllablePhysicsComponent::SetDirtyPosition(bool val) { void ControllablePhysicsComponent::SetDirtyPosition(bool val) {
m_DirtyPosition = val; m_DirtyPosition = val;
} }
void ControllablePhysicsComponent::SetDirtyVelocity(bool val) {
m_DirtyVelocity = val;
}
void ControllablePhysicsComponent::SetDirtyAngularVelocity(bool val) {
m_DirtyAngularVelocity = val;
}
void ControllablePhysicsComponent::AddPickupRadiusScale(float value) { void ControllablePhysicsComponent::AddPickupRadiusScale(float value) {
m_ActivePickupRadiusScales.push_back(value); m_ActivePickupRadiusScales.push_back(value);
if (value > m_PickupRadius) { if (value > m_PickupRadius) {

View File

@ -104,18 +104,6 @@ public:
*/ */
void SetDirtyPosition(bool val); void SetDirtyPosition(bool val);
/**
* Mark the velocity as dirty, forcing a serializtion update next tick
* @param val whether or not the velocity is dirty
*/
void SetDirtyVelocity(bool val);
/**
* Mark the angular velocity as dirty, forcing a serialization update next tick
* @param val whether or not the angular velocity is dirty
*/
void SetDirtyAngularVelocity(bool val);
/** /**
* Sets whether or not the entity is currently wearing a jetpack * Sets whether or not the entity is currently wearing a jetpack
* @param val whether or not the entity is currently wearing a jetpack * @param val whether or not the entity is currently wearing a jetpack
@ -310,21 +298,11 @@ 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
*/ */
NiPoint3 m_Velocity; NiPoint3 m_Velocity;
/**
* Whether or not the angular velocity is dirty, forcing a serialization
*/
bool m_DirtyAngularVelocity;
/** /**
* The current angular velocity of the entity * The current angular velocity of the entity
*/ */

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,34 +57,32 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
outBitStream.Write(m_IsOnGround); outBitStream.Write(m_IsOnGround);
outBitStream.Write(m_IsOnRail); outBitStream.Write(m_IsOnRail);
outBitStream.Write(bIsInitialUpdate || m_DirtyVelocity); bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
outBitStream.Write(isNotZero);
if (bIsInitialUpdate || m_DirtyVelocity) { 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);
m_DirtyVelocity = false;
} }
outBitStream.Write(bIsInitialUpdate || m_DirtyAngularVelocity); isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
outBitStream.Write(isNotZero);
if (bIsInitialUpdate || m_DirtyAngularVelocity) { 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);
m_DirtyAngularVelocity = false;
} }
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.Write1(); // has remote_input_info
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputX); outBitStream.Write(m_RemoteInputInfo.m_RemoteInputX);
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputY); outBitStream.Write(m_RemoteInputInfo.m_RemoteInputY);
outBitStream.Write(m_RemoteInputInfo.m_IsPowersliding); outBitStream.Write(m_RemoteInputInfo.m_IsPowersliding);
outBitStream.Write(m_RemoteInputInfo.m_IsModified); outBitStream.Write(m_RemoteInputInfo.m_IsModified);
m_DirtyRemoteInput = false;
}
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.
@ -110,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;
@ -213,7 +213,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;

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

@ -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

@ -324,8 +324,8 @@ void GameMessages::SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& s
bitStream.Write(entity->GetObjectID()); bitStream.Write(entity->GetObjectID());
bitStream.Write(eGameMessageType::PLAY_ND_AUDIO_EMITTER); bitStream.Write(eGameMessageType::PLAY_ND_AUDIO_EMITTER);
bitStream.Write0(); bitStream.Write0(); // callback message data {lwoobjid}
bitStream.Write0(); bitStream.Write0(); // audio emitterid {uint32_t}
uint32_t length = audioGUID.size(); uint32_t length = audioGUID.size();
bitStream.Write(length); bitStream.Write(length);
@ -333,9 +333,9 @@ void GameMessages::SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& s
bitStream.Write<char>(audioGUID[k]); bitStream.Write<char>(audioGUID[k]);
} }
bitStream.Write<uint32_t>(0); bitStream.Write<uint32_t>(0); // size of NDAudioMetaEventName (then print the string like the guid)
bitStream.Write0(); bitStream.Write0(); // result {bool}
bitStream.Write0(); bitStream.Write0(); // m_TargetObjectIDForNDAudioCallbackMessages {lwoobjid}
SEND_PACKET_BROADCAST; SEND_PACKET_BROADCAST;
} }

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 location because it is in %i and not the current zone (%i)", 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>

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

@ -15,8 +15,10 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_AM
"AmSkullkinDrillStand.cpp" "AmSkullkinDrillStand.cpp"
"AmSkullkinTower.cpp" "AmSkullkinTower.cpp"
"AmBlueX.cpp" "AmBlueX.cpp"
"AmTeapotServer.cpp") "AmTeapotServer.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

@ -0,0 +1,33 @@
#include "WanderingVendor.h"
#include "MovementAIComponent.h"
#include "ProximityMonitorComponent.h"
void WanderingVendor::OnStartup(Entity* self) {
auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// movementAIComponent->Resume();
self->SetProximityRadius(10, "playermonitor");
}
void WanderingVendor::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) {
if (status == "ENTER" && entering->IsPlayer()) {
auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// movementAIComponent->Pause();
self->CancelTimer("startWalking");
} else if (status == "LEAVE") {
auto* proximityMonitorComponent = self->GetComponent<ProximityMonitorComponent>();
if (!proximityMonitorComponent) self->AddComponent<ProximityMonitorComponent>();
const auto proxObjs = proximityMonitorComponent->GetProximityObjects("playermonitor");
if (proxObjs.empty()) self->AddTimer("startWalking", 1.5);
}
}
void WanderingVendor::OnTimerDone(Entity* self, std::string timerName) {
if (timerName == "startWalking") {
auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// movementAIComponent->Resume();
}
}

View File

@ -0,0 +1,13 @@
#ifndef __WANDERINGVENDOR__H__
#define __WANDERINGVENDOR__H__
#include "CppScripts.h"
class WanderingVendor : public CppScripts::Script {
public:
void OnStartup(Entity* self) override;
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) 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,11 +29,14 @@ 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"); int32_t boxFlag = self->GetVar<int32_t>(u"altFlagID");
if (boxFlag <= 0) { if (boxFlag <= 0) {
boxFlag = (10000 + Game::server->GetZoneID() + std::stoi(storyText.substr(storyText.length() - 2))); boxFlag = (10000 + Game::server->GetZoneID() + storyValue.value());
} }
if (user->GetCharacter()->GetPlayerFlag(boxFlag) == false) { if (user->GetCharacter()->GetPlayerFlag(boxFlag) == false) {
@ -41,3 +44,4 @@ void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) {
GameMessages::SendFireEventClientSide(self->GetObjectID(), user->GetSystemAddress(), u"achieve", LWOOBJID_EMPTY, 0, -1, LWOOBJID_EMPTY); 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

@ -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)

View File

@ -28,7 +28,7 @@ foreach(file ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB_BOSS_INSTANCE})
set(DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB} "boss_instance/${file}") set(DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB} "boss_instance/${file}")
endforeach() endforeach()
add_library(dScriptsServerMapNJHub ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB}) add_library(dScriptsServerMapNJHub OBJECT ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB})
target_include_directories(dScriptsServerMapNJHub PUBLIC "." "boss_instance") target_include_directories(dScriptsServerMapNJHub PUBLIC "." "boss_instance")
target_link_libraries(dScriptsServerMapNJHub target_link_libraries(dScriptsServerMapNJHub
dScriptsServerPets dScriptsServerPets

View File

@ -3,7 +3,7 @@ set(DSCRIPTS_SOURCES_02_SERVER_PETS
"PetFromObjectServer.cpp" "PetFromObjectServer.cpp"
"DamagingPets.cpp") "DamagingPets.cpp")
add_library(dScriptsServerPets STATIC ${DSCRIPTS_SOURCES_02_SERVER_PETS}) add_library(dScriptsServerPets OBJECT ${DSCRIPTS_SOURCES_02_SERVER_PETS})
target_include_directories(dScriptsServerPets PUBLIC ".") target_include_directories(dScriptsServerPets PUBLIC ".")
target_precompile_headers(dScriptsServerPets REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsServerPets REUSE_FROM dScriptsBase)

View File

@ -17,18 +17,22 @@ set(DSCRIPTS_SOURCES
link_libraries(dDatabase dPhysics) link_libraries(dDatabase dPhysics)
add_library(dScriptsBase STATIC ${DSCRIPTS_SOURCES}) add_library(dScriptsBase OBJECT ${DSCRIPTS_SOURCES})
target_include_directories(dScriptsBase PUBLIC .) target_link_libraries(dScriptsBase INTERFACE dGameBase dComponents)
target_link_libraries(dScriptsBase
INTERFACE dGameBase)
target_precompile_headers(dScriptsBase PRIVATE ${HEADERS_DGAME}) target_precompile_headers(dScriptsBase PRIVATE ${HEADERS_DGAME})
include_directories( include_directories(
${PROJECT_SOURCE_DIR}/dScripts "${PROJECT_SOURCE_DIR}/dScripts"
${PROJECT_SOURCE_DIR}/dGame "${PROJECT_SOURCE_DIR}/dGame"
"${PROJECT_SOURCE_DIR}/dGame/dComponents" # e.g. ScriptedActivityComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # e.g. direct ActivityManager
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # e.g. direct ActivityManager
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager.h
"${PROJECT_SOURCE_DIR}/dGame/dMission" # via MissionComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # viaInventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dZoneManager"
) )
link_libraries(dScriptsBase)
# dComponents
add_subdirectory(02_server) add_subdirectory(02_server)
add_subdirectory(ai) add_subdirectory(ai)
@ -37,14 +41,22 @@ add_subdirectory(EquipmentScripts)
add_subdirectory(EquipmentTriggers) add_subdirectory(EquipmentTriggers)
add_subdirectory(zone) add_subdirectory(zone)
add_library(dScripts STATIC "CppScripts.cpp") add_library(dScripts STATIC
$<TARGET_OBJECTS:dScriptsBase>
$<TARGET_OBJECTS:dScriptsClient>
$<TARGET_OBJECTS:dScriptsEquipmentScripts>
$<TARGET_OBJECTS:dScriptsEquipmentTriggers>
$<TARGET_OBJECTS:dScriptsZone>
"CppScripts.cpp"
)
target_link_libraries(dScripts PRIVATE dScriptsAI dScriptsServer)
target_include_directories(dScripts PRIVATE
$<TARGET_PROPERTY:dScriptsBase,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsServer,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAI,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsClient,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsEquipmentScripts,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsEquipmentTriggers,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsZone,INTERFACE_INCLUDE_DIRECTORIES>
)
target_precompile_headers(dScripts REUSE_FROM dScriptsBase) target_precompile_headers(dScripts REUSE_FROM dScriptsBase)
target_include_directories(dScripts PUBLIC ".")
target_link_libraries(dScripts
dScriptsBase
dScriptsServer
dScriptsAI
dScriptsClient
dScriptsEquipmentScripts
dScriptsEquipmentTriggers
dScriptsZone)

View File

@ -240,6 +240,7 @@
#include "AmDarklingDragon.h" #include "AmDarklingDragon.h"
#include "AmBlueX.h" #include "AmBlueX.h"
#include "AmTeapotServer.h" #include "AmTeapotServer.h"
#include "WanderingVendor.h"
// NJ Scripts // NJ Scripts
#include "NjGarmadonCelebration.h" #include "NjGarmadonCelebration.h"
@ -317,6 +318,8 @@
#include "WildNinjaSensei.h" #include "WildNinjaSensei.h"
#include "WildNinjaBricks.h" #include "WildNinjaBricks.h"
#include "VisToggleNotifierServer.h" #include "VisToggleNotifierServer.h"
#include "LupGenericInteract.h"
#include "WblRobotCitizen.h"
namespace { namespace {
InvalidScript* invalidToReturn = new InvalidScript(); InvalidScript* invalidToReturn = new InvalidScript();
@ -547,7 +550,7 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr
//PR: //PR:
else if (scriptName == "scripts\\client\\ai\\PR\\L_PR_WHISTLE.lua") else if (scriptName == "scripts\\client\\ai\\PR\\L_PR_WHISTLE.lua")
script = new PrWhistle(); script = new PrWhistle();
else if (scriptName == "scripts\\02_server\\Map\\PR\\L_PR_SEAGULL_FLY.lua") if (scriptName == "scripts\\02_server\\Map\\PR\\L_PR_SEAGULL_FLY.lua")
script = new PrSeagullFly(); script = new PrSeagullFly();
else if (scriptName == "scripts\\ai\\PETS\\L_HYDRANT_SMASHABLE.lua") else if (scriptName == "scripts\\ai\\PETS\\L_HYDRANT_SMASHABLE.lua")
script = new HydrantSmashable(); script = new HydrantSmashable();
@ -642,6 +645,8 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr
script = new MailBoxServer(); script = new MailBoxServer();
else if (scriptName == "scripts\\ai\\ACT\\L_ACT_MINE.lua") else if (scriptName == "scripts\\ai\\ACT\\L_ACT_MINE.lua")
script = new ActMine(); script = new ActMine();
else if (scriptName == "scripts\\02_server\\Map\\AM\\L_WANDERING_VENDOR.lua")
script = new WanderingVendor();
//Racing: //Racing:
else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\RACE_IMAGINE_CRATE_SERVER.lua") else if (scriptName == "scripts\\ai\\RACING\\OBJECTS\\RACE_IMAGINE_CRATE_SERVER.lua")
@ -726,7 +731,7 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr
script = new NTNaomiDirtServer(); script = new NTNaomiDirtServer();
//AM: //AM:
else if (scriptName == "scripts\\02_server\\Map\\AM\\L_AM_CONSOLE_TELEPORT_SERVER.lua") if (scriptName == "scripts\\02_server\\Map\\AM\\L_AM_CONSOLE_TELEPORT_SERVER.lua")
script = new AmConsoleTeleportServer(); script = new AmConsoleTeleportServer();
else if (scriptName == "scripts\\02_server\\Map\\AM\\L_RANDOM_SPAWNER_FIN.lua") else if (scriptName == "scripts\\02_server\\Map\\AM\\L_RANDOM_SPAWNER_FIN.lua")
script = new RandomSpawnerFin(); script = new RandomSpawnerFin();
@ -806,7 +811,7 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr
script = new Lieutenant(); script = new Lieutenant();
else if (scriptName == "scripts\\02_server\\Map\\njhub\\L_RAIN_OF_ARROWS.lua") else if (scriptName == "scripts\\02_server\\Map\\njhub\\L_RAIN_OF_ARROWS.lua")
script = new RainOfArrows(); script = new RainOfArrows();
else if (scriptName == "scripts\\02_server\\Map\\njhub\\L_CAVE_PRISON_CAGE.lua") if (scriptName == "scripts\\02_server\\Map\\njhub\\L_CAVE_PRISON_CAGE.lua")
script = new CavePrisonCage(); script = new CavePrisonCage();
else if (scriptName == "scripts\\02_server\\Map\\njhub\\boss_instance\\L_MONASTERY_BOSS_INSTANCE_SERVER.lua") else if (scriptName == "scripts\\02_server\\Map\\njhub\\boss_instance\\L_MONASTERY_BOSS_INSTANCE_SERVER.lua")
script = new NjMonastryBossInstance(); script = new NjMonastryBossInstance();
@ -938,6 +943,10 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr
script = new WildNinjaStudent(); script = new WildNinjaStudent();
else if (scriptName == "scripts\\ai\\WILD\\L_WILD_NINJA_SENSEI.lua") else if (scriptName == "scripts\\ai\\WILD\\L_WILD_NINJA_SENSEI.lua")
script = new WildNinjaSensei(); script = new WildNinjaSensei();
else if (scriptName == "scripts\\ai\\WILD\\L_LUP_generic_interact.lua")
script = new LupGenericInteract();
else if (scriptName.rfind("scripts\\zone\\LUPs\\RobotCity Intro\\WBL_RCIntro_RobotCitizen", 0) == 0)
script = new WblRobotCitizen();
// handle invalid script reporting if the path is greater than zero and it's not an ignored script // handle invalid script reporting if the path is greater than zero and it's not an ignored script
// information not really needed for sys admins but is for developers // information not really needed for sys admins but is for developers

View File

@ -8,6 +8,6 @@ set(DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS
"FireFirstSkillonStartup.cpp" "FireFirstSkillonStartup.cpp"
"StunImmunity.cpp") "StunImmunity.cpp")
add_library(dScriptsEquipmentScripts STATIC ${DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS}) add_library(dScriptsEquipmentScripts OBJECT ${DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS})
target_include_directories(dScriptsEquipmentScripts PUBLIC ".") target_include_directories(dScriptsEquipmentScripts PUBLIC ".")
target_precompile_headers(dScriptsEquipmentScripts REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsEquipmentScripts REUSE_FROM dScriptsBase)

View File

@ -1,6 +1,6 @@
set(DSCRIPTS_SOURCES_EQUIPMENTTRIGGERSSCRIPTS set(DSCRIPTS_SOURCES_EQUIPMENTTRIGGERSSCRIPTS
"CoilBackpackBase.cpp") "CoilBackpackBase.cpp")
add_library(dScriptsEquipmentTriggers STATIC ${DSCRIPTS_SOURCES_EQUIPMENTTRIGGERSSCRIPTS}) add_library(dScriptsEquipmentTriggers OBJECT ${DSCRIPTS_SOURCES_EQUIPMENTTRIGGERSSCRIPTS})
target_include_directories(dScriptsEquipmentTriggers PUBLIC ".") target_include_directories(dScriptsEquipmentTriggers PUBLIC ".")
target_precompile_headers(dScriptsEquipmentTriggers REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsEquipmentTriggers REUSE_FROM dScriptsBase)

View File

@ -9,6 +9,6 @@ foreach(file ${DSCRIPTS_SOURCES_AI_ACT_FOOTRACE})
set(DSCRIPTS_SOURCES_AI_ACT ${DSCRIPTS_SOURCES_AI_ACT} "FootRace/${file}") set(DSCRIPTS_SOURCES_AI_ACT ${DSCRIPTS_SOURCES_AI_ACT} "FootRace/${file}")
endforeach() endforeach()
add_library(dScriptsAiAct STATIC ${DSCRIPTS_SOURCES_AI_ACT}) add_library(dScriptsAiAct OBJECT ${DSCRIPTS_SOURCES_AI_ACT})
target_include_directories(dScriptsAiAct PUBLIC "." "FootRace") target_include_directories(dScriptsAiAct PUBLIC "." "FootRace")
target_precompile_headers(dScriptsAiAct REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiAct REUSE_FROM dScriptsBase)

View File

@ -16,6 +16,6 @@ set(DSCRIPTS_SOURCES_AI_AG
"AgStagePlatforms.cpp" "AgStagePlatforms.cpp"
"AgQbWall.cpp") "AgQbWall.cpp")
add_library(dScriptsAiAG STATIC ${DSCRIPTS_SOURCES_AI_AG}) add_library(dScriptsAiAG OBJECT ${DSCRIPTS_SOURCES_AI_AG})
target_include_directories(dScriptsAiAG PUBLIC ".") target_include_directories(dScriptsAiAG PUBLIC ".")
target_precompile_headers(dScriptsAiAG REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiAG REUSE_FROM dScriptsBase)

View File

@ -15,18 +15,34 @@ add_subdirectory(SPEC)
add_subdirectory(WILD) add_subdirectory(WILD)
add_library(dScriptsAI INTERFACE) add_library(dScriptsAI INTERFACE)
target_link_libraries(dScriptsAI INTERFACE target_sources(dScriptsAI INTERFACE
dScriptsAiAct $<TARGET_OBJECTS:dScriptsAiAct>
dScriptsAiAG $<TARGET_OBJECTS:dScriptsAiAG>
dScriptsAiFV $<TARGET_OBJECTS:dScriptsAiFV>
dScriptsAiGeneral $<TARGET_OBJECTS:dScriptsAiGeneral>
dScriptsAiGF $<TARGET_OBJECTS:dScriptsAiGF>
dScriptsAiMinigame $<TARGET_OBJECTS:dScriptsAiMinigame>
dScriptsAiNP $<TARGET_OBJECTS:dScriptsAiNP>
dScriptsAiNS $<TARGET_OBJECTS:dScriptsAiNS>
dScriptsAiPets $<TARGET_OBJECTS:dScriptsAiPets>
dScriptsAiProperty $<TARGET_OBJECTS:dScriptsAiProperty>
dScriptsAiRacing $<TARGET_OBJECTS:dScriptsAiRacing>
dScriptsAiSpec $<TARGET_OBJECTS:dScriptsAiSpec>
dScriptsAiWild $<TARGET_OBJECTS:dScriptsAiWild>
)
target_include_directories(dScriptsAI INTERFACE
$<TARGET_PROPERTY:dScriptsAiAct,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiAG,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiFV,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiGeneral,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiGF,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiMinigame,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiNP,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiNS,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiPets,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiProperty,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiRacing,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiSpec,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dScriptsAiWild,INTERFACE_INCLUDE_DIRECTORIES>
) )

View File

@ -18,7 +18,7 @@ set(DSCRIPTS_SOURCES_AI_FV
"FvMaelstromGeyser.cpp" "FvMaelstromGeyser.cpp"
"TriggerGas.cpp") "TriggerGas.cpp")
add_library(dScriptsAiFV STATIC ${DSCRIPTS_SOURCES_AI_FV}) add_library(dScriptsAiFV OBJECT ${DSCRIPTS_SOURCES_AI_FV})
target_include_directories(dScriptsAiFV PUBLIC ".") target_include_directories(dScriptsAiFV PUBLIC ".")
target_precompile_headers(dScriptsAiFV REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiFV REUSE_FROM dScriptsBase)

View File

@ -2,7 +2,7 @@ set(DSCRIPTS_SOURCES_AI_GENERAL
"InstanceExitTransferPlayerToLastNonInstance.cpp" "InstanceExitTransferPlayerToLastNonInstance.cpp"
"LegoDieRoll.cpp") "LegoDieRoll.cpp")
add_library(dScriptsAiGeneral STATIC ${DSCRIPTS_SOURCES_AI_GENERAL}) add_library(dScriptsAiGeneral OBJECT ${DSCRIPTS_SOURCES_AI_GENERAL})
target_include_directories(dScriptsAiGeneral PUBLIC ".") target_include_directories(dScriptsAiGeneral PUBLIC ".")
target_precompile_headers(dScriptsAiGeneral REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiGeneral REUSE_FROM dScriptsBase)

View File

@ -12,6 +12,6 @@ set(DSCRIPTS_SOURCES_AI_GF
"PirateRep.cpp" "PirateRep.cpp"
"GfParrotCrash.cpp") "GfParrotCrash.cpp")
add_library(dScriptsAiGF STATIC ${DSCRIPTS_SOURCES_AI_GF}) add_library(dScriptsAiGF OBJECT ${DSCRIPTS_SOURCES_AI_GF})
target_include_directories(dScriptsAiGF PUBLIC ".") target_include_directories(dScriptsAiGF PUBLIC ".")
target_precompile_headers(dScriptsAiGF REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiGF REUSE_FROM dScriptsBase)

View File

@ -12,6 +12,6 @@ foreach(file ${DSCRIPTS_SOURCES_AI_MINIGAME_OBJECTS})
set(DSCRIPTS_SOURCES_AI_MINIGAME ${DSCRIPTS_SOURCES_AI_MINIGAME} "Objects/${file}") set(DSCRIPTS_SOURCES_AI_MINIGAME ${DSCRIPTS_SOURCES_AI_MINIGAME} "Objects/${file}")
endforeach() endforeach()
add_library(dScriptsAiMinigame STATIC ${DSCRIPTS_SOURCES_AI_MINIGAME}) add_library(dScriptsAiMinigame OBJECT ${DSCRIPTS_SOURCES_AI_MINIGAME})
target_include_directories(dScriptsAiMinigame PUBLIC "." "Objects" "SG_GF" "SG_GF/SERVER") target_include_directories(dScriptsAiMinigame PUBLIC "." "Objects" "SG_GF" "SG_GF/SERVER")
target_precompile_headers(dScriptsAiMinigame REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiMinigame REUSE_FROM dScriptsBase)

View File

@ -1,6 +1,6 @@
set(DSCRIPTS_SOURCES_AI_NP set(DSCRIPTS_SOURCES_AI_NP
"NpcNpSpacemanBob.cpp") "NpcNpSpacemanBob.cpp")
add_library(dScriptsAiNP STATIC ${DSCRIPTS_SOURCES_AI_NP}) add_library(dScriptsAiNP OBJECT ${DSCRIPTS_SOURCES_AI_NP})
target_include_directories(dScriptsAiNP PUBLIC ".") target_include_directories(dScriptsAiNP PUBLIC ".")
target_precompile_headers(dScriptsAiNP REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiNP REUSE_FROM dScriptsBase)

View File

@ -21,7 +21,7 @@ foreach(file ${DSCRIPTS_SOURCES_AI_NS_WH})
set(DSCRIPTS_SOURCES_AI_NS ${DSCRIPTS_SOURCES_AI_NS} "WH/${file}") set(DSCRIPTS_SOURCES_AI_NS ${DSCRIPTS_SOURCES_AI_NS} "WH/${file}")
endforeach() endforeach()
add_library(dScriptsAiNS STATIC ${DSCRIPTS_SOURCES_AI_NS}) add_library(dScriptsAiNS OBJECT ${DSCRIPTS_SOURCES_AI_NS})
target_include_directories(dScriptsAiNS PUBLIC "." "NS_PP_01" "WH" target_include_directories(dScriptsAiNS PUBLIC "." "NS_PP_01" "WH"
PRIVATE PRIVATE
${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/NS) # NsConcertChoiceBuildManager.h ${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/NS) # NsConcertChoiceBuildManager.h

View File

@ -1,6 +1,6 @@
set(DSCRIPTS_SOURCES_AI_PETS set(DSCRIPTS_SOURCES_AI_PETS
"HydrantSmashable.cpp") "HydrantSmashable.cpp")
add_library(dScriptsAiPets STATIC ${DSCRIPTS_SOURCES_AI_PETS}) add_library(dScriptsAiPets OBJECT ${DSCRIPTS_SOURCES_AI_PETS})
target_include_directories(dScriptsAiPets PUBLIC "." "NS_PP_01" "WH") target_include_directories(dScriptsAiPets PUBLIC "." "NS_PP_01" "WH")
target_precompile_headers(dScriptsAiPets REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiPets REUSE_FROM dScriptsBase)

View File

@ -8,6 +8,6 @@ foreach(file ${DSCRIPTS_SOURCES_AI_PROPERTY_AG})
set(DSCRIPTS_SOURCES_AI_PROPERTY ${DSCRIPTS_SOURCES_AI_PROPERTY} "AG/${file}") set(DSCRIPTS_SOURCES_AI_PROPERTY ${DSCRIPTS_SOURCES_AI_PROPERTY} "AG/${file}")
endforeach() endforeach()
add_library(dScriptsAiProperty STATIC ${DSCRIPTS_SOURCES_AI_PROPERTY}) add_library(dScriptsAiProperty OBJECT ${DSCRIPTS_SOURCES_AI_PROPERTY})
target_include_directories(dScriptsAiProperty PUBLIC "." "AG") target_include_directories(dScriptsAiProperty PUBLIC "." "AG")
target_precompile_headers(dScriptsAiProperty REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiProperty REUSE_FROM dScriptsBase)

View File

@ -6,6 +6,6 @@ foreach(file ${DSCRIPTS_SOURCES_AI_RACING_OBJECTS})
set(DSCRIPTS_SOURCES_AI_RACING ${DSCRIPTS_SOURCES_AI_RACING} "OBJECTS/${file}") set(DSCRIPTS_SOURCES_AI_RACING ${DSCRIPTS_SOURCES_AI_RACING} "OBJECTS/${file}")
endforeach() endforeach()
add_library(dScriptsAiRacing STATIC ${DSCRIPTS_SOURCES_AI_RACING}) add_library(dScriptsAiRacing OBJECT ${DSCRIPTS_SOURCES_AI_RACING})
target_include_directories(dScriptsAiRacing PUBLIC "." "OBJECTS") target_include_directories(dScriptsAiRacing PUBLIC "." "OBJECTS")
target_precompile_headers(dScriptsAiRacing REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiRacing REUSE_FROM dScriptsBase)

View File

@ -3,6 +3,6 @@ set(DSCRIPTS_SOURCES_AI_SPEC
"SpecialPowerupSpawner.cpp" "SpecialPowerupSpawner.cpp"
"SpecialSpeedBuffSpawner.cpp") "SpecialSpeedBuffSpawner.cpp")
add_library(dScriptsAiSpec STATIC ${DSCRIPTS_SOURCES_AI_SPEC}) add_library(dScriptsAiSpec OBJECT ${DSCRIPTS_SOURCES_AI_SPEC})
target_include_directories(dScriptsAiSpec PUBLIC ".") target_include_directories(dScriptsAiSpec PUBLIC ".")
target_precompile_headers(dScriptsAiSpec REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiSpec REUSE_FROM dScriptsBase)

View File

@ -1,5 +1,6 @@
set(DSCRIPTS_SOURCES_AI_WILD set(DSCRIPTS_SOURCES_AI_WILD
"AllCrateChicken.cpp" "AllCrateChicken.cpp"
"LupGenericInteract.cpp"
"WildAmbients.cpp" "WildAmbients.cpp"
"WildAmbientCrab.cpp" "WildAmbientCrab.cpp"
"WildAndScared.cpp" "WildAndScared.cpp"
@ -9,6 +10,6 @@ set(DSCRIPTS_SOURCES_AI_WILD
"WildNinjaSensei.cpp" "WildNinjaSensei.cpp"
"WildPants.cpp") "WildPants.cpp")
add_library(dScriptsAiWild STATIC ${DSCRIPTS_SOURCES_AI_WILD}) add_library(dScriptsAiWild OBJECT ${DSCRIPTS_SOURCES_AI_WILD})
target_include_directories(dScriptsAiWild PUBLIC ".") target_include_directories(dScriptsAiWild PUBLIC ".")
target_precompile_headers(dScriptsAiWild REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsAiWild REUSE_FROM dScriptsBase)

View File

@ -0,0 +1,6 @@
#include "LupGenericInteract.h"
#include "GameMessages.h"
void LupGenericInteract::OnUse(Entity* self, Entity* user) {
GameMessages::SendPlayAnimation(self, u"interact");
}

View File

@ -0,0 +1,12 @@
#ifndef __LUCGENERICINTERACT__H__
#define __LUCGENERICINTERACT__H__
#include "CppScripts.h"
class LupGenericInteract : public CppScripts::Script {
public:
void OnUse(Entity* self, Entity* user) override;
};
#endif //!__LUCGENERICINTERACT__H__

View File

@ -6,6 +6,6 @@ foreach(file ${DSCRIPTS_SOURCES_CLIENT_AI})
set(DSCRIPTS_SOURCES_CLIENT ${DSCRIPTS_SOURCES_CLIENT} "ai/${file}") set(DSCRIPTS_SOURCES_CLIENT ${DSCRIPTS_SOURCES_CLIENT} "ai/${file}")
endforeach() endforeach()
add_library(dScriptsClient STATIC ${DSCRIPTS_SOURCES_CLIENT}) add_library(dScriptsClient OBJECT ${DSCRIPTS_SOURCES_CLIENT})
target_include_directories(dScriptsClient PUBLIC "." "ai" "ai/PR") target_include_directories(dScriptsClient PUBLIC "." "ai" "ai/PR")
target_precompile_headers(dScriptsClient REUSE_FROM dScriptsBase) target_precompile_headers(dScriptsClient REUSE_FROM dScriptsBase)

View File

@ -18,10 +18,11 @@ foreach(file ${DSCRIPTS_SOURCES_ZONE_PROPERTY})
set(DSCRIPTS_SOURCES_ZONE ${DSCRIPTS_SOURCES_ZONE} "PROPERTY/${file}") set(DSCRIPTS_SOURCES_ZONE ${DSCRIPTS_SOURCES_ZONE} "PROPERTY/${file}")
endforeach() endforeach()
add_library(dScriptsZone STATIC ${DSCRIPTS_SOURCES_ZONE}) add_library(dScriptsZone OBJECT ${DSCRIPTS_SOURCES_ZONE})
target_include_directories(dScriptsZone PUBLIC "." target_include_directories(dScriptsZone PUBLIC "."
"AG" "AG"
"LUPs" "LUPs"
"LUPs/RobotCity_Intro"
"PROPERTY" "PROPERTY"
"PROPERTY/FV" "PROPERTY/FV"
"PROPERTY/GF" "PROPERTY/GF"

View File

@ -1,3 +1,11 @@
set(DSCRIPTS_SOURCES_ZONE_LUPS set(DSCRIPTS_SOURCES_ZONE_LUPS
"WblGenericZone.cpp" "WblGenericZone.cpp"
PARENT_SCOPE) )
add_subdirectory(RobotCity_Intro)
foreach(file ${DSCRIPTS_SOURCES_ZONE_LUPS_ROBOTCITYINTRO})
set(DSCRIPTS_SOURCES_ZONE_LUPS ${DSCRIPTS_SOURCES_ZONE_LUPS} "RobotCity_Intro/${file}")
endforeach()
set(DSCRIPTS_SOURCES_ZONE_LUPS ${DSCRIPTS_SOURCES_ZONE_LUPS} PARENT_SCOPE)

View File

@ -0,0 +1,3 @@
set(DSCRIPTS_SOURCES_ZONE_LUPS_ROBOTCITYINTRO
"WblRobotCitizen.cpp"
PARENT_SCOPE)

View File

@ -0,0 +1,24 @@
#include "WblRobotCitizen.h"
#include "MovementAIComponent.h"
#include "RenderComponent.h"
void WblRobotCitizen::OnStartup(Entity* self) {
auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// movementAIComponent->Resume();
}
void WblRobotCitizen::OnUse(Entity* self, Entity* user) {
// auto movementAIComponent = self->GetComponent<MovementAIComponent>();
// if (!movementAIComponent) movementAIComponent->Pause();
auto face = NiQuaternion::LookAt(self->GetPosition(), user->GetPosition());
self->SetRotation(face);
auto timer = RenderComponent::PlayAnimation(self, "wave");
self->AddTimer("animation time", timer);
}
void WblRobotCitizen::OnTimerDone(Entity* self, std::string timerName) {
auto movementAIComponent = self->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// movementAIComponent->Resume();
}

View File

@ -0,0 +1,13 @@
#ifndef __WBLROBOTCITIZEN__H__
#define __WBLROBOTCITIZEN__H__
#include "CppScripts.h"
class WblRobotCitizen : public CppScripts::Script {
public:
void OnStartup(Entity* self) override;
void OnUse(Entity* self, Entity* user) override;
void OnTimerDone(Entity* self, std::string timerName) override;
};
#endif //!__WBLROBOTCITIZEN__H__

View File

@ -4,3 +4,7 @@ set(DSERVER_SOURCES
add_library(dServer STATIC ${DSERVER_SOURCES}) add_library(dServer STATIC ${DSERVER_SOURCES})
target_include_directories(dServer PUBLIC ".") target_include_directories(dServer PUBLIC ".")
target_include_directories(dServer PRIVATE
"${PROJECT_SOURCE_DIR}/dCommon/" # BinaryPathFinder.h
)

View File

@ -2,11 +2,22 @@ set(DWORLDSERVER_SOURCES
"PerformanceManager.cpp" "PerformanceManager.cpp"
) )
add_library(dWorldServer ${DWORLDSERVER_SOURCES}) add_library(dWorldServer OBJECT ${DWORLDSERVER_SOURCES})
target_link_libraries(dWorldServer PUBLIC dGameBase dCommon)
add_executable(WorldServer "WorldServer.cpp") add_executable(WorldServer "WorldServer.cpp")
target_include_directories(WorldServer PRIVATE "${PROJECT_SOURCE_DIR}/dChatFilter")
add_compile_definitions(WorldServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") add_compile_definitions(WorldServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"")
target_link_libraries(dWorldServer ${COMMON_LIBRARIES}) target_include_directories(WorldServer PRIVATE
target_link_libraries(WorldServer ${COMMON_LIBRARIES} dChatFilter dGame dZoneManager dPhysics Detour Recast tinyxml2 dWorldServer dNavigation dServer) "${PROJECT_SOURCE_DIR}/dServer" # BinaryPathFinder.h
target_include_directories(WorldServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer) )
target_link_libraries(WorldServer ${COMMON_LIBRARIES}
dScripts
dGameBase
dComponents
dUtilities
dGameMessages
dInventory
dGame dChatFilter dZoneManager dPhysics Detour Recast tinyxml2 dWorldServer dNavigation dServer)

View File

@ -3,7 +3,20 @@ set(DZONEMANAGER_SOURCES "dZoneManager.cpp"
"Spawner.cpp" "Spawner.cpp"
"Zone.cpp") "Zone.cpp")
add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES}) add_library(dZoneManager OBJECT ${DZONEMANAGER_SOURCES})
target_link_libraries(dZoneManager target_link_libraries(dZoneManager
PUBLIC dPhysics PRIVATE dDatabaseCDClient
INTERFACE dWorldServer) PUBLIC dPhysics)
#set_property(TARGET dZoneManager APPEND PROPERTY INTERFACE_LINK_LIBRARIES dWorldServer)
target_include_directories(dZoneManager PUBLIC "."
"${PROJECT_SOURCE_DIR}/dGame" # Entity.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # EntityInfo.h
PRIVATE
"${PROJECT_SOURCE_DIR}/dGame/dComponents" #InventoryComponent.h
"${PROJECT_SOURCE_DIR}/dGame/dInventory" #InventoryComponent.h (transitive)
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" #BehaviorSlot.h
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" #GameMessages.h
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" #VanityUtilities.h
)

View File

@ -419,7 +419,7 @@ void Zone::LoadPath(std::istream& file) {
if (path.pathType == PathType::MovingPlatform) { if (path.pathType == PathType::MovingPlatform) {
BinaryIO::BinaryRead(file, waypoint.movingPlatform.lockPlayer); BinaryIO::BinaryRead(file, waypoint.movingPlatform.lockPlayer);
BinaryIO::BinaryRead(file, waypoint.movingPlatform.speed); BinaryIO::BinaryRead(file, waypoint.speed);
BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait); BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait);
if (path.pathVersion >= 13) { if (path.pathVersion >= 13) {
BinaryIO::ReadString<uint8_t>(file, waypoint.movingPlatform.departSound, BinaryIO::ReadType::WideString); BinaryIO::ReadString<uint8_t>(file, waypoint.movingPlatform.departSound, BinaryIO::ReadType::WideString);
@ -438,7 +438,7 @@ void Zone::LoadPath(std::istream& file) {
BinaryIO::BinaryRead(file, waypoint.racing.planeHeight); BinaryIO::BinaryRead(file, waypoint.racing.planeHeight);
BinaryIO::BinaryRead(file, waypoint.racing.shortestDistanceToEnd); BinaryIO::BinaryRead(file, waypoint.racing.shortestDistanceToEnd);
} else if (path.pathType == PathType::Rail) { } else if (path.pathType == PathType::Rail) {
if (path.pathVersion > 16) BinaryIO::BinaryRead(file, waypoint.rail.speed); if (path.pathVersion > 16) BinaryIO::BinaryRead(file, waypoint.speed);
} }
// object LDF configs // object LDF configs

View File

@ -40,7 +40,6 @@ struct SceneTransition {
struct MovingPlatformPathWaypoint { struct MovingPlatformPathWaypoint {
uint8_t lockPlayer; uint8_t lockPlayer;
float speed;
float wait; float wait;
std::string departSound; std::string departSound;
std::string arriveSound; std::string arriveSound;
@ -62,17 +61,13 @@ struct RacingPathWaypoint {
float shortestDistanceToEnd; float shortestDistanceToEnd;
}; };
struct RailPathWaypoint {
float speed;
};
struct PathWaypoint { struct PathWaypoint {
NiPoint3 position; NiPoint3 position;
NiQuaternion rotation; // not included in all, but it's more convenient here NiQuaternion rotation; // not included in all, but it's more convenient here
MovingPlatformPathWaypoint movingPlatform; MovingPlatformPathWaypoint movingPlatform;
CameraPathWaypoint camera; CameraPathWaypoint camera;
RacingPathWaypoint racing; RacingPathWaypoint racing;
RailPathWaypoint rail; float speed;
std::vector<LDFBaseData*> config; std::vector<LDFBaseData*> config;
}; };

170
docs/Vanity.md Normal file
View File

@ -0,0 +1,170 @@
# DLU Vanity System
Darkflame Universe Vanity System is a method of defined objects to be spawned serverside and communicated to the client without modifying the game's assets.
You can check out the different `xml` files in `vanity/` and use `vanity/demo.xml` to follow along with this tutorial and documentation of thew various features, cabapilities, and limitations of this system.
## `vanity/root.xml`
`root.xml` is the only file the server will load in by default.
To load other files, you can do so like this:
```xml
<files>
<file name="dev-tribute.xml" enabled="1"/>
<file name="atm.xml" enabled="0"/>
<file name="demo.xml" enabled="0"/>
</files>
```
`name` is the name of the file relative to the vanity folder.
Ex: you have a folder like `vanity/events/` with a file called `halloween.xml` in it, you will include it as such:
`<file name="events/halloween.xml" enabled="1"/>`
`enabled` tells if that file should be loaded.
files will only be loaded in, if `enabled="1"`
There cannot be multiple `<files></files>` per xml file, only the first one will be read, but you can have as many `<files/>` in it as you wish.
## `vanity/demo.xml`
This demo file covers most of the features of defining objects to spawn server side and will go over them one by one.
The minimun data needed to define and ojbect to spawn is as follows:
```xml
<objects>
<object lot="1">
<locations>
<location zone="1200" x="0" y="0" z="0" rw="0" rx="0" ry="0" rz="0" />
</locations>
</object>
</objects>
```
* `lot` the LEGO Object Template to be spawned
* `<location/>` must have `zone`, `x`, `y`, `z` `rw`, `rx`, `ry`, and `rz` and one `location` must in exist in `locations` for it to be spawned
Everything else is is optional.
* LEGO Name Value (LNV) configs can control almost all functionality of the objects in the game, they are defined like `name=type:value`. types can be found in `dCommon/LDFFromat.h`
```xml
<config>
<key>bool=7:1</key>
</config>
```
### Story Plaque with custom text
lot 8193 is the story plaque that is used in game to give the game lore to the player.
DLU Vanity has the capability to provide custom text to it via a LNV config
From `demo.xml`
```xml
<object lot="8139">
<config>
<key>customText=13:This story plaque has custom text that is defined by DLU's vanity system. Check out &lt;font color="#000000" &gt;vanity/demo.xml&lt;/font&gt; to see how this works!</key>
</config>
<locations>
<location zone="1200" x="-26.281" y="288.896" z="-77.484" rw="0.997534" rx="0.00" ry="-0.070190" rz="0.00" />
</locations>
</object>
```
* The `customText` config must be a type of `13` (wstring)
* HTML like formatting can be used for font color, but `<` must be reaplaced withh `&gt;`, and `>` replaced with `&lt;`
### Object with multiple locations and scale
```xml
<object lot="3248">
<locations>
<location zone="1200" x="-15.0" y="288.8" z="-167.0" rw="0.984321" rx="0.00" ry="0.176388" rz="0.00" />
<location zone="1200" x="15.0" y="288.8" z="-158.0" rw="0.724628" rx="0.00" ry="-0.689141" rz="0.00" scale="0.30" />
</locations>
</object>
```
#### Multiple locations
Multiple location elements can be defined for an object.
For every location that object will spawn:
This will spawn two trees, one at each specified location.
#### Scale
Each location can specify a `scale` which defaults to `1`. The object will be scaled by this attribute in the location when defined.
### Object with multiple random locations and chance
```xml
<object lot="10141">
<config>
<key>useLocationsAsRandomSpawnPoint=7:1</key>
</config>
<locations>
<location zone="1200" x="31.819" y="288.896" z="-117.095" rw="0.630659" rx="0.00" ry="-0.776060" rz="0.00" chance="0.50"/>
<location zone="1200" x="42.755" y="291.897" z="-144.385" rw="0.855306" rx="0.00" ry="-0.518124" rz="0.00" chance="0.50"/>
<location zone="1200" x="3.984" y="288.896" z="-165.947" rw="0.978508" rx="0.00" ry="-0.206210" rz="0.00" chance="0.50"/>
</locations>
</object>
```
#### Random Spawn Point
If the LNV config `useLocationsAsRandomSpawnPoint=7:1` is defined and is set to `1`, instead of spawning the object at every location, it will randomly choose between all locations in the current zone to spawn one instance of the object.
If a location is not in the current zone, it will not be considered.
#### Chance
Each location can specify a `chance` attribute. This defines a chance from, `0` to `1` that the object will spawn, with `0` being never spawn, and `1` being always spawn. A `chance="0.8"` will have an 80% chance for the object to spawn at that location.
`useLocationsAsRandomSpawnPoint` and `chance` are independent of each other and be used separately
### Custom vendor with custom name and gear
```xml
<object name="Demo Fella - GM Items Vendor" lot="1867">
<equipment>7630, 1727, 7453, 7521</equipment>
<config>
<key>vendorInvOverride=0:1727,7292,16553,2243,14535,14538,14531,6730</key>
</config>
<locations>
<location zone="1200" x="35.935" y="288.896" z="-128.213" rw="0.882977" rx="0.00" ry="-0.469416" rz="0.00" />
</locations>
</object>
```
#### Custom vendor
For a custom vendor to work, you must use a LOT that already has a vendor compoenet attached to it.
Without an LNV keys, it will give it's normal inventory
You muse define `vendorInvOverride=0:` and then a list of LOTs that the vendor will sell. This will override all items the vendor was selling and use the list of LOTs provided.
LOTs must have an item component in order to be sold by a vendor.
#### Custom Name
The `name` attribute will give or override the name displayed for an object, if it displays one.
Using a ` - ` will allow you to define a title that will display under their name on their nametag (formally called a billboard).
#### Custom Gear
The `equipment` element is a lis of comma separated lots that will defind the geat an object will attempt to equip.
LOTs must have an inventory component in order to equipe custom gear.
### Creating Spawners
```xml
<object lot="176">
<config>
...
<key>spawntemplate=1:2295</key>
...
</config>
<locations>
<location zone="1200" x="4.232" y="288.895" z="-85.846" rw="-0.205988" rx="0.00" ry="0.978555" rz="0.00" />
</locations>
</object>
</objects>
```
LOT `167` is a spawner. The spawner config in the `demo.xml` was copied from an existing object via lcdr's luzviewer.
The main config to care about is `spawntemplate` as that controls what the spawner spawns.

View File

@ -1,20 +1,19 @@
message (STATUS "Testing is enabled. Fetching gtest...") message (STATUS "Testing is enabled.")
enable_testing() enable_testing()
include(FetchContent) find_package(GoogleTest REQUIRED)
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)
include(GoogleTest) include(GoogleTest)
message(STATUS "gtest fetched and is now ready.") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
if(APPLE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH True)
set(CMAKE_BUILD_WITH_INSTALL_RPATH True)
set(CMAKE_INSTALL_RPATH "@executable_path")
endif()
add_custom_target(conncpp_tests
${CMAKE_COMMAND} -E copy $<TARGET_FILE:MariaDB::ConnCpp> ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# Add the subdirectories # Add the subdirectories
add_subdirectory(dCommonTests) add_subdirectory(dCommonTests)

View File

@ -17,6 +17,19 @@ list(APPEND DCOMMONTEST_SOURCES ${DENUMS_TESTS})
# Set our executable # Set our executable
add_executable(dCommonTests ${DCOMMONTEST_SOURCES}) add_executable(dCommonTests ${DCOMMONTEST_SOURCES})
add_dependencies(dCommonTests conncpp_tests)
# Apple needs some special linkage for the mariadb connector for tests.
if(APPLE)
add_custom_command(TARGET dCommonTests POST_BUILD
COMMAND otool ARGS -l dCommonTests
COMMAND otool ARGS -L dCommonTests
COMMAND ls
COMMAND otool ARGS -D libmariadbcpp.dylib
COMMAND install_name_tool ARGS -change libmariadbcpp.dylib @rpath/libmariadbcpp.dylib dCommonTests
COMMAND otool ARGS -L dCommonTests
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
# Link needed libraries # Link needed libraries
target_link_libraries(dCommonTests ${COMMON_LIBRARIES} GTest::gtest_main) target_link_libraries(dCommonTests ${COMMON_LIBRARIES} GTest::gtest_main)

View File

@ -12,8 +12,18 @@ file(COPY ${GAMEMESSAGE_TESTBITSTREAMS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
# Add the executable. Remember to add all tests above this! # Add the executable. Remember to add all tests above this!
add_executable(dGameTests ${DGAMETEST_SOURCES}) add_executable(dGameTests ${DGAMETEST_SOURCES})
add_dependencies(dGameTests conncpp_tests)
target_link_libraries(dGameTests ${COMMON_LIBRARIES} GTest::gtest_main dGame dZoneManager dPhysics Detour Recast tinyxml2 dWorldServer dChatFilter dNavigation) # Apple needs some special linkage for the mariadb connector for tests.
if(APPLE)
add_custom_command(TARGET dGameTests POST_BUILD
COMMAND install_name_tool ARGS -change libmariadbcpp.dylib @rpath/libmariadbcpp.dylib dGameTests
COMMAND otool ARGS -L dGameTests
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
target_link_libraries(dGameTests ${COMMON_LIBRARIES} GTest::gtest_main
dGame dScripts dPhysics Detour Recast tinyxml2 dWorldServer dZoneManager dChatFilter dNavigation)
# Discover the tests # Discover the tests
gtest_discover_tests(dGameTests) gtest_discover_tests(dGameTests)

View File

@ -19,7 +19,11 @@ add_library(bcrypt ${SOURCES_LIBBCRYPT})
# Because we are not using the libbcrypt CMakeLists.txt, we need to include these headers for the library to use. # Because we are not using the libbcrypt CMakeLists.txt, we need to include these headers for the library to use.
# fortunately they are only needed for building the libbcrypt directory and nothing else, so these are marked private. # fortunately they are only needed for building the libbcrypt directory and nothing else, so these are marked private.
target_include_directories(bcrypt PRIVATE "libbcrypt/include") if(NOT WIN32)
target_include_directories(bcrypt PRIVATE "libbcrypt/include/bcrypt")
endif()
target_include_directories(bcrypt INTERFACE "libbcrypt/include")
target_include_directories(bcrypt PRIVATE "libbcrypt/src") target_include_directories(bcrypt PRIVATE "libbcrypt/src")
# Source code for sqlite # Source code for sqlite
@ -28,9 +32,6 @@ add_subdirectory(SQLite)
# Source code for magic_enum # Source code for magic_enum
add_subdirectory(magic_enum) add_subdirectory(magic_enum)
# MariaDB C++ Connector
include(CMakeMariaDBLists.txt)
# Create our third party library objects # Create our third party library objects
add_subdirectory(raknet) add_subdirectory(raknet)

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