Merge branch 'main' into remove-multiple-script-syntax-ffffffffff

This commit is contained in:
David Markowitz 2024-03-06 02:11:27 -08:00
commit 109f556ef7
15 changed files with 246 additions and 60 deletions

View File

@ -77,7 +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, serializes everything #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})
@ -215,12 +215,9 @@ add_subdirectory(thirdparty)
# Create our list of include directories # Create our list of include directories
set(INCLUDED_DIRECTORIES set(INCLUDED_DIRECTORIES
"dChatFilter"
"dPhysics" "dPhysics"
"dNavigation" "dNavigation"
"dNavigation/dTerrain"
"dNet" "dNet"
@ -240,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()
@ -250,7 +248,6 @@ foreach(dir ${INCLUDED_DIRECTORIES})
endforeach() endforeach()
# Add linking directories: # Add linking directories:
# link_directories(${PROJECT_BINARY_DIR})
if (UNIX) if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
endif() endif()

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})
@ -87,7 +87,6 @@ else() # Build from source
endif() endif()
set(MARIADBCPP_INSTALL_DIR ${PROJECT_BINARY_DIR}/prefix) set(MARIADBCPP_INSTALL_DIR ${PROJECT_BINARY_DIR}/prefix)
message("MariaDB C/C++ install prefix: " ${MARIADBCPP_INSTALL_DIR})
set(MARIADBCPP_LIBRARY_DIR ${PROJECT_BINARY_DIR}/mariadbcpp) set(MARIADBCPP_LIBRARY_DIR ${PROJECT_BINARY_DIR}/mariadbcpp)
set(MARIADBCPP_PLUGIN_DIR ${MARIADBCPP_LIBRARY_DIR}/plugin) set(MARIADBCPP_PLUGIN_DIR ${MARIADBCPP_LIBRARY_DIR}/plugin)
set(MARIADBCPP_SOURCE_DIR ${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp) set(MARIADBCPP_SOURCE_DIR ${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp)
@ -124,14 +123,10 @@ else() # Build from source
set(MARIADBCPP_SHARED_LIBRARY_LOCATION "${MARIADBCPP_LIBRARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}") set(MARIADBCPP_SHARED_LIBRARY_LOCATION "${MARIADBCPP_LIBRARY_DIR}/${MARIADB_SHARED_LIBRARY_NAME}")
if(WIN32) if(WIN32)
set(MARIADBC_SHARED_LIBRARY_LOCATION "${MARIADBCPP_LIBRARY_DIR}/libmariadb.lib") set(MARIADBC_SHARED_LIBRARY_LOCATION "${MARIADBCPP_LIBRARY_DIR}/libmariadb.lib")
#elseif(UNIX)
# set(MARIADBC_SHARED_LIBRARY_LOCATION "${MARIADBCPP_LIBRARY_DIR}/libmariadb.so.3")
endif() endif()
endif() endif()
# Create mariadb connector library object # Create mariadb connector library object
message("libmariadb: ${MARIADBC_SHARED_LIBRARY_LOCATION}")
message("libmariadbcpp: ${MARIADBCPP_SHARED_LIBRARY_LOCATION}")
add_library(MariaDB::ConnCpp SHARED IMPORTED GLOBAL) add_library(MariaDB::ConnCpp SHARED IMPORTED GLOBAL)
add_dependencies(MariaDB::ConnCpp mariadb_connector_cpp) add_dependencies(MariaDB::ConnCpp mariadb_connector_cpp)
set_target_properties(MariaDB::ConnCpp PROPERTIES set_target_properties(MariaDB::ConnCpp PROPERTIES

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

@ -65,3 +65,15 @@ target_include_directories(dGame INTERFACE
$<TARGET_PROPERTY:dPropertyBehaviors,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:dPropertyBehaviors,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:dUtilities,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:dUtilities,INTERFACE_INCLUDE_DIRECTORIES>
) )
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

@ -75,13 +75,8 @@ target_include_directories(dComponents PUBLIC "."
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # direct Loot.h "${PROJECT_SOURCE_DIR}/dGame/dUtilities" # direct Loot.h
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h "${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h
"${PROJECT_SOURCE_DIR}/dZoneManager" # via BouncerComponent.cpp, ActivityComponent.cpp "${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)
# INTERFACE link w/o dependency
#set_property(TARGET dComponents APPEND PROPERTY INTERFACE_LINK_LIBRARIES
# dUtilities dCommon dBehaviors dChatFilter dMission dInventory
# dPhysics
#)
target_link_libraries(dComponents INTERFACE dBehaviors) target_link_libraries(dComponents INTERFACE dBehaviors)

View File

@ -12,5 +12,6 @@ target_include_directories(dNavigation PUBLIC "."
"${PROJECT_SOURCE_DIR}/dZoneManager" "${PROJECT_SOURCE_DIR}/dZoneManager"
"${PROJECT_SOURCE_DIR}/dGame" "${PROJECT_SOURCE_DIR}/dGame"
"${PROJECT_SOURCE_DIR}/dGame/dEntity" "${PROJECT_SOURCE_DIR}/dGame/dEntity"
"${PROJECT_SOURCE_DIR}/dNavigation/dTerrain" # via dNavMesh.cpp
) )
target_link_libraries(dNavigation PRIVATE Detour Recast dCommon) target_link_libraries(dNavigation PRIVATE Detour Recast dCommon)

View File

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

View File

@ -6,7 +6,7 @@
#include "Entity.h" #include "Entity.h"
void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) {
if (self->GetVar<bool>(u"hasCustomText")) { if (self->HasVar(u"customText")) {
const auto& customText = self->GetVar<std::string>(u"customText"); const auto& customText = self->GetVar<std::string>(u"customText");
{ {
@ -29,15 +29,19 @@ void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) {
return; return;
} }
if (!self->HasVar(u"storyText") || !self->HasVar(u"altFlagID")) return;
const auto storyText = self->GetVarAsString(u"storyText"); const auto storyText = self->GetVarAsString(u"storyText");
if (storyText.length() > 2) {
auto storyValue = GeneralUtils::TryParse<uint32_t>(storyText.substr(storyText.length() - 2));
if(!storyValue) return;
int32_t boxFlag = self->GetVar<int32_t>(u"altFlagID"); 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) {
user->GetCharacter()->SetPlayerFlag(boxFlag, true); user->GetCharacter()->SetPlayerFlag(boxFlag, true);
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

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

View File

@ -6,10 +6,11 @@ add_library(dWorldServer OBJECT ${DWORLDSERVER_SOURCES})
target_link_libraries(dWorldServer PUBLIC dGameBase dCommon) 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_include_directories(WorldServer PRIVATE target_include_directories(WorldServer PRIVATE
${PROJECT_SOURCE_DIR}/dServer/ # BinaryPathFinder.h "${PROJECT_SOURCE_DIR}/dServer" # BinaryPathFinder.h
) )
target_link_libraries(WorldServer ${COMMON_LIBRARIES} target_link_libraries(WorldServer ${COMMON_LIBRARIES}

View File

@ -11,12 +11,12 @@ target_link_libraries(dZoneManager
#set_property(TARGET dZoneManager APPEND PROPERTY INTERFACE_LINK_LIBRARIES dWorldServer) #set_property(TARGET dZoneManager APPEND PROPERTY INTERFACE_LINK_LIBRARIES dWorldServer)
target_include_directories(dZoneManager PUBLIC "." target_include_directories(dZoneManager PUBLIC "."
${PROJECT_SOURCE_DIR}/dGame # Entity.h "${PROJECT_SOURCE_DIR}/dGame" # Entity.h
${PROJECT_SOURCE_DIR}/dGame/dEntity # EntityInfo.h "${PROJECT_SOURCE_DIR}/dGame/dEntity" # EntityInfo.h
PRIVATE PRIVATE
${PROJECT_SOURCE_DIR}/dGame/dComponents #InventoryComponent.h "${PROJECT_SOURCE_DIR}/dGame/dComponents" #InventoryComponent.h
${PROJECT_SOURCE_DIR}/dGame/dInventory #InventoryComponent.h (transitive) "${PROJECT_SOURCE_DIR}/dGame/dInventory" #InventoryComponent.h (transitive)
${PROJECT_SOURCE_DIR}/dGame/dBehaviors #BehaviorSlot.h "${PROJECT_SOURCE_DIR}/dGame/dBehaviors" #BehaviorSlot.h
${PROJECT_SOURCE_DIR}/dGame/dGameMessages #GameMessages.h "${PROJECT_SOURCE_DIR}/dGame/dGameMessages" #GameMessages.h
${PROJECT_SOURCE_DIR}/dGame/dUtilities #VanityUtilities.h "${PROJECT_SOURCE_DIR}/dGame/dUtilities" #VanityUtilities.h
) )

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

@ -19,6 +19,7 @@ list(APPEND DCOMMONTEST_SOURCES ${DENUMS_TESTS})
add_executable(dCommonTests ${DCOMMONTEST_SOURCES}) add_executable(dCommonTests ${DCOMMONTEST_SOURCES})
add_dependencies(dCommonTests conncpp_tests) add_dependencies(dCommonTests conncpp_tests)
# Apple needs some special linkage for the mariadb connector for tests.
if(APPLE) if(APPLE)
add_custom_command(TARGET dCommonTests POST_BUILD add_custom_command(TARGET dCommonTests POST_BUILD
COMMAND otool ARGS -l dCommonTests COMMAND otool ARGS -l dCommonTests

View File

@ -14,6 +14,7 @@ file(COPY ${GAMEMESSAGE_TESTBITSTREAMS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
add_executable(dGameTests ${DGAMETEST_SOURCES}) add_executable(dGameTests ${DGAMETEST_SOURCES})
add_dependencies(dGameTests conncpp_tests) add_dependencies(dGameTests conncpp_tests)
# Apple needs some special linkage for the mariadb connector for tests.
if(APPLE) if(APPLE)
add_custom_command(TARGET dGameTests POST_BUILD add_custom_command(TARGET dGameTests POST_BUILD
COMMAND install_name_tool ARGS -change libmariadbcpp.dylib @rpath/libmariadbcpp.dylib dGameTests COMMAND install_name_tool ARGS -change libmariadbcpp.dylib @rpath/libmariadbcpp.dylib dGameTests

View File

@ -1,4 +1,15 @@
<objects> <objects>
<!--A story plaque with custom text-->
<!--Font color can be set but you must encode the `<` as &lt; and `>` as &gt; >-->
<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>
<!--A tree spawned at two locations with different positions, rotations, and scales--> <!--A tree spawned at two locations with different positions, rotations, and scales-->
<!--Positions and rotations are easily gotten by typing /loc or /pos, and /rot into the in-game chat--> <!--Positions and rotations are easily gotten by typing /loc or /pos, and /rot into the in-game chat-->
<object lot="3248"> <object lot="3248">