mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-21 11:59:37 -06:00
Compare commits
73 Commits
ugc
...
MM12-Testi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05dc5d6fcd | ||
|
|
c24c756f73 | ||
|
|
bdb380aed2 | ||
|
|
2baef3f198 | ||
|
|
fbf7833b7b | ||
|
|
8920cd1063 | ||
|
|
05c67fd712 | ||
|
|
a580e3a2f5 | ||
|
|
a28a2e60cf | ||
| 5374c555f5 | |||
| 80f8dd8003 | |||
|
|
1ac898ba00 | ||
|
|
fc75d6048f | ||
|
|
9d4d618e63 | ||
|
|
8bcb4bd36d | ||
|
|
bad3845d83 | ||
|
|
7fcc8a6e84 | ||
|
|
1a34f6f74a | ||
|
|
1789ec7f20 | ||
|
|
dc7d0ce142 | ||
|
|
203a150a56 | ||
|
|
19be0a61b2 | ||
|
|
6aa7c592a2 | ||
|
|
09157506bf | ||
|
|
737eaba54d | ||
|
|
fab4414204 | ||
| 34b5f0f9d6 | |||
|
|
68187d9f96 | ||
|
|
9adbb7aa86 | ||
|
|
bd28e4051f | ||
|
|
716e8c646c | ||
|
|
d2cecd0073 | ||
|
|
99c0ca253c | ||
|
|
0e9c0a8917 | ||
|
|
e41ed68447 | ||
|
|
d97f374a90 | ||
| 5cc7d47074 | |||
|
|
1470af99c3 | ||
|
|
85ab573665 | ||
| 6ec921025d | |||
|
|
bbd5a49ea2 | ||
|
|
a6c6474e67 | ||
|
|
675cf1d2a4 | ||
| 9ebb06ba24 | |||
|
|
96313ecd69 | ||
|
|
015cbc06ea | ||
|
|
dff02773a0 | ||
|
|
d052ed6a63 | ||
|
|
fd9757d121 | ||
|
|
bd7f532a28 | ||
|
|
dbdf4ac46a | ||
|
|
51dd56f0a0 | ||
|
|
6ed504c88e | ||
|
|
9be2ab03b6 | ||
|
|
38eb441ca1 | ||
|
|
e53e31021f | ||
|
|
41b8762c8f | ||
|
|
559894024c | ||
|
|
0a31db9d44 | ||
|
|
f2fa81b5c3 | ||
|
|
da07a70d4d | ||
|
|
9f47b1f0bb | ||
|
|
d78b2958d3 | ||
|
|
9cfc126842 | ||
|
|
56e3d07669 | ||
|
|
2b56dfbc89 | ||
|
|
b33a3df012 | ||
|
|
0d460c0eb3 | ||
|
|
3f1b4339f5 | ||
|
|
e78dc0b874 | ||
|
|
b1d4153f00 | ||
|
|
3c581fffbb | ||
|
|
4775dbf27f |
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -14,12 +14,6 @@
|
||||
path = thirdparty/mariadb-connector-cpp
|
||||
url = https://github.com/mariadb-corporation/mariadb-connector-cpp.git
|
||||
ignore = dirty
|
||||
[submodule "thirdparty/docker-utils"]
|
||||
path = thirdparty/docker-utils
|
||||
url = https://github.com/lcdr/utils.git
|
||||
[submodule "thirdparty/LUnpack"]
|
||||
path = thirdparty/LUnpack
|
||||
url = https://github.com/Xiphoseer/LUnpack.git
|
||||
[submodule "thirdparty/AccountManager"]
|
||||
path = thirdparty/AccountManager
|
||||
url = https://github.com/DarkflameUniverse/AccountManager
|
||||
|
||||
@@ -89,8 +89,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
# Create a /res directory
|
||||
make_directory(${CMAKE_BINARY_DIR}/res)
|
||||
# Create a /resServer directory
|
||||
make_directory(${CMAKE_BINARY_DIR}/resServer)
|
||||
|
||||
# Create a /logs directory
|
||||
make_directory(${CMAKE_BINARY_DIR}/logs)
|
||||
@@ -176,6 +176,7 @@ set(INCLUDED_DIRECTORIES
|
||||
"dScripts/ai"
|
||||
"dScripts/client"
|
||||
"dScripts/EquipmentScripts"
|
||||
"dScripts/EquipmentTriggers"
|
||||
"dScripts/zone"
|
||||
"dScripts/02_server/DLU"
|
||||
"dScripts/02_server/Enemy"
|
||||
|
||||
@@ -23,10 +23,7 @@
|
||||
"name": "ci-macos-11",
|
||||
"displayName": "CI configure step for MacOS",
|
||||
"description": "Same as default, Used in GitHub actions workflow",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"OPENSSL_ROOT_DIR": "/usr/local/opt/openssl@3/"
|
||||
}
|
||||
"inherits": "default"
|
||||
},
|
||||
{
|
||||
"name": "ci-windows-2022",
|
||||
|
||||
@@ -8,15 +8,17 @@ LICENSE=AGPL-3.0
|
||||
# 171022 - Unmodded client
|
||||
NET_VERSION=171022
|
||||
# Debugging
|
||||
__dynamic=1
|
||||
# Set __dynamic to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs.
|
||||
# __ggdb=1
|
||||
__dynamic=1
|
||||
# Set __ggdb to 1 to enable the -ggdb flag for the linker, including more debug info.
|
||||
# __include_backtrace__=1
|
||||
# __ggdb=1
|
||||
# Set __include_backtrace__ to 1 to includes the backtrace library for better crashlogs.
|
||||
# __compile_backtrace__=1
|
||||
# __include_backtrace__=1
|
||||
# Set __compile_backtrace__ to 1 to compile the backtrace library instead of using system libraries.
|
||||
__maria_db_connector_compile_jobs__=1
|
||||
# __compile_backtrace__=1
|
||||
# Set to the number of jobs (make -j equivalent) to compile the mariadbconn files with.
|
||||
__enable_testing__=1
|
||||
__maria_db_connector_compile_jobs__=1
|
||||
# When set to 1 and uncommented, compiling and linking testing folders and libraries will be done.
|
||||
__enable_testing__=1
|
||||
# The path to OpenSSL. Change this if your OpenSSL install path is different than the default.
|
||||
OPENSSL_ROOT_DIR=/usr/local/opt/openssl@3/
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/) (Docker Desktop or on Linux normal Docker)
|
||||
- [Docker Compose](https://docs.docker.com/compose/install/) (Included in Docker Desktop)
|
||||
- LEGO® Universe packed Client. Check the main [README](./README.md) for details on this.
|
||||
- LEGO® Universe Client. Check the main [README](./README.md) for details on this.
|
||||
|
||||
## Run server inside Docker
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
11. Once the command has completed (you can see you path again and can enter commands), close the window.
|
||||
12. Inside the downloaded folder, copy `.env.example` and name the copy `.env`
|
||||
13. Open `.env` with Notepad by right-clicking it and selecting _Open With_ -> _More apps_ -> _Notepad_.
|
||||
14. Change the text after `CLIENT_PATH=` to the location of your client. The folder you are pointing to must contain a folder called `client` which should contain the client files.
|
||||
14. Change the text after `CLIENT_PATH=` to the location of your client. This folder must contain either a folder `client` or `legouniverse.exe`.
|
||||
> If you need the extra performance, place the client files in `\\wsl$\<your linux OS>\...` to avoid working across file systems, see [Docker Best Practices](https://docs.docker.com/desktop/windows/wsl/#best-practices) and [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/filesystems#file-storage-and-performance-across-file-systems).
|
||||
|
||||
15. Optionally, you can change the number after `BUILD_THREADS=` to the number of cores / threads your processor has. If your computer crashes while building, you can try to reduce this value.
|
||||
|
||||
611
README.md
611
README.md
@@ -18,210 +18,188 @@ Darkflame Universe is licensed under AGPLv3, please read [LICENSE](LICENSE). Som
|
||||
Throughout the entire build and setup process a level of familiarity with the command line and preferably a Unix-like development environment is greatly advantageous.
|
||||
|
||||
### Hosting a server
|
||||
We do not recommend hosting public servers. DLU is intended for small scale deployment, for example within a group of friends. It has not been tested for large scale deployment which comes with additional security risks.
|
||||
We do not recommend hosting public servers. Darkflame Universe is intended for small scale deployment, for example within a group of friends. It has not been tested for large scale deployment which comes with additional security risks.
|
||||
|
||||
### Supply of resource files
|
||||
Darkflame Universe is a server emulator and does not distribute any LEGO® Universe files. A separate game client is required to setup this server emulator and play the game, which we cannot supply. Users are strongly suggested to refer to the safe checksums listed in the resources tab below when checking if a client will work.
|
||||
Darkflame Universe is a server emulator and does not distribute any LEGO® Universe files. A separate game client is required to setup this server emulator and play the game, which we cannot supply. Users are strongly suggested to refer to the safe checksums listed [here](#verifying-your-client-files) to see if a client will work.
|
||||
|
||||
## Build
|
||||
Development of the latest iteration of Darkflame Universe has been done primarily in a Unix-like environment and is where it has been tested and designed for deployment. It is therefore highly recommended that Darkflame Universe be built and deployed using a Unix-like environment for the most streamlined experience.
|
||||
## Steps to setup server
|
||||
* [Clone this repository](#clone-the-repository)
|
||||
* [Install dependencies](#install-dependencies)
|
||||
* [Database setup](#database-setup)
|
||||
* [Build the server](#build-the-server)
|
||||
* [Configuring your server](#configuring-your-server)
|
||||
* [Required Configuration](#required-configuration)
|
||||
* [Optional Configuration](#optional-configuration)
|
||||
* [Verify your setup](#verify-your-setup)
|
||||
* [Running the server](#running-the-server)
|
||||
* [User Guide](#user-guide)
|
||||
|
||||
### Prerequisites
|
||||
#### Clone the repository
|
||||
## Clone the repository
|
||||
If you are on Windows, you will need to download and install git from [here](https://git-scm.com/download/win)
|
||||
|
||||
Then run the following command
|
||||
```bash
|
||||
git clone --recursive https://github.com/DarkflameUniverse/DarkflameServer
|
||||
```
|
||||
#### Python
|
||||
|
||||
Some tools utilized to streamline the setup process require Python 3, make sure you have it installed.
|
||||
## Install dependencies
|
||||
|
||||
### Windows packages
|
||||
Ensure that you have either the [MSVC C++ compiler](https://visualstudio.microsoft.com/vs/features/cplusplus/) (recommended) or the [Clang compiler](https://github.com/llvm/llvm-project/releases/) installed.
|
||||
You'll also need to download and install [CMake](https://cmake.org/download/) (version <font size="4">**CMake version 3.18**</font> or later!).
|
||||
|
||||
### Choosing the right version for your client
|
||||
DLU clients identify themselves using a higher version number than the regular live clients out there.
|
||||
This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client.
|
||||
### MacOS packages
|
||||
Ensure you have [brew](https://brew.sh) installed.
|
||||
You will need to install the following packages
|
||||
```bash
|
||||
brew install cmake gcc mariadb openssl zlib
|
||||
```
|
||||
|
||||
If you're using a DLU client you'll have to go into the "CMakeVariables.txt" file and change the NET_VERSION variable to 171023 to match the modified client's version number.
|
||||
### Linux packages
|
||||
Make sure packages like `gcc`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required as well as `openssl`. You will also need a MySQL database solution to use. We recommend using `mariadb-server`.
|
||||
|
||||
### Enabling testing
|
||||
While it is highly recommended to enable testing, if you would like to save compilation time, you'll want to comment out the enable_testing variable in CMakeVariables.txt.
|
||||
It is recommended that after building and if testing is enabled, to run `ctest` and make sure all the tests pass.
|
||||
For Ubuntu, you would run the following commands. On other systems, the package install command will differ.
|
||||
|
||||
### Using Docker
|
||||
Refer to [Docker.md](/Docker.md).
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade
|
||||
|
||||
For Windows, refer to [Docker_Windows.md](/Docker_Windows.md).
|
||||
# Install packages
|
||||
sudo apt install build-essential gcc zlib1g-dev libssl-dev openssl mariadb-server cmake
|
||||
```
|
||||
|
||||
### Linux builds
|
||||
Make sure packages like `gcc`, `cmake`, and `zlib` are installed. Depending on the distribution, these packages might already be installed. Note that on systems like Ubuntu, you will need the `zlib1g-dev` package so that the header files are available. `libssl-dev` will also be required as well as `openssl`.
|
||||
#### Required CMake version
|
||||
This project uses <font size="4">**CMake version 3.18**</font> or higher and as such you will need to ensure you have this version installed.
|
||||
You can check your CMake version by using the following command in a terminal.
|
||||
```bash
|
||||
cmake --version
|
||||
```
|
||||
|
||||
CMake must be version 3.14 or higher!
|
||||
If you are going to be using an Ubuntu environment to run the server, you may need to get a more recent version of `cmake` than the packages available may provide.
|
||||
|
||||
#### Build the repository
|
||||
The general approach to do so would be to obtain a copy of the signing key and then add the CMake repository to your apt.
|
||||
You can do so with the following commands.
|
||||
|
||||
[Source of the below commands](https://askubuntu.com/questions/355565/how-do-i-install-the-latest-version-of-cmake-from-the-command-line)
|
||||
|
||||
```bash
|
||||
# Remove the old version of CMake
|
||||
sudo apt purge --auto-remove cmake
|
||||
|
||||
# Prepare for installation
|
||||
sudo apt update && sudo apt install -y software-properties-common lsb-release && sudo apt clean all
|
||||
|
||||
# Obtain a copy of the signing key
|
||||
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
|
||||
|
||||
# Add the repository to your sources list.
|
||||
sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main"
|
||||
|
||||
# Next you'll want to ensure that Kitware's keyring stays up to date
|
||||
sudo apt update
|
||||
sudo apt install kitware-archive-keyring
|
||||
sudo rm /etc/apt/trusted.gpg.d/kitware.gpg
|
||||
|
||||
# If sudo apt update above returned an error, copy the public key at the end of the error message and run the following command
|
||||
# if the error message was "The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 6AF7F09730B3F0A4"
|
||||
# then the below command would be "sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6AF7F09730B3F0A4"
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys <TheCopiedPublicKey>
|
||||
|
||||
# Finally update and install
|
||||
sudo apt update
|
||||
sudo apt install cmake
|
||||
```
|
||||
|
||||
## Database setup
|
||||
First you'll need to start MariaDB.
|
||||
|
||||
For Windows the service is always running by default.
|
||||
|
||||
For MacOS, run the following command
|
||||
```bash
|
||||
brew services start mariadb
|
||||
```
|
||||
|
||||
For Linux, run the following command
|
||||
```bash
|
||||
sudo systemctl start mysql
|
||||
# If systemctl is not a known command on your distribution, try the following instead
|
||||
sudo service mysql start
|
||||
```
|
||||
|
||||
<font size="4">**You will need to run this command every time you restart your environment**</font>
|
||||
|
||||
If you are using Linux and `systemctl` and want the MariaDB instance to start on startup, run the following command
|
||||
```bash
|
||||
sudo systemctl enable --now mysql
|
||||
```
|
||||
|
||||
Once MariaDB is started, you'll need to create a user and an empty database for Darkflame Universe to use.
|
||||
|
||||
First, login to the MariaDB instance.
|
||||
|
||||
To do this on Ubuntu/Linux, MacOS, or another Unix like operating system, run the following command in a terminal
|
||||
```bash
|
||||
# Logs you into the MariaDB instance as root
|
||||
sudo mysql
|
||||
```
|
||||
|
||||
For Windows, run the following command in the `Command Prompt (MariaDB xx.xx)` terminal
|
||||
```bash
|
||||
# Logs you into the mysql instance
|
||||
mysql -u root -p
|
||||
# You will then be prompted for the password you set for root during installation of MariaDB
|
||||
```
|
||||
|
||||
Now that you are logged in, run the following commands.
|
||||
|
||||
```bash
|
||||
# Creates a user for this computer which uses a password and grant said user all privileges.
|
||||
# Change mydarkflameuser to a custom username and password to a custom password.
|
||||
GRANT ALL ON *.* TO 'mydarkflameuser'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
# Then create a database for Darkflame Universe to use.
|
||||
CREATE DATABASE darkflame;
|
||||
```
|
||||
|
||||
## Build the server
|
||||
You can either run `build.sh` when in the root folder of the repository:
|
||||
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
Or manually run the commands used in `build.sh`:
|
||||
Or manually run the commands used in [build.sh](build.sh).
|
||||
|
||||
```bash
|
||||
# Create the build directory, preserving it if it already exists
|
||||
mkdir -p build
|
||||
cd build
|
||||
### Notes
|
||||
Depending on your operating system, you may need to adjust some pre-processor defines in [CMakeVariables.txt](./CMakeVariables.txt) before building:
|
||||
* If you are on MacOS, ensure OPENSSL_ROOT_DIR is pointing to the openssl root directory.
|
||||
* If you are using a Darkflame Universe client, ensure NET_VERSION is changed to 171023.
|
||||
|
||||
# Run CMake to generate make files
|
||||
cmake ..
|
||||
## Configuring your server
|
||||
This server has a few steps that need to be taken to configure the server for your use case.
|
||||
|
||||
# To build utilizing multiple cores, append `-j` and the amount of cores to utilize, for example `cmake --build . --config Release -j8'
|
||||
cmake --build . --config Release
|
||||
```
|
||||
### Required Configuration
|
||||
Darkflame Universe can run with either a packed or an unpacked client.
|
||||
Navigate to `build/sharedconfig.ini` and fill in the following fields:
|
||||
* `mysql_host` (This is the IP address or hostname of your MariaDB server. This is highly likely `localhost`)
|
||||
* If you setup your MariaDB instance on a port other than 3306, which can be done on a Windows install, you will need to make this value `tcp://localhost:portNum` where portNum is replaced with the port you chose to run MariaDB on.
|
||||
* `mysql_database` (This is the database you created for the server)
|
||||
* `mysql_username` (This is the user you created for the server)
|
||||
* `mysql_password` (This is the password for the user you created for the server)
|
||||
* `client_location` (This is the location of the client files. This should be the folder path of a packed or unpacked client)
|
||||
* Ideally the path to the client should not contain any spaces.
|
||||
|
||||
### MacOS builds
|
||||
Ensure `cmake`, `zlib` and `open ssl` are installed as well as a compiler (e.g `clang` or `gcc`).
|
||||
|
||||
In the repository root folder run the following. Ensure -DOPENSSL_ROOT_DIR=/path/to/openssl points to your openssl install location
|
||||
```bash
|
||||
# Create the build directory, preserving it if it already exists
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
# Run CMake to generate build files
|
||||
cmake .. -DOPENSSL_ROOT_DIR=/path/to/openssl
|
||||
|
||||
# Get cmake to build the project. If make files are being used then using make and appending `-j` and the amount of cores to utilize may be preferable, for example `make -j8`
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### Windows builds (native)
|
||||
Ensure that you have either the [MSVC](https://visualstudio.microsoft.com/vs/) or the [Clang](https://github.com/llvm/llvm-project/releases/) (recommended) compiler installed. You will also need to install [CMake](https://cmake.org/download/). Currently on native Windows the server will only work in Release mode.
|
||||
|
||||
#### Build the repository
|
||||
```batch
|
||||
:: Create the build directory
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
:: Run CMake to generate make files
|
||||
cmake ..
|
||||
|
||||
:: Run CMake with build flag to build
|
||||
cmake --build . --config Release
|
||||
```
|
||||
#### Windows for ARM has not been tested but should build by doing the following
|
||||
```batch
|
||||
:: Create the build directory
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
:: Run CMake to generate make files
|
||||
cmake .. -DMARIADB_BUILD_SOURCE=ON
|
||||
|
||||
:: Run CMake with build flag to build
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### Windows builds (WSL)
|
||||
This section will go through how to install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) and building in a Linux environment under Windows. WSL requires Windows 10 version 2004 and higher (Build 19041 and higher) or Windows 11.
|
||||
|
||||
#### Open the Command Prompt application with Administrator permissions and run the following:
|
||||
```bash
|
||||
# Installing Windows Subsystem for Linux
|
||||
wsl --install
|
||||
```
|
||||
|
||||
#### Open the Ubuntu application and run the following:
|
||||
```bash
|
||||
# Make sure the install is up to date
|
||||
apt update && apt upgrade
|
||||
|
||||
# Make sure the gcc, cmake, and build-essentials are installed
|
||||
sudo apt install gcc
|
||||
sudo apt install cmake
|
||||
sudo apt install build-essential
|
||||
```
|
||||
|
||||
[**Follow the Linux instructions**](#linux-builds)
|
||||
|
||||
### ARM builds
|
||||
AArch64 builds should work on linux and MacOS using their respective build steps. Windows ARM should build but it has not been tested
|
||||
|
||||
### Updating your build
|
||||
To update your server to the latest version navigate to your cloned directory
|
||||
```bash
|
||||
cd /path/to/DarkflameServer
|
||||
```
|
||||
run the following commands to update to the latest changes
|
||||
```bash
|
||||
git pull
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
now follow the build section for your system
|
||||
|
||||
## Setting up the environment
|
||||
|
||||
### Resources
|
||||
|
||||
#### LEGO® Universe 1.10.64
|
||||
|
||||
This repository does not distribute any LEGO® Universe files. A full install of LEGO® Universe version 1.10.64 (latest) is required to finish setting up Darkflame Universe.
|
||||
|
||||
Known good SHA256 checksums of the client:
|
||||
- `8f6c7e84eca3bab93232132a88c4ae6f8367227d7eafeaa0ef9c40e86c14edf5` (packed client, rar compressed)
|
||||
- `c1531bf9401426042e8bab2de04ba1b723042dc01d9907c2635033d417de9e05` (packed client, includes extra locales, rar compressed)
|
||||
- `0d862f71eedcadc4494c4358261669721b40b2131101cbd6ef476c5a6ec6775b` (unpacked client, includes extra locales, rar compressed)
|
||||
|
||||
Known good *SHA1* checksum of the DLU client:
|
||||
- `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed)
|
||||
|
||||
How to generate a SHA256 checksum:
|
||||
```bash
|
||||
# Replace <file> with the file path to the client
|
||||
|
||||
# If on Linux or MacOS
|
||||
shasum -a 256 <file>
|
||||
|
||||
# If on Windows
|
||||
certutil -hashfile <file> SHA256
|
||||
```
|
||||
|
||||
#### Unpacking the client
|
||||
* Clone lcdr's utilities repository [here](https://github.com/lcdr/utils)
|
||||
* Use `pkextractor.pyw` to unpack the client files if they are not already unpacked
|
||||
|
||||
#### Setup resource directory
|
||||
* In the `build` directory create a `res` directory if it does not already exist.
|
||||
* Copy over or create symlinks from `macros`, `BrickModels`, `chatplus_en_us.txt`, `names`, and `maps` in your client `res` directory to the server `build/res` directory
|
||||
* Unzip the navmeshes [here](./resources/navmeshes.zip) and place them in `build/res/maps/navmeshes`
|
||||
|
||||
#### Setup locale
|
||||
* In the `build` directory create a `locale` directory if it does not already exist
|
||||
* Copy over or create symlinks from `locale.xml` in your client `locale` directory to the `build/locale` directory
|
||||
|
||||
#### Client database
|
||||
* Move the file `res/cdclient.fdb` from the unpacked client to the `build/res` folder on the server.
|
||||
* The server will automatically copy and convert the file from fdb to sqlite should `CDServer.sqlite` not already exist.
|
||||
* You can also convert the database manually using `fdb_to_sqlite.py` using lcdr's utilities. Just make sure to rename the file to `CDServer.sqlite` instead of `cdclient.sqlite`.
|
||||
* Migrations to the database are automatically run on server start. When migrations are needed to be ran, the server may take a bit longer to start.
|
||||
|
||||
### Database
|
||||
Darkflame Universe utilizes a MySQL/MariaDB database for account and character information.
|
||||
|
||||
Initial setup can vary drastically based on which operating system or distribution you are running; there are instructions out there for most setups, follow those and come back here when you have a database up and running.
|
||||
|
||||
* All that you need to do is create a database to connect to. As long as the server can connect to the database, the schema will always be kept up to date when you start the server.
|
||||
|
||||
#### Configuration
|
||||
|
||||
After the server has been built there should be four `ini` files in the build director: `sharedconfig.ini`, `authconfig.ini`, `chatconfig.ini`, `masterconfig.ini`, and `worldconfig.ini`. Go through them and fill in the database credentials and configure other settings if necessary.
|
||||
|
||||
#### Migrations
|
||||
|
||||
The database is automatically setup and migrated to what it should look like for the latest commit whenever you start the server.
|
||||
|
||||
#### Verify
|
||||
### Optional Configuration
|
||||
* After the server has been built there should be five `ini` files in the build directory: `sharedconfig.ini`, `authconfig.ini`, `chatconfig.ini`, `masterconfig.ini`, and `worldconfig.ini`.
|
||||
* `authconfig.ini` contains an option to enable or disable play keys on your server. Do not change the default port for auth.
|
||||
* `chatconfig.ini` contains a port option.
|
||||
* `masterconfig.ini` contains options related to permissions you want to run your servers with.
|
||||
* `sharedconfig.ini` contains several options that are shared across all servers
|
||||
* `worldconfig.ini` contains several options to turn on QOL improvements should you want them. If you would like the most vanilla experience possible, you will need to turn some of these settings off.
|
||||
|
||||
## Verify your setup
|
||||
Your build directory should now look like this:
|
||||
* AuthServer
|
||||
* ChatServer
|
||||
@@ -230,42 +208,35 @@ Your build directory should now look like this:
|
||||
* authconfig.ini
|
||||
* chatconfig.ini
|
||||
* masterconfig.ini
|
||||
* sharedconfig.ini
|
||||
* worldconfig.ini
|
||||
* **locale/**
|
||||
* locale.xml
|
||||
* **res/**
|
||||
* cdclient.fdb
|
||||
* chatplus_en_us.txt
|
||||
* **macros/**
|
||||
* ...
|
||||
* **BrickModels/**
|
||||
* ...
|
||||
* **maps/**
|
||||
* **navmeshes/**
|
||||
* ...
|
||||
* ...
|
||||
* ...
|
||||
|
||||
## Running the server
|
||||
If everything has been configured correctly you should now be able to run the `MasterServer` binary. Darkflame Universe utilizes port numbers under 1024, so under Linux you either have to give the binary network permissions or run it under sudo.
|
||||
If everything has been configured correctly you should now be able to run the `MasterServer` binary which is located in the `build` directory. Darkflame Universe utilizes port numbers under 1024, so under Linux you either have to give the `AuthServer` binary network permissions or run it under sudo.
|
||||
To give `AuthServer` network permissions and not require sudo, run the following command
|
||||
```bash
|
||||
sudo setcap 'cap_net_bind_service=+ep' AuthServer
|
||||
```
|
||||
and then go to `build/masterconfig.ini` and change `use_sudo_auth` to 0.
|
||||
|
||||
### First admin user
|
||||
Run `MasterServer -a` to get prompted to create an admin account. This method is only intended for the system administrator as a means to get started, do NOT use this method to create accounts for other users!
|
||||
|
||||
### Account Manager
|
||||
### Account management tool (Nexus Dashboard)
|
||||
**If you are just using this server for yourself, you can skip setting up Nexus Dashboard**
|
||||
|
||||
Follow the instructions [here](https://github.com/DarkflameUniverse/AccountManager) to setup the DLU account management Python web application. This is the intended way for users to create accounts.
|
||||
Follow the instructions [here](https://github.com/DarkflameUniverse/NexusDashboard) to setup the DLU Nexus Dashboard web application. This is the intended way for users to create accounts and the intended way for moderators to approve names/pets/properties and do other moderation actions.
|
||||
|
||||
### Admin levels
|
||||
The admin level, or Game Master level (hereafter referred to as gmlevel), is specified in the `accounts.gm_level` column in the MySQL database. Normal players should have this set to `0`, which comes with no special privileges. The system administrator will have this set to `9`, which comes will all privileges. gmlevel `8` should be used to give a player a majority of privileges without the safety critical once.
|
||||
|
||||
The admin level, or game master level, is specified in the `accounts.gm_level` column in the MySQL database. Normal players should have this set to `0`, which comes with no special privileges. The system administrator will have this set to `9`, which comes will all privileges. Admin level `8` should be used to give a player a majority of privileges without the safety critical once.
|
||||
While a character has a gmlevel of anything but `0`, some gameplay behavior will change. When testing gameplay, you should always use a character with a gmlevel of `0`.
|
||||
|
||||
While a character has a gmlevel of anything but 0, some gameplay behavior will change. When testing gameplay, you should always use a character with a gmlevel of 0.
|
||||
# User guide
|
||||
Some changes to the client `boot.cfg` file are needed to play on your server.
|
||||
|
||||
## User guide
|
||||
A few modifications have to be made to the client.
|
||||
|
||||
### Client configuration
|
||||
## Allowing a user to connect to your server
|
||||
To connect to a server follow these steps:
|
||||
* In the client directory, locate `boot.cfg`
|
||||
* Open it in a text editor and locate where it says `AUTHSERVERIP=0:`
|
||||
@@ -273,159 +244,88 @@ To connect to a server follow these steps:
|
||||
* Launch `legouniverse.exe`, through `wine` if on a Unix-like operating system
|
||||
* Note that if you are on WSL2, you will need to configure the public IP in the server and client to be the IP of the WSL2 instance and not localhost, which can be found by running `ifconfig` in the terminal. Windows defaults to WSL1, so this will not apply to most users.
|
||||
|
||||
### Brick-By-Brick building
|
||||
## Brick-By-Brick building
|
||||
Should you choose to do any brick building, you will want to have some form of a http server that returns a 404 error since we are unable to emulate live User Generated Content at the moment. If you attempt to do any brick building without a 404 server running properly, you will be unable to load into your game. Python is the easiest way to do this, but any thing that returns a 404 should work fine.
|
||||
* Note: the client hard codes this request on port 80.
|
||||
|
||||
Brick-By-Brick building requires `PATCHSERVERIP=0:` in the `boot.cfg` to point to a HTTP server which always returns `HTTP 404 - Not Found` for all requests. This can be achieved by pointing it to `localhost` while having `sudo python -m http.server 80` running in the background.
|
||||
<font size="4">**If you do not plan on doing any Brick Building, then you can skip this step.**</font>
|
||||
|
||||
### In-game commands
|
||||
Here is a summary of the commands available in-game. All commands are prefixed by `/` and typed in the in-game chat window. Some commands requires admin privileges. Operands within `<>` are required, operands within `()` are not. For the full list of in-game commands, please checkout [the source file](./dGame/dUtilities/SlashCommandHandler.cpp).
|
||||
The easiest way to do this is to install [python](https://www.python.org/downloads/).
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<th>
|
||||
Command
|
||||
</th>
|
||||
<th>
|
||||
Usage
|
||||
</th>
|
||||
<th>
|
||||
Description
|
||||
</th>
|
||||
<th>
|
||||
Admin Level Requirement
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
info
|
||||
</td>
|
||||
<td>
|
||||
/info
|
||||
</td>
|
||||
<td>
|
||||
Displays server info to the user, including where to find the server's source code.
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
credits
|
||||
</td>
|
||||
<td>
|
||||
/credits
|
||||
</td>
|
||||
<td>
|
||||
Displays the names of the people behind Darkflame Universe.
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
instanceinfo
|
||||
</td>
|
||||
<td>
|
||||
/instanceinfo
|
||||
</td>
|
||||
<td>
|
||||
Displays in the chat the current zone, clone, and instance id.
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
gmlevel
|
||||
</td>
|
||||
<td>
|
||||
/gmlevel <level>
|
||||
</td>
|
||||
<td>
|
||||
Within the authorized range of levels for the current account, changes the character's game master level to the specified value. This is required to use certain commands.
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
testmap
|
||||
</td>
|
||||
<td>
|
||||
/testmap <zone> (clone-id)
|
||||
</td>
|
||||
<td>
|
||||
Transfers you to the given zone by id and clone id.
|
||||
</td>
|
||||
<td>
|
||||
1
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
ban
|
||||
</td>
|
||||
<td>
|
||||
/ban <username>
|
||||
</td>
|
||||
<td>
|
||||
Bans a user from the server.
|
||||
</td>
|
||||
<td>
|
||||
4
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
gmadditem
|
||||
</td>
|
||||
<td>
|
||||
/gmadditem <id> (count)
|
||||
</td>
|
||||
<td>
|
||||
Adds the given item to your inventory by id.
|
||||
</td>
|
||||
<td>
|
||||
8
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
spawn
|
||||
</td>
|
||||
<td>
|
||||
/spawn <id>
|
||||
</td>
|
||||
<td>
|
||||
Spawns an object at your location by id.
|
||||
</td>
|
||||
<td>
|
||||
8
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
metrics
|
||||
</td>
|
||||
<td>
|
||||
/metrics
|
||||
</td>
|
||||
<td>
|
||||
Prints some information about the server's performance.
|
||||
</td>
|
||||
<td>
|
||||
8
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
### Allowing a user to build in Brick-by-Brick mode
|
||||
Brick-By-Brick building requires `PATCHSERVERIP=0:` and `UGCSERVERIP=0:` in the `boot.cfg` to point to a HTTP server which always returns `HTTP 404 - Not Found` for all requests. This can be most easily achieved by pointing both of those variables to `localhost` while having running in the background.
|
||||
Each client must have their own 404 server running if they are using a locally hosted 404 server.
|
||||
```bash
|
||||
# If on linux run this command. Because this is run on a port below 1024, binary network permissions are needed.
|
||||
sudo python3 -m http.server 80
|
||||
|
||||
# If on windows one of the following will work when run through Powershell or Command Prompt assuming python is installed
|
||||
python3 -m http.server 80
|
||||
python http.server 80
|
||||
py -m http.server 80
|
||||
```
|
||||
|
||||
## Updating your server
|
||||
To update your server to the latest version navigate to your cloned directory
|
||||
```bash
|
||||
cd path/to/DarkflameServer
|
||||
```
|
||||
Run the following commands to update to the latest changes
|
||||
```bash
|
||||
git pull
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
Now follow the [build](#build-the-server) section for your system and your server is up to date.
|
||||
|
||||
## In-game commands
|
||||
* A list of all in-game commands can be found [here](./docs/Commands.md).
|
||||
|
||||
## Verifying your client files
|
||||
|
||||
### LEGO® Universe 1.10.64
|
||||
To verify that you are indeed using a LEGO® Universe 1.10.64 client, make sure you have the full client compressed **in a rar file** and run the following command.
|
||||
```bash
|
||||
# Replace <file> with the file path to the zipped client
|
||||
|
||||
# If on Linux or MacOS
|
||||
shasum -a 256 <file>
|
||||
|
||||
# If on Windows using the Command Prompt
|
||||
certutil -hashfile <file> SHA256
|
||||
```
|
||||
|
||||
Below are known good SHA256 checksums of the client:
|
||||
* `8f6c7e84eca3bab93232132a88c4ae6f8367227d7eafeaa0ef9c40e86c14edf5` (packed client, rar compressed)
|
||||
* `c1531bf9401426042e8bab2de04ba1b723042dc01d9907c2635033d417de9e05` (packed client, includes extra locales, rar compressed)
|
||||
* `0d862f71eedcadc4494c4358261669721b40b2131101cbd6ef476c5a6ec6775b` (unpacked client, includes extra locales, rar compressed)
|
||||
|
||||
If the returned hash matches one of the lines above then you can continue with setting up the server. If you are using a fully downloaded and complete client from live, then it will work, but the hash above may not match. Otherwise you must obtain a full install of LEGO® Universe 1.10.64.
|
||||
|
||||
### Darkflame Universe Client
|
||||
Darkflame Universe clients identify themselves using a higher version number than the regular live clients out there.
|
||||
This was done make sure that older and incomplete clients wouldn't produce false positive bug reports for us, and because we made bug fixes and new content for the client.
|
||||
|
||||
To verify that you are indeed using a Darkflame Universe client, make sure you have the full client compressed **in a zip file** and run the following command.
|
||||
|
||||
```bash
|
||||
# Replace <file> with the file path to the zipped client
|
||||
|
||||
# If on Linux or MacOS
|
||||
shasum -a 1 <file>
|
||||
|
||||
# If on Windows using the Command Prompt
|
||||
certutil -hashfile <file> SHA1
|
||||
```
|
||||
|
||||
Known good *SHA1* checksum of the Darkflame Universe client:
|
||||
- `91498e09b83ce69f46baf9e521d48f23fe502985` (packed client, zip compressed)
|
||||
|
||||
# Development Documentation
|
||||
This is a Work in Progress, but below are some quick links to documentaion for systems and structs in the server
|
||||
[Networked message structs](https://lcdruniverse.org/lu_packets/lu_packets/index.html)
|
||||
[General system documentation](https://docs.lu-dev.net/en/latest/index.html)
|
||||
|
||||
# Credits
|
||||
## Active Contributors
|
||||
* [EmosewaMC](https://github.com/EmosewaMC)
|
||||
* [Jettford](https://github.com/Jettford)
|
||||
* [Aaron K.](https://github.com/aronwk-aaron)
|
||||
|
||||
## DLU Team
|
||||
* [DarwinAnim8or](https://github.com/DarwinAnim8or)
|
||||
@@ -434,25 +334,30 @@ Here is a summary of the commands available in-game. All commands are prefixed b
|
||||
* [averysumner](https://github.com/codeshaunted)
|
||||
* [Jon002](https://github.com/jaller200)
|
||||
* [Jonny](https://github.com/cuzitsjonny)
|
||||
* [Aaron K.](https://github.com/aronwk-aaron)
|
||||
|
||||
### Research and tools
|
||||
### Research and Tools
|
||||
* [lcdr](https://github.com/lcdr)
|
||||
* [Xiphoseer](https://github.com/Xiphoseer)
|
||||
|
||||
### Community management
|
||||
### Community Management
|
||||
* [Neal](https://github.com/NealSpellman)
|
||||
|
||||
### Former contributors
|
||||
### Logo
|
||||
* Cole Peterson (BlasterBuilder)
|
||||
|
||||
## Active Contributors
|
||||
* [EmosewaMC](https://github.com/EmosewaMC)
|
||||
* [Jettford](https://github.com/Jettford)
|
||||
|
||||
## Former Contributors
|
||||
* TheMachine
|
||||
* Matthew
|
||||
* [Raine](https://github.com/Rainebannister)
|
||||
* Bricknave
|
||||
|
||||
### Logo
|
||||
* Cole Peterson (BlasterBuilder)
|
||||
|
||||
## Special thanks
|
||||
## Special Thanks
|
||||
* humanoid24
|
||||
* pwjones1969
|
||||
* [Simon](https://github.com/SimonNitzsche)
|
||||
* ALL OF THE NETDEVIL AND LEGO TEAMS!
|
||||
* [ALL OF THE NETDEVIL AND LEGO TEAMS!](https://www.mobygames.com/game/macintosh/lego-universe/credits)
|
||||
|
||||
@@ -32,6 +32,8 @@ dLogger* SetupLogger();
|
||||
void HandlePacket(Packet* packet);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
constexpr uint32_t authFramerate = mediumFramerate;
|
||||
constexpr uint32_t authFrameDelta = mediumFrameDelta;
|
||||
Diagnostics::SetProcessName("Auth");
|
||||
Diagnostics::SetProcessFileName(argv[0]);
|
||||
Diagnostics::Initialize();
|
||||
@@ -67,7 +69,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
//Find out the master's IP:
|
||||
std::string masterIP;
|
||||
int masterPort = 1500;
|
||||
uint32_t masterPort = 1500;
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
|
||||
auto res = stmt->executeQuery();
|
||||
while (res->next()) {
|
||||
@@ -79,8 +81,8 @@ int main(int argc, char** argv) {
|
||||
delete stmt;
|
||||
|
||||
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
|
||||
int maxClients = 50;
|
||||
int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
|
||||
uint32_t maxClients = 50;
|
||||
uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
|
||||
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
||||
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
||||
|
||||
@@ -89,16 +91,18 @@ int main(int argc, char** argv) {
|
||||
//Run it until server gets a kill message from Master:
|
||||
auto t = std::chrono::high_resolution_clock::now();
|
||||
Packet* packet = nullptr;
|
||||
int framesSinceLastFlush = 0;
|
||||
int framesSinceMasterDisconnect = 0;
|
||||
int framesSinceLastSQLPing = 0;
|
||||
constexpr uint32_t logFlushTime = 30 * authFramerate; // 30 seconds in frames
|
||||
constexpr uint32_t sqlPingTime = 10 * 60 * authFramerate; // 10 minutes in frames
|
||||
uint32_t framesSinceLastFlush = 0;
|
||||
uint32_t framesSinceMasterDisconnect = 0;
|
||||
uint32_t framesSinceLastSQLPing = 0;
|
||||
|
||||
while (!Game::shouldShutdown) {
|
||||
//Check if we're still connected to master:
|
||||
if (!Game::server->GetIsConnectedToMaster()) {
|
||||
framesSinceMasterDisconnect++;
|
||||
|
||||
if (framesSinceMasterDisconnect >= 30)
|
||||
if (framesSinceMasterDisconnect >= authFramerate)
|
||||
break; //Exit our loop, shut down.
|
||||
} else framesSinceMasterDisconnect = 0;
|
||||
|
||||
@@ -114,16 +118,16 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
//Push our log every 30s:
|
||||
if (framesSinceLastFlush >= 900) {
|
||||
if (framesSinceLastFlush >= logFlushTime) {
|
||||
Game::logger->Flush();
|
||||
framesSinceLastFlush = 0;
|
||||
} else framesSinceLastFlush++;
|
||||
|
||||
//Every 10 min we ping our sql server to keep it alive hopefully:
|
||||
if (framesSinceLastSQLPing >= 40000) {
|
||||
if (framesSinceLastSQLPing >= sqlPingTime) {
|
||||
//Find out the master's IP for absolutely no reason:
|
||||
std::string masterIP;
|
||||
int masterPort;
|
||||
uint32_t masterPort;
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
|
||||
auto res = stmt->executeQuery();
|
||||
while (res->next()) {
|
||||
@@ -138,7 +142,7 @@ int main(int argc, char** argv) {
|
||||
} else framesSinceLastSQLPing++;
|
||||
|
||||
//Sleep our thread since auth can afford to.
|
||||
t += std::chrono::milliseconds(mediumFramerate); //Auth can run at a lower "fps"
|
||||
t += std::chrono::milliseconds(authFrameDelta); //Auth can run at a lower "fps"
|
||||
std::this_thread::sleep_until(t);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include "ChatPacketHandler.h"
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
//RakNet includes:
|
||||
#include "RakNetDefines.h"
|
||||
namespace Game {
|
||||
dLogger* logger = nullptr;
|
||||
dServer* server = nullptr;
|
||||
@@ -28,8 +31,6 @@ namespace Game {
|
||||
bool shouldShutdown = false;
|
||||
}
|
||||
|
||||
//RakNet includes:
|
||||
#include "RakNetDefines.h"
|
||||
|
||||
dLogger* SetupLogger();
|
||||
void HandlePacket(Packet* packet);
|
||||
@@ -37,6 +38,8 @@ void HandlePacket(Packet* packet);
|
||||
PlayerContainer playerContainer;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
constexpr uint32_t chatFramerate = mediumFramerate;
|
||||
constexpr uint32_t chatFrameDelta = mediumFrameDelta;
|
||||
Diagnostics::SetProcessName("Chat");
|
||||
Diagnostics::SetProcessFileName(argv[0]);
|
||||
Diagnostics::Initialize();
|
||||
@@ -65,7 +68,7 @@ int main(int argc, char** argv) {
|
||||
Game::assetManager = new AssetManager(clientPath);
|
||||
} catch (std::runtime_error& ex) {
|
||||
Game::logger->Log("ChatServer", "Got an error while setting up assets: %s", ex.what());
|
||||
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -87,7 +90,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
//Find out the master's IP:
|
||||
std::string masterIP;
|
||||
int masterPort = 1000;
|
||||
uint32_t masterPort = 1000;
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
|
||||
auto res = stmt->executeQuery();
|
||||
while (res->next()) {
|
||||
@@ -99,8 +102,8 @@ int main(int argc, char** argv) {
|
||||
delete stmt;
|
||||
|
||||
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
|
||||
int maxClients = 50;
|
||||
int ourPort = 1501;
|
||||
uint32_t maxClients = 50;
|
||||
uint32_t ourPort = 1501;
|
||||
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
||||
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
||||
|
||||
@@ -111,16 +114,18 @@ int main(int argc, char** argv) {
|
||||
//Run it until server gets a kill message from Master:
|
||||
auto t = std::chrono::high_resolution_clock::now();
|
||||
Packet* packet = nullptr;
|
||||
int framesSinceLastFlush = 0;
|
||||
int framesSinceMasterDisconnect = 0;
|
||||
int framesSinceLastSQLPing = 0;
|
||||
constexpr uint32_t logFlushTime = 30 * chatFramerate; // 30 seconds in frames
|
||||
constexpr uint32_t sqlPingTime = 10 * 60 * chatFramerate; // 10 minutes in frames
|
||||
uint32_t framesSinceLastFlush = 0;
|
||||
uint32_t framesSinceMasterDisconnect = 0;
|
||||
uint32_t framesSinceLastSQLPing = 0;
|
||||
|
||||
while (!Game::shouldShutdown) {
|
||||
//Check if we're still connected to master:
|
||||
if (!Game::server->GetIsConnectedToMaster()) {
|
||||
framesSinceMasterDisconnect++;
|
||||
|
||||
if (framesSinceMasterDisconnect >= 30)
|
||||
if (framesSinceMasterDisconnect >= chatFramerate)
|
||||
break; //Exit our loop, shut down.
|
||||
} else framesSinceMasterDisconnect = 0;
|
||||
|
||||
@@ -136,16 +141,16 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
//Push our log every 30s:
|
||||
if (framesSinceLastFlush >= 900) {
|
||||
if (framesSinceLastFlush >= logFlushTime) {
|
||||
Game::logger->Flush();
|
||||
framesSinceLastFlush = 0;
|
||||
} else framesSinceLastFlush++;
|
||||
|
||||
//Every 10 min we ping our sql server to keep it alive hopefully:
|
||||
if (framesSinceLastSQLPing >= 40000) {
|
||||
if (framesSinceLastSQLPing >= sqlPingTime) {
|
||||
//Find out the master's IP for absolutely no reason:
|
||||
std::string masterIP;
|
||||
int masterPort;
|
||||
uint32_t masterPort;
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
|
||||
auto res = stmt->executeQuery();
|
||||
while (res->next()) {
|
||||
@@ -160,7 +165,7 @@ int main(int argc, char** argv) {
|
||||
} else framesSinceLastSQLPing++;
|
||||
|
||||
//Sleep our thread since auth can afford to.
|
||||
t += std::chrono::milliseconds(mediumFramerate); //Chat can run at a lower "fps"
|
||||
t += std::chrono::milliseconds(chatFrameDelta); //Chat can run at a lower "fps"
|
||||
std::this_thread::sleep_until(t);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
#include "GeneralUtils.h"
|
||||
#include "Game.h"
|
||||
#include "dLogger.h"
|
||||
#include "AssetManager.h"
|
||||
|
||||
#include "eSqliteDataType.h"
|
||||
|
||||
std::map<eSqliteDataType, std::string> FdbToSqlite::Convert::sqliteType = {
|
||||
std::map<eSqliteDataType, std::string> FdbToSqlite::Convert::m_SqliteType = {
|
||||
{ eSqliteDataType::NONE, "none"},
|
||||
{ eSqliteDataType::INT32, "int32"},
|
||||
{ eSqliteDataType::REAL, "real"},
|
||||
@@ -23,20 +24,23 @@ std::map<eSqliteDataType, std::string> FdbToSqlite::Convert::sqliteType = {
|
||||
{ eSqliteDataType::TEXT_8, "text_8"}
|
||||
};
|
||||
|
||||
FdbToSqlite::Convert::Convert(std::string basePath) {
|
||||
this->basePath = basePath;
|
||||
FdbToSqlite::Convert::Convert(std::string binaryOutPath) {
|
||||
this->m_BinaryOutPath = binaryOutPath;
|
||||
}
|
||||
|
||||
bool FdbToSqlite::Convert::ConvertDatabase() {
|
||||
fdb.open(basePath + "/cdclient.fdb", std::ios::binary);
|
||||
bool FdbToSqlite::Convert::ConvertDatabase(AssetMemoryBuffer& buffer) {
|
||||
if (m_ConversionStarted) return false;
|
||||
|
||||
std::istream cdClientBuffer(&buffer);
|
||||
|
||||
this->m_ConversionStarted = true;
|
||||
try {
|
||||
CDClientDatabase::Connect(basePath + "/CDServer.sqlite");
|
||||
CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite");
|
||||
|
||||
CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
|
||||
|
||||
int32_t numberOfTables = ReadInt32();
|
||||
ReadTables(numberOfTables);
|
||||
int32_t numberOfTables = ReadInt32(cdClientBuffer);
|
||||
ReadTables(numberOfTables, cdClientBuffer);
|
||||
|
||||
CDClientDatabase::ExecuteQuery("COMMIT;");
|
||||
} catch (CppSQLite3Exception& e) {
|
||||
@@ -44,138 +48,133 @@ bool FdbToSqlite::Convert::ConvertDatabase() {
|
||||
return false;
|
||||
}
|
||||
|
||||
fdb.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t FdbToSqlite::Convert::ReadInt32() {
|
||||
int32_t FdbToSqlite::Convert::ReadInt32(std::istream& cdClientBuffer) {
|
||||
int32_t nextInt{};
|
||||
BinaryIO::BinaryRead(fdb, nextInt);
|
||||
BinaryIO::BinaryRead(cdClientBuffer, nextInt);
|
||||
return nextInt;
|
||||
}
|
||||
|
||||
int64_t FdbToSqlite::Convert::ReadInt64() {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
int64_t FdbToSqlite::Convert::ReadInt64(std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
int64_t value{};
|
||||
BinaryIO::BinaryRead(fdb, value);
|
||||
BinaryIO::BinaryRead(cdClientBuffer, value);
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string FdbToSqlite::Convert::ReadString() {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
std::string FdbToSqlite::Convert::ReadString(std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
auto readString = BinaryIO::ReadString(fdb);
|
||||
auto readString = BinaryIO::ReadString(cdClientBuffer);
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
return readString;
|
||||
}
|
||||
|
||||
int32_t FdbToSqlite::Convert::SeekPointer() {
|
||||
int32_t FdbToSqlite::Convert::SeekPointer(std::istream& cdClientBuffer) {
|
||||
int32_t position{};
|
||||
BinaryIO::BinaryRead(fdb, position);
|
||||
int32_t prevPosition = fdb.tellg();
|
||||
fdb.seekg(position);
|
||||
BinaryIO::BinaryRead(cdClientBuffer, position);
|
||||
int32_t prevPosition = cdClientBuffer.tellg();
|
||||
cdClientBuffer.seekg(position);
|
||||
return prevPosition;
|
||||
}
|
||||
|
||||
std::string FdbToSqlite::Convert::ReadColumnHeader() {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
std::string FdbToSqlite::Convert::ReadColumnHeader(std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
int32_t numberOfColumns = ReadInt32();
|
||||
std::string tableName = ReadString();
|
||||
int32_t numberOfColumns = ReadInt32(cdClientBuffer);
|
||||
std::string tableName = ReadString(cdClientBuffer);
|
||||
|
||||
auto columns = ReadColumns(numberOfColumns);
|
||||
auto columns = ReadColumns(numberOfColumns, cdClientBuffer);
|
||||
std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");";
|
||||
CDClientDatabase::ExecuteDML(newTable);
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
|
||||
return tableName;
|
||||
}
|
||||
|
||||
void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables) {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
void FdbToSqlite::Convert::ReadTables(int32_t& numberOfTables, std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
for (int32_t i = 0; i < numberOfTables; i++) {
|
||||
auto columnHeader = ReadColumnHeader();
|
||||
ReadRowHeader(columnHeader);
|
||||
auto columnHeader = ReadColumnHeader(cdClientBuffer);
|
||||
ReadRowHeader(columnHeader, cdClientBuffer);
|
||||
}
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
}
|
||||
|
||||
std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns) {
|
||||
std::string FdbToSqlite::Convert::ReadColumns(int32_t& numberOfColumns, std::istream& cdClientBuffer) {
|
||||
std::stringstream columnsToCreate;
|
||||
int32_t prevPosition = SeekPointer();
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
std::string name{};
|
||||
eSqliteDataType dataType{};
|
||||
for (int32_t i = 0; i < numberOfColumns; i++) {
|
||||
if (i != 0) columnsToCreate << ", ";
|
||||
dataType = static_cast<eSqliteDataType>(ReadInt32());
|
||||
name = ReadString();
|
||||
columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::sqliteType[dataType];
|
||||
dataType = static_cast<eSqliteDataType>(ReadInt32(cdClientBuffer));
|
||||
name = ReadString(cdClientBuffer);
|
||||
columnsToCreate << "'" << name << "' " << FdbToSqlite::Convert::m_SqliteType[dataType];
|
||||
}
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
return columnsToCreate.str();
|
||||
}
|
||||
|
||||
void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName) {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
void FdbToSqlite::Convert::ReadRowHeader(std::string& tableName, std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
int32_t numberOfAllocatedRows = ReadInt32();
|
||||
int32_t numberOfAllocatedRows = ReadInt32(cdClientBuffer);
|
||||
if (numberOfAllocatedRows != 0) assert((numberOfAllocatedRows & (numberOfAllocatedRows - 1)) == 0); // assert power of 2 allocation size
|
||||
ReadRows(numberOfAllocatedRows, tableName);
|
||||
ReadRows(numberOfAllocatedRows, tableName, cdClientBuffer);
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
}
|
||||
|
||||
void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName) {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
void FdbToSqlite::Convert::ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName, std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
int32_t rowid = 0;
|
||||
for (int32_t row = 0; row < numberOfAllocatedRows; row++) {
|
||||
int32_t rowPointer = ReadInt32();
|
||||
int32_t rowPointer = ReadInt32(cdClientBuffer);
|
||||
if (rowPointer == -1) rowid++;
|
||||
else ReadRow(rowid, rowPointer, tableName);
|
||||
else ReadRow(rowPointer, tableName, cdClientBuffer);
|
||||
}
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
}
|
||||
|
||||
void FdbToSqlite::Convert::ReadRow(int32_t& rowid, int32_t& position, std::string& tableName) {
|
||||
int32_t prevPosition = fdb.tellg();
|
||||
fdb.seekg(position);
|
||||
void FdbToSqlite::Convert::ReadRow(int32_t& position, std::string& tableName, std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = cdClientBuffer.tellg();
|
||||
cdClientBuffer.seekg(position);
|
||||
|
||||
while (true) {
|
||||
ReadRowInfo(tableName);
|
||||
int32_t linked = ReadInt32();
|
||||
|
||||
rowid += 1;
|
||||
|
||||
ReadRowInfo(tableName, cdClientBuffer);
|
||||
int32_t linked = ReadInt32(cdClientBuffer);
|
||||
if (linked == -1) break;
|
||||
|
||||
fdb.seekg(linked);
|
||||
cdClientBuffer.seekg(linked);
|
||||
}
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
}
|
||||
|
||||
void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName) {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
void FdbToSqlite::Convert::ReadRowInfo(std::string& tableName, std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
int32_t numberOfColumns = ReadInt32();
|
||||
ReadRowValues(numberOfColumns, tableName);
|
||||
int32_t numberOfColumns = ReadInt32(cdClientBuffer);
|
||||
ReadRowValues(numberOfColumns, tableName, cdClientBuffer);
|
||||
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
}
|
||||
|
||||
void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName) {
|
||||
int32_t prevPosition = SeekPointer();
|
||||
void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& tableName, std::istream& cdClientBuffer) {
|
||||
int32_t prevPosition = SeekPointer(cdClientBuffer);
|
||||
|
||||
int32_t emptyValue{};
|
||||
int32_t intValue{};
|
||||
@@ -189,26 +188,26 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string&
|
||||
|
||||
for (int32_t i = 0; i < numberOfColumns; i++) {
|
||||
if (i != 0) insertedRow << ", "; // Only append comma and space after first entry in row.
|
||||
switch (static_cast<eSqliteDataType>(ReadInt32())) {
|
||||
switch (static_cast<eSqliteDataType>(ReadInt32(cdClientBuffer))) {
|
||||
case eSqliteDataType::NONE:
|
||||
BinaryIO::BinaryRead(fdb, emptyValue);
|
||||
BinaryIO::BinaryRead(cdClientBuffer, emptyValue);
|
||||
assert(emptyValue == 0);
|
||||
insertedRow << "NULL";
|
||||
break;
|
||||
|
||||
case eSqliteDataType::INT32:
|
||||
intValue = ReadInt32();
|
||||
intValue = ReadInt32(cdClientBuffer);
|
||||
insertedRow << intValue;
|
||||
break;
|
||||
|
||||
case eSqliteDataType::REAL:
|
||||
BinaryIO::BinaryRead(fdb, floatValue);
|
||||
BinaryIO::BinaryRead(cdClientBuffer, floatValue);
|
||||
insertedRow << std::fixed << std::setprecision(34) << floatValue; // maximum precision of floating point number
|
||||
break;
|
||||
|
||||
case eSqliteDataType::TEXT_4:
|
||||
case eSqliteDataType::TEXT_8: {
|
||||
stringValue = ReadString();
|
||||
stringValue = ReadString(cdClientBuffer);
|
||||
size_t position = 0;
|
||||
|
||||
// Need to escape quote with a double of ".
|
||||
@@ -224,12 +223,12 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string&
|
||||
}
|
||||
|
||||
case eSqliteDataType::INT_BOOL:
|
||||
BinaryIO::BinaryRead(fdb, boolValue);
|
||||
BinaryIO::BinaryRead(cdClientBuffer, boolValue);
|
||||
insertedRow << static_cast<bool>(boolValue);
|
||||
break;
|
||||
|
||||
case eSqliteDataType::INT64:
|
||||
int64Value = ReadInt64();
|
||||
int64Value = ReadInt64(cdClientBuffer);
|
||||
insertedRow << std::to_string(int64Value);
|
||||
break;
|
||||
|
||||
@@ -244,5 +243,5 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string&
|
||||
|
||||
auto copiedString = insertedRow.str();
|
||||
CDClientDatabase::ExecuteDML(copiedString);
|
||||
fdb.seekg(prevPosition);
|
||||
cdClientBuffer.seekg(prevPosition);
|
||||
}
|
||||
|
||||
@@ -7,43 +7,139 @@
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
|
||||
class AssetMemoryBuffer;
|
||||
|
||||
enum class eSqliteDataType : int32_t;
|
||||
|
||||
namespace FdbToSqlite {
|
||||
class Convert {
|
||||
public:
|
||||
Convert(std::string inputFile);
|
||||
/**
|
||||
* Create a new convert object with an input .fdb file and an output binary path.
|
||||
*
|
||||
* @param inputFile The file which ends in .fdb to be converted
|
||||
* @param binaryPath The base path where the file will be saved
|
||||
*/
|
||||
Convert(std::string binaryOutPath);
|
||||
|
||||
bool ConvertDatabase();
|
||||
/**
|
||||
* Converts the input file to sqlite. Calling multiple times is safe.
|
||||
*
|
||||
* @return true if the database was converted properly, false otherwise.
|
||||
*/
|
||||
bool ConvertDatabase(AssetMemoryBuffer& buffer);
|
||||
|
||||
int32_t ReadInt32();
|
||||
/**
|
||||
* @brief Reads a 32 bit int from the fdb file.
|
||||
*
|
||||
* @return The read value
|
||||
*/
|
||||
int32_t ReadInt32(std::istream& cdClientBuffer);
|
||||
|
||||
int64_t ReadInt64();
|
||||
/**
|
||||
* @brief Reads a 64 bit integer from the fdb file.
|
||||
*
|
||||
* @return The read value
|
||||
*/
|
||||
int64_t ReadInt64(std::istream& cdClientBuffer);
|
||||
|
||||
std::string ReadString();
|
||||
/**
|
||||
* @brief Reads a string from the fdb file.
|
||||
*
|
||||
* @return The read string
|
||||
*
|
||||
* TODO This needs to be translated to latin-1!
|
||||
*/
|
||||
std::string ReadString(std::istream& cdClientBuffer);
|
||||
|
||||
int32_t SeekPointer();
|
||||
/**
|
||||
* @brief Seeks to a pointer position.
|
||||
*
|
||||
* @return The previous position before the seek
|
||||
*/
|
||||
int32_t SeekPointer(std::istream& cdClientBuffer);
|
||||
|
||||
std::string ReadColumnHeader();
|
||||
/**
|
||||
* @brief Reads a column header from the fdb file and creates the table in the database
|
||||
*
|
||||
* @return The table name
|
||||
*/
|
||||
std::string ReadColumnHeader(std::istream& cdClientBuffer);
|
||||
|
||||
void ReadTables(int32_t& numberOfTables);
|
||||
/**
|
||||
* @brief Read the tables from the fdb file.
|
||||
*
|
||||
* @param numberOfTables The number of tables to read
|
||||
*/
|
||||
void ReadTables(int32_t& numberOfTables, std::istream& cdClientBuffer);
|
||||
|
||||
std::string ReadColumns(int32_t& numberOfColumns);
|
||||
/**
|
||||
* @brief Reads the columns from the fdb file.
|
||||
*
|
||||
* @param numberOfColumns The number of columns to read
|
||||
* @return All columns of the table formatted for a sql query
|
||||
*/
|
||||
std::string ReadColumns(int32_t& numberOfColumns, std::istream& cdClientBuffer);
|
||||
|
||||
void ReadRowHeader(std::string& tableName);
|
||||
/**
|
||||
* @brief Reads the row header from the fdb file.
|
||||
*
|
||||
* @param tableName The tables name
|
||||
*/
|
||||
void ReadRowHeader(std::string& tableName, std::istream& cdClientBuffer);
|
||||
|
||||
void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName);
|
||||
/**
|
||||
* @brief Read the rows from the fdb file.,
|
||||
*
|
||||
* @param numberOfAllocatedRows The number of rows that were allocated. Always a power of 2!
|
||||
* @param tableName The tables name.
|
||||
*/
|
||||
void ReadRows(int32_t& numberOfAllocatedRows, std::string& tableName, std::istream& cdClientBuffer);
|
||||
|
||||
void ReadRow(int32_t& rowid, int32_t& position, std::string& tableName);
|
||||
/**
|
||||
* @brief Reads a row from the fdb file.
|
||||
*
|
||||
* @param position The position to seek in the fdb to
|
||||
* @param tableName The tables name
|
||||
*/
|
||||
void ReadRow(int32_t& position, std::string& tableName, std::istream& cdClientBuffer);
|
||||
|
||||
void ReadRowInfo(std::string& tableName);
|
||||
/**
|
||||
* @brief Reads the row info from the fdb file.
|
||||
*
|
||||
* @param tableName The tables name
|
||||
*/
|
||||
void ReadRowInfo(std::string& tableName, std::istream& cdClientBuffer);
|
||||
|
||||
void ReadRowValues(int32_t& numberOfColumns, std::string& tableName);
|
||||
/**
|
||||
* @brief Reads each row and its values from the fdb file and inserts them into the database
|
||||
*
|
||||
* @param numberOfColumns The number of columns to read in
|
||||
* @param tableName The tables name
|
||||
*/
|
||||
void ReadRowValues(int32_t& numberOfColumns, std::string& tableName, std::istream& cdClientBuffer);
|
||||
private:
|
||||
static std::map<eSqliteDataType, std::string> sqliteType;
|
||||
std::string basePath{};
|
||||
std::ifstream fdb{};
|
||||
}; // class FdbToSqlite
|
||||
|
||||
/**
|
||||
* Maps each sqlite data type to its string equivalent.
|
||||
*/
|
||||
static std::map<eSqliteDataType, std::string> m_SqliteType;
|
||||
|
||||
/**
|
||||
* Base path of the folder containing the fdb file
|
||||
*/
|
||||
std::string m_BasePath{};
|
||||
|
||||
/**
|
||||
* Whether or not a conversion was started. If one was started, do not attempt to convert the file again.
|
||||
*/
|
||||
bool m_ConversionStarted{};
|
||||
|
||||
/**
|
||||
* The path where the CDServer will be stored
|
||||
*/
|
||||
std::string m_BinaryOutPath{};
|
||||
}; //! class FdbToSqlite
|
||||
}; //! namespace FdbToSqlite
|
||||
|
||||
#endif //!__FDBTOSQLITE__H__
|
||||
|
||||
@@ -45,9 +45,6 @@ AssetManager::AssetManager(const std::filesystem::path& path) {
|
||||
switch (m_AssetBundleType) {
|
||||
case eAssetBundleType::Packed: {
|
||||
this->LoadPackIndex();
|
||||
|
||||
this->UnpackRequiredAssets();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -160,31 +157,6 @@ AssetMemoryBuffer AssetManager::GetFileAsBuffer(const char* name) {
|
||||
return AssetMemoryBuffer(buf, len, success);
|
||||
}
|
||||
|
||||
void AssetManager::UnpackRequiredAssets() {
|
||||
if (std::filesystem::exists(m_ResPath / "cdclient.fdb")) return;
|
||||
|
||||
char* data;
|
||||
uint32_t size;
|
||||
|
||||
bool success = this->GetFile("cdclient.fdb", &data, &size);
|
||||
|
||||
if (!success) {
|
||||
Game::logger->Log("AssetManager", "Failed to extract required files from the packs.");
|
||||
|
||||
delete data;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::ofstream cdclientOutput(m_ResPath / "cdclient.fdb", std::ios::out | std::ios::binary);
|
||||
cdclientOutput.write(data, size);
|
||||
cdclientOutput.close();
|
||||
|
||||
delete data;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t AssetManager::crc32b(uint32_t base, uint8_t* message, size_t l) {
|
||||
size_t i, j;
|
||||
uint32_t crc, msb;
|
||||
|
||||
@@ -60,7 +60,6 @@ public:
|
||||
|
||||
private:
|
||||
void LoadPackIndex();
|
||||
void UnpackRequiredAssets();
|
||||
|
||||
// Modified crc algorithm (mpeg2)
|
||||
// Reference: https://stackoverflow.com/questions/54339800/how-to-modify-crc-32-to-crc-32-mpeg-2
|
||||
|
||||
@@ -24,7 +24,6 @@ public:
|
||||
* Reloads the config file to reset values
|
||||
*/
|
||||
void ReloadConfig();
|
||||
|
||||
private:
|
||||
void ProcessLine(const std::string& line);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* Represents the possible states a mission can be in
|
||||
*/
|
||||
enum class MissionState : int {
|
||||
enum class MissionState : int32_t {
|
||||
/**
|
||||
* The mission state is unknown
|
||||
*/
|
||||
|
||||
@@ -6,15 +6,25 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "../thirdparty/raknet/Source/BitStream.h"
|
||||
#include "BitStream.h"
|
||||
|
||||
#pragma warning (disable:4251) //Disables SQL warnings
|
||||
|
||||
typedef int RESTICKET;
|
||||
|
||||
const int highFrameRate = 16; //60fps
|
||||
const int mediumFramerate = 33; //30fps
|
||||
const int lowFramerate = 66; //15fps
|
||||
// These are the same define, but they mean two different things in different contexts
|
||||
// so a different define to distinguish what calculation is happening will help clarity.
|
||||
#define FRAMES_TO_MS(x) 1000 / x
|
||||
#define MS_TO_FRAMES(x) 1000 / x
|
||||
|
||||
//=========== FRAME TIMINGS ===========
|
||||
constexpr uint32_t highFramerate = 60;
|
||||
constexpr uint32_t mediumFramerate = 30;
|
||||
constexpr uint32_t lowFramerate = 15;
|
||||
|
||||
constexpr uint32_t highFrameDelta = FRAMES_TO_MS(highFramerate);
|
||||
constexpr uint32_t mediumFrameDelta = FRAMES_TO_MS(mediumFramerate);
|
||||
constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
|
||||
|
||||
//========== MACROS ===========
|
||||
|
||||
@@ -356,7 +366,7 @@ enum eControlSceme {
|
||||
SCHEME_WEAR_A_ROBOT //== freecam?
|
||||
};
|
||||
|
||||
enum eStunState {
|
||||
enum class eStateChangeType : uint32_t {
|
||||
PUSH,
|
||||
POP
|
||||
};
|
||||
|
||||
@@ -293,6 +293,7 @@ enum GAME_MSG : unsigned short {
|
||||
GAME_MSG_POP_EQUIPPED_ITEMS_STATE = 192,
|
||||
GAME_MSG_SET_GM_LEVEL = 193,
|
||||
GAME_MSG_SET_STUNNED = 198,
|
||||
GAME_MSG_SET_STUN_IMMUNITY = 200,
|
||||
GAME_MSG_KNOCKBACK = 202,
|
||||
GAME_MSG_REBUILD_CANCEL = 209,
|
||||
GAME_MSG_ENABLE_REBUILD = 213,
|
||||
@@ -373,6 +374,8 @@ enum GAME_MSG : unsigned short {
|
||||
GAME_MSG_PET_TAMING_TRY_BUILD_RESULT = 668,
|
||||
GAME_MSG_NOTIFY_TAMING_BUILD_SUCCESS = 673,
|
||||
GAME_MSG_NOTIFY_TAMING_MODEL_LOADED_ON_SERVER = 674,
|
||||
GAME_MSG_ACTIVATE_BUBBLE_BUFF = 678,
|
||||
GAME_MSG_DEACTIVATE_BUBBLE_BUFF = 679,
|
||||
GAME_MSG_ADD_PET_TO_PLAYER = 681,
|
||||
GAME_MSG_REQUEST_SET_PET_NAME = 683,
|
||||
GAME_MSG_SET_PET_NAME = 684,
|
||||
@@ -385,7 +388,10 @@ enum GAME_MSG : unsigned short {
|
||||
GAME_MSG_QUERY_PROPERTY_DATA = 717,
|
||||
GAME_MSG_PROPERTY_EDITOR_BEGIN = 724,
|
||||
GAME_MSG_PROPERTY_EDITOR_END = 725,
|
||||
GAME_MSG_START_PATHING = 735,
|
||||
GAME_MSG_IS_MINIFIG_IN_A_BUBBLE = 729,
|
||||
GAME_MSG_START_PATHING = 733,
|
||||
GAME_MSG_ACTIVATE_BUBBLE_BUFF_FROM_SERVER = 734,
|
||||
GAME_MSG_DEACTIVATE_BUBBLE_BUFF_FROM_SERVER = 735,
|
||||
GAME_MSG_NOTIFY_CLIENT_ZONE_OBJECT = 737,
|
||||
GAME_MSG_UPDATE_REPUTATION = 746,
|
||||
GAME_MSG_PROPERTY_RENTAL_RESPONSE = 750,
|
||||
@@ -512,6 +518,7 @@ enum GAME_MSG : unsigned short {
|
||||
GAME_MSG_UPDATE_CHAT_MODE = 1395,
|
||||
GAME_MSG_VEHICLE_NOTIFY_FINISHED_RACE = 1396,
|
||||
GAME_MSG_SET_CONSUMABLE_ITEM = 1409,
|
||||
GAME_MSG_SET_STATUS_IMMUNITY = 1435,
|
||||
GAME_MSG_SET_PET_NAME_MODERATED = 1448,
|
||||
GAME_MSG_MODIFY_LEGO_SCORE = 1459,
|
||||
GAME_MSG_RESTORE_TO_POST_LOAD_STATS = 1468,
|
||||
|
||||
12
dCommon/dEnums/eBasicAttackSuccessTypes.h
Normal file
12
dCommon/dEnums/eBasicAttackSuccessTypes.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __EBASICATTACKSUCCESSTYPES__H__
|
||||
#define __EBASICATTACKSUCCESSTYPES__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eBasicAttackSuccessTypes : uint8_t {
|
||||
SUCCESS = 1,
|
||||
FAILARMOR,
|
||||
FAILIMMUNE
|
||||
};
|
||||
|
||||
#endif //!__EBASICATTACKSUCCESSTYPES__H__
|
||||
14
dCommon/dEnums/eBubbleType.h
Normal file
14
dCommon/dEnums/eBubbleType.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __EBUBBLETYPE__H__
|
||||
#define __EBUBBLETYPE__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eBubbleType : uint32_t {
|
||||
DEFAULT = 0,
|
||||
ENERGY = 1,
|
||||
SKUNK = 2,
|
||||
};
|
||||
|
||||
#endif //!__EBUBBLETYPE__H__
|
||||
16
dCommon/dEnums/eMovementPlatformState.h
Normal file
16
dCommon/dEnums/eMovementPlatformState.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __EMOVEMENTPLATFORMSTATE__H__
|
||||
#define __EMOVEMENTPLATFORMSTATE__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* The different types of platform movement state, supposedly a bitmap
|
||||
*/
|
||||
enum class eMovementPlatformState : uint32_t
|
||||
{
|
||||
Moving = 0b00010,
|
||||
Stationary = 0b11001,
|
||||
Stopped = 0b01100
|
||||
};
|
||||
|
||||
#endif //!__EMOVEMENTPLATFORMSTATE__H__
|
||||
@@ -89,7 +89,7 @@ void dLogger::Log(const std::string& className, const std::string& message) {
|
||||
void dLogger::LogDebug(const char* className, const char* format, ...) {
|
||||
if (!m_logDebugStatements) return;
|
||||
va_list args;
|
||||
std::string log = "[" + std::string(className) + "] " + std::string(format);
|
||||
std::string log = "[" + std::string(className) + "] " + std::string(format) + "\n";
|
||||
va_start(args, format);
|
||||
vLog(log.c_str(), args);
|
||||
va_end(args);
|
||||
|
||||
@@ -54,7 +54,7 @@ void MigrationRunner::RunMigrations() {
|
||||
if (doExit) continue;
|
||||
|
||||
Game::logger->Log("MigrationRunner", "Running migration: %s", migration.name.c_str());
|
||||
if (migration.name == "5_brick_model_sd0.sql") {
|
||||
if (migration.name == "dlu/5_brick_model_sd0.sql") {
|
||||
runSd0Migrations = true;
|
||||
} else {
|
||||
finalSQL.append(migration.data.c_str());
|
||||
|
||||
@@ -21,25 +21,25 @@ CDActivitiesTable::CDActivitiesTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Activities");
|
||||
while (!tableData.eof()) {
|
||||
CDActivities entry;
|
||||
entry.ActivityID = tableData.getIntField(0, -1);
|
||||
entry.locStatus = tableData.getIntField(1, -1);
|
||||
entry.instanceMapID = tableData.getIntField(2, -1);
|
||||
entry.minTeams = tableData.getIntField(3, -1);
|
||||
entry.maxTeams = tableData.getIntField(4, -1);
|
||||
entry.minTeamSize = tableData.getIntField(5, -1);
|
||||
entry.maxTeamSize = tableData.getIntField(6, -1);
|
||||
entry.waitTime = tableData.getIntField(7, -1);
|
||||
entry.startDelay = tableData.getIntField(8, -1);
|
||||
entry.requiresUniqueData = tableData.getIntField(9, -1);
|
||||
entry.leaderboardType = tableData.getIntField(10, -1);
|
||||
entry.localize = tableData.getIntField(11, -1);
|
||||
entry.optionalCostLOT = tableData.getIntField(12, -1);
|
||||
entry.optionalCostCount = tableData.getIntField(13, -1);
|
||||
entry.showUIRewards = tableData.getIntField(14, -1);
|
||||
entry.CommunityActivityFlagID = tableData.getIntField(15, -1);
|
||||
entry.gate_version = tableData.getStringField(16, "");
|
||||
entry.noTeamLootOnDeath = tableData.getIntField(17, -1);
|
||||
entry.optionalPercentage = tableData.getFloatField(18, -1.0f);
|
||||
entry.ActivityID = tableData.getIntField("ActivityID", -1);
|
||||
entry.locStatus = tableData.getIntField("locStatus", -1);
|
||||
entry.instanceMapID = tableData.getIntField("instanceMapID", -1);
|
||||
entry.minTeams = tableData.getIntField("minTeams", -1);
|
||||
entry.maxTeams = tableData.getIntField("maxTeams", -1);
|
||||
entry.minTeamSize = tableData.getIntField("minTeamSize", -1);
|
||||
entry.maxTeamSize = tableData.getIntField("maxTeamSize", -1);
|
||||
entry.waitTime = tableData.getIntField("waitTime", -1);
|
||||
entry.startDelay = tableData.getIntField("startDelay", -1);
|
||||
entry.requiresUniqueData = tableData.getIntField("requiresUniqueData", -1);
|
||||
entry.leaderboardType = tableData.getIntField("leaderboardType", -1);
|
||||
entry.localize = tableData.getIntField("localize", -1);
|
||||
entry.optionalCostLOT = tableData.getIntField("optionalCostLOT", -1);
|
||||
entry.optionalCostCount = tableData.getIntField("optionalCostCount", -1);
|
||||
entry.showUIRewards = tableData.getIntField("showUIRewards", -1);
|
||||
entry.CommunityActivityFlagID = tableData.getIntField("CommunityActivityFlagID", -1);
|
||||
entry.gate_version = tableData.getStringField("gate_version", "");
|
||||
entry.noTeamLootOnDeath = tableData.getIntField("noTeamLootOnDeath", -1);
|
||||
entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -70,3 +70,4 @@ std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActiviti
|
||||
std::vector<CDActivities> CDActivitiesTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,13 @@ CDActivityRewardsTable::CDActivityRewardsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards");
|
||||
while (!tableData.eof()) {
|
||||
CDActivityRewards entry;
|
||||
entry.objectTemplate = tableData.getIntField(0, -1);
|
||||
entry.ActivityRewardIndex = tableData.getIntField(1, -1);
|
||||
entry.activityRating = tableData.getIntField(2, -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField(3, -1);
|
||||
entry.CurrencyIndex = tableData.getIntField(4, -1);
|
||||
entry.ChallengeRating = tableData.getIntField(5, -1);
|
||||
entry.description = tableData.getStringField(6, "");
|
||||
entry.objectTemplate = tableData.getIntField("objectTemplate", -1);
|
||||
entry.ActivityRewardIndex = tableData.getIntField("ActivityRewardIndex", -1);
|
||||
entry.activityRating = tableData.getIntField("activityRating", -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
|
||||
entry.CurrencyIndex = tableData.getIntField("CurrencyIndex", -1);
|
||||
entry.ChallengeRating = tableData.getIntField("ChallengeRating", -1);
|
||||
entry.description = tableData.getStringField("description", "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -58,3 +58,4 @@ std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool(
|
||||
std::vector<CDActivityRewards> CDActivityRewardsTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,19 +21,19 @@ CDAnimationsTable::CDAnimationsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
|
||||
while (!tableData.eof()) {
|
||||
CDAnimations entry;
|
||||
entry.animationGroupID = tableData.getIntField(0, -1);
|
||||
entry.animation_type = tableData.getStringField(1, "");
|
||||
entry.animation_name = tableData.getStringField(2, "");
|
||||
entry.chance_to_play = tableData.getFloatField(3, -1.0f);
|
||||
entry.min_loops = tableData.getIntField(4, -1);
|
||||
entry.max_loops = tableData.getIntField(5, -1);
|
||||
entry.animation_length = tableData.getFloatField(6, -1.0f);
|
||||
entry.hideEquip = tableData.getIntField(7, -1) == 1 ? true : false;
|
||||
entry.ignoreUpperBody = tableData.getIntField(8, -1) == 1 ? true : false;
|
||||
entry.restartable = tableData.getIntField(9, -1) == 1 ? true : false;
|
||||
entry.face_animation_name = tableData.getStringField(10, "");
|
||||
entry.priority = tableData.getFloatField(11, -1.0f);
|
||||
entry.blendTime = tableData.getFloatField(12, -1.0f);
|
||||
entry.animationGroupID = tableData.getIntField("animationGroupID", -1);
|
||||
entry.animation_type = tableData.getStringField("animation_type", "");
|
||||
entry.animation_name = tableData.getStringField("animation_name", "");
|
||||
entry.chance_to_play = tableData.getFloatField("chance_to_play", -1.0f);
|
||||
entry.min_loops = tableData.getIntField("min_loops", -1);
|
||||
entry.max_loops = tableData.getIntField("max_loops", -1);
|
||||
entry.animation_length = tableData.getFloatField("animation_length", -1.0f);
|
||||
entry.hideEquip = tableData.getIntField("hideEquip", -1) == 1 ? true : false;
|
||||
entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", -1) == 1 ? true : false;
|
||||
entry.restartable = tableData.getIntField("restartable", -1) == 1 ? true : false;
|
||||
entry.face_animation_name = tableData.getStringField("face_animation_name", "");
|
||||
entry.priority = tableData.getFloatField("priority", -1.0f);
|
||||
entry.blendTime = tableData.getFloatField("blendTime", -1.0f);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -64,3 +64,4 @@ std::vector<CDAnimations> CDAnimationsTable::Query(std::function<bool(CDAnimatio
|
||||
std::vector<CDAnimations> CDAnimationsTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,25 +4,23 @@
|
||||
//! Constructor
|
||||
CDBehaviorParameterTable::CDBehaviorParameterTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
|
||||
size_t hash = 0;
|
||||
uint32_t uniqueParameterId = 0;
|
||||
uint64_t hash = 0;
|
||||
while (!tableData.eof()) {
|
||||
hash = 0;
|
||||
CDBehaviorParameter entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
auto candidateStringToAdd = std::string(tableData.getStringField(1, ""));
|
||||
entry.behaviorID = tableData.getIntField("behaviorID", -1);
|
||||
auto candidateStringToAdd = std::string(tableData.getStringField("parameterID", ""));
|
||||
auto parameter = m_ParametersList.find(candidateStringToAdd);
|
||||
if (parameter != m_ParametersList.end()) {
|
||||
entry.parameterID = parameter;
|
||||
} else {
|
||||
entry.parameterID = m_ParametersList.insert(candidateStringToAdd).first;
|
||||
entry.parameterID = m_ParametersList.insert(std::make_pair(candidateStringToAdd, uniqueParameterId)).first;
|
||||
uniqueParameterId++;
|
||||
}
|
||||
entry.value = tableData.getFloatField(2, -1.0f);
|
||||
hash = entry.behaviorID;
|
||||
hash = (hash << 31U) | entry.parameterID->second;
|
||||
entry.value = tableData.getFloatField("value", -1.0f);
|
||||
|
||||
GeneralUtils::hash_combine(hash, entry.behaviorID);
|
||||
GeneralUtils::hash_combine(hash, *entry.parameterID);
|
||||
|
||||
auto it = m_Entries.find(entry.behaviorID);
|
||||
m_ParametersList.insert(*entry.parameterID);
|
||||
m_Entries.insert(std::make_pair(hash, entry));
|
||||
|
||||
tableData.nextRow();
|
||||
@@ -38,32 +36,30 @@ std::string CDBehaviorParameterTable::GetName(void) const {
|
||||
return "BehaviorParameter";
|
||||
}
|
||||
|
||||
CDBehaviorParameter CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
|
||||
CDBehaviorParameter returnValue;
|
||||
returnValue.behaviorID = 0;
|
||||
returnValue.parameterID = m_ParametersList.end();
|
||||
returnValue.value = defaultValue;
|
||||
float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
|
||||
auto parameterID = this->m_ParametersList.find(name);
|
||||
if (parameterID == this->m_ParametersList.end()) return defaultValue;
|
||||
|
||||
size_t hash = 0;
|
||||
GeneralUtils::hash_combine(hash, behaviorID);
|
||||
GeneralUtils::hash_combine(hash, name);
|
||||
uint64_t hash = behaviorID;
|
||||
|
||||
hash = (hash << 31U) | parameterID->second;
|
||||
|
||||
// Search for specific parameter
|
||||
const auto& it = m_Entries.find(hash);
|
||||
return it != m_Entries.end() ? it->second : returnValue;
|
||||
return it != m_Entries.end() ? it->second.value : defaultValue;
|
||||
}
|
||||
|
||||
std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) {
|
||||
size_t hash;
|
||||
uint64_t hashBase = behaviorID;
|
||||
std::map<std::string, float> returnInfo;
|
||||
for (auto parameterCandidate : m_ParametersList) {
|
||||
hash = 0;
|
||||
GeneralUtils::hash_combine(hash, behaviorID);
|
||||
GeneralUtils::hash_combine(hash, parameterCandidate);
|
||||
uint64_t hash;
|
||||
for (auto& parameterCandidate : m_ParametersList) {
|
||||
hash = (hashBase << 31U) | parameterCandidate.second;
|
||||
auto infoCandidate = m_Entries.find(hash);
|
||||
if (infoCandidate != m_Entries.end()) {
|
||||
returnInfo.insert(std::make_pair(*(infoCandidate->second.parameterID), infoCandidate->second.value));
|
||||
returnInfo.insert(std::make_pair(infoCandidate->second.parameterID->first, infoCandidate->second.value));
|
||||
}
|
||||
}
|
||||
return returnInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
|
||||
//! BehaviorParameter Entry Struct
|
||||
struct CDBehaviorParameter {
|
||||
unsigned int behaviorID; //!< The Behavior ID
|
||||
std::unordered_set<std::string>::iterator parameterID; //!< The Parameter ID
|
||||
float value; //!< The value of the behavior template
|
||||
unsigned int behaviorID; //!< The Behavior ID
|
||||
std::unordered_map<std::string, uint32_t>::iterator parameterID; //!< The Parameter ID
|
||||
float value; //!< The value of the behavior template
|
||||
};
|
||||
|
||||
//! BehaviorParameter table
|
||||
class CDBehaviorParameterTable : public CDTable {
|
||||
private:
|
||||
std::unordered_map<size_t, CDBehaviorParameter> m_Entries;
|
||||
std::unordered_set<std::string> m_ParametersList;
|
||||
std::unordered_map<uint64_t, CDBehaviorParameter> m_Entries;
|
||||
std::unordered_map<std::string, uint32_t> m_ParametersList;
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
*/
|
||||
std::string GetName(void) const override;
|
||||
|
||||
CDBehaviorParameter GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0);
|
||||
float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0);
|
||||
|
||||
std::map<std::string, float> GetParametersByBehaviorID(uint32_t behaviorID);
|
||||
};
|
||||
|
||||
@@ -21,9 +21,9 @@ CDBehaviorTemplateTable::CDBehaviorTemplateTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorTemplate");
|
||||
while (!tableData.eof()) {
|
||||
CDBehaviorTemplate entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
entry.templateID = tableData.getIntField(1, -1);
|
||||
entry.effectID = tableData.getIntField(2, -1);
|
||||
entry.behaviorID = tableData.getIntField("behaviorID", -1);
|
||||
entry.templateID = tableData.getIntField("templateID", -1);
|
||||
entry.effectID = tableData.getIntField("effectID", -1);
|
||||
auto candidateToAdd = tableData.getStringField(3, "");
|
||||
auto parameter = m_EffectHandles.find(candidateToAdd);
|
||||
if (parameter != m_EffectHandles.end()) {
|
||||
@@ -75,3 +75,4 @@ const CDBehaviorTemplate CDBehaviorTemplateTable::GetByBehaviorID(uint32_t behav
|
||||
return entry->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ CDBrickIDTableTable::CDBrickIDTableTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BrickIDTable");
|
||||
while (!tableData.eof()) {
|
||||
CDBrickIDTable entry;
|
||||
entry.NDObjectID = tableData.getIntField(0, -1);
|
||||
entry.LEGOBrickID = tableData.getIntField(1, -1);
|
||||
entry.NDObjectID = tableData.getIntField("NDObjectID", -1);
|
||||
entry.LEGOBrickID = tableData.getIntField("LEGOBrickID", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -53,3 +53,4 @@ std::vector<CDBrickIDTable> CDBrickIDTableTable::Query(std::function<bool(CDBric
|
||||
std::vector<CDBrickIDTable> CDBrickIDTableTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ CDComponentsRegistryTable::CDComponentsRegistryTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ComponentsRegistry");
|
||||
while (!tableData.eof()) {
|
||||
CDComponentsRegistry entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.component_type = tableData.getIntField(1, -1);
|
||||
entry.component_id = tableData.getIntField(2, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.component_type = tableData.getIntField("component_type", -1);
|
||||
entry.component_id = tableData.getIntField("component_id", -1);
|
||||
|
||||
this->mappedEntries.insert_or_assign(((uint64_t)entry.component_type) << 32 | ((uint64_t)entry.id), entry.component_id);
|
||||
|
||||
@@ -91,9 +91,9 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen
|
||||
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
|
||||
while (!tableData.eof()) {
|
||||
CDComponentsRegistry entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.component_type = tableData.getIntField(1, -1);
|
||||
entry.component_id = tableData.getIntField(2, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.component_type = tableData.getIntField("component_type", -1);
|
||||
entry.component_id = tableData.getIntField("component_id", -1);
|
||||
|
||||
//this->entries.push_back(entry);
|
||||
|
||||
@@ -126,3 +126,4 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, uint32_t componen
|
||||
return defaultValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ CDCurrencyTableTable::CDCurrencyTableTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM CurrencyTable");
|
||||
while (!tableData.eof()) {
|
||||
CDCurrencyTable entry;
|
||||
entry.currencyIndex = tableData.getIntField(0, -1);
|
||||
entry.npcminlevel = tableData.getIntField(1, -1);
|
||||
entry.minvalue = tableData.getIntField(2, -1);
|
||||
entry.maxvalue = tableData.getIntField(3, -1);
|
||||
entry.id = tableData.getIntField(4, -1);
|
||||
entry.currencyIndex = tableData.getIntField("currencyIndex", -1);
|
||||
entry.npcminlevel = tableData.getIntField("npcminlevel", -1);
|
||||
entry.minvalue = tableData.getIntField("minvalue", -1);
|
||||
entry.maxvalue = tableData.getIntField("maxvalue", -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -56,3 +56,4 @@ std::vector<CDCurrencyTable> CDCurrencyTableTable::Query(std::function<bool(CDCu
|
||||
std::vector<CDCurrencyTable> CDCurrencyTableTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,20 +21,20 @@ CDDestructibleComponentTable::CDDestructibleComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DestructibleComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDDestructibleComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.faction = tableData.getIntField(1, -1);
|
||||
entry.factionList = tableData.getStringField(2, "");
|
||||
entry.life = tableData.getIntField(3, -1);
|
||||
entry.imagination = tableData.getIntField(4, -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField(5, -1);
|
||||
entry.CurrencyIndex = tableData.getIntField(6, -1);
|
||||
entry.level = tableData.getIntField(7, -1);
|
||||
entry.armor = tableData.getFloatField(8, -1.0f);
|
||||
entry.death_behavior = tableData.getIntField(9, -1);
|
||||
entry.isnpc = tableData.getIntField(10, -1) == 1 ? true : false;
|
||||
entry.attack_priority = tableData.getIntField(11, -1);
|
||||
entry.isSmashable = tableData.getIntField(12, -1) == 1 ? true : false;
|
||||
entry.difficultyLevel = tableData.getIntField(13, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.faction = tableData.getIntField("faction", -1);
|
||||
entry.factionList = tableData.getStringField("factionList", "");
|
||||
entry.life = tableData.getIntField("life", -1);
|
||||
entry.imagination = tableData.getIntField("imagination", -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
|
||||
entry.CurrencyIndex = tableData.getIntField("CurrencyIndex", -1);
|
||||
entry.level = tableData.getIntField("level", -1);
|
||||
entry.armor = tableData.getFloatField("armor", -1.0f);
|
||||
entry.death_behavior = tableData.getIntField("death_behavior", -1);
|
||||
entry.isnpc = tableData.getIntField("isnpc", -1) == 1 ? true : false;
|
||||
entry.attack_priority = tableData.getIntField("attack_priority", -1);
|
||||
entry.isSmashable = tableData.getIntField("isSmashable", -1) == 1 ? true : false;
|
||||
entry.difficultyLevel = tableData.getIntField("difficultyLevel", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -65,3 +65,4 @@ std::vector<CDDestructibleComponent> CDDestructibleComponentTable::Query(std::fu
|
||||
std::vector<CDDestructibleComponent> CDDestructibleComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,14 @@ CDEmoteTableTable::CDEmoteTableTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Emotes");
|
||||
while (!tableData.eof()) {
|
||||
CDEmoteTable* entry = new CDEmoteTable();
|
||||
entry->ID = tableData.getIntField(0, -1);
|
||||
entry->animationName = tableData.getStringField(1, "");
|
||||
entry->iconFilename = tableData.getStringField(2, "");
|
||||
entry->channel = tableData.getIntField(3, -1);
|
||||
entry->locked = tableData.getIntField(5, -1) != 0;
|
||||
entry->localize = tableData.getIntField(6, -1) != 0;
|
||||
entry->locState = tableData.getIntField(7, -1);
|
||||
entry->gateVersion = tableData.getIntField(8, -1);
|
||||
entry->ID = tableData.getIntField("id", -1);
|
||||
entry->animationName = tableData.getStringField("animationName", "");
|
||||
entry->iconFilename = tableData.getStringField("iconFilename", "");
|
||||
entry->channel = tableData.getIntField("channel", -1);
|
||||
entry->locked = tableData.getIntField("locked", -1) != 0;
|
||||
entry->localize = tableData.getIntField("localize", -1) != 0;
|
||||
entry->locState = tableData.getIntField("locStatus", -1);
|
||||
entry->gateVersion = tableData.getStringField("gate_version", "");
|
||||
|
||||
entries.insert(std::make_pair(entry->ID, entry));
|
||||
tableData.nextRow();
|
||||
@@ -42,3 +42,4 @@ CDEmoteTable* CDEmoteTableTable::GetEmote(int id) {
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ struct CDEmoteTable {
|
||||
channel = -1;
|
||||
locked = false;
|
||||
localize = false;
|
||||
gateVersion = -1;
|
||||
gateVersion = "";
|
||||
}
|
||||
|
||||
int ID;
|
||||
@@ -29,7 +29,7 @@ struct CDEmoteTable {
|
||||
int channel;
|
||||
bool locked;
|
||||
bool localize;
|
||||
int gateVersion;
|
||||
std::string gateVersion;
|
||||
};
|
||||
|
||||
//! CDEmoteTable table
|
||||
|
||||
@@ -21,11 +21,11 @@ CDFeatureGatingTable::CDFeatureGatingTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM FeatureGating");
|
||||
while (!tableData.eof()) {
|
||||
CDFeatureGating entry;
|
||||
entry.featureName = tableData.getStringField(0, "");
|
||||
entry.major = tableData.getIntField(1, -1);
|
||||
entry.current = tableData.getIntField(2, -1);
|
||||
entry.minor = tableData.getIntField(3, -1);
|
||||
entry.description = tableData.getStringField(4, "");
|
||||
entry.featureName = tableData.getStringField("featureName", "");
|
||||
entry.major = tableData.getIntField("major", -1);
|
||||
entry.current = tableData.getIntField("current", -1);
|
||||
entry.minor = tableData.getIntField("minor", -1);
|
||||
entry.description = tableData.getStringField("description", "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -66,3 +66,4 @@ bool CDFeatureGatingTable::FeatureUnlocked(const std::string& feature) const {
|
||||
std::vector<CDFeatureGating> CDFeatureGatingTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ CDInventoryComponentTable::CDInventoryComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM InventoryComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDInventoryComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.itemid = tableData.getIntField(1, -1);
|
||||
entry.count = tableData.getIntField(2, -1);
|
||||
entry.equip = tableData.getIntField(3, -1) == 1 ? true : false;
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.itemid = tableData.getIntField("itemid", -1);
|
||||
entry.count = tableData.getIntField("count", -1);
|
||||
entry.equip = tableData.getIntField("equip", -1) == 1 ? true : false;
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -55,3 +55,4 @@ std::vector<CDInventoryComponent> CDInventoryComponentTable::Query(std::function
|
||||
std::vector<CDInventoryComponent> CDInventoryComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,48 +23,48 @@ CDItemComponentTable::CDItemComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDItemComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.equipLocation = tableData.getStringField(1, "");
|
||||
entry.baseValue = tableData.getIntField(2, -1);
|
||||
entry.isKitPiece = tableData.getIntField(3, -1) == 1 ? true : false;
|
||||
entry.rarity = tableData.getIntField(4, 0);
|
||||
entry.itemType = tableData.getIntField(5, -1);
|
||||
entry.itemInfo = tableData.getInt64Field(6, -1);
|
||||
entry.inLootTable = tableData.getIntField(7, -1) == 1 ? true : false;
|
||||
entry.inVendor = tableData.getIntField(8, -1) == 1 ? true : false;
|
||||
entry.isUnique = tableData.getIntField(9, -1) == 1 ? true : false;
|
||||
entry.isBOP = tableData.getIntField(10, -1) == 1 ? true : false;
|
||||
entry.isBOE = tableData.getIntField(11, -1) == 1 ? true : false;
|
||||
entry.reqFlagID = tableData.getIntField(12, -1);
|
||||
entry.reqSpecialtyID = tableData.getIntField(13, -1);
|
||||
entry.reqSpecRank = tableData.getIntField(14, -1);
|
||||
entry.reqAchievementID = tableData.getIntField(15, -1);
|
||||
entry.stackSize = tableData.getIntField(16, -1);
|
||||
entry.color1 = tableData.getIntField(17, -1);
|
||||
entry.decal = tableData.getIntField(18, -1);
|
||||
entry.offsetGroupID = tableData.getIntField(19, -1);
|
||||
entry.buildTypes = tableData.getIntField(20, -1);
|
||||
entry.reqPrecondition = tableData.getStringField(21, "");
|
||||
entry.animationFlag = tableData.getIntField(22, 0);
|
||||
entry.equipEffects = tableData.getIntField(23, -1);
|
||||
entry.readyForQA = tableData.getIntField(24, -1) == 1 ? true : false;
|
||||
entry.itemRating = tableData.getIntField(25, -1);
|
||||
entry.isTwoHanded = tableData.getIntField(26, -1) == 1 ? true : false;
|
||||
entry.minNumRequired = tableData.getIntField(27, -1);
|
||||
entry.delResIndex = tableData.getIntField(28, -1);
|
||||
entry.currencyLOT = tableData.getIntField(29, -1);
|
||||
entry.altCurrencyCost = tableData.getIntField(30, -1);
|
||||
entry.subItems = tableData.getStringField(31, "");
|
||||
entry.audioEventUse = tableData.getStringField(32, "");
|
||||
entry.noEquipAnimation = tableData.getIntField(33, -1) == 1 ? true : false;
|
||||
entry.commendationLOT = tableData.getIntField(34, -1);
|
||||
entry.commendationCost = tableData.getIntField(35, -1);
|
||||
entry.audioEquipMetaEventSet = tableData.getStringField(36, "");
|
||||
entry.currencyCosts = tableData.getStringField(37, "");
|
||||
entry.ingredientInfo = tableData.getStringField(38, "");
|
||||
entry.locStatus = tableData.getIntField(39, -1);
|
||||
entry.forgeType = tableData.getIntField(40, -1);
|
||||
entry.SellMultiplier = tableData.getFloatField(41, -1.0f);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.equipLocation = tableData.getStringField("equipLocation", "");
|
||||
entry.baseValue = tableData.getIntField("baseValue", -1);
|
||||
entry.isKitPiece = tableData.getIntField("isKitPiece", -1) == 1 ? true : false;
|
||||
entry.rarity = tableData.getIntField("rarity", 0);
|
||||
entry.itemType = tableData.getIntField("itemType", -1);
|
||||
entry.itemInfo = tableData.getInt64Field("itemInfo", -1);
|
||||
entry.inLootTable = tableData.getIntField("inLootTable", -1) == 1 ? true : false;
|
||||
entry.inVendor = tableData.getIntField("inVendor", -1) == 1 ? true : false;
|
||||
entry.isUnique = tableData.getIntField("isUnique", -1) == 1 ? true : false;
|
||||
entry.isBOP = tableData.getIntField("isBOP", -1) == 1 ? true : false;
|
||||
entry.isBOE = tableData.getIntField("isBOE", -1) == 1 ? true : false;
|
||||
entry.reqFlagID = tableData.getIntField("reqFlagID", -1);
|
||||
entry.reqSpecialtyID = tableData.getIntField("reqSpecialtyID", -1);
|
||||
entry.reqSpecRank = tableData.getIntField("reqSpecRank", -1);
|
||||
entry.reqAchievementID = tableData.getIntField("reqAchievementID", -1);
|
||||
entry.stackSize = tableData.getIntField("stackSize", -1);
|
||||
entry.color1 = tableData.getIntField("color1", -1);
|
||||
entry.decal = tableData.getIntField("decal", -1);
|
||||
entry.offsetGroupID = tableData.getIntField("offsetGroupID", -1);
|
||||
entry.buildTypes = tableData.getIntField("buildTypes", -1);
|
||||
entry.reqPrecondition = tableData.getStringField("reqPrecondition", "");
|
||||
entry.animationFlag = tableData.getIntField("animationFlag", 0);
|
||||
entry.equipEffects = tableData.getIntField("equipEffects", -1);
|
||||
entry.readyForQA = tableData.getIntField("readyForQA", -1) == 1 ? true : false;
|
||||
entry.itemRating = tableData.getIntField("itemRating", -1);
|
||||
entry.isTwoHanded = tableData.getIntField("isTwoHanded", -1) == 1 ? true : false;
|
||||
entry.minNumRequired = tableData.getIntField("minNumRequired", -1);
|
||||
entry.delResIndex = tableData.getIntField("delResIndex", -1);
|
||||
entry.currencyLOT = tableData.getIntField("currencyLOT", -1);
|
||||
entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1);
|
||||
entry.subItems = tableData.getStringField("subItems", "");
|
||||
entry.audioEventUse = tableData.getStringField("audioEventUse", "");
|
||||
entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false;
|
||||
entry.commendationLOT = tableData.getIntField("commendationLOT", -1);
|
||||
entry.commendationCost = tableData.getIntField("commendationCost", -1);
|
||||
entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", "");
|
||||
entry.currencyCosts = tableData.getStringField("currencyCosts", "");
|
||||
entry.ingredientInfo = tableData.getStringField("ingredientInfo", "");
|
||||
entry.locStatus = tableData.getIntField("locStatus", -1);
|
||||
entry.forgeType = tableData.getIntField("forgeType", -1);
|
||||
entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f);
|
||||
|
||||
this->entries.insert(std::make_pair(entry.id, entry));
|
||||
tableData.nextRow();
|
||||
@@ -101,48 +101,48 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(unsigned int s
|
||||
|
||||
while (!tableData.eof()) {
|
||||
CDItemComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.equipLocation = tableData.getStringField(1, "");
|
||||
entry.baseValue = tableData.getIntField(2, -1);
|
||||
entry.isKitPiece = tableData.getIntField(3, -1) == 1 ? true : false;
|
||||
entry.rarity = tableData.getIntField(4, 0);
|
||||
entry.itemType = tableData.getIntField(5, -1);
|
||||
entry.itemInfo = tableData.getInt64Field(6, -1);
|
||||
entry.inLootTable = tableData.getIntField(7, -1) == 1 ? true : false;
|
||||
entry.inVendor = tableData.getIntField(8, -1) == 1 ? true : false;
|
||||
entry.isUnique = tableData.getIntField(9, -1) == 1 ? true : false;
|
||||
entry.isBOP = tableData.getIntField(10, -1) == 1 ? true : false;
|
||||
entry.isBOE = tableData.getIntField(11, -1) == 1 ? true : false;
|
||||
entry.reqFlagID = tableData.getIntField(12, -1);
|
||||
entry.reqSpecialtyID = tableData.getIntField(13, -1);
|
||||
entry.reqSpecRank = tableData.getIntField(14, -1);
|
||||
entry.reqAchievementID = tableData.getIntField(15, -1);
|
||||
entry.stackSize = tableData.getIntField(16, -1);
|
||||
entry.color1 = tableData.getIntField(17, -1);
|
||||
entry.decal = tableData.getIntField(18, -1);
|
||||
entry.offsetGroupID = tableData.getIntField(19, -1);
|
||||
entry.buildTypes = tableData.getIntField(20, -1);
|
||||
entry.reqPrecondition = tableData.getStringField(21, "");
|
||||
entry.animationFlag = tableData.getIntField(22, 0);
|
||||
entry.equipEffects = tableData.getIntField(23, -1);
|
||||
entry.readyForQA = tableData.getIntField(24, -1) == 1 ? true : false;
|
||||
entry.itemRating = tableData.getIntField(25, -1);
|
||||
entry.isTwoHanded = tableData.getIntField(26, -1) == 1 ? true : false;
|
||||
entry.minNumRequired = tableData.getIntField(27, -1);
|
||||
entry.delResIndex = tableData.getIntField(28, -1);
|
||||
entry.currencyLOT = tableData.getIntField(29, -1);
|
||||
entry.altCurrencyCost = tableData.getIntField(30, -1);
|
||||
entry.subItems = tableData.getStringField(31, "");
|
||||
UNUSED(entry.audioEventUse = tableData.getStringField(32, ""));
|
||||
entry.noEquipAnimation = tableData.getIntField(33, -1) == 1 ? true : false;
|
||||
entry.commendationLOT = tableData.getIntField(34, -1);
|
||||
entry.commendationCost = tableData.getIntField(35, -1);
|
||||
UNUSED(entry.audioEquipMetaEventSet = tableData.getStringField(36, ""));
|
||||
entry.currencyCosts = tableData.getStringField(37, "");
|
||||
UNUSED(entry.ingredientInfo = tableData.getStringField(38, ""));
|
||||
entry.locStatus = tableData.getIntField(39, -1);
|
||||
entry.forgeType = tableData.getIntField(40, -1);
|
||||
entry.SellMultiplier = tableData.getFloatField(41, -1.0f);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.equipLocation = tableData.getStringField("equipLocation", "");
|
||||
entry.baseValue = tableData.getIntField("baseValue", -1);
|
||||
entry.isKitPiece = tableData.getIntField("isKitPiece", -1) == 1 ? true : false;
|
||||
entry.rarity = tableData.getIntField("rarity", 0);
|
||||
entry.itemType = tableData.getIntField("itemType", -1);
|
||||
entry.itemInfo = tableData.getInt64Field("itemInfo", -1);
|
||||
entry.inLootTable = tableData.getIntField("inLootTable", -1) == 1 ? true : false;
|
||||
entry.inVendor = tableData.getIntField("inVendor", -1) == 1 ? true : false;
|
||||
entry.isUnique = tableData.getIntField("isUnique", -1) == 1 ? true : false;
|
||||
entry.isBOP = tableData.getIntField("isBOP", -1) == 1 ? true : false;
|
||||
entry.isBOE = tableData.getIntField("isBOE", -1) == 1 ? true : false;
|
||||
entry.reqFlagID = tableData.getIntField("reqFlagID", -1);
|
||||
entry.reqSpecialtyID = tableData.getIntField("reqSpecialtyID", -1);
|
||||
entry.reqSpecRank = tableData.getIntField("reqSpecRank", -1);
|
||||
entry.reqAchievementID = tableData.getIntField("reqAchievementID", -1);
|
||||
entry.stackSize = tableData.getIntField("stackSize", -1);
|
||||
entry.color1 = tableData.getIntField("color1", -1);
|
||||
entry.decal = tableData.getIntField("decal", -1);
|
||||
entry.offsetGroupID = tableData.getIntField("offsetGroupID", -1);
|
||||
entry.buildTypes = tableData.getIntField("buildTypes", -1);
|
||||
entry.reqPrecondition = tableData.getStringField("reqPrecondition", "");
|
||||
entry.animationFlag = tableData.getIntField("animationFlag", 0);
|
||||
entry.equipEffects = tableData.getIntField("equipEffects", -1);
|
||||
entry.readyForQA = tableData.getIntField("readyForQA", -1) == 1 ? true : false;
|
||||
entry.itemRating = tableData.getIntField("itemRating", -1);
|
||||
entry.isTwoHanded = tableData.getIntField("isTwoHanded", -1) == 1 ? true : false;
|
||||
entry.minNumRequired = tableData.getIntField("minNumRequired", -1);
|
||||
entry.delResIndex = tableData.getIntField("delResIndex", -1);
|
||||
entry.currencyLOT = tableData.getIntField("currencyLOT", -1);
|
||||
entry.altCurrencyCost = tableData.getIntField("altCurrencyCost", -1);
|
||||
entry.subItems = tableData.getStringField("subItems", "");
|
||||
UNUSED(entry.audioEventUse = tableData.getStringField("audioEventUse", ""));
|
||||
entry.noEquipAnimation = tableData.getIntField("noEquipAnimation", -1) == 1 ? true : false;
|
||||
entry.commendationLOT = tableData.getIntField("commendationLOT", -1);
|
||||
entry.commendationCost = tableData.getIntField("commendationCost", -1);
|
||||
UNUSED(entry.audioEquipMetaEventSet = tableData.getStringField("audioEquipMetaEventSet", ""));
|
||||
entry.currencyCosts = tableData.getStringField("currencyCosts", "");
|
||||
UNUSED(entry.ingredientInfo = tableData.getStringField("ingredientInfo", ""));
|
||||
entry.locStatus = tableData.getIntField("locStatus", -1);
|
||||
entry.forgeType = tableData.getIntField("forgeType", -1);
|
||||
entry.SellMultiplier = tableData.getFloatField("SellMultiplier", -1.0f);
|
||||
|
||||
this->entries.insert(std::make_pair(entry.id, entry));
|
||||
tableData.nextRow();
|
||||
@@ -177,3 +177,4 @@ std::map<LOT, uint32_t> CDItemComponentTable::ParseCraftingCurrencies(const CDIt
|
||||
|
||||
return currencies;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ CDItemSetSkillsTable::CDItemSetSkillsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSetSkills");
|
||||
while (!tableData.eof()) {
|
||||
CDItemSetSkills entry;
|
||||
entry.SkillSetID = tableData.getIntField(0, -1);
|
||||
entry.SkillID = tableData.getIntField(1, -1);
|
||||
entry.SkillCastType = tableData.getIntField(2, -1);
|
||||
entry.SkillSetID = tableData.getIntField("SkillSetID", -1);
|
||||
entry.SkillID = tableData.getIntField("SkillID", -1);
|
||||
entry.SkillCastType = tableData.getIntField("SkillCastType", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -65,3 +65,4 @@ std::vector<CDItemSetSkills> CDItemSetSkillsTable::GetBySkillID(unsigned int Ski
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,21 +21,21 @@ CDItemSetsTable::CDItemSetsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ItemSets");
|
||||
while (!tableData.eof()) {
|
||||
CDItemSets entry;
|
||||
entry.setID = tableData.getIntField(0, -1);
|
||||
entry.locStatus = tableData.getIntField(1, -1);
|
||||
entry.itemIDs = tableData.getStringField(2, "");
|
||||
entry.kitType = tableData.getIntField(3, -1);
|
||||
entry.kitRank = tableData.getIntField(4, -1);
|
||||
entry.kitImage = tableData.getIntField(5, -1);
|
||||
entry.skillSetWith2 = tableData.getIntField(6, -1);
|
||||
entry.skillSetWith3 = tableData.getIntField(7, -1);
|
||||
entry.skillSetWith4 = tableData.getIntField(8, -1);
|
||||
entry.skillSetWith5 = tableData.getIntField(9, -1);
|
||||
entry.skillSetWith6 = tableData.getIntField(10, -1);
|
||||
entry.localize = tableData.getIntField(11, -1) == 1 ? true : false;
|
||||
entry.gate_version = tableData.getStringField(12, "");
|
||||
entry.kitID = tableData.getIntField(13, -1);
|
||||
entry.priority = tableData.getFloatField(14, -1.0f);
|
||||
entry.setID = tableData.getIntField("setID", -1);
|
||||
entry.locStatus = tableData.getIntField("locStatus", -1);
|
||||
entry.itemIDs = tableData.getStringField("itemIDs", "");
|
||||
entry.kitType = tableData.getIntField("kitType", -1);
|
||||
entry.kitRank = tableData.getIntField("kitRank", -1);
|
||||
entry.kitImage = tableData.getIntField("kitImage", -1);
|
||||
entry.skillSetWith2 = tableData.getIntField("skillSetWith2", -1);
|
||||
entry.skillSetWith3 = tableData.getIntField("skillSetWith3", -1);
|
||||
entry.skillSetWith4 = tableData.getIntField("skillSetWith4", -1);
|
||||
entry.skillSetWith5 = tableData.getIntField("skillSetWith5", -1);
|
||||
entry.skillSetWith6 = tableData.getIntField("skillSetWith6", -1);
|
||||
entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false;
|
||||
entry.gate_version = tableData.getStringField("gate_version", "");
|
||||
entry.kitID = tableData.getIntField("kitID", -1);
|
||||
entry.priority = tableData.getFloatField("priority", -1.0f);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -66,3 +66,4 @@ std::vector<CDItemSets> CDItemSetsTable::Query(std::function<bool(CDItemSets)> p
|
||||
std::vector<CDItemSets> CDItemSetsTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ CDLevelProgressionLookupTable::CDLevelProgressionLookupTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LevelProgressionLookup");
|
||||
while (!tableData.eof()) {
|
||||
CDLevelProgressionLookup entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.requiredUScore = tableData.getIntField(1, -1);
|
||||
entry.BehaviorEffect = tableData.getStringField(2, "");
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.requiredUScore = tableData.getIntField("requiredUScore", -1);
|
||||
entry.BehaviorEffect = tableData.getStringField("BehaviorEffect", "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -54,3 +54,4 @@ std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::Query(std::
|
||||
std::vector<CDLevelProgressionLookup> CDLevelProgressionLookupTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,15 +21,15 @@ CDLootMatrixTable::CDLootMatrixTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootMatrix");
|
||||
while (!tableData.eof()) {
|
||||
CDLootMatrix entry;
|
||||
entry.LootMatrixIndex = tableData.getIntField(0, -1);
|
||||
entry.LootTableIndex = tableData.getIntField(1, -1);
|
||||
entry.RarityTableIndex = tableData.getIntField(2, -1);
|
||||
entry.percent = tableData.getFloatField(3, -1.0f);
|
||||
entry.minToDrop = tableData.getIntField(4, -1);
|
||||
entry.maxToDrop = tableData.getIntField(5, -1);
|
||||
entry.id = tableData.getIntField(6, -1);
|
||||
entry.flagID = tableData.getIntField(7, -1);
|
||||
UNUSED(entry.gate_version = tableData.getStringField(8, ""));
|
||||
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
|
||||
entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1);
|
||||
entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1);
|
||||
entry.percent = tableData.getFloatField("percent", -1.0f);
|
||||
entry.minToDrop = tableData.getIntField("minToDrop", -1);
|
||||
entry.maxToDrop = tableData.getIntField("maxToDrop", -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.flagID = tableData.getIntField("flagID", -1);
|
||||
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -60,3 +60,4 @@ std::vector<CDLootMatrix> CDLootMatrixTable::Query(std::function<bool(CDLootMatr
|
||||
const std::vector<CDLootMatrix>& CDLootMatrixTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,12 @@ CDLootTableTable::CDLootTableTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootTable");
|
||||
while (!tableData.eof()) {
|
||||
CDLootTable entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.itemid = tableData.getIntField(0, -1);
|
||||
entry.LootTableIndex = tableData.getIntField(1, -1);
|
||||
entry.id = tableData.getIntField(2, -1);
|
||||
entry.MissionDrop = tableData.getIntField(3, -1) == 1 ? true : false;
|
||||
entry.sortPriority = tableData.getIntField(4, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.itemid = tableData.getIntField("itemid", -1);
|
||||
entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.MissionDrop = tableData.getIntField("MissionDrop", -1) == 1 ? true : false;
|
||||
entry.sortPriority = tableData.getIntField("sortPriority", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -57,3 +57,4 @@ std::vector<CDLootTable> CDLootTableTable::Query(std::function<bool(CDLootTable)
|
||||
const std::vector<CDLootTable>& CDLootTableTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,14 +21,14 @@ CDMissionEmailTable::CDMissionEmailTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionEmail");
|
||||
while (!tableData.eof()) {
|
||||
CDMissionEmail entry;
|
||||
entry.ID = tableData.getIntField(0, -1);
|
||||
entry.messageType = tableData.getIntField(1, -1);
|
||||
entry.notificationGroup = tableData.getIntField(2, -1);
|
||||
entry.missionID = tableData.getIntField(3, -1);
|
||||
entry.attachmentLOT = tableData.getIntField(4, 0);
|
||||
entry.localize = (bool)tableData.getIntField(5, -1);
|
||||
entry.locStatus = tableData.getIntField(6, -1);
|
||||
entry.gate_version = tableData.getStringField(7, "");
|
||||
entry.ID = tableData.getIntField("ID", -1);
|
||||
entry.messageType = tableData.getIntField("messageType", -1);
|
||||
entry.notificationGroup = tableData.getIntField("notificationGroup", -1);
|
||||
entry.missionID = tableData.getIntField("missionID", -1);
|
||||
entry.attachmentLOT = tableData.getIntField("attachmentLOT", 0);
|
||||
entry.localize = (bool)tableData.getIntField("localize", -1);
|
||||
entry.locStatus = tableData.getIntField("locStatus", -1);
|
||||
entry.gate_version = tableData.getStringField("gate_version", "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -59,3 +59,4 @@ std::vector<CDMissionEmail> CDMissionEmailTable::Query(std::function<bool(CDMiss
|
||||
std::vector<CDMissionEmail> CDMissionEmailTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ CDMissionNPCComponentTable::CDMissionNPCComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionNPCComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDMissionNPCComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.missionID = tableData.getIntField(1, -1);
|
||||
entry.offersMission = tableData.getIntField(2, -1) == 1 ? true : false;
|
||||
entry.acceptsMission = tableData.getIntField(3, -1) == 1 ? true : false;
|
||||
entry.gate_version = tableData.getStringField(4, "");
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.missionID = tableData.getIntField("missionID", -1);
|
||||
entry.offersMission = tableData.getIntField("offersMission", -1) == 1 ? true : false;
|
||||
entry.acceptsMission = tableData.getIntField("acceptsMission", -1) == 1 ? true : false;
|
||||
entry.gate_version = tableData.getStringField("gate_version", "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -56,3 +56,4 @@ std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::Query(std::functi
|
||||
std::vector<CDMissionNPCComponent> CDMissionNPCComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,19 +21,19 @@ CDMissionTasksTable::CDMissionTasksTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MissionTasks");
|
||||
while (!tableData.eof()) {
|
||||
CDMissionTasks entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
UNUSED(entry.locStatus = tableData.getIntField(1, -1));
|
||||
entry.taskType = tableData.getIntField(2, -1);
|
||||
entry.target = tableData.getIntField(3, -1);
|
||||
entry.targetGroup = tableData.getStringField(4, "");
|
||||
entry.targetValue = tableData.getIntField(5, -1);
|
||||
entry.taskParam1 = tableData.getStringField(6, "");
|
||||
UNUSED(entry.largeTaskIcon = tableData.getStringField(7, ""));
|
||||
UNUSED(entry.IconID = tableData.getIntField(8, -1));
|
||||
entry.uid = tableData.getIntField(9, -1);
|
||||
UNUSED(entry.largeTaskIconID = tableData.getIntField(10, -1));
|
||||
UNUSED(entry.localize = tableData.getIntField(11, -1) == 1 ? true : false);
|
||||
UNUSED(entry.gate_version = tableData.getStringField(12, ""));
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
|
||||
entry.taskType = tableData.getIntField("taskType", -1);
|
||||
entry.target = tableData.getIntField("target", -1);
|
||||
entry.targetGroup = tableData.getStringField("targetGroup", "");
|
||||
entry.targetValue = tableData.getIntField("targetValue", -1);
|
||||
entry.taskParam1 = tableData.getStringField("taskParam1", "");
|
||||
UNUSED(entry.largeTaskIcon = tableData.getStringField("largeTaskIcon", ""));
|
||||
UNUSED(entry.IconID = tableData.getIntField("IconID", -1));
|
||||
entry.uid = tableData.getIntField("uid", -1);
|
||||
UNUSED(entry.largeTaskIconID = tableData.getIntField("largeTaskIconID", -1));
|
||||
UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false);
|
||||
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -78,3 +78,4 @@ std::vector<CDMissionTasks*> CDMissionTasksTable::GetByMissionID(uint32_t missio
|
||||
const std::vector<CDMissionTasks>& CDMissionTasksTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,58 +23,58 @@ CDMissionsTable::CDMissionsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Missions");
|
||||
while (!tableData.eof()) {
|
||||
CDMissions entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.defined_type = tableData.getStringField(1, "");
|
||||
entry.defined_subtype = tableData.getStringField(2, "");
|
||||
entry.UISortOrder = tableData.getIntField(3, -1);
|
||||
entry.offer_objectID = tableData.getIntField(4, -1);
|
||||
entry.target_objectID = tableData.getIntField(5, -1);
|
||||
entry.reward_currency = tableData.getInt64Field(6, -1);
|
||||
entry.LegoScore = tableData.getIntField(7, -1);
|
||||
entry.reward_reputation = tableData.getIntField(8, -1);
|
||||
entry.isChoiceReward = tableData.getIntField(9, -1) == 1 ? true : false;
|
||||
entry.reward_item1 = tableData.getIntField(10, 0);
|
||||
entry.reward_item1_count = tableData.getIntField(11, 0);
|
||||
entry.reward_item2 = tableData.getIntField(12, 0);
|
||||
entry.reward_item2_count = tableData.getIntField(13, 0);
|
||||
entry.reward_item3 = tableData.getIntField(14, 0);
|
||||
entry.reward_item3_count = tableData.getIntField(15, 0);
|
||||
entry.reward_item4 = tableData.getIntField(16, 0);
|
||||
entry.reward_item4_count = tableData.getIntField(17, 0);
|
||||
entry.reward_emote = tableData.getIntField(18, -1);
|
||||
entry.reward_emote2 = tableData.getIntField(19, -1);
|
||||
entry.reward_emote3 = tableData.getIntField(20, -1);
|
||||
entry.reward_emote4 = tableData.getIntField(21, -1);
|
||||
entry.reward_maximagination = tableData.getIntField(22, -1);
|
||||
entry.reward_maxhealth = tableData.getIntField(23, -1);
|
||||
entry.reward_maxinventory = tableData.getIntField(24, -1);
|
||||
entry.reward_maxmodel = tableData.getIntField(25, -1);
|
||||
entry.reward_maxwidget = tableData.getIntField(26, -1);
|
||||
entry.reward_maxwallet = tableData.getIntField(27, -1);
|
||||
entry.repeatable = tableData.getIntField(28, -1) == 1 ? true : false;
|
||||
entry.reward_currency_repeatable = tableData.getIntField(29, -1);
|
||||
entry.reward_item1_repeatable = tableData.getIntField(30, -1);
|
||||
entry.reward_item1_repeat_count = tableData.getIntField(31, -1);
|
||||
entry.reward_item2_repeatable = tableData.getIntField(32, -1);
|
||||
entry.reward_item2_repeat_count = tableData.getIntField(33, -1);
|
||||
entry.reward_item3_repeatable = tableData.getIntField(34, -1);
|
||||
entry.reward_item3_repeat_count = tableData.getIntField(35, -1);
|
||||
entry.reward_item4_repeatable = tableData.getIntField(36, -1);
|
||||
entry.reward_item4_repeat_count = tableData.getIntField(37, -1);
|
||||
entry.time_limit = tableData.getIntField(38, -1);
|
||||
entry.isMission = tableData.getIntField(39, -1) ? true : false;
|
||||
entry.missionIconID = tableData.getIntField(40, -1);
|
||||
entry.prereqMissionID = tableData.getStringField(41, "");
|
||||
entry.localize = tableData.getIntField(42, -1) == 1 ? true : false;
|
||||
entry.inMOTD = tableData.getIntField(43, -1) == 1 ? true : false;
|
||||
entry.cooldownTime = tableData.getInt64Field(44, -1);
|
||||
entry.isRandom = tableData.getIntField(45, -1) == 1 ? true : false;
|
||||
entry.randomPool = tableData.getStringField(46, "");
|
||||
entry.UIPrereqID = tableData.getIntField(47, -1);
|
||||
UNUSED(entry.gate_version = tableData.getStringField(48, ""));
|
||||
UNUSED(entry.HUDStates = tableData.getStringField(49, ""));
|
||||
UNUSED(entry.locStatus = tableData.getIntField(50, -1));
|
||||
entry.reward_bankinventory = tableData.getIntField(51, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.defined_type = tableData.getStringField("defined_type", "");
|
||||
entry.defined_subtype = tableData.getStringField("defined_subtype", "");
|
||||
entry.UISortOrder = tableData.getIntField("UISortOrder", -1);
|
||||
entry.offer_objectID = tableData.getIntField("offer_objectID", -1);
|
||||
entry.target_objectID = tableData.getIntField("target_objectID", -1);
|
||||
entry.reward_currency = tableData.getInt64Field("reward_currency", -1);
|
||||
entry.LegoScore = tableData.getIntField("LegoScore", -1);
|
||||
entry.reward_reputation = tableData.getIntField("reward_reputation", -1);
|
||||
entry.isChoiceReward = tableData.getIntField("isChoiceReward", -1) == 1 ? true : false;
|
||||
entry.reward_item1 = tableData.getIntField("reward_item1", 0);
|
||||
entry.reward_item1_count = tableData.getIntField("reward_item1_count", 0);
|
||||
entry.reward_item2 = tableData.getIntField("reward_item2", 0);
|
||||
entry.reward_item2_count = tableData.getIntField("reward_item2_count", 0);
|
||||
entry.reward_item3 = tableData.getIntField("reward_item3", 0);
|
||||
entry.reward_item3_count = tableData.getIntField("reward_item3_count", 0);
|
||||
entry.reward_item4 = tableData.getIntField("reward_item4", 0);
|
||||
entry.reward_item4_count = tableData.getIntField("reward_item4_count", 0);
|
||||
entry.reward_emote = tableData.getIntField("reward_emote", -1);
|
||||
entry.reward_emote2 = tableData.getIntField("reward_emote2", -1);
|
||||
entry.reward_emote3 = tableData.getIntField("reward_emote3", -1);
|
||||
entry.reward_emote4 = tableData.getIntField("reward_emote4", -1);
|
||||
entry.reward_maximagination = tableData.getIntField("reward_maximagination", -1);
|
||||
entry.reward_maxhealth = tableData.getIntField("reward_maxhealth", -1);
|
||||
entry.reward_maxinventory = tableData.getIntField("reward_maxinventory", -1);
|
||||
entry.reward_maxmodel = tableData.getIntField("reward_maxmodel", -1);
|
||||
entry.reward_maxwidget = tableData.getIntField("reward_maxwidget", -1);
|
||||
entry.reward_maxwallet = tableData.getIntField("reward_maxwallet", -1);
|
||||
entry.repeatable = tableData.getIntField("repeatable", -1) == 1 ? true : false;
|
||||
entry.reward_currency_repeatable = tableData.getIntField("reward_currency_repeatable", -1);
|
||||
entry.reward_item1_repeatable = tableData.getIntField("reward_item1_repeatable", -1);
|
||||
entry.reward_item1_repeat_count = tableData.getIntField("reward_item1_repeat_count", -1);
|
||||
entry.reward_item2_repeatable = tableData.getIntField("reward_item2_repeatable", -1);
|
||||
entry.reward_item2_repeat_count = tableData.getIntField("reward_item2_repeat_count", -1);
|
||||
entry.reward_item3_repeatable = tableData.getIntField("reward_item3_repeatable", -1);
|
||||
entry.reward_item3_repeat_count = tableData.getIntField("reward_item3_repeat_count", -1);
|
||||
entry.reward_item4_repeatable = tableData.getIntField("reward_item4_repeatable", -1);
|
||||
entry.reward_item4_repeat_count = tableData.getIntField("reward_item4_repeat_count", -1);
|
||||
entry.time_limit = tableData.getIntField("time_limit", -1);
|
||||
entry.isMission = tableData.getIntField("isMission", -1) ? true : false;
|
||||
entry.missionIconID = tableData.getIntField("missionIconID", -1);
|
||||
entry.prereqMissionID = tableData.getStringField("prereqMissionID", "");
|
||||
entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false;
|
||||
entry.inMOTD = tableData.getIntField("inMOTD", -1) == 1 ? true : false;
|
||||
entry.cooldownTime = tableData.getInt64Field("cooldownTime", -1);
|
||||
entry.isRandom = tableData.getIntField("isRandom", -1) == 1 ? true : false;
|
||||
entry.randomPool = tableData.getStringField("randomPool", "");
|
||||
entry.UIPrereqID = tableData.getIntField("UIPrereqID", -1);
|
||||
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
|
||||
UNUSED(entry.HUDStates = tableData.getStringField("HUDStates", ""));
|
||||
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
|
||||
entry.reward_bankinventory = tableData.getIntField("reward_bankinventory", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -131,3 +131,4 @@ const CDMissions& CDMissionsTable::GetByMissionID(uint32_t missionID, bool& foun
|
||||
|
||||
return Default;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,14 +21,14 @@ CDMovementAIComponentTable::CDMovementAIComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM MovementAIComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDMovementAIComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.MovementType = tableData.getStringField(1, "");
|
||||
entry.WanderChance = tableData.getFloatField(2, -1.0f);
|
||||
entry.WanderDelayMin = tableData.getFloatField(3, -1.0f);
|
||||
entry.WanderDelayMax = tableData.getFloatField(4, -1.0f);
|
||||
entry.WanderSpeed = tableData.getFloatField(5, -1.0f);
|
||||
entry.WanderRadius = tableData.getFloatField(6, -1.0f);
|
||||
entry.attachedPath = tableData.getStringField(7, "");
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.MovementType = tableData.getStringField("MovementType", "");
|
||||
entry.WanderChance = tableData.getFloatField("WanderChance", -1.0f);
|
||||
entry.WanderDelayMin = tableData.getFloatField("WanderDelayMin", -1.0f);
|
||||
entry.WanderDelayMax = tableData.getFloatField("WanderDelayMax", -1.0f);
|
||||
entry.WanderSpeed = tableData.getFloatField("WanderSpeed", -1.0f);
|
||||
entry.WanderRadius = tableData.getFloatField("WanderRadius", -1.0f);
|
||||
entry.attachedPath = tableData.getStringField("attachedPath", "");
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -59,3 +59,4 @@ std::vector<CDMovementAIComponent> CDMovementAIComponentTable::Query(std::functi
|
||||
std::vector<CDMovementAIComponent> CDMovementAIComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ CDObjectSkillsTable::CDObjectSkillsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ObjectSkills");
|
||||
while (!tableData.eof()) {
|
||||
CDObjectSkills entry;
|
||||
entry.objectTemplate = tableData.getIntField(0, -1);
|
||||
entry.skillID = tableData.getIntField(1, -1);
|
||||
entry.castOnType = tableData.getIntField(2, -1);
|
||||
entry.AICombatWeight = tableData.getIntField(3, -1);
|
||||
entry.objectTemplate = tableData.getIntField("objectTemplate", -1);
|
||||
entry.skillID = tableData.getIntField("skillID", -1);
|
||||
entry.castOnType = tableData.getIntField("castOnType", -1);
|
||||
entry.AICombatWeight = tableData.getIntField("AICombatWeight", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -55,3 +55,4 @@ std::vector<CDObjectSkills> CDObjectSkillsTable::Query(std::function<bool(CDObje
|
||||
std::vector<CDObjectSkills> CDObjectSkillsTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,20 +18,20 @@ CDObjectsTable::CDObjectsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Objects");
|
||||
while (!tableData.eof()) {
|
||||
CDObjects entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.name = tableData.getStringField(1, "");
|
||||
entry.placeable = tableData.getIntField(2, -1);
|
||||
entry.type = tableData.getStringField(3, "");
|
||||
entry.description = tableData.getStringField(4, "");
|
||||
entry.localize = tableData.getIntField(5, -1);
|
||||
entry.npcTemplateID = tableData.getIntField(6, -1);
|
||||
entry.displayName = tableData.getStringField(7, "");
|
||||
entry.interactionDistance = tableData.getFloatField(8, -1.0f);
|
||||
entry.nametag = tableData.getIntField(9, -1);
|
||||
entry._internalNotes = tableData.getStringField(10, "");
|
||||
entry.locStatus = tableData.getIntField(11, -1);
|
||||
entry.gate_version = tableData.getStringField(12, "");
|
||||
entry.HQ_valid = tableData.getIntField(13, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.name = tableData.getStringField("name", "");
|
||||
entry.placeable = tableData.getIntField("placeable", -1);
|
||||
entry.type = tableData.getStringField("type", "");
|
||||
entry.description = tableData.getStringField("description", "");
|
||||
entry.localize = tableData.getIntField("localize", -1);
|
||||
entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1);
|
||||
entry.displayName = tableData.getStringField("displayName", "");
|
||||
entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f);
|
||||
entry.nametag = tableData.getIntField("nametag", -1);
|
||||
entry._internalNotes = tableData.getStringField("_internalNotes", "");
|
||||
entry.locStatus = tableData.getIntField("locStatus", -1);
|
||||
entry.gate_version = tableData.getStringField("gate_version", "");
|
||||
entry.HQ_valid = tableData.getIntField("HQ_valid", -1);
|
||||
|
||||
this->entries.insert(std::make_pair(entry.id, entry));
|
||||
tableData.nextRow();
|
||||
@@ -71,20 +71,20 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) {
|
||||
// Now get the data
|
||||
while (!tableData.eof()) {
|
||||
CDObjects entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.name = tableData.getStringField(1, "");
|
||||
UNUSED(entry.placeable = tableData.getIntField(2, -1));
|
||||
entry.type = tableData.getStringField(3, "");
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.name = tableData.getStringField("name", "");
|
||||
UNUSED(entry.placeable = tableData.getIntField("placeable", -1));
|
||||
entry.type = tableData.getStringField("type", "");
|
||||
UNUSED(ntry.description = tableData.getStringField(4, ""));
|
||||
UNUSED(entry.localize = tableData.getIntField(5, -1));
|
||||
UNUSED(entry.npcTemplateID = tableData.getIntField(6, -1));
|
||||
UNUSED(entry.displayName = tableData.getStringField(7, ""));
|
||||
entry.interactionDistance = tableData.getFloatField(8, -1.0f);
|
||||
UNUSED(entry.nametag = tableData.getIntField(9, -1));
|
||||
UNUSED(entry._internalNotes = tableData.getStringField(10, ""));
|
||||
UNUSED(entry.locStatus = tableData.getIntField(11, -1));
|
||||
UNUSED(entry.gate_version = tableData.getStringField(12, ""));
|
||||
UNUSED(entry.HQ_valid = tableData.getIntField(13, -1));
|
||||
UNUSED(entry.localize = tableData.getIntField("localize", -1));
|
||||
UNUSED(entry.npcTemplateID = tableData.getIntField("npcTemplateID", -1));
|
||||
UNUSED(entry.displayName = tableData.getStringField("displayName", ""));
|
||||
entry.interactionDistance = tableData.getFloatField("interactionDistance", -1.0f);
|
||||
UNUSED(entry.nametag = tableData.getIntField("nametag", -1));
|
||||
UNUSED(entry._internalNotes = tableData.getStringField("_internalNotes", ""));
|
||||
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
|
||||
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
|
||||
UNUSED(entry.HQ_valid = tableData.getIntField("HQ_valid", -1));
|
||||
|
||||
this->entries.insert(std::make_pair(entry.id, entry));
|
||||
tableData.nextRow();
|
||||
@@ -100,3 +100,4 @@ const CDObjects& CDObjectsTable::GetByID(unsigned int LOT) {
|
||||
|
||||
return m_default;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ CDPackageComponentTable::CDPackageComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PackageComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDPackageComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField(1, -1);
|
||||
entry.packageType = tableData.getIntField(2, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
|
||||
entry.packageType = tableData.getIntField("packageType", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -54,3 +54,4 @@ std::vector<CDPackageComponent> CDPackageComponentTable::Query(std::function<boo
|
||||
std::vector<CDPackageComponent> CDPackageComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,22 +4,22 @@ CDPhysicsComponentTable::CDPhysicsComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PhysicsComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDPhysicsComponent* entry = new CDPhysicsComponent();
|
||||
entry->id = tableData.getIntField(0, -1);
|
||||
entry->bStatic = tableData.getIntField(1, -1) != 0;
|
||||
entry->physicsAsset = tableData.getStringField(2, "");
|
||||
UNUSED(entry->jump = tableData.getIntField(3, -1) != 0);
|
||||
UNUSED(entry->doublejump = tableData.getIntField(4, -1) != 0);
|
||||
entry->speed = tableData.getFloatField(5, -1);
|
||||
UNUSED(entry->rotSpeed = tableData.getFloatField(6, -1));
|
||||
entry->playerHeight = tableData.getFloatField(7);
|
||||
entry->playerRadius = tableData.getFloatField(8);
|
||||
entry->pcShapeType = tableData.getIntField(9);
|
||||
entry->collisionGroup = tableData.getIntField(10);
|
||||
UNUSED(entry->airSpeed = tableData.getFloatField(11));
|
||||
UNUSED(entry->boundaryAsset = tableData.getStringField(12));
|
||||
UNUSED(entry->jumpAirSpeed = tableData.getFloatField(13));
|
||||
UNUSED(entry->friction = tableData.getFloatField(14));
|
||||
UNUSED(entry->gravityVolumeAsset = tableData.getStringField(15));
|
||||
entry->id = tableData.getIntField("id", -1);
|
||||
entry->bStatic = tableData.getIntField("static", -1) != 0;
|
||||
entry->physicsAsset = tableData.getStringField("physics_asset", "");
|
||||
UNUSED(entry->jump = tableData.getIntField("jump", -1) != 0);
|
||||
UNUSED(entry->doublejump = tableData.getIntField("doublejump", -1) != 0);
|
||||
entry->speed = tableData.getFloatField("speed", -1);
|
||||
UNUSED(entry->rotSpeed = tableData.getFloatField("rotSpeed", -1));
|
||||
entry->playerHeight = tableData.getFloatField("playerHeight");
|
||||
entry->playerRadius = tableData.getFloatField("playerRadius");
|
||||
entry->pcShapeType = tableData.getIntField("pcShapeType");
|
||||
entry->collisionGroup = tableData.getIntField("collisionGroup");
|
||||
UNUSED(entry->airSpeed = tableData.getFloatField("airSpeed"));
|
||||
UNUSED(entry->boundaryAsset = tableData.getStringField("boundaryAsset"));
|
||||
UNUSED(entry->jumpAirSpeed = tableData.getFloatField("jumpAirSpeed"));
|
||||
UNUSED(entry->friction = tableData.getFloatField("friction"));
|
||||
UNUSED(entry->gravityVolumeAsset = tableData.getStringField("gravityVolumeAsset"));
|
||||
|
||||
m_entries.insert(std::make_pair(entry->id, entry));
|
||||
tableData.nextRow();
|
||||
@@ -47,3 +47,4 @@ CDPhysicsComponent* CDPhysicsComponentTable::GetByID(unsigned int componentID) {
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ CDPropertyEntranceComponentTable::CDPropertyEntranceComponentTable() {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PropertyEntranceComponent;");
|
||||
while (!tableData.eof()) {
|
||||
auto entry = CDPropertyEntranceComponent{
|
||||
static_cast<uint32_t>(tableData.getIntField(0, -1)),
|
||||
static_cast<uint32_t>(tableData.getIntField(1, -1)),
|
||||
tableData.getStringField(2, ""),
|
||||
static_cast<bool>(tableData.getIntField(3, false)),
|
||||
tableData.getStringField(4, "")
|
||||
static_cast<uint32_t>(tableData.getIntField("id", -1)),
|
||||
static_cast<uint32_t>(tableData.getIntField("mapID", -1)),
|
||||
tableData.getStringField("propertyName", ""),
|
||||
static_cast<bool>(tableData.getIntField("isOnProperty", false)),
|
||||
tableData.getStringField("groupType", "")
|
||||
};
|
||||
|
||||
this->entries.push_back(entry);
|
||||
@@ -46,3 +46,4 @@ CDPropertyEntranceComponent CDPropertyEntranceComponentTable::GetByID(uint32_t i
|
||||
|
||||
return defaultEntry;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ CDPropertyTemplateTable::CDPropertyTemplateTable() {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM PropertyTemplate;");
|
||||
while (!tableData.eof()) {
|
||||
auto entry = CDPropertyTemplate{
|
||||
static_cast<uint32_t>(tableData.getIntField(0, -1)),
|
||||
static_cast<uint32_t>(tableData.getIntField(1, -1)),
|
||||
static_cast<uint32_t>(tableData.getIntField(2, -1)),
|
||||
tableData.getStringField(3, "")
|
||||
static_cast<uint32_t>(tableData.getIntField("id", -1)),
|
||||
static_cast<uint32_t>(tableData.getIntField("mapID", -1)),
|
||||
static_cast<uint32_t>(tableData.getIntField("vendorMapID", -1)),
|
||||
tableData.getStringField("spawnName", "")
|
||||
};
|
||||
|
||||
this->entries.push_back(entry);
|
||||
@@ -44,3 +44,4 @@ CDPropertyTemplate CDPropertyTemplateTable::GetByMapID(uint32_t mapID) {
|
||||
|
||||
return defaultEntry;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ CDProximityMonitorComponentTable::CDProximityMonitorComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ProximityMonitorComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDProximityMonitorComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.Proximities = tableData.getStringField(1, "");
|
||||
entry.LoadOnClient = tableData.getIntField(2, -1);
|
||||
entry.LoadOnServer = tableData.getIntField(3, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.Proximities = tableData.getStringField("Proximities", "");
|
||||
entry.LoadOnClient = tableData.getIntField("LoadOnClient", -1);
|
||||
entry.LoadOnServer = tableData.getIntField("LoadOnServer", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -55,3 +55,4 @@ std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::Query
|
||||
std::vector<CDProximityMonitorComponent> CDProximityMonitorComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,35 +6,35 @@ CDRailActivatorComponentTable::CDRailActivatorComponentTable() {
|
||||
while (!tableData.eof()) {
|
||||
CDRailActivatorComponent entry;
|
||||
|
||||
entry.id = tableData.getIntField(0);
|
||||
entry.id = tableData.getIntField("id", 0);
|
||||
|
||||
entry.startAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField(1, ""));
|
||||
entry.loopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField(2, ""));
|
||||
entry.stopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField(3, ""));
|
||||
entry.startSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField(4, ""));
|
||||
entry.loopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField(5, ""));
|
||||
entry.stopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField(6, ""));
|
||||
entry.startAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField("startAnim", ""));
|
||||
entry.loopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField("loopAnim", ""));
|
||||
entry.stopAnimation = GeneralUtils::ASCIIToUTF16(tableData.getStringField("stopAnim", ""));
|
||||
entry.startSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField("startSound", ""));
|
||||
entry.loopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField("loopSound", ""));
|
||||
entry.stopSound = GeneralUtils::ASCIIToUTF16(tableData.getStringField("stopSound", ""));
|
||||
|
||||
std::string loopEffectString(tableData.getStringField(7, ""));
|
||||
std::string loopEffectString(tableData.getStringField("effectIDs", ""));
|
||||
entry.loopEffectID = EffectPairFromString(loopEffectString);
|
||||
|
||||
entry.preconditions = tableData.getStringField(8, "-1");
|
||||
entry.preconditions = tableData.getStringField("preconditions", "-1");
|
||||
|
||||
entry.playerCollision = tableData.getIntField(9, 0);
|
||||
entry.playerCollision = tableData.getIntField("playerCollision", 0);
|
||||
|
||||
entry.cameraLocked = tableData.getIntField(10, 0);
|
||||
entry.cameraLocked = tableData.getIntField("cameraLocked", 0);
|
||||
|
||||
std::string startEffectString(tableData.getStringField(11, ""));
|
||||
std::string startEffectString(tableData.getStringField("StartEffectID", ""));
|
||||
entry.startEffectID = EffectPairFromString(startEffectString);
|
||||
|
||||
std::string stopEffectString(tableData.getStringField(12, ""));
|
||||
std::string stopEffectString(tableData.getStringField("StopEffectID", ""));
|
||||
entry.stopEffectID = EffectPairFromString(stopEffectString);
|
||||
|
||||
entry.damageImmune = tableData.getIntField(13, 0);
|
||||
entry.damageImmune = tableData.getIntField("DamageImmune", 0);
|
||||
|
||||
entry.noAggro = tableData.getIntField(14, 0);
|
||||
entry.noAggro = tableData.getIntField("NoAggro", 0);
|
||||
|
||||
entry.showNameBillboard = tableData.getIntField(15, 0);
|
||||
entry.showNameBillboard = tableData.getIntField("ShowNameBillboard", 0);
|
||||
|
||||
m_Entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -70,3 +70,4 @@ std::pair<uint32_t, std::u16string> CDRailActivatorComponentTable::EffectPairFro
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ CDRarityTableTable::CDRarityTableTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RarityTable");
|
||||
while (!tableData.eof()) {
|
||||
CDRarityTable entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.randmax = tableData.getFloatField(1, -1);
|
||||
entry.rarity = tableData.getIntField(2, -1);
|
||||
entry.RarityTableIndex = tableData.getIntField(3, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.randmax = tableData.getFloatField("randmax", -1);
|
||||
entry.rarity = tableData.getIntField("rarity", -1);
|
||||
entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -55,3 +55,4 @@ std::vector<CDRarityTable> CDRarityTableTable::Query(std::function<bool(CDRarity
|
||||
const std::vector<CDRarityTable>& CDRarityTableTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,16 +21,16 @@ CDRebuildComponentTable::CDRebuildComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RebuildComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDRebuildComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.reset_time = tableData.getFloatField(1, -1.0f);
|
||||
entry.complete_time = tableData.getFloatField(2, -1.0f);
|
||||
entry.take_imagination = tableData.getIntField(3, -1);
|
||||
entry.interruptible = tableData.getIntField(4, -1) == 1 ? true : false;
|
||||
entry.self_activator = tableData.getIntField(5, -1) == 1 ? true : false;
|
||||
entry.custom_modules = tableData.getStringField(6, "");
|
||||
entry.activityID = tableData.getIntField(7, -1);
|
||||
entry.post_imagination_cost = tableData.getIntField(8, -1);
|
||||
entry.time_before_smash = tableData.getFloatField(9, -1.0f);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.reset_time = tableData.getFloatField("reset_time", -1.0f);
|
||||
entry.complete_time = tableData.getFloatField("complete_time", -1.0f);
|
||||
entry.take_imagination = tableData.getIntField("take_imagination", -1);
|
||||
entry.interruptible = tableData.getIntField("interruptible", -1) == 1 ? true : false;
|
||||
entry.self_activator = tableData.getIntField("self_activator", -1) == 1 ? true : false;
|
||||
entry.custom_modules = tableData.getStringField("custom_modules", "");
|
||||
entry.activityID = tableData.getIntField("activityID", -1);
|
||||
entry.post_imagination_cost = tableData.getIntField("post_imagination_cost", -1);
|
||||
entry.time_before_smash = tableData.getFloatField("time_before_smash", -1.0f);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -61,3 +61,4 @@ std::vector<CDRebuildComponent> CDRebuildComponentTable::Query(std::function<boo
|
||||
std::vector<CDRebuildComponent> CDRebuildComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ CDRewardsTable::CDRewardsTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Rewards");
|
||||
while (!tableData.eof()) {
|
||||
CDRewards* entry = new CDRewards();
|
||||
entry->id = tableData.getIntField(0, -1);
|
||||
entry->levelID = tableData.getIntField(1, -1);
|
||||
entry->missionID = tableData.getIntField(2, -1);
|
||||
entry->rewardType = tableData.getIntField(3, -1);
|
||||
entry->value = tableData.getIntField(4, -1);
|
||||
entry->count = tableData.getIntField(5, -1);
|
||||
entry->id = tableData.getIntField("id", -1);
|
||||
entry->levelID = tableData.getIntField("LevelID", -1);
|
||||
entry->missionID = tableData.getIntField("MissionID", -1);
|
||||
entry->rewardType = tableData.getIntField("RewardType", -1);
|
||||
entry->value = tableData.getIntField("value", -1);
|
||||
entry->count = tableData.getIntField("count", -1);
|
||||
|
||||
m_entries.insert(std::make_pair(entry->id, entry));
|
||||
tableData.nextRow();
|
||||
@@ -38,3 +38,4 @@ std::vector<CDRewards*> CDRewardsTable::GetByLevelID(uint32_t levelID) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ CDScriptComponentTable::CDScriptComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ScriptComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDScriptComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.script_name = tableData.getStringField(1, "");
|
||||
entry.client_script_name = tableData.getStringField(2, "");
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.script_name = tableData.getStringField("script_name", "");
|
||||
entry.client_script_name = tableData.getStringField("client_script_name", "");
|
||||
|
||||
this->entries.insert(std::make_pair(entry.id, entry));
|
||||
tableData.nextRow();
|
||||
@@ -45,3 +45,4 @@ const CDScriptComponent& CDScriptComponentTable::GetByID(unsigned int id) {
|
||||
|
||||
return m_ToReturnWhenNoneFound;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,25 +23,25 @@ CDSkillBehaviorTable::CDSkillBehaviorTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM SkillBehavior");
|
||||
while (!tableData.eof()) {
|
||||
CDSkillBehavior entry;
|
||||
entry.skillID = tableData.getIntField(0, -1);
|
||||
UNUSED(entry.locStatus = tableData.getIntField(1, -1));
|
||||
entry.behaviorID = tableData.getIntField(2, -1);
|
||||
entry.imaginationcost = tableData.getIntField(3, -1);
|
||||
entry.cooldowngroup = tableData.getIntField(4, -1);
|
||||
entry.cooldown = tableData.getFloatField(5, -1.0f);
|
||||
UNUSED(entry.isNpcEditor = tableData.getIntField(6, -1) == 1 ? true : false);
|
||||
UNUSED(entry.skillIcon = tableData.getIntField(7, -1));
|
||||
UNUSED(entry.oomSkillID = tableData.getStringField(8, ""));
|
||||
UNUSED(entry.oomBehaviorEffectID = tableData.getIntField(9, -1));
|
||||
UNUSED(entry.castTypeDesc = tableData.getIntField(10, -1));
|
||||
UNUSED(entry.imBonusUI = tableData.getIntField(11, -1));
|
||||
UNUSED(entry.lifeBonusUI = tableData.getIntField(12, -1));
|
||||
UNUSED(entry.armorBonusUI = tableData.getIntField(13, -1));
|
||||
UNUSED(entry.damageUI = tableData.getIntField(14, -1));
|
||||
UNUSED(entry.hideIcon = tableData.getIntField(15, -1) == 1 ? true : false);
|
||||
UNUSED(entry.localize = tableData.getIntField(16, -1) == 1 ? true : false);
|
||||
UNUSED(entry.gate_version = tableData.getStringField(17, ""));
|
||||
UNUSED(entry.cancelType = tableData.getIntField(18, -1));
|
||||
entry.skillID = tableData.getIntField("skillID", -1);
|
||||
UNUSED(entry.locStatus = tableData.getIntField("locStatus", -1));
|
||||
entry.behaviorID = tableData.getIntField("behaviorID", -1);
|
||||
entry.imaginationcost = tableData.getIntField("imaginationcost", -1);
|
||||
entry.cooldowngroup = tableData.getIntField("cooldowngroup", -1);
|
||||
entry.cooldown = tableData.getFloatField("cooldown", -1.0f);
|
||||
UNUSED(entry.isNpcEditor = tableData.getIntField("isNpcEditor", -1) == 1 ? true : false);
|
||||
UNUSED(entry.skillIcon = tableData.getIntField("skillIcon", -1));
|
||||
UNUSED(entry.oomSkillID = tableData.getStringField("oomSkillID", ""));
|
||||
UNUSED(entry.oomBehaviorEffectID = tableData.getIntField("oomBehaviorEffectID", -1));
|
||||
UNUSED(entry.castTypeDesc = tableData.getIntField("castTypeDesc", -1));
|
||||
UNUSED(entry.imBonusUI = tableData.getIntField("imBonusUI", -1));
|
||||
UNUSED(entry.lifeBonusUI = tableData.getIntField("lifeBonusUI", -1));
|
||||
UNUSED(entry.armorBonusUI = tableData.getIntField("armorBonusUI", -1));
|
||||
UNUSED(entry.damageUI = tableData.getIntField("damageUI", -1));
|
||||
UNUSED(entry.hideIcon = tableData.getIntField("hideIcon", -1) == 1 ? true : false);
|
||||
UNUSED(entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false);
|
||||
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
|
||||
UNUSED(entry.cancelType = tableData.getIntField("cancelType", -1));
|
||||
|
||||
this->entries.insert(std::make_pair(entry.skillID, entry));
|
||||
//this->entries.push_back(entry);
|
||||
@@ -82,3 +82,4 @@ const CDSkillBehavior& CDSkillBehaviorTable::GetSkillByID(unsigned int skillID)
|
||||
|
||||
return m_empty;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ CDVendorComponentTable::CDVendorComponentTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM VendorComponent");
|
||||
while (!tableData.eof()) {
|
||||
CDVendorComponent entry;
|
||||
entry.id = tableData.getIntField(0, -1);
|
||||
entry.buyScalar = tableData.getFloatField(1, -1.0f);
|
||||
entry.sellScalar = tableData.getFloatField(2, -1.0f);
|
||||
entry.refreshTimeSeconds = tableData.getFloatField(3, -1.0f);
|
||||
entry.LootMatrixIndex = tableData.getIntField(4, -1);
|
||||
entry.id = tableData.getIntField("id", -1);
|
||||
entry.buyScalar = tableData.getFloatField("buyScalar", -1.0f);
|
||||
entry.sellScalar = tableData.getFloatField("sellScalar", -1.0f);
|
||||
entry.refreshTimeSeconds = tableData.getFloatField("refreshTimeSeconds", -1.0f);
|
||||
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);
|
||||
|
||||
this->entries.push_back(entry);
|
||||
tableData.nextRow();
|
||||
@@ -56,3 +56,4 @@ std::vector<CDVendorComponent> CDVendorComponentTable::Query(std::function<bool(
|
||||
std::vector<CDVendorComponent> CDVendorComponentTable::GetEntries(void) const {
|
||||
return this->entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,33 +18,33 @@ CDZoneTableTable::CDZoneTableTable(void) {
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ZoneTable");
|
||||
while (!tableData.eof()) {
|
||||
CDZoneTable entry;
|
||||
entry.zoneID = tableData.getIntField(0, -1);
|
||||
entry.locStatus = tableData.getIntField(1, -1);
|
||||
entry.zoneName = tableData.getStringField(2, "");
|
||||
entry.scriptID = tableData.getIntField(3, -1);
|
||||
entry.ghostdistance_min = tableData.getFloatField(4, -1.0f);
|
||||
entry.ghostdistance = tableData.getFloatField(5, -1.0f);
|
||||
entry.population_soft_cap = tableData.getIntField(6, -1);
|
||||
entry.population_hard_cap = tableData.getIntField(7, -1);
|
||||
UNUSED(entry.DisplayDescription = tableData.getStringField(8, ""));
|
||||
UNUSED(entry.mapFolder = tableData.getStringField(9, ""));
|
||||
entry.smashableMinDistance = tableData.getFloatField(10, -1.0f);
|
||||
entry.smashableMaxDistance = tableData.getFloatField(11, -1.0f);
|
||||
UNUSED(entry.mixerProgram = tableData.getStringField(12, ""));
|
||||
UNUSED(entry.clientPhysicsFramerate = tableData.getStringField(13, ""));
|
||||
UNUSED(entry.serverPhysicsFramerate = tableData.getStringField(14, ""));
|
||||
entry.zoneControlTemplate = tableData.getIntField(15, -1);
|
||||
entry.widthInChunks = tableData.getIntField(16, -1);
|
||||
entry.heightInChunks = tableData.getIntField(17, -1);
|
||||
entry.petsAllowed = tableData.getIntField(18, -1) == 1 ? true : false;
|
||||
entry.localize = tableData.getIntField(19, -1) == 1 ? true : false;
|
||||
entry.fZoneWeight = tableData.getFloatField(20, -1.0f);
|
||||
UNUSED(entry.thumbnail = tableData.getStringField(21, ""));
|
||||
entry.PlayerLoseCoinsOnDeath = tableData.getIntField(22, -1) == 1 ? true : false;
|
||||
UNUSED(entry.disableSaveLoc = tableData.getIntField(23, -1) == 1 ? true : false);
|
||||
entry.teamRadius = tableData.getFloatField(24, -1.0f);
|
||||
UNUSED(entry.gate_version = tableData.getStringField(25, ""));
|
||||
UNUSED(entry.mountsAllowed = tableData.getIntField(26, -1) == 1 ? true : false);
|
||||
entry.zoneID = tableData.getIntField("zoneID", -1);
|
||||
entry.locStatus = tableData.getIntField("locStatus", -1);
|
||||
entry.zoneName = tableData.getStringField("zoneName", "");
|
||||
entry.scriptID = tableData.getIntField("scriptID", -1);
|
||||
entry.ghostdistance_min = tableData.getFloatField("ghostdistance_min", -1.0f);
|
||||
entry.ghostdistance = tableData.getFloatField("ghostdistance", -1.0f);
|
||||
entry.population_soft_cap = tableData.getIntField("population_soft_cap", -1);
|
||||
entry.population_hard_cap = tableData.getIntField("population_hard_cap", -1);
|
||||
UNUSED(entry.DisplayDescription = tableData.getStringField("DisplayDescription", ""));
|
||||
UNUSED(entry.mapFolder = tableData.getStringField("mapFolder", ""));
|
||||
entry.smashableMinDistance = tableData.getFloatField("smashableMinDistance", -1.0f);
|
||||
entry.smashableMaxDistance = tableData.getFloatField("smashableMaxDistance", -1.0f);
|
||||
UNUSED(entry.mixerProgram = tableData.getStringField("mixerProgram", ""));
|
||||
UNUSED(entry.clientPhysicsFramerate = tableData.getStringField("clientPhysicsFramerate", ""));
|
||||
UNUSED(entry.serverPhysicsFramerate = tableData.getStringField("serverPhysicsFramerate", ""));
|
||||
entry.zoneControlTemplate = tableData.getIntField("zoneControlTemplate", -1);
|
||||
entry.widthInChunks = tableData.getIntField("widthInChunks", -1);
|
||||
entry.heightInChunks = tableData.getIntField("heightInChunks", -1);
|
||||
entry.petsAllowed = tableData.getIntField("petsAllowed", -1) == 1 ? true : false;
|
||||
entry.localize = tableData.getIntField("localize", -1) == 1 ? true : false;
|
||||
entry.fZoneWeight = tableData.getFloatField("fZoneWeight", -1.0f);
|
||||
UNUSED(entry.thumbnail = tableData.getStringField("thumbnail", ""));
|
||||
entry.PlayerLoseCoinsOnDeath = tableData.getIntField("PlayerLoseCoinsOnDeath", -1) == 1 ? true : false;
|
||||
UNUSED(entry.disableSaveLoc = tableData.getIntField("disableSaveLoc", -1) == 1 ? true : false);
|
||||
entry.teamRadius = tableData.getFloatField("teamRadius", -1.0f);
|
||||
UNUSED(entry.gate_version = tableData.getStringField("gate_version", ""));
|
||||
UNUSED(entry.mountsAllowed = tableData.getIntField("mountsAllowed", -1) == 1 ? true : false);
|
||||
|
||||
this->m_Entries.insert(std::make_pair(entry.zoneID, entry));
|
||||
tableData.nextRow();
|
||||
@@ -71,3 +71,4 @@ const CDZoneTable* CDZoneTableTable::Query(unsigned int zoneID) {
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
#include "UserManager.h"
|
||||
#include "dpWorld.h"
|
||||
#include "Player.h"
|
||||
#include "LUTriggers.h"
|
||||
#include "User.h"
|
||||
#include "EntityTimer.h"
|
||||
#include "EntityCallbackTimer.h"
|
||||
#include "Loot.h"
|
||||
|
||||
//Component includes:
|
||||
#include "Component.h"
|
||||
@@ -824,6 +829,22 @@ std::vector<ScriptComponent*> Entity::GetScriptComponents() {
|
||||
return comps;
|
||||
}
|
||||
|
||||
void Entity::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName) {
|
||||
if (notificationName == "HitOrHealResult" || notificationName == "Hit") {
|
||||
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
||||
if (!destroyableComponent) return;
|
||||
destroyableComponent->Subscribe(scriptObjId, scriptToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName) {
|
||||
if (notificationName == "HitOrHealResult" || notificationName == "Hit") {
|
||||
auto* destroyableComponent = GetComponent<DestroyableComponent>();
|
||||
if (!destroyableComponent) return;
|
||||
destroyableComponent->Unsubscribe(scriptObjId);
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::SetProximityRadius(float proxRadius, std::string name) {
|
||||
ProximityMonitorComponent* proxMon = GetComponent<ProximityMonitorComponent>();
|
||||
if (!proxMon) {
|
||||
|
||||
@@ -4,29 +4,39 @@
|
||||
#include <functional>
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "../thirdparty/raknet/Source/Replica.h"
|
||||
#include "../thirdparty/raknet/Source/ReplicaManager.h"
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include "User.h"
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
#include "LDFFormat.h"
|
||||
#include "Loot.h"
|
||||
#include "Zone.h"
|
||||
|
||||
#include "EntityTimer.h"
|
||||
#include "EntityCallbackTimer.h"
|
||||
#include "EntityInfo.h"
|
||||
namespace Loot {
|
||||
class Info;
|
||||
};
|
||||
|
||||
namespace tinyxml2 {
|
||||
class XMLDocument;
|
||||
};
|
||||
namespace LUTriggers {
|
||||
struct Trigger;
|
||||
};
|
||||
|
||||
class Player;
|
||||
class EntityInfo;
|
||||
class User;
|
||||
class Spawner;
|
||||
class ScriptComponent;
|
||||
class dpEntity;
|
||||
class EntityTimer;
|
||||
class Component;
|
||||
class Item;
|
||||
class Character;
|
||||
class EntityCallbackTimer;
|
||||
|
||||
namespace CppScripts {
|
||||
class Script;
|
||||
};
|
||||
|
||||
/**
|
||||
* An entity in the world. Has multiple components.
|
||||
@@ -139,6 +149,9 @@ public:
|
||||
|
||||
std::vector<ScriptComponent*> GetScriptComponents();
|
||||
|
||||
void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName);
|
||||
void Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName);
|
||||
|
||||
void SetProximityRadius(float proxRadius, std::string name);
|
||||
void SetProximityRadius(dpEntity* entity, std::string name);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "MissionComponent.h"
|
||||
#include "Game.h"
|
||||
#include "dLogger.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
|
||||
EntityManager* EntityManager::m_Address = nullptr;
|
||||
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
#define ENTITYMANAGER_H
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include "../thirdparty/raknet/Source/Replica.h"
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
#include "Entity.h"
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
class Entity;
|
||||
class EntityInfo;
|
||||
class Player;
|
||||
class User;
|
||||
|
||||
struct SystemAddress;
|
||||
class User;
|
||||
|
||||
class EntityManager {
|
||||
public:
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#include "dZoneManager.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "Mail.h"
|
||||
#include "User.h"
|
||||
#include "CppScripts.h"
|
||||
#include "Loot.h"
|
||||
|
||||
std::vector<Player*> Player::m_Players = {};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "SkillComponent.h"
|
||||
#include "AssetManager.h"
|
||||
#include "CDClientDatabase.h"
|
||||
#include "dMessageIdentifiers.h"
|
||||
|
||||
UserManager* UserManager::m_Address = nullptr;
|
||||
|
||||
|
||||
@@ -48,9 +48,8 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b
|
||||
|
||||
void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
auto* self = EntityManager::Instance()->GetEntity(context->caster);
|
||||
|
||||
if (self == nullptr) {
|
||||
Game::logger->Log("TacArcBehavior", "Invalid self for (%llu)!", context->originator);
|
||||
Game::logger->Log("AreaOfEffectBehavior", "Invalid self for (%llu)!", context->originator);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -79,7 +78,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream
|
||||
auto* entity = EntityManager::Instance()->GetEntity(validTarget);
|
||||
|
||||
if (entity == nullptr) {
|
||||
Game::logger->Log("TacArcBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);
|
||||
Game::logger->Log("AreaOfEffectBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "EntityManager.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "BehaviorContext.h"
|
||||
|
||||
#include "eBasicAttackSuccessTypes.h"
|
||||
|
||||
void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
if (context->unmanaged) {
|
||||
@@ -31,130 +31,120 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi
|
||||
}
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Number of allocated bits %i", allocatedBits);
|
||||
const auto baseAddress = bitStream->GetReadOffset();
|
||||
|
||||
DoHandleBehavior(context, bitStream, branch);
|
||||
|
||||
bitStream->SetReadOffset(baseAddress + allocatedBits);
|
||||
}
|
||||
|
||||
void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target);
|
||||
if (!targetEntity) {
|
||||
Game::logger->Log("BasicAttackBehavior", "Target targetEntity %llu not found.", branch.target);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
|
||||
if (!destroyableComponent) {
|
||||
Game::logger->Log("BasicAttackBehavior", "No destroyable found on the obj/lot %llu/%i", branch.target, targetEntity->GetLOT());
|
||||
return;
|
||||
}
|
||||
|
||||
bool isBlocked{};
|
||||
bool isImmune{};
|
||||
bool isSuccess{};
|
||||
|
||||
if (!bitStream->Read(isBlocked)) {
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unable to read isBlocked");
|
||||
Game::logger->Log("BasicAttackBehavior", "Unable to read isBlocked");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBlocked) return;
|
||||
if (isBlocked) {
|
||||
destroyableComponent->SetAttacksToBlock(std::min(destroyableComponent->GetAttacksToBlock() - 1, 0U));
|
||||
EntityManager::Instance()->SerializeEntity(targetEntity);
|
||||
this->m_OnFailBlocked->Handle(context, bitStream, branch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bitStream->Read(isImmune)) {
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unable to read isImmune");
|
||||
Game::logger->Log("BasicAttackBehavior", "Unable to read isImmune");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isImmune) return;
|
||||
if (isImmune) {
|
||||
this->m_OnFailImmune->Handle(context, bitStream, branch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bitStream->Read(isSuccess) && isSuccess) { // Success
|
||||
uint32_t unknown{};
|
||||
if (!bitStream->Read(unknown)) {
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unable to read unknown");
|
||||
if (!bitStream->Read(isSuccess)) {
|
||||
Game::logger->Log("BasicAttackBehavior", "failed to read success from bitstream");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSuccess) {
|
||||
uint32_t armorDamageDealt{};
|
||||
if (!bitStream->Read(armorDamageDealt)) {
|
||||
Game::logger->Log("BasicAttackBehavior", "Unable to read armorDamageDealt");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t damageDealt{};
|
||||
if (!bitStream->Read(damageDealt)) {
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unable to read damageDealt");
|
||||
uint32_t healthDamageDealt{};
|
||||
if (!bitStream->Read(healthDamageDealt)) {
|
||||
Game::logger->Log("BasicAttackBehavior", "Unable to read healthDamageDealt");
|
||||
return;
|
||||
}
|
||||
|
||||
// A value that's too large may be a cheating attempt, so we set it to MIN too
|
||||
if (damageDealt > this->m_MaxDamage || damageDealt < this->m_MinDamage) {
|
||||
damageDealt = this->m_MinDamage;
|
||||
uint32_t totalDamageDealt = armorDamageDealt + healthDamageDealt;
|
||||
|
||||
// A value that's too large may be a cheating attempt, so we set it to MIN
|
||||
if (totalDamageDealt > this->m_MaxDamage) {
|
||||
totalDamageDealt = this->m_MinDamage;
|
||||
}
|
||||
|
||||
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
|
||||
bool died{};
|
||||
if (!bitStream->Read(died)) {
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unable to read died");
|
||||
Game::logger->Log("BasicAttackBehavior", "Unable to read died");
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity != nullptr) {
|
||||
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
|
||||
if (destroyableComponent != nullptr) {
|
||||
PlayFx(u"onhit", entity->GetObjectID());
|
||||
destroyableComponent->Damage(damageDealt, context->originator, context->skillID);
|
||||
}
|
||||
}
|
||||
auto previousArmor = destroyableComponent->GetArmor();
|
||||
auto previousHealth = destroyableComponent->GetHealth();
|
||||
PlayFx(u"onhit", targetEntity->GetObjectID());
|
||||
destroyableComponent->Damage(totalDamageDealt, context->originator, context->skillID);
|
||||
}
|
||||
|
||||
uint8_t successState{};
|
||||
if (!bitStream->Read(successState)) {
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unable to read success state");
|
||||
Game::logger->Log("BasicAttackBehavior", "Unable to read success state");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (successState) {
|
||||
case 1:
|
||||
switch (static_cast<eBasicAttackSuccessTypes>(successState)) {
|
||||
case eBasicAttackSuccessTypes::SUCCESS:
|
||||
this->m_OnSuccess->Handle(context, bitStream, branch);
|
||||
break;
|
||||
case eBasicAttackSuccessTypes::FAILARMOR:
|
||||
this->m_OnFailArmor->Handle(context, bitStream, branch);
|
||||
break;
|
||||
default:
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unknown success state (%i)!", successState);
|
||||
if (static_cast<eBasicAttackSuccessTypes>(successState) != eBasicAttackSuccessTypes::FAILIMMUNE) {
|
||||
Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState);
|
||||
return;
|
||||
}
|
||||
this->m_OnFailImmune->Handle(context, bitStream, branch);
|
||||
break;
|
||||
}
|
||||
|
||||
bitStream->SetReadOffset(baseAddress + allocatedBits);
|
||||
}
|
||||
|
||||
void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
auto* self = EntityManager::Instance()->GetEntity(context->originator);
|
||||
if (self == nullptr) {
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Invalid self entity (%llu)!", context->originator);
|
||||
return;
|
||||
}
|
||||
|
||||
bitStream->AlignWriteToByteBoundary();
|
||||
|
||||
const auto allocatedAddress = bitStream->GetWriteOffset();
|
||||
|
||||
bitStream->Write(uint16_t(0));
|
||||
bitStream->Write<uint16_t>(0);
|
||||
|
||||
const auto startAddress = bitStream->GetWriteOffset();
|
||||
|
||||
bitStream->Write0(); // Blocked
|
||||
bitStream->Write0(); // Immune
|
||||
bitStream->Write1(); // Success
|
||||
|
||||
if (true) {
|
||||
uint32_t unknown3 = 0;
|
||||
bitStream->Write(unknown3);
|
||||
|
||||
auto damage = this->m_MinDamage;
|
||||
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
|
||||
|
||||
if (entity == nullptr) {
|
||||
damage = 0;
|
||||
bitStream->Write(damage);
|
||||
bitStream->Write(false);
|
||||
} else {
|
||||
bitStream->Write(damage);
|
||||
bitStream->Write(true);
|
||||
|
||||
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
|
||||
if (damage != 0 && destroyableComponent != nullptr) {
|
||||
PlayFx(u"onhit", entity->GetObjectID(), 1);
|
||||
destroyableComponent->Damage(damage, context->originator, context->skillID, false);
|
||||
context->ScheduleUpdate(branch.target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t successState = 1;
|
||||
bitStream->Write(successState);
|
||||
|
||||
switch (successState) {
|
||||
case 1:
|
||||
this->m_OnSuccess->Calculate(context, bitStream, branch);
|
||||
break;
|
||||
default:
|
||||
Game::logger->LogDebug("BasicAttackBehavior", "Unknown success state (%i)!", successState);
|
||||
break;
|
||||
}
|
||||
DoBehaviorCalculation(context, bitStream, branch);
|
||||
|
||||
const auto endAddress = bitStream->GetWriteOffset();
|
||||
const uint16_t allocate = endAddress - startAddress + 1;
|
||||
@@ -164,6 +154,87 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream*
|
||||
bitStream->SetWriteOffset(startAddress + allocate);
|
||||
}
|
||||
|
||||
void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target);
|
||||
if (!targetEntity) {
|
||||
Game::logger->Log("BasicAttackBehavior", "Target entity %llu is null!", branch.target);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* destroyableComponent = targetEntity->GetComponent<DestroyableComponent>();
|
||||
if (!destroyableComponent || !destroyableComponent->GetParent()) {
|
||||
Game::logger->Log("BasicAttackBehavior", "No destroyable component on %llu", branch.target);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isBlocking = destroyableComponent->GetAttacksToBlock() > 0;
|
||||
|
||||
bitStream->Write(isBlocking);
|
||||
|
||||
if (isBlocking) {
|
||||
destroyableComponent->SetAttacksToBlock(destroyableComponent->GetAttacksToBlock() - 1);
|
||||
EntityManager::Instance()->SerializeEntity(targetEntity);
|
||||
this->m_OnFailBlocked->Calculate(context, bitStream, branch);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isImmune = destroyableComponent->IsImmune();
|
||||
|
||||
bitStream->Write(isImmune);
|
||||
|
||||
if (isImmune) {
|
||||
this->m_OnFailImmune->Calculate(context, bitStream, branch);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isSuccess = false;
|
||||
const uint32_t previousHealth = destroyableComponent->GetHealth();
|
||||
const uint32_t previousArmor = destroyableComponent->GetArmor();
|
||||
|
||||
const auto damage = this->m_MinDamage;
|
||||
|
||||
PlayFx(u"onhit", targetEntity->GetObjectID(), 1);
|
||||
destroyableComponent->Damage(damage, context->originator, context->skillID, false);
|
||||
context->ScheduleUpdate(branch.target);
|
||||
|
||||
const uint32_t armorDamageDealt = previousArmor - destroyableComponent->GetArmor();
|
||||
const uint32_t healthDamageDealt = previousHealth - destroyableComponent->GetHealth();
|
||||
isSuccess = armorDamageDealt > 0 || healthDamageDealt > 0 || (armorDamageDealt + healthDamageDealt) > 0;
|
||||
|
||||
bitStream->Write(isSuccess);
|
||||
|
||||
eBasicAttackSuccessTypes successState = eBasicAttackSuccessTypes::FAILIMMUNE;
|
||||
if (isSuccess) {
|
||||
if (healthDamageDealt >= 1) {
|
||||
successState = eBasicAttackSuccessTypes::SUCCESS;
|
||||
} else if (armorDamageDealt >= 1) {
|
||||
successState = this->m_OnFailArmor->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY ? eBasicAttackSuccessTypes::FAILIMMUNE : eBasicAttackSuccessTypes::FAILARMOR;
|
||||
}
|
||||
|
||||
bitStream->Write(armorDamageDealt);
|
||||
bitStream->Write(healthDamageDealt);
|
||||
bitStream->Write(targetEntity->GetIsDead());
|
||||
}
|
||||
|
||||
bitStream->Write(successState);
|
||||
|
||||
switch (static_cast<eBasicAttackSuccessTypes>(successState)) {
|
||||
case eBasicAttackSuccessTypes::SUCCESS:
|
||||
this->m_OnSuccess->Calculate(context, bitStream, branch);
|
||||
break;
|
||||
case eBasicAttackSuccessTypes::FAILARMOR:
|
||||
this->m_OnFailArmor->Calculate(context, bitStream, branch);
|
||||
break;
|
||||
default:
|
||||
if (static_cast<eBasicAttackSuccessTypes>(successState) != eBasicAttackSuccessTypes::FAILIMMUNE) {
|
||||
Game::logger->Log("BasicAttackBehavior", "Unknown success state (%i)!", successState);
|
||||
break;
|
||||
}
|
||||
this->m_OnFailImmune->Calculate(context, bitStream, branch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BasicAttackBehavior::Load() {
|
||||
this->m_MinDamage = GetInt("min damage");
|
||||
if (this->m_MinDamage == 0) this->m_MinDamage = 1;
|
||||
@@ -171,7 +242,14 @@ void BasicAttackBehavior::Load() {
|
||||
this->m_MaxDamage = GetInt("max damage");
|
||||
if (this->m_MaxDamage == 0) this->m_MaxDamage = 1;
|
||||
|
||||
// The client sets the minimum damage to maximum, so we'll do the same. These are usually the same value anyways.
|
||||
if (this->m_MinDamage < this->m_MaxDamage) this->m_MinDamage = this->m_MaxDamage;
|
||||
|
||||
this->m_OnSuccess = GetAction("on_success");
|
||||
|
||||
this->m_OnFailArmor = GetAction("on_fail_armor");
|
||||
|
||||
this->m_OnFailImmune = GetAction("on_fail_immune");
|
||||
|
||||
this->m_OnFailBlocked = GetAction("on_fail_blocked");
|
||||
}
|
||||
|
||||
@@ -7,10 +7,45 @@ public:
|
||||
explicit BasicAttackBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a 16bit short from the bitStream and when the actual behavior handling finishes with all of its branches, the bitStream
|
||||
* is then offset to after the allocated bits for this stream.
|
||||
*
|
||||
*/
|
||||
void DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch);
|
||||
|
||||
/**
|
||||
* @brief Handles a client initialized Basic Attack Behavior cast to be deserialized and verified on the server.
|
||||
*
|
||||
* @param context The Skill's Behavior context. All behaviors in the same tree share the same context
|
||||
* @param bitStream The bitStream to deserialize. BitStreams will always check their bounds before reading in a behavior
|
||||
* and will fail gracefully if an overread is detected.
|
||||
* @param branch The context of this specific branch of the Skill Behavior. Changes based on which branch you are going down.
|
||||
*/
|
||||
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
|
||||
|
||||
/**
|
||||
* @brief Writes a 16bit short to the bitStream and when the actual behavior calculation finishes with all of its branches, the number
|
||||
* of bits used is then written to where the 16bit short initially was.
|
||||
*
|
||||
*/
|
||||
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
|
||||
|
||||
/**
|
||||
* @brief Calculates a server initialized Basic Attack Behavior cast to be serialized to the client
|
||||
*
|
||||
* @param context The Skill's Behavior context. All behaviors in the same tree share the same context
|
||||
* @param bitStream The bitStream to serialize to.
|
||||
* @param branch The context of this specific branch of the Skill Behavior. Changes based on which branch you are going down.
|
||||
*/
|
||||
void DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch);
|
||||
|
||||
/**
|
||||
* @brief Loads this Behaviors parameters from the database. For this behavior specifically:
|
||||
* max and min damage will always be the same. If min is less than max, they are both set to max.
|
||||
* If an action is not in the database, then no action is taken for that result.
|
||||
*
|
||||
*/
|
||||
void Load() override;
|
||||
private:
|
||||
uint32_t m_MinDamage;
|
||||
@@ -20,4 +55,8 @@ private:
|
||||
Behavior* m_OnSuccess;
|
||||
|
||||
Behavior* m_OnFailArmor;
|
||||
|
||||
Behavior* m_OnFailImmune;
|
||||
|
||||
Behavior* m_OnFailBlocked;
|
||||
};
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "PlayEffectBehavior.h"
|
||||
#include "DamageAbsorptionBehavior.h"
|
||||
#include "VentureVisionBehavior.h"
|
||||
#include "PropertyTeleportBehavior.h"
|
||||
#include "BlockBehavior.h"
|
||||
#include "ClearTargetBehavior.h"
|
||||
#include "PullToPointBehavior.h"
|
||||
@@ -61,6 +62,7 @@
|
||||
#include "DamageReductionBehavior.h"
|
||||
#include "JetPackBehavior.h"
|
||||
#include "ChangeIdleFlagsBehavior.h"
|
||||
#include "DarkInspirationBehavior.h"
|
||||
|
||||
//CDClient includes
|
||||
#include "CDBehaviorParameterTable.h"
|
||||
@@ -169,7 +171,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
|
||||
case BehaviorTemplates::BEHAVIOR_SPEED:
|
||||
behavior = new SpeedBehavior(behaviorId);
|
||||
break;
|
||||
case BehaviorTemplates::BEHAVIOR_DARK_INSPIRATION: break;
|
||||
case BehaviorTemplates::BEHAVIOR_DARK_INSPIRATION:
|
||||
behavior = new DarkInspirationBehavior(behaviorId);
|
||||
break;
|
||||
case BehaviorTemplates::BEHAVIOR_LOOT_BUFF:
|
||||
behavior = new LootBuffBehavior(behaviorId);
|
||||
break;
|
||||
@@ -260,7 +264,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
|
||||
case BehaviorTemplates::BEHAVIOR_DAMAGE_REDUCTION:
|
||||
behavior = new DamageReductionBehavior(behaviorId);
|
||||
break;
|
||||
case BehaviorTemplates::BEHAVIOR_PROPERTY_TELEPORT: break;
|
||||
case BehaviorTemplates::BEHAVIOR_PROPERTY_TELEPORT:
|
||||
behavior = new PropertyTeleportBehavior(behaviorId);
|
||||
break;
|
||||
case BehaviorTemplates::BEHAVIOR_PROPERTY_CLEAR_TARGET:
|
||||
behavior = new ClearTargetBehavior(behaviorId);
|
||||
break;
|
||||
@@ -436,7 +442,7 @@ Behavior::Behavior(const uint32_t behaviorId) {
|
||||
float Behavior::GetFloat(const std::string& name, const float defaultValue) const {
|
||||
// Get the behavior parameter entry and return its value.
|
||||
if (!BehaviorParameterTable) BehaviorParameterTable = CDClientManager::Instance()->GetTable<CDBehaviorParameterTable>("BehaviorParameter");
|
||||
return BehaviorParameterTable->GetEntry(this->m_behaviorId, name, defaultValue).value;
|
||||
return BehaviorParameterTable->GetValue(this->m_behaviorId, name, defaultValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ struct BehaviorBranchContext
|
||||
|
||||
uint32_t start = 0;
|
||||
|
||||
bool isSync = false;
|
||||
|
||||
BehaviorBranchContext();
|
||||
|
||||
BehaviorBranchContext(LWOOBJID target, float duration = 0, const NiPoint3& referencePosition = NiPoint3(0, 0, 0));
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#include "dMessageIdentifiers.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "EchoSyncSkill.h"
|
||||
#include "PhantomPhysicsComponent.h"
|
||||
#include "RebuildComponent.h"
|
||||
|
||||
@@ -51,6 +52,7 @@ void BehaviorContext::RegisterSyncBehavior(const uint32_t syncId, Behavior* beha
|
||||
entry.handle = syncId;
|
||||
entry.behavior = behavior;
|
||||
entry.branchContext = branchContext;
|
||||
entry.branchContext.isSync = true;
|
||||
entry.ignoreInterrupts = ignoreInterrupts;
|
||||
|
||||
this->syncEntries.push_back(entry);
|
||||
@@ -215,7 +217,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
|
||||
}
|
||||
|
||||
// Echo sync
|
||||
GameMessages::EchoSyncSkill echo;
|
||||
EchoSyncSkill echo;
|
||||
|
||||
echo.bDone = true;
|
||||
echo.uiBehaviorHandle = entry.handle;
|
||||
|
||||
@@ -18,6 +18,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp"
|
||||
"ClearTargetBehavior.cpp"
|
||||
"DamageAbsorptionBehavior.cpp"
|
||||
"DamageReductionBehavior.cpp"
|
||||
"DarkInspirationBehavior.cpp"
|
||||
"DurationBehavior.cpp"
|
||||
"EmptyBehavior.cpp"
|
||||
"EndBehavior.cpp"
|
||||
@@ -34,6 +35,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp"
|
||||
"OverTimeBehavior.cpp"
|
||||
"PlayEffectBehavior.cpp"
|
||||
"ProjectileAttackBehavior.cpp"
|
||||
"PropertyTeleportBehavior.cpp"
|
||||
"PullToPointBehavior.cpp"
|
||||
"RemoveBuffBehavior.cpp"
|
||||
"RepairBehavior.cpp"
|
||||
|
||||
52
dGame/dBehaviors/DarkInspirationBehavior.cpp
Normal file
52
dGame/dBehaviors/DarkInspirationBehavior.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "DarkInspirationBehavior.h"
|
||||
|
||||
#include "BehaviorBranchContext.h"
|
||||
#include "Entity.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "BehaviorContext.h"
|
||||
|
||||
void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
|
||||
auto* target = EntityManager::Instance()->GetEntity(branch.target);
|
||||
|
||||
if (target == nullptr) {
|
||||
Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
|
||||
|
||||
if (destroyableComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (destroyableComponent->HasFaction(m_FactionList)) {
|
||||
this->m_ActionIfFactionMatches->Handle(context, bitStream, branch);
|
||||
}
|
||||
}
|
||||
|
||||
void DarkInspirationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
auto* target = EntityManager::Instance()->GetEntity(branch.target);
|
||||
|
||||
if (target == nullptr) {
|
||||
Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
|
||||
|
||||
if (destroyableComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (destroyableComponent->HasFaction(m_FactionList)) {
|
||||
this->m_ActionIfFactionMatches->Calculate(context, bitStream, branch);
|
||||
}
|
||||
}
|
||||
|
||||
void DarkInspirationBehavior::Load() {
|
||||
this->m_ActionIfFactionMatches = GetAction("action");
|
||||
|
||||
this->m_FactionList = GetInt("faction_list");
|
||||
}
|
||||
22
dGame/dBehaviors/DarkInspirationBehavior.h
Normal file
22
dGame/dBehaviors/DarkInspirationBehavior.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "Behavior.h"
|
||||
|
||||
class DarkInspirationBehavior final : public Behavior
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Inherited
|
||||
*/
|
||||
|
||||
explicit DarkInspirationBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
|
||||
}
|
||||
|
||||
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
|
||||
|
||||
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
|
||||
|
||||
void Load() override;
|
||||
private:
|
||||
Behavior* m_ActionIfFactionMatches;
|
||||
uint32_t m_FactionList;
|
||||
};
|
||||
@@ -6,28 +6,47 @@
|
||||
#include "Game.h"
|
||||
#include "dLogger.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "ControllablePhysicsComponent.h"
|
||||
|
||||
void ImmunityBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
|
||||
auto* target = EntityManager::Instance()->GetEntity(branch.target);
|
||||
|
||||
if (target == nullptr) {
|
||||
if (!target) {
|
||||
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE));
|
||||
|
||||
if (destroyable == nullptr) {
|
||||
return;
|
||||
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
|
||||
if (destroyableComponent) {
|
||||
destroyableComponent->SetStatusImmunity(
|
||||
eStateChangeType::PUSH,
|
||||
this->m_ImmuneToBasicAttack,
|
||||
this->m_ImmuneToDamageOverTime,
|
||||
this->m_ImmuneToKnockback,
|
||||
this->m_ImmuneToInterrupt,
|
||||
this->m_ImmuneToSpeed,
|
||||
this->m_ImmuneToImaginationGain,
|
||||
this->m_ImmuneToImaginationLoss,
|
||||
this->m_ImmuneToQuickbuildInterrupt,
|
||||
this->m_ImmuneToPullToPoint
|
||||
);
|
||||
}
|
||||
|
||||
if (!this->m_immuneBasicAttack) {
|
||||
return;
|
||||
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
|
||||
if (controllablePhysicsComponent) {
|
||||
controllablePhysicsComponent->SetStunImmunity(
|
||||
eStateChangeType::PUSH,
|
||||
context->caster,
|
||||
this->m_ImmuneToStunAttack,
|
||||
this->m_ImmuneToStunEquip,
|
||||
this->m_ImmuneToStunInteract,
|
||||
this->m_ImmuneToStunJump,
|
||||
this->m_ImmuneToStunMove,
|
||||
this->m_ImmuneToStunTurn,
|
||||
this->m_ImmuneToStunUseItem
|
||||
);
|
||||
}
|
||||
|
||||
destroyable->PushImmunity();
|
||||
|
||||
context->RegisterTimerBehavior(this, branch, target->GetObjectID());
|
||||
}
|
||||
|
||||
@@ -38,21 +57,60 @@ void ImmunityBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi
|
||||
void ImmunityBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) {
|
||||
auto* target = EntityManager::Instance()->GetEntity(second);
|
||||
|
||||
if (target == nullptr) {
|
||||
if (!target) {
|
||||
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto* destroyable = static_cast<DestroyableComponent*>(target->GetComponent(COMPONENT_TYPE_DESTROYABLE));
|
||||
|
||||
if (destroyable == nullptr) {
|
||||
return;
|
||||
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();
|
||||
if (destroyableComponent) {
|
||||
destroyableComponent->SetStatusImmunity(
|
||||
eStateChangeType::POP,
|
||||
this->m_ImmuneToBasicAttack,
|
||||
this->m_ImmuneToDamageOverTime,
|
||||
this->m_ImmuneToKnockback,
|
||||
this->m_ImmuneToInterrupt,
|
||||
this->m_ImmuneToSpeed,
|
||||
this->m_ImmuneToImaginationGain,
|
||||
this->m_ImmuneToImaginationLoss,
|
||||
this->m_ImmuneToQuickbuildInterrupt,
|
||||
this->m_ImmuneToPullToPoint
|
||||
);
|
||||
}
|
||||
|
||||
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
|
||||
if (controllablePhysicsComponent) {
|
||||
controllablePhysicsComponent->SetStunImmunity(
|
||||
eStateChangeType::POP,
|
||||
context->caster,
|
||||
this->m_ImmuneToStunAttack,
|
||||
this->m_ImmuneToStunEquip,
|
||||
this->m_ImmuneToStunInteract,
|
||||
this->m_ImmuneToStunJump,
|
||||
this->m_ImmuneToStunMove,
|
||||
this->m_ImmuneToStunTurn,
|
||||
this->m_ImmuneToStunUseItem
|
||||
);
|
||||
}
|
||||
|
||||
destroyable->PopImmunity();
|
||||
}
|
||||
|
||||
void ImmunityBehavior::Load() {
|
||||
this->m_immuneBasicAttack = GetBoolean("immune_basic_attack");
|
||||
//Stun
|
||||
this->m_ImmuneToStunAttack = GetBoolean("immune_stun_attack", false);
|
||||
this->m_ImmuneToStunEquip = GetBoolean("immune_stun_equip", false);
|
||||
this->m_ImmuneToStunInteract = GetBoolean("immune_stun_interact", false);
|
||||
this->m_ImmuneToStunMove = GetBoolean("immune_stun_move", false);
|
||||
this->m_ImmuneToStunTurn = GetBoolean("immune_stun_rotate", false);
|
||||
|
||||
// Status
|
||||
this->m_ImmuneToBasicAttack = GetBoolean("immune_basic_attack", false);
|
||||
this->m_ImmuneToDamageOverTime = GetBoolean("immune_damage_over_time", false);
|
||||
this->m_ImmuneToKnockback = GetBoolean("immune_knockback", false);
|
||||
this->m_ImmuneToInterrupt = GetBoolean("immune_interrupt", false);
|
||||
this->m_ImmuneToSpeed = GetBoolean("immune_speed", false);
|
||||
this->m_ImmuneToImaginationGain = GetBoolean("immune_imagination_gain", false);
|
||||
this->m_ImmuneToImaginationLoss = GetBoolean("immune_imagination_loss", false);
|
||||
this->m_ImmuneToQuickbuildInterrupt = GetBoolean("immune_quickbuild_interrupts", false);
|
||||
this->m_ImmuneToPullToPoint = GetBoolean("immune_pulltopoint", false);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
class ImmunityBehavior final : public Behavior
|
||||
{
|
||||
public:
|
||||
uint32_t m_immuneBasicAttack;
|
||||
|
||||
/*
|
||||
* Inherited
|
||||
*/
|
||||
@@ -20,4 +18,25 @@ public:
|
||||
void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
|
||||
|
||||
void Load() override;
|
||||
|
||||
private:
|
||||
// stuns
|
||||
bool m_ImmuneToStunAttack = false;
|
||||
bool m_ImmuneToStunEquip = false;
|
||||
bool m_ImmuneToStunInteract = false;
|
||||
bool m_ImmuneToStunJump = false; // Unused
|
||||
bool m_ImmuneToStunMove = false;
|
||||
bool m_ImmuneToStunTurn = false;
|
||||
bool m_ImmuneToStunUseItem = false; // Unused
|
||||
|
||||
//status
|
||||
bool m_ImmuneToBasicAttack = false;
|
||||
bool m_ImmuneToDamageOverTime = false;
|
||||
bool m_ImmuneToKnockback = false;
|
||||
bool m_ImmuneToInterrupt = false;
|
||||
bool m_ImmuneToSpeed = false;
|
||||
bool m_ImmuneToImaginationGain = false;
|
||||
bool m_ImmuneToImaginationLoss = false;
|
||||
bool m_ImmuneToQuickbuildInterrupt = false;
|
||||
bool m_ImmuneToPullToPoint = false; // Unused in cdclient, but used in client
|
||||
};
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
#include "dLogger.h"
|
||||
|
||||
void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
|
||||
if (this->m_groundAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_jumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_fallingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_doubleJumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_airAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_jetpackAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t movementType{};
|
||||
if (!bitStream->Read(movementType)) {
|
||||
if (this->m_groundAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_jumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_fallingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_doubleJumpAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_airAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_jetpackAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY &&
|
||||
this->m_movingAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) {
|
||||
return;
|
||||
}
|
||||
Game::logger->Log("MovementSwitchBehavior", "Unable to read movementType from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
|
||||
return;
|
||||
};
|
||||
@@ -27,33 +27,40 @@ void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream*
|
||||
this->m_jumpAction->Handle(context, bitStream, branch);
|
||||
break;
|
||||
case 3:
|
||||
this->m_fallingAction->Handle(context, bitStream, branch);
|
||||
this->m_airAction->Handle(context, bitStream, branch);
|
||||
break;
|
||||
case 4:
|
||||
this->m_doubleJumpAction->Handle(context, bitStream, branch);
|
||||
break;
|
||||
case 5:
|
||||
this->m_airAction->Handle(context, bitStream, branch);
|
||||
this->m_fallingAction->Handle(context, bitStream, branch);
|
||||
break;
|
||||
case 6:
|
||||
this->m_jetpackAction->Handle(context, bitStream, branch);
|
||||
break;
|
||||
default:
|
||||
Game::logger->Log("MovementSwitchBehavior", "Invalid movement behavior type (%i)!", movementType);
|
||||
this->m_groundAction->Handle(context, bitStream, branch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MovementSwitchBehavior::Load() {
|
||||
this->m_airAction = GetAction("air_action");
|
||||
|
||||
this->m_doubleJumpAction = GetAction("double_jump_action");
|
||||
|
||||
this->m_fallingAction = GetAction("falling_action");
|
||||
|
||||
this->m_groundAction = GetAction("ground_action");
|
||||
|
||||
this->m_jetpackAction = GetAction("jetpack_action");
|
||||
|
||||
this->m_jumpAction = GetAction("jump_action");
|
||||
Behavior* MovementSwitchBehavior::LoadMovementType(std::string movementType) {
|
||||
float actionValue = GetFloat(movementType, -1.0f);
|
||||
auto loadedBehavior = GetAction(actionValue != -1.0f ? actionValue : 0.0f);
|
||||
if (actionValue == -1.0f && loadedBehavior->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) {
|
||||
loadedBehavior = this->m_groundAction;
|
||||
}
|
||||
return loadedBehavior;
|
||||
}
|
||||
|
||||
void MovementSwitchBehavior::Load() {
|
||||
float groundActionValue = GetFloat("ground_action", -1.0f);
|
||||
this->m_groundAction = GetAction(groundActionValue != -1.0f ? groundActionValue : 0.0f);
|
||||
|
||||
this->m_airAction = LoadMovementType("air_action");
|
||||
this->m_doubleJumpAction = LoadMovementType("double_jump_action");
|
||||
this->m_fallingAction = LoadMovementType("falling_action");
|
||||
this->m_jetpackAction = LoadMovementType("jetpack_action");
|
||||
this->m_jumpAction = LoadMovementType("jump_action");
|
||||
this->m_movingAction = LoadMovementType("moving_action");
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
class MovementSwitchBehavior final : public Behavior
|
||||
{
|
||||
public:
|
||||
private:
|
||||
/*
|
||||
* Members
|
||||
*/
|
||||
@@ -19,6 +19,17 @@ public:
|
||||
|
||||
Behavior* m_jumpAction;
|
||||
|
||||
Behavior* m_movingAction;
|
||||
|
||||
/**
|
||||
* @brief Loads a movement type from the database into a behavior
|
||||
*
|
||||
* @param movementType The movement type to lookup in the database
|
||||
* @param behaviorToLoad The Behavior where the result will be stored
|
||||
*/
|
||||
Behavior* LoadMovementType(std::string movementType);
|
||||
|
||||
public:
|
||||
/*
|
||||
* Inherited
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ProjectileType == 1) {
|
||||
if (m_useMouseposit && !branch.isSync) {
|
||||
NiPoint3 targetPosition = NiPoint3::ZERO;
|
||||
if (!bitStream->Read(targetPosition)) {
|
||||
Game::logger->Log("ProjectileAttackBehavior", "Unable to read targetPosition from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
|
||||
|
||||
61
dGame/dBehaviors/PropertyTeleportBehavior.cpp
Normal file
61
dGame/dBehaviors/PropertyTeleportBehavior.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "PropertyTeleportBehavior.h"
|
||||
|
||||
#include "BehaviorBranchContext.h"
|
||||
#include "BehaviorContext.h"
|
||||
#include "Character.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "WorldPackets.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Game.h"
|
||||
#include "ZoneInstanceManager.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
auto* caster = EntityManager::Instance()->GetEntity(context->caster);
|
||||
if (!caster) return;
|
||||
|
||||
auto* character = caster->GetCharacter();
|
||||
if (!character) return;
|
||||
|
||||
LWOOBJID objId = caster->GetObjectID();
|
||||
|
||||
LWOMAPID targetMapId = m_MapId;
|
||||
LWOCLONEID targetCloneId = character->GetPropertyCloneID();
|
||||
|
||||
if (dZoneManager::Instance()->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) {
|
||||
targetMapId = character->GetLastNonInstanceZoneID();
|
||||
targetCloneId = 0;
|
||||
} else {
|
||||
character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZoneID().GetMapID());
|
||||
}
|
||||
|
||||
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, false, [objId](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
|
||||
|
||||
auto* entity = EntityManager::Instance()->GetEntity(objId);
|
||||
if (!entity) return;
|
||||
|
||||
const auto sysAddr = entity->GetSystemAddress();
|
||||
|
||||
if (zoneClone != 0) ChatPackets::SendSystemMessage(sysAddr, u"Transfering to your property!");
|
||||
else ChatPackets::SendSystemMessage(sysAddr, u"Transfering back to previous world!");
|
||||
|
||||
Game::logger->Log("PropertyTeleportBehavior", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
|
||||
if (entity->GetCharacter()) {
|
||||
entity->GetCharacter()->SetZoneID(zoneID);
|
||||
entity->GetCharacter()->SetZoneInstance(zoneInstance);
|
||||
entity->GetCharacter()->SetZoneClone(zoneClone);
|
||||
entity->GetComponent<CharacterComponent>()->SetLastRocketConfig(u"");
|
||||
}
|
||||
|
||||
entity->GetCharacter()->SaveXMLToDatabase();
|
||||
|
||||
WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift);
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
void PropertyTeleportBehavior::Load() {
|
||||
this->m_CancelIfInteracting = GetBoolean("cancel_if_interacting"); // TODO unused
|
||||
this->m_MapId = LWOMAPID(GetInt("mapID"));
|
||||
}
|
||||
21
dGame/dBehaviors/PropertyTeleportBehavior.h
Normal file
21
dGame/dBehaviors/PropertyTeleportBehavior.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "Behavior.h"
|
||||
|
||||
class PropertyTeleportBehavior final : public Behavior
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Inherited
|
||||
*/
|
||||
|
||||
explicit PropertyTeleportBehavior(const uint32_t behavior_id) : Behavior(behavior_id) {
|
||||
}
|
||||
|
||||
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
|
||||
|
||||
void Load() override;
|
||||
|
||||
private:
|
||||
LWOMAPID m_MapId;
|
||||
bool m_CancelIfInteracting;
|
||||
};
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "dLogger.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "RebuildComponent.h"
|
||||
#include "Entity.h"
|
||||
#include "EntityInfo.h"
|
||||
|
||||
void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
||||
auto* origin = EntityManager::Instance()->GetEntity(context->originator);
|
||||
|
||||
@@ -29,6 +29,14 @@ void SpeedBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt
|
||||
Handle(context, bitStream, branch);
|
||||
}
|
||||
|
||||
void SpeedBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
|
||||
End(context, branch, LWOOBJID_EMPTY);
|
||||
}
|
||||
|
||||
void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
|
||||
End(context, branch, second);
|
||||
}
|
||||
|
||||
void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
|
||||
auto* target = EntityManager::Instance()->GetEntity(branch.target);
|
||||
if (!target) return;
|
||||
@@ -40,10 +48,6 @@ void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch,
|
||||
EntityManager::Instance()->SerializeEntity(target);
|
||||
}
|
||||
|
||||
void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
|
||||
End(context, branch, second);
|
||||
}
|
||||
|
||||
void SpeedBehavior::Load() {
|
||||
m_RunSpeed = GetFloat("run_speed");
|
||||
m_AffectsCaster = GetBoolean("affects_caster");
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
|
||||
void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
|
||||
|
||||
void UnCast(BehaviorContext* context, BehaviorBranchContext branch) override;
|
||||
|
||||
void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
|
||||
|
||||
void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override;
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include "RebuildComponent.h"
|
||||
#include "DestroyableComponent.h"
|
||||
|
||||
BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) : Component(parent) {
|
||||
BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): Component(parent) {
|
||||
m_Target = LWOOBJID_EMPTY;
|
||||
m_State = AiState::spawn;
|
||||
SetAiState(AiState::spawn);
|
||||
m_Timer = 1.0f;
|
||||
m_StartPosition = parent->GetPosition();
|
||||
m_MovementAI = nullptr;
|
||||
@@ -179,7 +179,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) {
|
||||
|
||||
if (m_Disabled || m_Parent->GetIsDead())
|
||||
return;
|
||||
|
||||
bool stunnedThisFrame = m_Stunned;
|
||||
CalculateCombat(deltaTime); // Putting this here for now
|
||||
|
||||
if (m_StartPosition == NiPoint3::ZERO) {
|
||||
@@ -192,7 +192,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Stunned) {
|
||||
if (stunnedThisFrame) {
|
||||
m_MovementAI->Stop();
|
||||
|
||||
return;
|
||||
@@ -206,7 +206,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) {
|
||||
switch (m_State) {
|
||||
case AiState::spawn:
|
||||
Stun(2.0f);
|
||||
m_State = AiState::idle;
|
||||
SetAiState(AiState::idle);
|
||||
break;
|
||||
|
||||
case AiState::idle:
|
||||
@@ -248,13 +248,13 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
|
||||
|
||||
if (m_Disabled) return;
|
||||
|
||||
if (m_StunTime > 0.0f) {
|
||||
if (m_Stunned) {
|
||||
m_StunTime -= deltaTime;
|
||||
|
||||
if (m_StunTime > 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_StunTime = 0.0f;
|
||||
m_Stunned = false;
|
||||
}
|
||||
|
||||
@@ -320,9 +320,9 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
|
||||
m_Timer = 0;
|
||||
}
|
||||
|
||||
m_State = AiState::aggro;
|
||||
SetAiState(AiState::aggro);
|
||||
} else {
|
||||
m_State = AiState::idle;
|
||||
SetAiState(AiState::idle);
|
||||
}
|
||||
|
||||
for (auto i = 0; i < m_SkillEntries.size(); ++i) {
|
||||
@@ -348,7 +348,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
|
||||
}
|
||||
|
||||
if (m_Target == LWOOBJID_EMPTY) {
|
||||
m_State = AiState::idle;
|
||||
SetAiState(AiState::idle);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -375,7 +375,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
|
||||
m_MovementAI->Stop();
|
||||
}
|
||||
|
||||
m_State = AiState::aggro;
|
||||
SetAiState(AiState::aggro);
|
||||
|
||||
m_Timer = 0;
|
||||
|
||||
@@ -532,11 +532,20 @@ bool BaseCombatAIComponent::IsMech() {
|
||||
|
||||
|
||||
void BaseCombatAIComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
|
||||
outBitStream->Write1();
|
||||
outBitStream->Write(uint32_t(m_State));
|
||||
outBitStream->Write(m_Target);
|
||||
outBitStream->Write(m_DirtyStateOrTarget || bIsInitialUpdate);
|
||||
if (m_DirtyStateOrTarget || bIsInitialUpdate) {
|
||||
outBitStream->Write(uint32_t(m_State));
|
||||
outBitStream->Write(m_Target);
|
||||
m_DirtyStateOrTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetAiState(AiState newState) {
|
||||
if (newState == this->m_State) return;
|
||||
this->m_State = newState;
|
||||
m_DirtyStateOrTarget = true;
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
bool BaseCombatAIComponent::IsEnemy(LWOOBJID target) const {
|
||||
auto* entity = EntityManager::Instance()->GetEntity(target);
|
||||
@@ -585,7 +594,10 @@ bool BaseCombatAIComponent::IsEnemy(LWOOBJID target) const {
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetTarget(const LWOOBJID target) {
|
||||
if (this->m_Target == target) return;
|
||||
m_Target = target;
|
||||
m_DirtyStateOrTarget = true;
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
Entity* BaseCombatAIComponent::GetTargetEntity() const {
|
||||
@@ -700,7 +712,7 @@ void BaseCombatAIComponent::OnAggro() {
|
||||
|
||||
m_MovementAI->SetDestination(targetPos);
|
||||
|
||||
m_State = AiState::tether;
|
||||
SetAiState(AiState::tether);
|
||||
}
|
||||
|
||||
m_Timer += 0.5f;
|
||||
@@ -726,7 +738,7 @@ void BaseCombatAIComponent::OnTether() {
|
||||
|
||||
m_MovementAI->SetDestination(m_StartPosition);
|
||||
|
||||
m_State = AiState::aggro;
|
||||
SetAiState(AiState::aggro);
|
||||
} else {
|
||||
if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return;
|
||||
|
||||
|
||||
@@ -243,6 +243,12 @@ private:
|
||||
*/
|
||||
std::vector<LWOOBJID> GetTargetWithinAggroRange() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the AiState and prepares the entity for serialization next frame.
|
||||
*
|
||||
*/
|
||||
void SetAiState(AiState newState);
|
||||
|
||||
/**
|
||||
* The current state of the AI
|
||||
*/
|
||||
@@ -374,6 +380,12 @@ private:
|
||||
*/
|
||||
bool m_DirtyThreat = false;
|
||||
|
||||
/**
|
||||
* Whether or not the Component has dirty information and should update next frame
|
||||
*
|
||||
*/
|
||||
bool m_DirtyStateOrTarget = false;
|
||||
|
||||
/**
|
||||
* Whether the current entity is a mech enemy, needed as mechs tether radius works differently
|
||||
* @return whether this entity is a mech
|
||||
|
||||
@@ -170,17 +170,10 @@ void BuffComponent::ApplyBuffEffect(int32_t id) {
|
||||
|
||||
destroyable->SetMaxImagination(destroyable->GetMaxImagination() + maxImagination);
|
||||
} else if (parameter.name == "speed") {
|
||||
const auto speed = parameter.value;
|
||||
|
||||
auto* controllablePhysicsComponent = this->GetParent()->GetComponent<ControllablePhysicsComponent>();
|
||||
|
||||
if (controllablePhysicsComponent == nullptr) return;
|
||||
|
||||
const auto current = controllablePhysicsComponent->GetSpeedMultiplier();
|
||||
|
||||
controllablePhysicsComponent->SetSpeedMultiplier(current + ((speed - 500.0f) / 500.0f));
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(this->GetParent());
|
||||
if (!controllablePhysicsComponent) return;
|
||||
const auto speed = parameter.value;
|
||||
controllablePhysicsComponent->AddSpeedboost(speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,17 +206,10 @@ void BuffComponent::RemoveBuffEffect(int32_t id) {
|
||||
|
||||
destroyable->SetMaxImagination(destroyable->GetMaxImagination() - maxImagination);
|
||||
} else if (parameter.name == "speed") {
|
||||
const auto speed = parameter.value;
|
||||
|
||||
auto* controllablePhysicsComponent = this->GetParent()->GetComponent<ControllablePhysicsComponent>();
|
||||
|
||||
if (controllablePhysicsComponent == nullptr) return;
|
||||
|
||||
const auto current = controllablePhysicsComponent->GetSpeedMultiplier();
|
||||
|
||||
controllablePhysicsComponent->SetSpeedMultiplier(current - ((speed - 500.0f) / 500.0f));
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(this->GetParent());
|
||||
if (!controllablePhysicsComponent) return;
|
||||
const auto speed = parameter.value;
|
||||
controllablePhysicsComponent->RemoveSpeedboost(speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "VehiclePhysicsComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Item.h"
|
||||
#include "AMFFormat.h"
|
||||
|
||||
CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) {
|
||||
m_Character = character;
|
||||
|
||||
@@ -31,10 +31,25 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Com
|
||||
m_GravityScale = 1;
|
||||
m_DirtyCheats = false;
|
||||
m_IgnoreMultipliers = false;
|
||||
|
||||
m_DirtyEquippedItemInfo = true;
|
||||
m_PickupRadius = 0.0f;
|
||||
m_DirtyPickupRadiusScale = true;
|
||||
|
||||
m_DirtyBubble = false;
|
||||
m_IsInBubble = false;
|
||||
m_SpecialAnims = false;
|
||||
m_BubbleType = eBubbleType::DEFAULT;
|
||||
|
||||
m_IsTeleporting = false;
|
||||
|
||||
m_ImmuneToStunAttackCount = 0;
|
||||
m_ImmuneToStunEquipCount = 0;
|
||||
m_ImmuneToStunInteractCount = 0;
|
||||
m_ImmuneToStunJumpCount = 0;
|
||||
m_ImmuneToStunMoveCount = 0;
|
||||
m_ImmuneToStunTurnCount = 0;
|
||||
m_ImmuneToStunUseItemCount = 0;
|
||||
|
||||
if (entity->GetLOT() != 1) // Other physics entities we care about will be added by BaseCombatAI
|
||||
return;
|
||||
|
||||
@@ -71,7 +86,14 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bo
|
||||
outBitStream->Write(m_JetpackBypassChecks);
|
||||
}
|
||||
|
||||
outBitStream->Write0(); //This contains info about immunities, but for now I'm leaving it out.
|
||||
outBitStream->Write1(); // always write these on construction
|
||||
outBitStream->Write(m_ImmuneToStunMoveCount);
|
||||
outBitStream->Write(m_ImmuneToStunJumpCount);
|
||||
outBitStream->Write(m_ImmuneToStunTurnCount);
|
||||
outBitStream->Write(m_ImmuneToStunAttackCount);
|
||||
outBitStream->Write(m_ImmuneToStunUseItemCount);
|
||||
outBitStream->Write(m_ImmuneToStunEquipCount);
|
||||
outBitStream->Write(m_ImmuneToStunInteractCount);
|
||||
}
|
||||
|
||||
if (m_IgnoreMultipliers) m_DirtyCheats = false;
|
||||
@@ -84,14 +106,22 @@ void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bo
|
||||
m_DirtyCheats = false;
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyPickupRadiusScale);
|
||||
if (m_DirtyPickupRadiusScale) {
|
||||
outBitStream->Write(m_DirtyEquippedItemInfo);
|
||||
if (m_DirtyEquippedItemInfo) {
|
||||
outBitStream->Write(m_PickupRadius);
|
||||
outBitStream->Write0(); //No clue what this is so im leaving it false.
|
||||
m_DirtyPickupRadiusScale = false;
|
||||
outBitStream->Write(m_InJetpackMode);
|
||||
m_DirtyEquippedItemInfo = false;
|
||||
}
|
||||
|
||||
outBitStream->Write0();
|
||||
outBitStream->Write(m_DirtyBubble);
|
||||
if (m_DirtyBubble) {
|
||||
outBitStream->Write(m_IsInBubble);
|
||||
if (m_IsInBubble) {
|
||||
outBitStream->Write(m_BubbleType);
|
||||
outBitStream->Write(m_SpecialAnims);
|
||||
}
|
||||
m_DirtyBubble = false;
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyPosition || bIsInitialUpdate);
|
||||
if (m_DirtyPosition || bIsInitialUpdate) {
|
||||
@@ -248,7 +278,7 @@ void ControllablePhysicsComponent::AddPickupRadiusScale(float value) {
|
||||
m_ActivePickupRadiusScales.push_back(value);
|
||||
if (value > m_PickupRadius) {
|
||||
m_PickupRadius = value;
|
||||
m_DirtyPickupRadiusScale = true;
|
||||
m_DirtyEquippedItemInfo = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +294,7 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) {
|
||||
|
||||
// Recalculate pickup radius since we removed one by now
|
||||
m_PickupRadius = 0.0f;
|
||||
m_DirtyPickupRadiusScale = true;
|
||||
m_DirtyEquippedItemInfo = true;
|
||||
for (uint32_t i = 0; i < m_ActivePickupRadiusScales.size(); i++) {
|
||||
auto candidateRadius = m_ActivePickupRadiusScales[i];
|
||||
if (m_PickupRadius < candidateRadius) m_PickupRadius = candidateRadius;
|
||||
@@ -298,3 +328,62 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) {
|
||||
SetSpeedMultiplier(m_SpeedBoost / 500.0f); // 500 being the base speed
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bool specialAnims){
|
||||
if (m_IsInBubble) {
|
||||
Game::logger->Log("ControllablePhysicsComponent", "Already in bubble");
|
||||
return;
|
||||
}
|
||||
m_BubbleType = bubbleType;
|
||||
m_IsInBubble = true;
|
||||
m_DirtyBubble = true;
|
||||
m_SpecialAnims = specialAnims;
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::DeactivateBubbleBuff(){
|
||||
m_DirtyBubble = true;
|
||||
m_IsInBubble = false;
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
};
|
||||
|
||||
void ControllablePhysicsComponent::SetStunImmunity(
|
||||
const eStateChangeType state,
|
||||
const LWOOBJID originator,
|
||||
const bool bImmuneToStunAttack,
|
||||
const bool bImmuneToStunEquip,
|
||||
const bool bImmuneToStunInteract,
|
||||
const bool bImmuneToStunJump,
|
||||
const bool bImmuneToStunMove,
|
||||
const bool bImmuneToStunTurn,
|
||||
const bool bImmuneToStunUseItem){
|
||||
|
||||
if (state == eStateChangeType::POP){
|
||||
if (bImmuneToStunAttack && m_ImmuneToStunAttackCount > 0) m_ImmuneToStunAttackCount -= 1;
|
||||
if (bImmuneToStunEquip && m_ImmuneToStunEquipCount > 0) m_ImmuneToStunEquipCount -= 1;
|
||||
if (bImmuneToStunInteract && m_ImmuneToStunInteractCount > 0) m_ImmuneToStunInteractCount -= 1;
|
||||
if (bImmuneToStunJump && m_ImmuneToStunJumpCount > 0) m_ImmuneToStunJumpCount -= 1;
|
||||
if (bImmuneToStunMove && m_ImmuneToStunMoveCount > 0) m_ImmuneToStunMoveCount -= 1;
|
||||
if (bImmuneToStunTurn && m_ImmuneToStunTurnCount > 0) m_ImmuneToStunTurnCount -= 1;
|
||||
if (bImmuneToStunUseItem && m_ImmuneToStunUseItemCount > 0) m_ImmuneToStunUseItemCount -= 1;
|
||||
} else if (state == eStateChangeType::PUSH) {
|
||||
if (bImmuneToStunAttack) m_ImmuneToStunAttackCount += 1;
|
||||
if (bImmuneToStunEquip) m_ImmuneToStunEquipCount += 1;
|
||||
if (bImmuneToStunInteract) m_ImmuneToStunInteractCount += 1;
|
||||
if (bImmuneToStunJump) m_ImmuneToStunJumpCount += 1;
|
||||
if (bImmuneToStunMove) m_ImmuneToStunMoveCount += 1;
|
||||
if (bImmuneToStunTurn) m_ImmuneToStunTurnCount += 1;
|
||||
if (bImmuneToStunUseItem) m_ImmuneToStunUseItemCount += 1;
|
||||
}
|
||||
|
||||
GameMessages::SendSetStunImmunity(
|
||||
m_Parent->GetObjectID(), state, m_Parent->GetSystemAddress(), originator,
|
||||
bImmuneToStunAttack,
|
||||
bImmuneToStunEquip,
|
||||
bImmuneToStunInteract,
|
||||
bImmuneToStunJump,
|
||||
bImmuneToStunMove,
|
||||
bImmuneToStunTurn,
|
||||
bImmuneToStunUseItem
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Component.h"
|
||||
#include "dpCollisionChecks.h"
|
||||
#include "PhantomPhysicsComponent.h"
|
||||
#include "eBubbleType.h"
|
||||
|
||||
class Entity;
|
||||
class dpEntity;
|
||||
@@ -257,13 +258,63 @@ public:
|
||||
*/
|
||||
std::vector<float> GetActivePickupRadiusScales() { return m_ActivePickupRadiusScales; };
|
||||
|
||||
|
||||
/**
|
||||
* Add a Speed boost to the entity
|
||||
* This will recalculate the speed boost based on what is being added
|
||||
*/
|
||||
void AddSpeedboost(float value);
|
||||
|
||||
/**
|
||||
* Remove speed boost from entity
|
||||
* This will recalculate the speed boost based on what is the last one in te vector
|
||||
*/
|
||||
void RemoveSpeedboost(float value);
|
||||
|
||||
/**
|
||||
* The speed boosts of this component.
|
||||
* @return All active Speed boosts for this component.
|
||||
*/
|
||||
std::vector<float> GetActiveSpeedboosts() { return m_ActivePickupRadiusScales; };
|
||||
|
||||
/**
|
||||
* Activates the Bubble Buff
|
||||
*/
|
||||
void ActivateBubbleBuff(eBubbleType bubbleType = eBubbleType::DEFAULT, bool specialAnims = true);
|
||||
|
||||
/**
|
||||
* Deactivates the Bubble Buff
|
||||
*/
|
||||
void DeactivateBubbleBuff();
|
||||
|
||||
/**
|
||||
* Gets if the Entity is in a bubble
|
||||
*/
|
||||
bool GetIsInBubble(){ return m_IsInBubble; };
|
||||
|
||||
/**
|
||||
* Push or Pop a layer of stun immunity to this entity
|
||||
*/
|
||||
void SetStunImmunity(
|
||||
const eStateChangeType state,
|
||||
const LWOOBJID originator = LWOOBJID_EMPTY,
|
||||
const bool bImmuneToStunAttack = false,
|
||||
const bool bImmuneToStunEquip = false,
|
||||
const bool bImmuneToStunInteract = false,
|
||||
const bool bImmuneToStunJump = false,
|
||||
const bool bImmuneToStunMove = false,
|
||||
const bool bImmuneToStunTurn = false,
|
||||
const bool bImmuneToStunUseItem = false
|
||||
);
|
||||
|
||||
// getters for stun immunities
|
||||
const bool GetImmuneToStunAttack() { return m_ImmuneToStunAttackCount > 0;};
|
||||
const bool GetImmuneToStunEquip() { return m_ImmuneToStunEquipCount > 0;};
|
||||
const bool GetImmuneToStunInteract() { return m_ImmuneToStunInteractCount > 0;};
|
||||
const bool GetImmuneToStunJump() { return m_ImmuneToStunJumpCount > 0;};
|
||||
const bool GetImmuneToStunMove() { return m_ImmuneToStunMoveCount > 0;};
|
||||
const bool GetImmuneToStunTurn() { return m_ImmuneToStunTurnCount > 0;};
|
||||
const bool GetImmuneToStunUseItem() { return m_ImmuneToStunUseItemCount > 0;};
|
||||
|
||||
private:
|
||||
/**
|
||||
* The entity that owns this component
|
||||
@@ -363,7 +414,7 @@ private:
|
||||
/**
|
||||
* Whether the pickup scale is dirty.
|
||||
*/
|
||||
bool m_DirtyPickupRadiusScale;
|
||||
bool m_DirtyEquippedItemInfo;
|
||||
|
||||
/**
|
||||
* The list of pickup radius scales for this entity
|
||||
@@ -389,6 +440,37 @@ private:
|
||||
* The active speed boost for this entity
|
||||
*/
|
||||
float m_SpeedBoost;
|
||||
|
||||
/*
|
||||
* If Bubble info is dirty
|
||||
*/
|
||||
bool m_DirtyBubble;
|
||||
|
||||
/*
|
||||
* If the entity is in a bubble
|
||||
*/
|
||||
bool m_IsInBubble;
|
||||
|
||||
/*
|
||||
* The type of bubble the entity has
|
||||
*/
|
||||
eBubbleType m_BubbleType;
|
||||
|
||||
/*
|
||||
* If the entity should be using the special animations
|
||||
*/
|
||||
bool m_SpecialAnims;
|
||||
|
||||
/**
|
||||
* stun immunity counters
|
||||
*/
|
||||
int32_t m_ImmuneToStunAttackCount;
|
||||
int32_t m_ImmuneToStunEquipCount;
|
||||
int32_t m_ImmuneToStunInteractCount;
|
||||
int32_t m_ImmuneToStunJumpCount;
|
||||
int32_t m_ImmuneToStunMoveCount;
|
||||
int32_t m_ImmuneToStunTurnCount;
|
||||
int32_t m_ImmuneToStunUseItemCount;
|
||||
};
|
||||
|
||||
#endif // CONTROLLABLEPHYSICSCOMPONENT_H
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "PossessorComponent.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "WorldConfig.h"
|
||||
|
||||
DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
|
||||
m_iArmor = 0;
|
||||
@@ -54,8 +55,17 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
|
||||
m_LootMatrixID = 0;
|
||||
m_MinCoins = 0;
|
||||
m_MaxCoins = 0;
|
||||
m_ImmuneStacks = 0;
|
||||
m_DamageReduction = 0;
|
||||
|
||||
m_ImmuneToBasicAttackCount = 0;
|
||||
m_ImmuneToDamageOverTimeCount = 0;
|
||||
m_ImmuneToKnockbackCount = 0;
|
||||
m_ImmuneToInterruptCount = 0;
|
||||
m_ImmuneToSpeedCount = 0;
|
||||
m_ImmuneToImaginationGainCount = 0;
|
||||
m_ImmuneToImaginationLossCount = 0;
|
||||
m_ImmuneToQuickbuildInterruptCount = 0;
|
||||
m_ImmuneToPullToPointCount = 0;
|
||||
}
|
||||
|
||||
DestroyableComponent::~DestroyableComponent() {
|
||||
@@ -105,7 +115,16 @@ void DestroyableComponent::Reinitialize(LOT templateID) {
|
||||
|
||||
void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags) {
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write0(); //Contains info about immunities this object has, but it's left out for now.
|
||||
outBitStream->Write1(); // always write these on construction
|
||||
outBitStream->Write(m_ImmuneToBasicAttackCount);
|
||||
outBitStream->Write(m_ImmuneToDamageOverTimeCount);
|
||||
outBitStream->Write(m_ImmuneToKnockbackCount);
|
||||
outBitStream->Write(m_ImmuneToInterruptCount);
|
||||
outBitStream->Write(m_ImmuneToSpeedCount);
|
||||
outBitStream->Write(m_ImmuneToImaginationGainCount);
|
||||
outBitStream->Write(m_ImmuneToImaginationLossCount);
|
||||
outBitStream->Write(m_ImmuneToQuickbuildInterruptCount);
|
||||
outBitStream->Write(m_ImmuneToPullToPointCount);
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyHealth || bIsInitialUpdate);
|
||||
@@ -335,7 +354,7 @@ void DestroyableComponent::SetDamageReduction(int32_t value) {
|
||||
|
||||
void DestroyableComponent::SetIsImmune(bool value) {
|
||||
m_DirtyHealth = true;
|
||||
m_ImmuneStacks = value ? 1 : 0;
|
||||
m_ImmuneToBasicAttackCount = value ? 1 : 0;
|
||||
}
|
||||
|
||||
void DestroyableComponent::SetIsGMImmune(bool value) {
|
||||
@@ -438,7 +457,7 @@ void DestroyableComponent::SetAttacksToBlock(const uint32_t value) {
|
||||
}
|
||||
|
||||
bool DestroyableComponent::IsImmune() const {
|
||||
return m_ImmuneStacks > 0 || m_IsGMImmune;
|
||||
return m_IsGMImmune || m_ImmuneToBasicAttackCount > 0;
|
||||
}
|
||||
|
||||
bool DestroyableComponent::IsKnockbackImmune() const {
|
||||
@@ -631,6 +650,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
auto* attacker = EntityManager::Instance()->GetEntity(source);
|
||||
m_Parent->OnHit(attacker);
|
||||
m_Parent->OnHitOrHealResult(attacker, sourceDamage);
|
||||
NotifySubscribers(attacker, sourceDamage);
|
||||
|
||||
for (const auto& cb : m_OnHitCallbacks) {
|
||||
cb(attacker);
|
||||
@@ -648,6 +668,29 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
Smash(source, eKillType::VIOLENT, u"", skillID);
|
||||
}
|
||||
|
||||
void DestroyableComponent::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd) {
|
||||
m_SubscribedScripts.insert(std::make_pair(scriptObjId, scriptToAdd));
|
||||
Game::logger->LogDebug("DestroyableComponent", "Added script %llu to entity %llu", scriptObjId, m_Parent->GetObjectID());
|
||||
Game::logger->LogDebug("DestroyableComponent", "Number of subscribed scripts %i", m_SubscribedScripts.size());
|
||||
}
|
||||
|
||||
void DestroyableComponent::Unsubscribe(LWOOBJID scriptObjId) {
|
||||
auto foundScript = m_SubscribedScripts.find(scriptObjId);
|
||||
if (foundScript != m_SubscribedScripts.end()) {
|
||||
m_SubscribedScripts.erase(foundScript);
|
||||
Game::logger->LogDebug("DestroyableComponent", "Removed script %llu from entity %llu", scriptObjId, m_Parent->GetObjectID());
|
||||
} else {
|
||||
Game::logger->LogDebug("DestroyableComponent", "Tried to remove a script for Entity %llu but script %llu didnt exist", m_Parent->GetObjectID(), scriptObjId);
|
||||
}
|
||||
Game::logger->LogDebug("DestroyableComponent", "Number of subscribed scripts %i", m_SubscribedScripts.size());
|
||||
}
|
||||
|
||||
void DestroyableComponent::NotifySubscribers(Entity* attacker, uint32_t damage) {
|
||||
for (auto script : m_SubscribedScripts) {
|
||||
script.second->NotifyHitOrHealResult(m_Parent, attacker, damage);
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType, uint32_t skillID) {
|
||||
if (m_iHealth > 0) {
|
||||
SetArmor(0);
|
||||
@@ -670,13 +713,13 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
auto* inventoryComponent = owner->GetComponent<InventoryComponent>();
|
||||
|
||||
if (inventoryComponent != nullptr && isEnemy) {
|
||||
inventoryComponent->TriggerPassiveAbility(PassiveAbilityTrigger::EnemySmashed);
|
||||
inventoryComponent->TriggerPassiveAbility(PassiveAbilityTrigger::EnemySmashed, m_Parent);
|
||||
}
|
||||
|
||||
auto* missions = owner->GetComponent<MissionComponent>();
|
||||
|
||||
if (missions != nullptr) {
|
||||
if (team != nullptr && isEnemy) {
|
||||
if (team != nullptr) {
|
||||
for (const auto memberId : team->members) {
|
||||
auto* member = EntityManager::Instance()->GetEntity(memberId);
|
||||
|
||||
@@ -739,22 +782,17 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
if (dZoneManager::Instance()->GetPlayerLoseCoinOnDeath()) {
|
||||
auto* character = m_Parent->GetCharacter();
|
||||
uint64_t coinsTotal = character->GetCoins();
|
||||
const uint64_t minCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMin;
|
||||
if (coinsTotal >= minCoinsToLose) {
|
||||
const uint64_t maxCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMax;
|
||||
const float coinPercentageToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathPercent;
|
||||
|
||||
if (coinsTotal > 0) {
|
||||
uint64_t coinsToLoose = 1;
|
||||
uint64_t coinsToLose = std::max(static_cast<uint64_t>(coinsTotal * coinPercentageToLose), minCoinsToLose);
|
||||
coinsToLose = std::min(maxCoinsToLose, coinsToLose);
|
||||
|
||||
if (coinsTotal >= 200) {
|
||||
float hundreth = (coinsTotal / 100.0f);
|
||||
coinsToLoose = static_cast<int>(hundreth);
|
||||
}
|
||||
coinsTotal -= coinsToLose;
|
||||
|
||||
if (coinsToLoose > 10000) {
|
||||
coinsToLoose = 10000;
|
||||
}
|
||||
|
||||
coinsTotal -= coinsToLoose;
|
||||
|
||||
LootGenerator::Instance().DropLoot(m_Parent, m_Parent, -1, coinsToLoose, coinsToLoose);
|
||||
LootGenerator::Instance().DropLoot(m_Parent, m_Parent, -1, coinsToLose, coinsToLose);
|
||||
character->SetCoins(coinsTotal, eLootSourceType::LOOT_SOURCE_PICKUP);
|
||||
}
|
||||
}
|
||||
@@ -784,12 +822,53 @@ void DestroyableComponent::SetFaction(int32_t factionID, bool ignoreChecks) {
|
||||
AddFaction(factionID, ignoreChecks);
|
||||
}
|
||||
|
||||
void DestroyableComponent::PushImmunity(int32_t stacks) {
|
||||
m_ImmuneStacks += stacks;
|
||||
}
|
||||
void DestroyableComponent::SetStatusImmunity(
|
||||
const eStateChangeType state,
|
||||
const bool bImmuneToBasicAttack,
|
||||
const bool bImmuneToDamageOverTime,
|
||||
const bool bImmuneToKnockback,
|
||||
const bool bImmuneToInterrupt,
|
||||
const bool bImmuneToSpeed,
|
||||
const bool bImmuneToImaginationGain,
|
||||
const bool bImmuneToImaginationLoss,
|
||||
const bool bImmuneToQuickbuildInterrupt,
|
||||
const bool bImmuneToPullToPoint) {
|
||||
|
||||
void DestroyableComponent::PopImmunity(int32_t stacks) {
|
||||
m_ImmuneStacks -= stacks;
|
||||
if (state == eStateChangeType::POP) {
|
||||
if (bImmuneToBasicAttack && m_ImmuneToBasicAttackCount > 0) m_ImmuneToBasicAttackCount -= 1;
|
||||
if (bImmuneToDamageOverTime && m_ImmuneToDamageOverTimeCount > 0) m_ImmuneToDamageOverTimeCount -= 1;
|
||||
if (bImmuneToKnockback && m_ImmuneToKnockbackCount > 0) m_ImmuneToKnockbackCount -= 1;
|
||||
if (bImmuneToInterrupt && m_ImmuneToInterruptCount > 0) m_ImmuneToInterruptCount -= 1;
|
||||
if (bImmuneToSpeed && m_ImmuneToSpeedCount > 0) m_ImmuneToSpeedCount -= 1;
|
||||
if (bImmuneToImaginationGain && m_ImmuneToImaginationGainCount > 0) m_ImmuneToImaginationGainCount -= 1;
|
||||
if (bImmuneToImaginationLoss && m_ImmuneToImaginationLossCount > 0) m_ImmuneToImaginationLossCount -= 1;
|
||||
if (bImmuneToQuickbuildInterrupt && m_ImmuneToQuickbuildInterruptCount > 0) m_ImmuneToQuickbuildInterruptCount -= 1;
|
||||
if (bImmuneToPullToPoint && m_ImmuneToPullToPointCount > 0) m_ImmuneToPullToPointCount -= 1;
|
||||
|
||||
} else if (state == eStateChangeType::PUSH){
|
||||
if (bImmuneToBasicAttack) m_ImmuneToBasicAttackCount += 1;
|
||||
if (bImmuneToDamageOverTime) m_ImmuneToDamageOverTimeCount += 1;
|
||||
if (bImmuneToKnockback) m_ImmuneToKnockbackCount += 1;
|
||||
if (bImmuneToInterrupt) m_ImmuneToInterruptCount += 1;
|
||||
if (bImmuneToSpeed) m_ImmuneToSpeedCount += 1;
|
||||
if (bImmuneToImaginationGain) m_ImmuneToImaginationGainCount += 1;
|
||||
if (bImmuneToImaginationLoss) m_ImmuneToImaginationLossCount += 1;
|
||||
if (bImmuneToQuickbuildInterrupt) m_ImmuneToQuickbuildInterruptCount += 1;
|
||||
if (bImmuneToPullToPoint) m_ImmuneToPullToPointCount += 1;
|
||||
}
|
||||
|
||||
GameMessages::SendSetStatusImmunity(
|
||||
m_Parent->GetObjectID(), state, m_Parent->GetSystemAddress(),
|
||||
bImmuneToBasicAttack,
|
||||
bImmuneToDamageOverTime,
|
||||
bImmuneToKnockback,
|
||||
bImmuneToInterrupt,
|
||||
bImmuneToSpeed,
|
||||
bImmuneToImaginationGain,
|
||||
bImmuneToImaginationLoss,
|
||||
bImmuneToQuickbuildInterrupt,
|
||||
bImmuneToPullToPoint
|
||||
);
|
||||
}
|
||||
|
||||
void DestroyableComponent::FixStats() {
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include "Entity.h"
|
||||
#include "Component.h"
|
||||
|
||||
namespace CppScripts {
|
||||
class Script;
|
||||
}; //! namespace CppScripts
|
||||
|
||||
/**
|
||||
* Represents the stats of an entity, for example its health, imagination and armor. Also handles factions, which
|
||||
* indicate which enemies this entity has.
|
||||
@@ -392,16 +396,31 @@ public:
|
||||
void Smash(LWOOBJID source, eKillType killType = eKillType::VIOLENT, const std::u16string& deathType = u"", uint32_t skillID = 0);
|
||||
|
||||
/**
|
||||
* Pushes a layer of immunity to this entity, making it immune for longer
|
||||
* @param stacks the amount of immunity to add
|
||||
* Push or Pop a layer of status immunity to this entity
|
||||
*/
|
||||
void PushImmunity(int32_t stacks = 1);
|
||||
void SetStatusImmunity(
|
||||
const eStateChangeType state,
|
||||
const bool bImmuneToBasicAttack = false,
|
||||
const bool bImmuneToDamageOverTime = false,
|
||||
const bool bImmuneToKnockback = false,
|
||||
const bool bImmuneToInterrupt = false,
|
||||
const bool bImmuneToSpeed = false,
|
||||
const bool bImmuneToImaginationGain = false,
|
||||
const bool bImmuneToImaginationLoss = false,
|
||||
const bool bImmuneToQuickbuildInterrupt = false,
|
||||
const bool bImmuneToPullToPoint = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Pops layers of immunity, making it immune for less longer
|
||||
* @param stacks the number of layers of immunity to remove
|
||||
*/
|
||||
void PopImmunity(int32_t stacks = 1);
|
||||
// Getters for status immunities
|
||||
const bool GetImmuneToBasicAttack() {return m_ImmuneToBasicAttackCount > 0;};
|
||||
const bool GetImmuneToDamageOverTime() {return m_ImmuneToDamageOverTimeCount > 0;};
|
||||
const bool GetImmuneToKnockback() {return m_ImmuneToKnockbackCount > 0;};
|
||||
const bool GetImmuneToInterrupt() {return m_ImmuneToInterruptCount > 0;};
|
||||
const bool GetImmuneToSpeed() {return m_ImmuneToSpeedCount > 0;};
|
||||
const bool GetImmuneToImaginationGain() {return m_ImmuneToImaginationGainCount > 0;};
|
||||
const bool GetImmuneToImaginationLoss() {return m_ImmuneToImaginationLossCount > 0;};
|
||||
const bool GetImmuneToQuickbuildInterrupt() {return m_ImmuneToQuickbuildInterruptCount > 0;};
|
||||
const bool GetImmuneToPullToPoint() {return m_ImmuneToPullToPointCount > 0;};
|
||||
|
||||
/**
|
||||
* Utility to reset all stats to the default stats based on items and completed missions
|
||||
@@ -422,6 +441,17 @@ public:
|
||||
*/
|
||||
void AddFactionNoLookup(int32_t faction) { m_FactionIDs.push_back(faction); };
|
||||
|
||||
/**
|
||||
* Notify subscribed scripts of Damage actions.
|
||||
*
|
||||
* @param attacker The attacking Entity
|
||||
* @param damage The amount of damage that was done
|
||||
*/
|
||||
void NotifySubscribers(Entity* attacker, uint32_t damage);
|
||||
|
||||
void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd);
|
||||
void Unsubscribe(LWOOBJID scriptObjId);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Whether or not the health should be serialized
|
||||
@@ -478,11 +508,6 @@ private:
|
||||
*/
|
||||
uint32_t m_AttacksToBlock;
|
||||
|
||||
/**
|
||||
* The layers of immunity this entity has left
|
||||
*/
|
||||
int32_t m_ImmuneStacks;
|
||||
|
||||
/**
|
||||
* The amount of damage that should be reduced from every attack
|
||||
*/
|
||||
@@ -557,6 +582,24 @@ private:
|
||||
* The list of callbacks that will be called when this entity gets hit
|
||||
*/
|
||||
std::vector<std::function<void(Entity*)>> m_OnHitCallbacks;
|
||||
|
||||
/**
|
||||
* The list of scripts subscribed to this components actions
|
||||
*/
|
||||
std::map<LWOOBJID, CppScripts::Script*> m_SubscribedScripts;
|
||||
|
||||
/**
|
||||
* status immunity counters
|
||||
*/
|
||||
uint32_t m_ImmuneToBasicAttackCount;
|
||||
uint32_t m_ImmuneToDamageOverTimeCount;
|
||||
uint32_t m_ImmuneToKnockbackCount;
|
||||
uint32_t m_ImmuneToInterruptCount;
|
||||
uint32_t m_ImmuneToSpeedCount;
|
||||
uint32_t m_ImmuneToImaginationGainCount;
|
||||
uint32_t m_ImmuneToImaginationLossCount;
|
||||
uint32_t m_ImmuneToQuickbuildInterruptCount;
|
||||
uint32_t m_ImmuneToPullToPointCount;
|
||||
};
|
||||
|
||||
#endif // DESTROYABLECOMPONENT_H
|
||||
|
||||
@@ -27,8 +27,9 @@
|
||||
#include "dConfig.h"
|
||||
#include "eItemType.h"
|
||||
#include "eUnequippableActiveType.h"
|
||||
#include "CppScripts.h"
|
||||
|
||||
InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) {
|
||||
InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) {
|
||||
this->m_Dirty = true;
|
||||
this->m_Equipped = {};
|
||||
this->m_Pushed = {};
|
||||
@@ -867,6 +868,8 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) {
|
||||
|
||||
AddItemSkills(item->GetLot());
|
||||
|
||||
EquipScripts(item);
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
@@ -895,6 +898,8 @@ void InventoryComponent::UnEquipItem(Item* item) {
|
||||
|
||||
PurgeProxies(item);
|
||||
|
||||
UnequipScripts(item);
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
|
||||
// Trigger property event
|
||||
@@ -904,6 +909,37 @@ void InventoryComponent::UnEquipItem(Item* item) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InventoryComponent::EquipScripts(Item* equippedItem) {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry");
|
||||
if (!compRegistryTable) return;
|
||||
int32_t scriptComponentID = compRegistryTable->GetByIDAndType(equippedItem->GetLot(), COMPONENT_TYPE_SCRIPT, -1);
|
||||
if (scriptComponentID > -1) {
|
||||
CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent");
|
||||
CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID);
|
||||
auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name);
|
||||
if (!itemScript) {
|
||||
Game::logger->Log("InventoryComponent", "null script?");
|
||||
}
|
||||
itemScript->OnFactionTriggerItemEquipped(m_Parent, equippedItem->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::UnequipScripts(Item* unequippedItem) {
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry");
|
||||
if (!compRegistryTable) return;
|
||||
int32_t scriptComponentID = compRegistryTable->GetByIDAndType(unequippedItem->GetLot(), COMPONENT_TYPE_SCRIPT, -1);
|
||||
if (scriptComponentID > -1) {
|
||||
CDScriptComponentTable* scriptCompTable = CDClientManager::Instance()->GetTable<CDScriptComponentTable>("ScriptComponent");
|
||||
CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID);
|
||||
auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name);
|
||||
if (!itemScript) {
|
||||
Game::logger->Log("InventoryComponent", "null script?");
|
||||
}
|
||||
itemScript->OnFactionTriggerItemUnequipped(m_Parent, unequippedItem->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::HandlePossession(Item* item) {
|
||||
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
|
||||
if (!characterComponent) return;
|
||||
@@ -923,7 +959,7 @@ void InventoryComponent::HandlePossession(Item* item) {
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStunState::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true);
|
||||
GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStateChangeType::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true);
|
||||
|
||||
// Set the mount Item ID so that we know what were handling
|
||||
possessorComponent->SetMountItemID(item->GetId());
|
||||
@@ -1160,9 +1196,9 @@ void InventoryComponent::RemoveItemSkills(const LOT lot) {
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger) {
|
||||
void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger, Entity* target) {
|
||||
for (auto* set : m_Itemsets) {
|
||||
set->TriggerPassiveAbility(trigger);
|
||||
set->TriggerPassiveAbility(trigger, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +283,7 @@ public:
|
||||
* Triggers one of the passive abilities from the equipped item set
|
||||
* @param trigger the trigger to fire
|
||||
*/
|
||||
void TriggerPassiveAbility(PassiveAbilityTrigger trigger);
|
||||
void TriggerPassiveAbility(PassiveAbilityTrigger trigger, Entity* target = nullptr);
|
||||
|
||||
/**
|
||||
* Returns if the entity has any of the passed passive abilities equipped
|
||||
@@ -352,6 +352,20 @@ public:
|
||||
*/
|
||||
static uint32_t FindSkill(LOT lot);
|
||||
|
||||
/**
|
||||
* Call this when you equip an item. This calls OnFactionTriggerItemEquipped for any scripts found on the items.
|
||||
*
|
||||
* @param equippedItem The item script to lookup and call equip on
|
||||
*/
|
||||
void EquipScripts(Item* equippedItem);
|
||||
|
||||
/**
|
||||
* Call this when you unequip an item. This calls OnFactionTriggerItemUnequipped for any scripts found on the items.
|
||||
*
|
||||
* @param unequippedItem The item script to lookup and call unequip on
|
||||
*/
|
||||
void UnequipScripts(Item* unequippedItem);
|
||||
|
||||
~InventoryComponent() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
#include "GameMessages.h"
|
||||
#include "CppScripts.h"
|
||||
#include "SimplePhysicsComponent.h"
|
||||
#include "Zone.h"
|
||||
|
||||
MoverSubComponent::MoverSubComponent(const NiPoint3& startPos) {
|
||||
mPosition = {};
|
||||
|
||||
mState = MovementPlatformState::Stopped;
|
||||
mState = eMovementPlatformState::Stopped;
|
||||
mDesiredWaypointIndex = 0; // -1;
|
||||
mInReverse = false;
|
||||
mShouldStopAtDesiredWaypoint = false;
|
||||
@@ -127,7 +128,7 @@ void MovingPlatformComponent::OnCompleteRebuild() {
|
||||
StartPathing();
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::SetMovementState(MovementPlatformState value) {
|
||||
void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) {
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
|
||||
subComponent->mState = value;
|
||||
@@ -152,7 +153,7 @@ void MovingPlatformComponent::StartPathing() {
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
|
||||
subComponent->mShouldStopAtDesiredWaypoint = true;
|
||||
subComponent->mState = MovementPlatformState::Stationary;
|
||||
subComponent->mState = eMovementPlatformState::Stationary;
|
||||
|
||||
NiPoint3 targetPosition;
|
||||
|
||||
@@ -174,7 +175,7 @@ void MovingPlatformComponent::StartPathing() {
|
||||
}
|
||||
|
||||
m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] {
|
||||
SetMovementState(MovementPlatformState::Moving);
|
||||
SetMovementState(eMovementPlatformState::Moving);
|
||||
});
|
||||
|
||||
const auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5f;
|
||||
@@ -199,7 +200,7 @@ void MovingPlatformComponent::StartPathing() {
|
||||
void MovingPlatformComponent::ContinuePathing() {
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
|
||||
subComponent->mState = MovementPlatformState::Stationary;
|
||||
subComponent->mState = eMovementPlatformState::Stationary;
|
||||
|
||||
subComponent->mCurrentWaypointIndex = subComponent->mNextWaypointIndex;
|
||||
|
||||
@@ -282,7 +283,7 @@ void MovingPlatformComponent::ContinuePathing() {
|
||||
m_Parent->CancelCallbackTimers();
|
||||
|
||||
m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] {
|
||||
SetMovementState(MovementPlatformState::Moving);
|
||||
SetMovementState(eMovementPlatformState::Moving);
|
||||
});
|
||||
|
||||
auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5;
|
||||
@@ -313,7 +314,7 @@ void MovingPlatformComponent::StopPathing() {
|
||||
|
||||
m_PathingStopped = true;
|
||||
|
||||
subComponent->mState = MovementPlatformState::Stopped;
|
||||
subComponent->mState = eMovementPlatformState::Stopped;
|
||||
subComponent->mDesiredWaypointIndex = -1;
|
||||
subComponent->mShouldStopAtDesiredWaypoint = false;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user