mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b3f9f356d | ||
|
|
e42dc2e1d2 | ||
|
|
c611a25385 | ||
|
|
f74efcaa5f | ||
|
|
eb4e7d694c | ||
|
|
ecc0d4b5c0 | ||
|
|
8175ae6187 | ||
|
|
e8f4ffd628 | ||
|
|
0447618f7e | ||
|
|
e71ce001ff | ||
|
|
1575a2af40 | ||
|
|
4b69df646c | ||
|
|
044b9c1420 | ||
|
|
0bbb5b90e7 | ||
|
|
6506ad5b51 | ||
|
|
dcaa0ecdaa | ||
|
|
9b143132be | ||
|
|
231bf8b4ec | ||
|
|
dee58f9a91 | ||
|
|
1eb89edbbd | ||
|
|
e015d0d67e | ||
|
|
ba78394ce9 | ||
|
|
060f6e377d | ||
|
|
92c8b0e585 | ||
|
|
33df8ea665 | ||
|
|
9668074d94 | ||
|
|
822a5dcac4 | ||
|
|
0c65a4febe | ||
|
|
02f66de679 | ||
|
|
145111f11e | ||
|
|
a4e47d9180 | ||
|
|
207ee2daa0 | ||
|
|
1fe5d9fa4f | ||
|
|
ed3f6c2a40 | ||
|
|
adb3196ca5 | ||
|
|
e13b133ac8 | ||
|
|
d475428157 | ||
|
|
00b66ce432 | ||
|
|
4d12dd5c43 | ||
|
|
c4f408bffc | ||
|
|
d876c6df2a | ||
|
|
d142e1ca81 | ||
|
|
d9f4d49ef4 | ||
|
|
0a1df5bbb6 | ||
|
|
41f3d7ff31 | ||
|
|
0afef19d26 | ||
|
|
e9be2d76c3 | ||
|
|
ffa813b92c | ||
|
|
909de47acd | ||
|
|
73a5f11e17 | ||
|
|
9544e100c3 | ||
|
|
f3232cdc3a | ||
|
|
b8884d6572 | ||
|
|
323a0c0b27 | ||
|
|
ab45d4358d | ||
|
|
f7775c7a75 | ||
|
|
659a960401 | ||
|
|
07d484597d | ||
|
|
fc470d5f83 |
11
.devcontainer/.gitignore
vendored
11
.devcontainer/.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
!Makefile
|
||||
base/*.sql
|
||||
base/*.zip
|
||||
base/db/
|
||||
base/maps/
|
||||
!base/expansion/Makefile
|
||||
base/
|
||||
!base/*.json
|
||||
override/
|
||||
repo/
|
||||
cache/
|
||||
|
||||
@ -1,196 +1,127 @@
|
||||
# Build binaries: make cmake, make build
|
||||
# One time initial setup (or to reset db): make prep, make inject-mariadb, make maps
|
||||
# Update custom db edits: make inject-custom
|
||||
# Start up server: make shared, make login, make world, make zone
|
||||
# in game, stop combat spam #logs set gmsay 79 0
|
||||
# in game, stop loot spam #logs set gmsay 69 0
|
||||
NAME := eqemu-server
|
||||
.ONESHELL:
|
||||
|
||||
DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
|
||||
DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
|
||||
|
||||
.PHONY: cmake
|
||||
cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
mkdir -p build$$BUILD_SUFFIX
|
||||
@cd build$$BUILD_SUFFIX && cmake -DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_TESTS=ON \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G Ninja ..
|
||||
|
||||
clean:
|
||||
ifneq (,$(findstring .devcontainer,$$PWD))
|
||||
@make -C ../ -f .devcontainer/Makefile clean --no-print-directory
|
||||
endif
|
||||
rm -rf build
|
||||
|
||||
docker-cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARGS} make cmake
|
||||
|
||||
docker-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARGS} make build
|
||||
|
||||
# Build image if it doesn't exist
|
||||
docker-image-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-image-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
ifeq ($(shell docker images -q ${NAME} 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.dev -t ${NAME} .
|
||||
endif
|
||||
|
||||
docker-arm-cmake: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARM64_ARGS} make cmake BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-build: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARM64_ARGS} make build BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-image-build:
|
||||
ifeq ($(shell docker images -q ${NAME}-arm64 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.arm.dev -t ${NAME}-arm64 .
|
||||
endif
|
||||
|
||||
docker-clean: clean
|
||||
|
||||
.PHONY: prep
|
||||
prep:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile prep --no-print-directory
|
||||
exit
|
||||
endif
|
||||
prep: is-vscode
|
||||
@echo "Preparing build/bin for usage..."
|
||||
mkdir -p build/bin/assets/patches
|
||||
cp -R -u -p .devcontainer/base/eqemu_config.json build/bin/eqemu_config.json
|
||||
cp -R -u -p .devcontainer/base/login.json build/bin/login.json
|
||||
cp -R -u -p loginserver/login_util/* build/bin/assets/patches/
|
||||
mkdir -p build/bin/assets
|
||||
cp -R -u -p utils/patches build/bin/assets/
|
||||
-unlink build/bin/lua_modules
|
||||
cd build/bin && ln -s quests/lua_modules lua_modules
|
||||
-unlink build/bin/mods
|
||||
cd build/bin && ln -s quests/mods mods
|
||||
-unlink build/bin/maps
|
||||
cd build/bin && ln -s ../../base/maps maps
|
||||
mkdir -p build/bin/logs
|
||||
mkdir -p build/bin/shared
|
||||
|
||||
@echo "Prepping folders..."
|
||||
@mkdir -p .devcontainer/override
|
||||
@mkdir -p .devcontainer/repo
|
||||
@mkdir -p .devcontainer/cache
|
||||
@mkdir -p build/bin/logs
|
||||
@mkdir -p build/bin/shared
|
||||
@mkdir -p build/bin/assets
|
||||
|
||||
@echo "Applying overrides..."
|
||||
@if [ ! -f .devcontainer/override/eqemu_config.json ]; then cp .devcontainer/base/eqemu_config.json .devcontainer/override/eqemu_config.json; fi
|
||||
@if [ -f build/bin/eqemu_config.json ]; then unlink build/bin/eqemu_config.json; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/override/eqemu_config.json eqemu_config.json
|
||||
@if [ ! -f .devcontainer/override/login.json ]; then cp .devcontainer/base/login.json .devcontainer/override/login.json; fi
|
||||
@if [ -f build/bin/login.json ]; then unlink build/bin/login.json; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/override/login.json login.json
|
||||
|
||||
@echo "Cloning repositories..."
|
||||
cd .devcontainer/repo && if [ ! -d "quests" ]; then cd ../../.devcontainer/repo/ && git clone https://github.com/ProjectEQ/projecteqquests.git quests; fi
|
||||
cd .devcontainer/repo && if [ ! -d "eqemu-definitions" ]; then cd ../../.devcontainer/repo/ && git clone https://github.com/xackery/eqemu-definitions.git eqemu-definitions; fi
|
||||
cd .devcontainer/repo && if [ ! -d "maps" ]; then cd ../../ && make maps; fi
|
||||
@if [ -d build/bin/quests ]; then unlink build/bin/quests; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/repo/quests quests
|
||||
@if [ -d build/bin/maps ]; then unlink build/bin/maps; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/repo/maps maps
|
||||
@if [ -d build/bin/eqemu-definitions ]; then unlink build/bin/eqemu-definitions; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/repo/eqemu-definitions eqemu-definitions
|
||||
@mkdir -p build/bin/quests/mods
|
||||
|
||||
@echo "Applying base links..."
|
||||
cp -R -u -p utils/patches .devcontainer/base/
|
||||
@if [ -d build/bin/assets/patches ]; then unlink build/bin/assets/patches; fi
|
||||
cd build/bin/assets && ln -s ../../../.devcontainer/base/patches patches
|
||||
@if [ -d build/bin/lua_modules ]; then unlink build/bin/lua_modules; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/repo/quests/lua_modules lua_modules
|
||||
@if [ -d build/bin/mods ]; then unlink build/bin/mods; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/repo/quests/mods mods
|
||||
@if [ -d build/bin/plugins ]; then unlink build/bin/plugins; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/repo/quests/plugins plugins
|
||||
|
||||
@echo "Eqemu is prepared. Edit build/bin/eqemu_config.json to configure."
|
||||
|
||||
maps:
|
||||
@echo "Downloading maps..."
|
||||
@mkdir -p base/maps
|
||||
@cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
|
||||
@cd base/maps && unzip -o master.zip
|
||||
@cd base/maps && mv eqemu-maps-master/* .
|
||||
@cd base/maps && rm -rf eqemu-maps-master
|
||||
@echo "Maps downloaded."
|
||||
is-vscode:
|
||||
@if [ -z "$$REMOTE_CONTAINERS" ]; then \
|
||||
echo "Not running in VS Code devcontainer"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
quests:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile quests --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && git clone https://github.com/ProjectEQ/projecteqquests.git quests
|
||||
clean: is-vscode
|
||||
rm -rf build
|
||||
|
||||
.PHONY: maps
|
||||
maps: is-vscode
|
||||
@echo "Downloading maps..."
|
||||
@mkdir -p .devcontainer/repo/maps
|
||||
@cd .devcontainer/repo/maps && wget -nc https://github.com/EQEmu/maps/archive/refs/heads/master.zip
|
||||
@cd .devcontainer/repo/maps && unzip -o master.zip
|
||||
@cd .devcontainer/repo/maps && mv maps-master/* .
|
||||
@cd .devcontainer/repo/maps && rm -rf maps-master
|
||||
@echo "Maps downloaded."
|
||||
|
||||
# Runs tests
|
||||
.PHONY: test
|
||||
test:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
|
||||
exit
|
||||
endif
|
||||
test: is-vscode
|
||||
cd build/bin && ./tests
|
||||
|
||||
# Runs login binary
|
||||
.PHONY: login
|
||||
login:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile login --no-print-directory
|
||||
exit
|
||||
endif
|
||||
login: is-vscode check-mariadb
|
||||
cd build/bin && ./loginserver
|
||||
|
||||
.PHONY: hotfix
|
||||
hotfix: shared
|
||||
|
||||
# Runs shared_memory binary
|
||||
.PHONY: shared
|
||||
shared:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile shared --no-print-directory
|
||||
exit
|
||||
endif
|
||||
shared: is-vscode check-mariadb
|
||||
cd build/bin && ./shared_memory
|
||||
|
||||
# Runs zone binary
|
||||
.PHONY: zone
|
||||
zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/zone/zone*.log
|
||||
zone: is-vscode check-mariadb
|
||||
@find build/bin/logs/zone/ -type f -name 'zone*.log' -exec rm -f {} +
|
||||
cd build/bin && ./zone
|
||||
|
||||
check-mariadb: is-vscode
|
||||
@if ! sudo service mariadb status | grep -q 'active (running)'; then \
|
||||
sudo service mariadb start; \
|
||||
fi
|
||||
|
||||
# Runs world binary
|
||||
.PHONY: world
|
||||
world:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile world --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/world*.log
|
||||
world: is-vscode check-mariadb
|
||||
@find build/bin/logs/ -type f -name 'world*.log' -exec rm -f {} +
|
||||
cd build/bin && ./world
|
||||
|
||||
# Runs ucs binary
|
||||
.PHONY: ucs
|
||||
ucs:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile ucs --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/ucs*.log
|
||||
ucs: is-vscode check-mariadb
|
||||
@find build/bin/logs/ -type f -name 'ucs*.log' -exec rm -f {} +
|
||||
cd build/bin && ./ucs
|
||||
|
||||
# Runs queryserv binary
|
||||
.PHONY: queryserv
|
||||
queryserv:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile queryserv --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/query_server*.log
|
||||
queryserv: is-vscode check-mariadb
|
||||
@find build/bin/logs/ -type f -name 'query_server*.log' -exec rm -f {} +
|
||||
cd build/bin && ./queryserv
|
||||
|
||||
valgrind-%:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
|
||||
exit
|
||||
endif
|
||||
reset-content:
|
||||
@echo "Resetting content tables in database peq..."
|
||||
cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql"
|
||||
|
||||
valgrind-%: is-vscode
|
||||
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
|
||||
|
||||
# Start mariaDB standalone
|
||||
@ -201,30 +132,33 @@ mariadb:
|
||||
.PHONY: inject-mariadb
|
||||
inject-mariadb:
|
||||
-sudo service mariadb start
|
||||
-mkdir -p base/db/
|
||||
-mkdir -p .devcontainer/cache/db/
|
||||
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
|
||||
-sudo mariadb -e 'CREATE DATABASE peq;'
|
||||
-sudo mariadb -e "CREATE USER 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
|
||||
-sudo mariadb -e "CREATE USER IF NOT EXISTS 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
|
||||
-sudo mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'peq'@'127.0.0.1';"
|
||||
ifeq (,$(wildcard base/db/db.sql.zip))
|
||||
@echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
|
||||
wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
|
||||
-cd base/db && unzip db.sql.zip
|
||||
ifeq (,$(wildcard .devcontainer/cache/db/db.sql.zip))
|
||||
@echo ".devcontainer/cache/db.sql.zip not found. Downloading database from https://db.eqemu.dev/latest"
|
||||
wget -nc https://db.eqemu.dev/latest -O .devcontainer/cache/db/db.sql.zip
|
||||
-cd .devcontainer/cache/db && unzip db.sql.zip
|
||||
endif
|
||||
@echo "Sourcing db may take a while, please wait..."
|
||||
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
|
||||
|
||||
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql"
|
||||
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_login.sql"
|
||||
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_player.sql"
|
||||
@# deprecated cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_queryserv.sql"
|
||||
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_state.sql"
|
||||
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_system.sql"
|
||||
|
||||
@echo "MariaDB is now injected."
|
||||
|
||||
.PHONY: gm-%
|
||||
gm-%:
|
||||
gm-%: is-vscode
|
||||
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
|
||||
@echo "Account $* is now a GM. /camp to have it go into effect."
|
||||
|
||||
depends:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile depends --no-print-directory
|
||||
exit
|
||||
endif
|
||||
depends: is-vscode
|
||||
sudo apt install graphviz pip time
|
||||
pip3 install graphviz
|
||||
mkdir -p build/depends
|
||||
@ -241,44 +175,54 @@ endif
|
||||
@echo "Common..."
|
||||
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
|
||||
|
||||
backup:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile backup --no-print-directory
|
||||
exit
|
||||
endif
|
||||
backup: is-vscode
|
||||
@mkdir -p build/bin/backup
|
||||
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
|
||||
|
||||
cpu-zone:
|
||||
restore-%: is-vscode
|
||||
@if [ -z "$*" ]; then \
|
||||
echo "Please provide a backup file to restore from. Example: make restore-backup.sql"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "Restoring from backup $*"
|
||||
@sudo mariadb --database peq -e "$*"
|
||||
|
||||
|
||||
cpu-zone: is-vscode
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile cpu-zone --no-print-directory
|
||||
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && CPUPROFILE=prof.out ./zone
|
||||
|
||||
pprof-zone:
|
||||
pprof-zone: is-vscode
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-zone --no-print-directory
|
||||
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
|
||||
pprof-web-zone:
|
||||
|
||||
pprof-gv-zone: is-vscode
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-web-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --web zone prof.out
|
||||
pprof-gv-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-gv-zone --no-print-directory
|
||||
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --gv zone prof.out > prof.gv
|
||||
heap-zone:
|
||||
|
||||
heap-zone: is-vscode
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile heap-zone --no-print-directory
|
||||
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && HEAPPROFILE=prof.out ./zone
|
||||
|
||||
|
||||
.PHONY: pull
|
||||
pull:
|
||||
git pull
|
||||
@if [ ! -d "quests" ]; then git clone https://github.com/rebuildeq/quests.git quests; fi
|
||||
cd quests && git pull
|
||||
@if [ ! -d "eqemu-definitions" ]; then git clone https://github.com/xackery/eqemu-definitions.git eqemu-definitions; fi
|
||||
cd eqemu-definitions && git pull
|
||||
@ -40,10 +40,41 @@
|
||||
"GitHub.copilot",
|
||||
"xackery.make-magic",
|
||||
"Gruntfuggly.todo-tree",
|
||||
"ms-vscode.cmake-tools"
|
||||
]
|
||||
"ms-vscode.cmake-tools",
|
||||
"sumneko.lua"
|
||||
],
|
||||
"settings": {
|
||||
"Lua.runtime.version": "Lua 5.1",
|
||||
"Lua.workspace.library": [
|
||||
"/src/repo/eqemu-definitions"
|
||||
],
|
||||
"Lua.diagnostics.disable": [
|
||||
"lowercase-global"
|
||||
],
|
||||
"cmake.statusbar.advanced": {
|
||||
"kit": {
|
||||
"visibility": "hidden"
|
||||
},
|
||||
"debug": {
|
||||
"visibility": "hidden"
|
||||
},
|
||||
"buildTarget": {
|
||||
"visibility": "compact"
|
||||
},
|
||||
"launch": {
|
||||
"visibility": "hidden"
|
||||
},
|
||||
"ctest": {
|
||||
"visibility": "icon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mounts": [
|
||||
"source=${localWorkspaceFolder}/.devcontainer/Makefile,target=/src/Makefile,type=bind,consistency=cached"
|
||||
],
|
||||
|
||||
"workspaceFolder": "/src",
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached"
|
||||
}
|
||||
98
.drone.yml
98
.drone.yml
@ -1,98 +0,0 @@
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: Build Linux
|
||||
|
||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||
concurrency:
|
||||
limit: 1
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /var/lib/cache-release
|
||||
|
||||
steps:
|
||||
- name: Build Linux X64
|
||||
image: akkadius/eqemu-server:v14
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
commands:
|
||||
- ./utils/scripts/build/linux-build.sh
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /home/eqemu/.ccache/
|
||||
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: exec
|
||||
name: Build Windows
|
||||
|
||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||
concurrency:
|
||||
limit: 1
|
||||
|
||||
platform:
|
||||
os: windows
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: Build Windows X64
|
||||
environment:
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
commands:
|
||||
- .\utils\scripts\build\windows-build.ps1
|
||||
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: Publish Artifacts to Github
|
||||
|
||||
steps:
|
||||
- name: Upload Artifacts
|
||||
image: akkadius/eqemu-build-releaser:v3
|
||||
environment:
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
GH_RELEASE_GITHUB_API_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
commands:
|
||||
- ./utils/scripts/build/should-release/should-release
|
||||
- rclone config create remote ftp env_auth true > /dev/null
|
||||
- |
|
||||
rclone copy remote: --include "eqemu-server*.zip" .
|
||||
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
|
||||
- |
|
||||
rclone delete remote: --include "eqemu-server*.zip"
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
|
||||
depends_on:
|
||||
- Build Windows
|
||||
- Build Linux
|
||||
|
||||
|
||||
81
.github/workflows/build.yaml
vendored
Normal file
81
.github/workflows/build.yaml
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-ccache
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential ninja-build ccache libmariadb-dev libmariadb-dev-compat libboost-all-dev libperl-dev liblua5.1-0-dev libluajit-5.1-dev zlib1g-dev uuid-dev libssl-dev libsodium-dev libmbedtls-dev
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -S . -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DEQEMU_BUILD_TESTS=ON \
|
||||
-DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_LUA=ON \
|
||||
-DEQEMU_BUILD_PERL=ON \
|
||||
-DEQEMU_BUILD_CLIENT_FILES=ON
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: build
|
||||
run: ./bin/tests
|
||||
|
||||
windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Enable long paths
|
||||
run: git config --global core.longpaths true
|
||||
|
||||
- name: Setup MSVC environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: Configure
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 `
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo `
|
||||
-DEQEMU_BUILD_TESTS=ON `
|
||||
-DEQEMU_BUILD_LOGIN=ON `
|
||||
-DEQEMU_BUILD_LUA=ON `
|
||||
-DEQEMU_BUILD_ZLIB=ON `
|
||||
-DEQEMU_BUILD_CLIENT_FILES=ON
|
||||
|
||||
- name: Build
|
||||
shell: pwsh
|
||||
run: cmake --build build --config RelWithDebInfo --target ALL_BUILD -- /m
|
||||
|
||||
- name: Test
|
||||
working-directory: build
|
||||
run: ./bin/RelWithDebInfo/tests.exe
|
||||
25
.vscode/settings.json
vendored
25
.vscode/settings.json
vendored
@ -21,14 +21,6 @@
|
||||
"${workspaceFolder}/dependencies/zlibng"
|
||||
],
|
||||
"telemetry.enableTelemetry": false,
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||
"cmake.configureArgs": [
|
||||
"-DEQEMU_BUILD_LOGIN=ON",
|
||||
"-DEQEMU_BUILD_TESTS=ON",
|
||||
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
|
||||
"-DEQEMU_ADD_PROFILER=ON",
|
||||
"Ninja"
|
||||
],
|
||||
"cmake.skipConfigureIfCachePresent": true,
|
||||
"cmake.configureOnOpen": false,
|
||||
"files.associations": {
|
||||
@ -115,22 +107,5 @@
|
||||
"format": "cpp",
|
||||
"ranges": "cpp",
|
||||
"span": "cpp"
|
||||
},
|
||||
"cmake.statusbar.advanced": {
|
||||
"kit": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"debug": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"buildTarget": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"launch": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"ctest": {
|
||||
"visibility": "icon",
|
||||
}
|
||||
}
|
||||
}
|
||||
130
CHANGELOG.md
130
CHANGELOG.md
@ -1,3 +1,133 @@
|
||||
## [23.10.3] 9/16/2025
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Hotfix crashes occurring in #4987. @Akkadius 2025-09-17
|
||||
|
||||
## [23.10.2] 9/16/2025
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Revert #4996 as it was causing critical issues with spells that needs to be further investigated. @Akkadius 2025-09-17
|
||||
|
||||
## [23.10.1] 9/16/2025
|
||||
|
||||
### Hotfix
|
||||
* Fixed Mail Key Bug ([#5015](https://github.com/EQEmu/Server/pull/5015)) @Kinglykrab 2025-09-16
|
||||
|
||||
## [23.10.0] 9/15/2025
|
||||
|
||||
### Build
|
||||
|
||||
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
|
||||
|
||||
### Code
|
||||
|
||||
* Add #npcedit npc_tint_id Help Message ([#4982](https://github.com/EQEmu/Server/pull/4982)) @Kinglykrab 2025-08-17
|
||||
* Cleanup #show ip_lookup Message ([#5005](https://github.com/EQEmu/Server/pull/5005)) @Kinglykrab 2025-08-30
|
||||
* Fix #set race 0 Message ([#5004](https://github.com/EQEmu/Server/pull/5004)) @Kinglykrab 2025-08-30
|
||||
* Fix Issues with Strings::Commify and Mob::SendStatsWindow ([#4984](https://github.com/EQEmu/Server/pull/4984)) @Kinglykrab 2025-08-17
|
||||
* Remove Attributions ([#4988](https://github.com/EQEmu/Server/pull/4988)) @KimLS 2025-08-16
|
||||
* Remove Unused errorname Variable ([#5001](https://github.com/EQEmu/Server/pull/5001)) @Kinglykrab 2025-08-29
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #find account Subcommand ([#4981](https://github.com/EQEmu/Server/pull/4981)) @Kinglykrab 2025-08-17
|
||||
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
|
||||
* Add #task complete Saylink to #task show ([#4985](https://github.com/EQEmu/Server/pull/4985)) @Kinglykrab 2025-08-17
|
||||
|
||||
### Constants
|
||||
|
||||
* Change Race Changes to Race Namespace ([#5000](https://github.com/EQEmu/Server/pull/5000)) @Kinglykrab 2025-08-30
|
||||
* Convert SE Defines to SpellEffect Namespace ([#4999](https://github.com/EQEmu/Server/pull/4999)) @Kinglykrab 2025-08-30
|
||||
|
||||
### Database
|
||||
|
||||
* Add `heal_amount` to `character_stats_record` ([#4986](https://github.com/EQEmu/Server/pull/4986)) @Kinglykrab 2025-08-17
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix #show recipe uint16 Cap ([#4978](https://github.com/EQEmu/Server/pull/4978)) @Kinglykrab 2025-08-11
|
||||
* Fix Race 474 for Titanium ([#4979](https://github.com/EQEmu/Server/pull/4979)) @regneq 2025-08-11
|
||||
* Fix Recipe Inspect Bug ([#4994](https://github.com/EQEmu/Server/pull/4994)) @Kinglykrab 2025-08-30
|
||||
* Fix Several Evolving Item Bugs ([#4992](https://github.com/EQEmu/Server/pull/4992)) @neckkola 2025-09-08
|
||||
* Fix Task Reloading ([#5002](https://github.com/EQEmu/Server/pull/5002)) @Kinglykrab 2025-08-29
|
||||
|
||||
### Loginserver
|
||||
|
||||
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
|
||||
|
||||
### Pets
|
||||
|
||||
* Add Pet Constants and Methods ([#4987](https://github.com/EQEmu/Server/pull/4987)) @Kinglykrab 2025-08-17
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add EVENT_CHARM_START and EVENT_CHARM_END ([#5013](https://github.com/EQEmu/Server/pull/5013)) @Kinglykrab 2025-09-15
|
||||
* Add GetKeyRing() to Perl/Lua ([#4980](https://github.com/EQEmu/Server/pull/4980)) @Kinglykrab 2025-08-17
|
||||
* Add GetNPCTintIndex() to Perl/Lua ([#4983](https://github.com/EQEmu/Server/pull/4983)) @Kinglykrab 2025-08-17
|
||||
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
|
||||
* Add Identifiers to Get/Modify NPC Stat Methods ([#5012](https://github.com/EQEmu/Server/pull/5012)) @Kinglykrab 2025-09-15
|
||||
|
||||
### Repositories
|
||||
|
||||
* Convert Character Inspect Messages to Repositories ([#4997](https://github.com/EQEmu/Server/pull/4997)) @Kinglykrab 2025-08-30
|
||||
* Convert Damage Shield Types to Repositories ([#4995](https://github.com/EQEmu/Server/pull/4995)) @Kinglykrab 2025-08-30
|
||||
* Convert Item Loading to Repositories ([#4998](https://github.com/EQEmu/Server/pull/4998)) @Kinglykrab 2025-08-30
|
||||
* Convert Mail Key to Repositories ([#5007](https://github.com/EQEmu/Server/pull/5007)) @Kinglykrab 2025-09-15
|
||||
* Convert Shared Bank Platinum to Repositories ([#5006](https://github.com/EQEmu/Server/pull/5006)) @Kinglykrab 2025-09-02
|
||||
* Convert Spell Loading to Repositories ([#4996](https://github.com/EQEmu/Server/pull/4996)) @Kinglykrab 2025-08-30
|
||||
* Convert Total Time Played to Repositories ([#5008](https://github.com/EQEmu/Server/pull/5008)) @Kinglykrab 2025-09-15
|
||||
|
||||
## [23.9.1] 8/2/2025
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Fix Quest Ownership Edge Case ([#4977](https://github.com/EQEmu/Server/pull/4977)) @Kinglykrab 2025-08-02
|
||||
|
||||
## [23.9.0] 8/2/2025
|
||||
|
||||
### Bots
|
||||
|
||||
* Fix FinishBuffing rule ([#4961](https://github.com/EQEmu/Server/pull/4961)) @nytmyr 2025-07-01
|
||||
* Fix ^cast resurrects ([#4958](https://github.com/EQEmu/Server/pull/4958)) @nytmyr 2025-06-29
|
||||
|
||||
### Build
|
||||
|
||||
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
|
||||
* More Build Speed Improvements ([#4959](https://github.com/EQEmu/Server/pull/4959)) @Akkadius 2025-06-30
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
|
||||
|
||||
### Database
|
||||
|
||||
* Add Indexes to NPC's Spawns Loot ([#4972](https://github.com/EQEmu/Server/pull/4972)) @Akkadius 2025-07-30
|
||||
|
||||
### Feature
|
||||
|
||||
* Zone Scripting ([#4908](https://github.com/EQEmu/Server/pull/4908)) @Kinglykrab 2025-07-10
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add a missing Froglok starting area for Titanium Startzone. ([#4962](https://github.com/EQEmu/Server/pull/4962)) @regneq 2025-07-04
|
||||
* Fix Hero's Forge Ingame and Character Select ([#4966](https://github.com/EQEmu/Server/pull/4966)) @Kinglykrab 2025-07-30
|
||||
* Show player count on the server list status. ([#4971](https://github.com/EQEmu/Server/pull/4971)) @regneq 2025-07-30
|
||||
|
||||
### Loginserver
|
||||
|
||||
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
|
||||
|
||||
### Performance
|
||||
|
||||
* Clear Wearchange Deduplication Cache ([#4960](https://github.com/EQEmu/Server/pull/4960)) @Akkadius 2025-06-30
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetMemberRole() to Perl/Lua ([#4963](https://github.com/EQEmu/Server/pull/4963)) @Barathos 2025-07-10
|
||||
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
|
||||
|
||||
## [23.8.1] 6/28/2025
|
||||
|
||||
### Crash Fix
|
||||
|
||||
@ -363,6 +363,8 @@ MESSAGE(STATUS "**************************************************")
|
||||
#setup server libs and headers
|
||||
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
|
||||
|
||||
set(FMT_HEADER_ONLY OFF)
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")
|
||||
|
||||
49
CMakePresets.json
Normal file
49
CMakePresets.json
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 19,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "linux-debug",
|
||||
"displayName": "Linux Debug",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"CMAKE_C_COMPILER_LAUNCHER": "ccache",
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "ccache",
|
||||
"EQEMU_BUILD_LOGIN": "ON",
|
||||
"EQEMU_BUILD_TESTS": "ON",
|
||||
"EQEMU_ADD_PROFILER": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-release",
|
||||
"displayName": "Linux Release",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_C_COMPILER_LAUNCHER": "ccache",
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "ccache",
|
||||
"EQEMU_BUILD_LOGIN": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "win-msvc",
|
||||
"displayName": "Windows MSVC (VS 2022)",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"binaryDir": "${sourceDir}/build/{presetName}",
|
||||
"architecture": { "value": "x64" },
|
||||
"cacheVariables": {
|
||||
"CMAKE_CONFIGURATION_TYPES": "Debug;Release",
|
||||
"EQEMU_BUILD_LOGIN": "ON",
|
||||
"EQEMU_BUILD_TESTS": "ON"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,60 +35,55 @@ ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
||||
MESSAGE(STATUS "Resolving vcpkg dependencies...")
|
||||
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
|
||||
|
||||
|
||||
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
|
||||
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
|
||||
ENDIF()
|
||||
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
|
||||
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
||||
#Try to find perl first, (so you can use your active install first)
|
||||
FIND_PACKAGE(PerlLibs)
|
||||
|
||||
IF(NOT PerlLibs_FOUND)
|
||||
MESSAGE(STATUS "Resolving perl dependencies...")
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
|
||||
|
||||
MESSAGE(STATUS "Downloading portable perl...")
|
||||
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
|
||||
)
|
||||
MESSAGE(STATUS "Resolving perl dependencies...")
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
|
||||
|
||||
MESSAGE(STATUS "Downloading portable perl...")
|
||||
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
|
||||
ENDIF()
|
||||
|
||||
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
|
||||
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
|
||||
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
|
||||
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
|
||||
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
|
||||
ENDIF()
|
||||
|
||||
@ -104,9 +104,9 @@ SET(common_sources
|
||||
net/console_server.cpp
|
||||
net/console_server_connection.cpp
|
||||
net/crc32.cpp
|
||||
net/daybreak_connection.cpp
|
||||
net/eqstream.cpp
|
||||
net/packet.cpp
|
||||
net/reliable_stream_connection.cpp
|
||||
net/servertalk_client_connection.cpp
|
||||
net/servertalk_legacy_client_connection.cpp
|
||||
net/servertalk_server.cpp
|
||||
@ -603,7 +603,6 @@ SET(common_headers
|
||||
ipc_mutex.h
|
||||
ip_util.h
|
||||
item_data.h
|
||||
item_fieldlist.h
|
||||
item_instance.h
|
||||
json_config.h
|
||||
light_source.h
|
||||
@ -671,13 +670,13 @@ SET(common_headers
|
||||
net/console_server.h
|
||||
net/console_server_connection.h
|
||||
net/crc32.h
|
||||
net/daybreak_connection.h
|
||||
net/daybreak_pooling.h
|
||||
net/daybreak_structs.h
|
||||
net/dns.h
|
||||
net/endian.h
|
||||
net/eqstream.h
|
||||
net/packet.h
|
||||
net/reliable_stream_connection.h
|
||||
net/reliable_stream_pooling.h
|
||||
net/reliable_stream_structs.h
|
||||
net/servertalk_client_connection.h
|
||||
net/servertalk_legacy_client_connection.h
|
||||
net/servertalk_common.h
|
||||
@ -743,10 +742,6 @@ SOURCE_GROUP(Net FILES
|
||||
net/console_server_connection.h
|
||||
net/crc32.cpp
|
||||
net/crc32.h
|
||||
net/daybreak_connection.cpp
|
||||
net/daybreak_connection.h
|
||||
net/daybreak_pooling.h
|
||||
net/daybreak_structs.h
|
||||
net/dns.h
|
||||
net/endian.h
|
||||
net/eqmq.cpp
|
||||
@ -755,6 +750,10 @@ SOURCE_GROUP(Net FILES
|
||||
net/eqstream.h
|
||||
net/packet.cpp
|
||||
net/packet.h
|
||||
net/reliable_stream_connection.cpp
|
||||
net/reliable_stream_connection.h
|
||||
net/reliable_stream_pooling.h
|
||||
net/reliable_stream_structs.h
|
||||
net/servertalk_client_connection.cpp
|
||||
net/servertalk_client_connection.h
|
||||
net/servertalk_legacy_client_connection.cpp
|
||||
@ -841,8 +840,13 @@ IF (UNIX)
|
||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
||||
ENDIF (UNIX)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
IF (EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/std-pch.h)
|
||||
# Avoid PCH/__OPTIMIZE__ mismatch when compiling certain patch sources with -O0
|
||||
# These files are compiled with -O0 on UNIX (see COMPILE_FLAGS above), which
|
||||
# disables the __OPTIMIZE__ predefined macro. Disabling PCH for them prevents
|
||||
# Clang from erroring due to macro state differences between the PCH and TU.
|
||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
|
||||
ENDIF ()
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
@ -23,7 +23,7 @@ void SendCrashReport(const std::string &crash_report)
|
||||
{
|
||||
// can configure multiple endpoints if need be
|
||||
std::vector<std::string> endpoints = {
|
||||
"https://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||
"https://spire.eqemu.dev/api/v1/analytics/server-crash-report",
|
||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||
};
|
||||
|
||||
|
||||
@ -7133,6 +7133,56 @@ CREATE INDEX idx_event_type_char_id ON player_event_logs (event_type_id, charact
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_corpses`
|
||||
ADD COLUMN `entity_variables` TEXT DEFAULT NULL AFTER `rezzable`;
|
||||
)",
|
||||
.content_schema_update = false
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9326,
|
||||
.description = "2025_07_27_add_indexes_npc_spawns_loot.sql",
|
||||
.check = "SHOW INDEX FROM npc_types",
|
||||
.condition = "missing",
|
||||
.match = "idx_npc_types_loottable_id",
|
||||
.sql = R"(
|
||||
ALTER TABLE npc_types
|
||||
ADD INDEX idx_npc_types_loottable_id (loottable_id);
|
||||
|
||||
ALTER TABLE spawnentry
|
||||
ADD INDEX idx_spawnentry_spawngroup_id (spawngroupID),
|
||||
ADD INDEX idx_spawnentry_npc_id (npcID);
|
||||
|
||||
ALTER TABLE lootdrop_entries
|
||||
ADD INDEX idx_lootdrop_entries_lootdrop_id (lootdrop_id),
|
||||
ADD INDEX idx_lootdrop_entries_item_id (item_id);
|
||||
|
||||
ALTER TABLE loottable_entries
|
||||
ADD INDEX idx_loottable_entries_lootdrop_id (lootdrop_id),
|
||||
ADD INDEX idx_loottable_entries_loottable_id (loottable_id);
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9327,
|
||||
.description = "2025_08_13_character_stats_record_heal_amount.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_stats_record` LIKE 'heal_amount'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_stats_record`
|
||||
ADD COLUMN `heal_amount` int(11) NULL DEFAULT 0 AFTER `spell_damage`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9328,
|
||||
.description = "2025_08_22_character_parcel_updates.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_parcels` LIKE 'evolve_amount'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_parcels`
|
||||
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
|
||||
|
||||
ALTER TABLE `character_parcels_containers`
|
||||
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
|
||||
)",
|
||||
.content_schema_update = false
|
||||
},
|
||||
|
||||
@ -451,3 +451,23 @@ bool LDoNTheme::IsValid(uint32 theme_id)
|
||||
{
|
||||
return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
|
||||
}
|
||||
|
||||
std::string PetCommand::GetName(uint8 pet_command)
|
||||
{
|
||||
return IsValid(pet_command) ? pet_commands[pet_command] : "UNKNOWN PET COMMAND";
|
||||
}
|
||||
|
||||
bool PetCommand::IsValid(uint8 pet_command)
|
||||
{
|
||||
return pet_commands.find(pet_command) != pet_commands.end();
|
||||
}
|
||||
|
||||
std::string PetType::GetName(uint8 pet_type)
|
||||
{
|
||||
return IsValid(pet_type) ? pet_types[pet_type] : "UNKNOWN PET TYPE";
|
||||
}
|
||||
|
||||
bool PetType::IsValid(uint8 pet_type)
|
||||
{
|
||||
return pet_types.find(pet_type) != pet_types.end();
|
||||
}
|
||||
|
||||
@ -792,4 +792,131 @@ namespace BookType {
|
||||
constexpr uint8 ItemInfo = 2;
|
||||
}
|
||||
|
||||
namespace PetButton {
|
||||
constexpr uint8 Sit = 0;
|
||||
constexpr uint8 Stop = 1;
|
||||
constexpr uint8 Regroup = 2;
|
||||
constexpr uint8 Follow = 3;
|
||||
constexpr uint8 Guard = 4;
|
||||
constexpr uint8 Taunt = 5;
|
||||
constexpr uint8 Hold = 6;
|
||||
constexpr uint8 GreaterHold = 7;
|
||||
constexpr uint8 Focus = 8;
|
||||
constexpr uint8 SpellHold = 9;
|
||||
}
|
||||
|
||||
namespace PetButtonState {
|
||||
constexpr uint8 Off = 0;
|
||||
constexpr uint8 On = 1;
|
||||
}
|
||||
|
||||
namespace PetCommand {
|
||||
constexpr uint8 HealthReport = 0; // /pet health or Pet Window
|
||||
constexpr uint8 Leader = 1; // /pet leader or Pet Window
|
||||
constexpr uint8 Attack = 2; // /pet attack or Pet Window
|
||||
constexpr uint8 QAttack = 3; // /pet qattack or Pet Window
|
||||
constexpr uint8 FollowMe = 4; // /pet follow or Pet Window
|
||||
constexpr uint8 GuardHere = 5; // /pet guard or Pet Window
|
||||
constexpr uint8 Sit = 6; // /pet sit or Pet Window
|
||||
constexpr uint8 SitDown = 7; // /pet sit on
|
||||
constexpr uint8 StandUp = 8; // /pet sit off
|
||||
constexpr uint8 Stop = 9; // /pet stop or Pet Window - Not implemented
|
||||
constexpr uint8 StopOn = 10; // /pet stop on - Not implemented
|
||||
constexpr uint8 StopOff = 11; // /pet stop off - Not implemented
|
||||
constexpr uint8 Taunt = 12; // /pet taunt or Pet Window
|
||||
constexpr uint8 TauntOn = 13; // /pet taunt on
|
||||
constexpr uint8 TauntOff = 14; // /pet taunt off
|
||||
constexpr uint8 Hold = 15; // /pet hold or Pet Window, won't add to hate list unless attacking
|
||||
constexpr uint8 HoldOn = 16; // /pet hold on
|
||||
constexpr uint8 HoldOff = 17; // /pet hold off
|
||||
constexpr uint8 GreaterHold = 18; // /pet ghold, will never add to hate list unless told to
|
||||
constexpr uint8 GreaterHoldOn = 19; // /pet ghold on
|
||||
constexpr uint8 GreaterHoldOff = 20; // /pet ghold off
|
||||
constexpr uint8 SpellHold = 21; // /pet no cast or /pet spellhold or Pet Window
|
||||
constexpr uint8 SpellHoldOn = 22; // /pet spellhold on
|
||||
constexpr uint8 SpellHoldOff = 23; // /pet spellhold off
|
||||
constexpr uint8 Focus = 24; // /pet focus or Pet Window
|
||||
constexpr uint8 FocusOn = 25; // /pet focus on
|
||||
constexpr uint8 FocusOff = 26; // /pet focus off
|
||||
constexpr uint8 Feign = 27; // /pet feign
|
||||
constexpr uint8 BackOff = 28; // /pet back off
|
||||
constexpr uint8 GetLost = 29; // /pet get lost
|
||||
constexpr uint8 GuardMe = 30; // Same as /pet follow, but different message in older clients
|
||||
constexpr uint8 Regroup = 31; // /pet regroup, acts like classic hold
|
||||
constexpr uint8 RegroupOn = 32; // /pet regroup on
|
||||
constexpr uint8 RegroupOff = 33; // /pet regroup off
|
||||
constexpr uint8 Max = 34;
|
||||
|
||||
static std::map<uint8, std::string> pet_commands = {
|
||||
{ PetCommand::HealthReport, "Health Report" },
|
||||
{ PetCommand::Leader, "Leader" },
|
||||
{ PetCommand::Attack, "Attack" },
|
||||
{ PetCommand::QAttack, "QAttack" },
|
||||
{ PetCommand::FollowMe, "Follow Me" },
|
||||
{ PetCommand::GuardHere, "Guard Here" },
|
||||
{ PetCommand::Sit, "Sit" },
|
||||
{ PetCommand::SitDown, "Sit Down" },
|
||||
{ PetCommand::StandUp, "Stand Up" },
|
||||
{ PetCommand::Stop, "Stop" },
|
||||
{ PetCommand::StopOn, "Stop On" },
|
||||
{ PetCommand::StopOff, "Stop Off" },
|
||||
{ PetCommand::Taunt, "Taunt" },
|
||||
{ PetCommand::TauntOn, "Taunt On" },
|
||||
{ PetCommand::TauntOff, "Taunt Off" },
|
||||
{ PetCommand::Hold, "Hold" },
|
||||
{ PetCommand::HoldOn, "Hold On" },
|
||||
{ PetCommand::HoldOff, "Hold Off" },
|
||||
{ PetCommand::GreaterHold, "Greater Hold" },
|
||||
{ PetCommand::GreaterHoldOn, "Greater Hold On" },
|
||||
{ PetCommand::GreaterHoldOff, "Greater Hold Off" },
|
||||
{ PetCommand::SpellHold, "Spell Hold" },
|
||||
{ PetCommand::SpellHoldOn, "Spell Hold On" },
|
||||
{ PetCommand::SpellHoldOff, "Spell Hold Off" },
|
||||
{ PetCommand::Focus, "Focus" },
|
||||
{ PetCommand::FocusOn, "Focus On" },
|
||||
{ PetCommand::FocusOff, "Focus Off" },
|
||||
{ PetCommand::Feign, "Feign" },
|
||||
{ PetCommand::BackOff, "Back Off" },
|
||||
{ PetCommand::GetLost, "Get Lost" },
|
||||
{ PetCommand::GuardMe, "Guard Me" },
|
||||
{ PetCommand::Regroup, "Regroup" },
|
||||
{ PetCommand::RegroupOn, "Regroup On" },
|
||||
{ PetCommand::RegroupOff, "Regroup Off" },
|
||||
{ PetCommand::Max, "Max" }
|
||||
};
|
||||
|
||||
std::string GetName(uint8 pet_command);
|
||||
bool IsValid(uint8 pet_command);
|
||||
}
|
||||
|
||||
namespace PetOrder {
|
||||
constexpr uint8 Follow = 0;
|
||||
constexpr uint8 Sit = 1;
|
||||
constexpr uint8 Guard = 2;
|
||||
constexpr uint8 Feign = 3;
|
||||
}
|
||||
|
||||
namespace PetType {
|
||||
constexpr uint8 Familiar = 0;
|
||||
constexpr uint8 Animation = 1;
|
||||
constexpr uint8 Normal = 2;
|
||||
constexpr uint8 Charmed = 3;
|
||||
constexpr uint8 Follow = 4;
|
||||
constexpr uint8 TargetLock = 5;
|
||||
constexpr uint8 None = 255;
|
||||
|
||||
static std::map<uint8, std::string> pet_types = {
|
||||
{ PetType::Familiar, "Familiar" },
|
||||
{ PetType::Animation, "Animation" },
|
||||
{ PetType::Normal, "Normal" },
|
||||
{ PetType::Charmed, "Charmed" },
|
||||
{ PetType::Follow, "Follow" },
|
||||
{ PetType::TargetLock, "Target Lock" },
|
||||
{ PetType::None, "None" }
|
||||
};
|
||||
|
||||
std::string GetName(uint8 pet_type);
|
||||
bool IsValid(uint8 pet_type);
|
||||
}
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
@ -988,7 +988,8 @@ enum StartZoneIndex {
|
||||
Felwithe,
|
||||
Akanon,
|
||||
Cabilis,
|
||||
SharVahl
|
||||
SharVahl,
|
||||
RatheMtn
|
||||
};
|
||||
|
||||
enum FVNoDropFlagRule
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include <string>
|
||||
#include "emu_versions.h"
|
||||
#include "eq_packet.h"
|
||||
#include "net/daybreak_connection.h"
|
||||
#include "net/reliable_stream_connection.h"
|
||||
|
||||
typedef enum {
|
||||
ESTABLISHED,
|
||||
@ -33,18 +33,18 @@ struct EQStreamManagerInterfaceOptions
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//but that might be because it was still a bit buggy when i was testing that.
|
||||
if (compressed) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||
}
|
||||
else if (encoded) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
||||
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
||||
}
|
||||
|
||||
daybreak_options.port = port;
|
||||
reliable_stream_options.port = port;
|
||||
}
|
||||
|
||||
int opcode_size;
|
||||
bool track_opcode_stats;
|
||||
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
|
||||
EQ::Net::ReliableStreamConnectionManagerOptions reliable_stream_options;
|
||||
};
|
||||
|
||||
class EQStreamManagerInterface
|
||||
@ -80,7 +80,7 @@ public:
|
||||
|
||||
struct Stats
|
||||
{
|
||||
EQ::Net::DaybreakConnectionStats DaybreakStats;
|
||||
EQ::Net::ReliableStreamConnectionStats ReliableStreamStats;
|
||||
int RecvCount[_maxEmuOpcode];
|
||||
int SentCount[_maxEmuOpcode];
|
||||
};
|
||||
|
||||
@ -74,6 +74,10 @@ void EvolvingItemsManager::DoLootChecks(const uint32 char_id, const uint16 slot_
|
||||
e.item_id = inst.GetID();
|
||||
e.equipped = inst.GetEvolveEquipped();
|
||||
e.final_item_id = EvolvingItemsManager::Instance()->GetFinalItemID(inst);
|
||||
if (inst.GetEvolveCurrentAmount() > 0) {
|
||||
e.current_amount = inst.GetEvolveCurrentAmount();
|
||||
inst.CalculateEvolveProgression();
|
||||
}
|
||||
|
||||
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
|
||||
e.id = r.id;
|
||||
|
||||
@ -95,12 +95,12 @@ bool IsOfEqualRace(int r1, int r2)
|
||||
}
|
||||
// TODO: add more values
|
||||
switch (r1) {
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
if (r2 == Race::NeriakCitizen) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case BARBARIAN:
|
||||
case Race::Barbarian:
|
||||
if (r2 == Race::HalasCitizen) {
|
||||
return true;
|
||||
}
|
||||
@ -116,49 +116,49 @@ bool IsOfIndiffRace(int r1, int r2)
|
||||
}
|
||||
// TODO: add more values
|
||||
switch (r1) {
|
||||
case DARK_ELF:
|
||||
case OGRE:
|
||||
case TROLL:
|
||||
if (r2 == OGRE || r2 == TROLL || r2 == DARK_ELF) {
|
||||
case Race::DarkElf:
|
||||
case Race::Ogre:
|
||||
case Race::Troll:
|
||||
if (r2 == Race::Ogre || r2 == Race::Troll || r2 == Race::DarkElf) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case HUMAN:
|
||||
case BARBARIAN:
|
||||
case HALF_ELF:
|
||||
case GNOME:
|
||||
case HALFLING:
|
||||
case WOOD_ELF:
|
||||
if (r2 == HUMAN ||
|
||||
r2 == BARBARIAN ||
|
||||
r2 == ERUDITE ||
|
||||
r2 == HALF_ELF ||
|
||||
r2 == GNOME ||
|
||||
r2 == HALFLING ||
|
||||
r2 == DWARF ||
|
||||
r2 == HIGH_ELF ||
|
||||
r2 == WOOD_ELF) {
|
||||
case Race::Human:
|
||||
case Race::Barbarian:
|
||||
case Race::HalfElf:
|
||||
case Race::Gnome:
|
||||
case Race::Halfling:
|
||||
case Race::WoodElf:
|
||||
if (r2 == Race::Human ||
|
||||
r2 == Race::Barbarian ||
|
||||
r2 == Race::Erudite ||
|
||||
r2 == Race::HalfElf ||
|
||||
r2 == Race::Gnome ||
|
||||
r2 == Race::Halfling ||
|
||||
r2 == Race::Dwarf ||
|
||||
r2 == Race::HighElf ||
|
||||
r2 == Race::WoodElf) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case ERUDITE:
|
||||
if (r2 == HUMAN || r2 == HALF_ELF) {
|
||||
case Race::Erudite:
|
||||
if (r2 == Race::Human || r2 == Race::HalfElf) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DWARF:
|
||||
if (r2 == HALFLING || r2 == GNOME) {
|
||||
case Race::Dwarf:
|
||||
if (r2 == Race::Halfling || r2 == Race::Gnome) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case HIGH_ELF:
|
||||
if (r2 == WOOD_ELF) {
|
||||
case Race::HighElf:
|
||||
if (r2 == Race::WoodElf) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
return true;
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -438,7 +438,7 @@ namespace EQ
|
||||
//uint32 Unk054 {};
|
||||
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
|
||||
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
|
||||
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
|
||||
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SpellEffect::FFItemClass)
|
||||
uint8 Material {}; // Item material type
|
||||
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
|
||||
float SellRate {}; // Sell rate
|
||||
|
||||
@ -1,206 +0,0 @@
|
||||
/*
|
||||
|
||||
|
||||
These fields must be in the order of how they are serialized!
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
F(itemclass)
|
||||
F(name)
|
||||
F(lore)
|
||||
F(idfile)
|
||||
F(id)
|
||||
F(weight)
|
||||
F(norent)
|
||||
F(nodrop)
|
||||
F(size)
|
||||
F(slots)
|
||||
F(price)
|
||||
F(icon)
|
||||
F(UNK012)
|
||||
F(UNK013)
|
||||
F(benefitflag)
|
||||
F(tradeskills)
|
||||
F(cr)
|
||||
F(dr)
|
||||
F(pr)
|
||||
F(mr)
|
||||
F(fr)
|
||||
F(astr)
|
||||
F(asta)
|
||||
F(aagi)
|
||||
F(adex)
|
||||
F(acha)
|
||||
F(aint)
|
||||
F(awis)
|
||||
F(hp)
|
||||
F(mana)
|
||||
F(ac)
|
||||
F(deity)
|
||||
F(skillmodvalue)
|
||||
F(UNK033)
|
||||
F(skillmodmax)
|
||||
F(skillmodtype)
|
||||
F(banedmgrace)
|
||||
F(banedmgamt)
|
||||
F(banedmgbody)
|
||||
F(magic)
|
||||
F(casttime_)
|
||||
F(reqlevel)
|
||||
F(bardtype)
|
||||
F(bardvalue)
|
||||
F(light)
|
||||
F(delay)
|
||||
F(reclevel)
|
||||
F(recskill)
|
||||
F(elemdmgtype)
|
||||
F(elemdmgamt)
|
||||
F(range)
|
||||
F(damage)
|
||||
F(color)
|
||||
F(classes)
|
||||
F(races)
|
||||
F(UNK054)
|
||||
F(maxcharges)
|
||||
F(itemtype)
|
||||
F(material)
|
||||
F(herosforgemodel)
|
||||
F(sellrate)
|
||||
F(UNK059)
|
||||
F(casttime)
|
||||
F(elitematerial)
|
||||
F(procrate)
|
||||
F(combateffects)
|
||||
F(shielding)
|
||||
F(stunresist)
|
||||
F(strikethrough)
|
||||
F(extradmgskill)
|
||||
F(extradmgamt)
|
||||
F(spellshield)
|
||||
F(avoidance)
|
||||
F(accuracy)
|
||||
F(charmfileid)
|
||||
F(factionmod1)
|
||||
F(factionmod2)
|
||||
F(factionmod3)
|
||||
F(factionmod4)
|
||||
F(factionamt1)
|
||||
F(factionamt2)
|
||||
F(factionamt3)
|
||||
F(factionamt4)
|
||||
F(charmfile)
|
||||
F(augtype)
|
||||
F(augslot1type)
|
||||
F(augslot1visible)
|
||||
F(augslot2type)
|
||||
F(augslot2visible)
|
||||
F(augslot3type)
|
||||
F(augslot3visible)
|
||||
F(augslot4type)
|
||||
F(augslot4visible)
|
||||
F(augslot5type)
|
||||
F(augslot5visible)
|
||||
F(augslot6type)
|
||||
F(augslot6visible)
|
||||
F(ldontheme)
|
||||
F(ldonprice)
|
||||
F(ldonsold)
|
||||
F(bagtype)
|
||||
F(bagslots)
|
||||
F(bagsize)
|
||||
F(bagwr)
|
||||
F(book)
|
||||
F(booktype)
|
||||
F(filename)
|
||||
F(banedmgraceamt)
|
||||
F(augrestrict)
|
||||
F(loregroup)
|
||||
F(pendingloreflag)
|
||||
F(artifactflag)
|
||||
F(summonedflag)
|
||||
F(favor)
|
||||
F(fvnodrop)
|
||||
F(endur)
|
||||
F(dotshielding)
|
||||
F(attack)
|
||||
F(regen)
|
||||
F(manaregen)
|
||||
F(enduranceregen)
|
||||
F(haste)
|
||||
F(damageshield)
|
||||
F(recastdelay)
|
||||
F(recasttype)
|
||||
F(guildfavor)
|
||||
F(augdistiller)
|
||||
F(UNK123)
|
||||
F(UNK124)
|
||||
F(attuneable)
|
||||
F(nopet)
|
||||
F(UNK127)
|
||||
F(pointtype)
|
||||
F(potionbelt)
|
||||
F(potionbeltslots)
|
||||
F(stacksize)
|
||||
F(notransfer)
|
||||
F(stackable)
|
||||
F(UNK134)
|
||||
F(clickeffect)
|
||||
F(clicktype)
|
||||
F(clicklevel)
|
||||
F(clicklevel2)
|
||||
F(proceffect)
|
||||
F(proctype)
|
||||
F(proclevel)
|
||||
F(proclevel2)
|
||||
F(worneffect)
|
||||
F(worntype)
|
||||
F(wornlevel)
|
||||
F(wornlevel2)
|
||||
F(focuseffect)
|
||||
F(focustype)
|
||||
F(focuslevel)
|
||||
F(focuslevel2)
|
||||
F(scrolleffect)
|
||||
F(scrolltype)
|
||||
F(scrolllevel)
|
||||
F(scrolllevel2)
|
||||
F(bardeffect)
|
||||
F(bardeffecttype)
|
||||
F(bardlevel2)
|
||||
F(bardlevel)
|
||||
F(questitemflag)
|
||||
F(svcorruption)
|
||||
F(purity)
|
||||
F(evoitem)
|
||||
F(evoid)
|
||||
F(evolvinglevel)
|
||||
F(evomax)
|
||||
F(backstabdmg)
|
||||
F(dsmitigation)
|
||||
F(heroic_str)
|
||||
F(heroic_int)
|
||||
F(heroic_wis)
|
||||
F(heroic_agi)
|
||||
F(heroic_dex)
|
||||
F(heroic_sta)
|
||||
F(heroic_cha)
|
||||
F(heroic_mr)
|
||||
F(heroic_fr)
|
||||
F(heroic_cr)
|
||||
F(heroic_dr)
|
||||
F(heroic_pr)
|
||||
F(heroic_svcorrup)
|
||||
F(healamt)
|
||||
F(spelldmg)
|
||||
F(ldonsellbackrate)
|
||||
F(scriptfileid)
|
||||
F(expendablearrow)
|
||||
F(clairvoyance)
|
||||
F(clickname)
|
||||
F(procname)
|
||||
F(wornname)
|
||||
F(focusname)
|
||||
F(scrollname)
|
||||
F(subtype)
|
||||
@ -1,11 +1,11 @@
|
||||
#include "eqstream.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
|
||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options)
|
||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_reliable_stream(options.reliable_stream_options)
|
||||
{
|
||||
m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
|
||||
m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
m_reliable_stream.OnNewConnection(std::bind(&EQStreamManager::ReliableStreamNewConnection, this, std::placeholders::_1));
|
||||
m_reliable_stream.OnConnectionStateChange(std::bind(&EQStreamManager::ReliableStreamConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_reliable_stream.OnPacketRecv(std::bind(&EQStreamManager::ReliableStreamPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
EQ::Net::EQStreamManager::~EQStreamManager()
|
||||
@ -15,11 +15,11 @@ EQ::Net::EQStreamManager::~EQStreamManager()
|
||||
void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options)
|
||||
{
|
||||
m_options = options;
|
||||
auto &opts = m_daybreak.GetOptions();
|
||||
opts = options.daybreak_options;
|
||||
auto &opts = m_reliable_stream.GetOptions();
|
||||
opts = options.reliable_stream_options;
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
||||
void EQ::Net::EQStreamManager::ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection)
|
||||
{
|
||||
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
||||
m_streams.emplace(std::make_pair(connection, stream));
|
||||
@ -28,7 +28,7 @@ void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakCon
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
||||
void EQ::Net::EQStreamManager::ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
||||
{
|
||||
auto iter = m_streams.find(connection);
|
||||
if (iter != m_streams.end()) {
|
||||
@ -42,7 +42,7 @@ void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<Day
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p)
|
||||
void EQ::Net::EQStreamManager::ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p)
|
||||
{
|
||||
auto iter = m_streams.find(connection);
|
||||
if (iter != m_streams.end()) {
|
||||
@ -53,7 +53,7 @@ void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnec
|
||||
}
|
||||
}
|
||||
|
||||
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<DaybreakConnection> connection)
|
||||
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<ReliableStreamConnection> connection)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_connection = connection;
|
||||
@ -235,7 +235,7 @@ EQStreamState EQ::Net::EQStream::GetState() {
|
||||
EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const
|
||||
{
|
||||
Stats ret;
|
||||
ret.DaybreakStats = m_connection->GetStats();
|
||||
ret.ReliableStreamStats = m_connection->GetStats();
|
||||
|
||||
for (int i = 0; i < _maxEmuOpcode; ++i) {
|
||||
ret.RecvCount[i] = 0;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include "../eq_packet.h"
|
||||
#include "../eq_stream_intf.h"
|
||||
#include "../opcodemgr.h"
|
||||
#include "daybreak_connection.h"
|
||||
#include "reliable_stream_connection.h"
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
@ -23,21 +23,21 @@ namespace EQ
|
||||
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
|
||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||
private:
|
||||
DaybreakConnectionManager m_daybreak;
|
||||
ReliableStreamConnectionManager m_reliable_stream;
|
||||
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
|
||||
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
|
||||
std::map<std::shared_ptr<ReliableStreamConnection>, std::shared_ptr<EQStream>> m_streams;
|
||||
|
||||
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
|
||||
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
||||
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
|
||||
void ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection);
|
||||
void ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
||||
void ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p);
|
||||
friend class EQStream;
|
||||
};
|
||||
|
||||
class EQStream : public EQStreamInterface
|
||||
{
|
||||
public:
|
||||
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<DaybreakConnection> connection);
|
||||
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<ReliableStreamConnection> connection);
|
||||
~EQStream();
|
||||
|
||||
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
|
||||
@ -67,7 +67,7 @@ namespace EQ
|
||||
virtual EQStreamManagerInterface* GetManager() const;
|
||||
private:
|
||||
EQStreamManagerInterface *m_owner;
|
||||
std::shared_ptr<DaybreakConnection> m_connection;
|
||||
std::shared_ptr<ReliableStreamConnection> m_connection;
|
||||
OpcodeManager **m_opcode_manager;
|
||||
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
|
||||
std::unordered_map<int, int> m_packet_recv_count;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "daybreak_connection.h"
|
||||
#include "reliable_stream_connection.h"
|
||||
#include "../event/event_loop.h"
|
||||
#include "../data_verification.h"
|
||||
#include "crc32.h"
|
||||
@ -12,7 +12,7 @@ constexpr size_t MAX_CLIENT_RECV_BYTES_PER_WINDOW = 140 * 1024;
|
||||
// buffer pools
|
||||
SendBufferPool send_buffer_pool;
|
||||
|
||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
||||
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager()
|
||||
{
|
||||
m_attached = nullptr;
|
||||
memset(&m_timer, 0, sizeof(uv_timer_t));
|
||||
@ -21,7 +21,7 @@ EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
||||
Attach(EQ::EventLoop::Get().Handle());
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts)
|
||||
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts)
|
||||
{
|
||||
m_attached = nullptr;
|
||||
m_options = opts;
|
||||
@ -31,12 +31,12 @@ EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConn
|
||||
Attach(EQ::EventLoop::Get().Handle());
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnectionManager::~DaybreakConnectionManager()
|
||||
EQ::Net::ReliableStreamConnectionManager::~ReliableStreamConnectionManager()
|
||||
{
|
||||
Detach();
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
|
||||
{
|
||||
if (!m_attached) {
|
||||
uv_timer_init(loop, &m_timer);
|
||||
@ -45,7 +45,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
auto update_rate = (uint64_t)(1000.0 / m_options.tic_rate_hertz);
|
||||
|
||||
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
|
||||
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
|
||||
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data;
|
||||
c->UpdateDataBudget();
|
||||
c->Process();
|
||||
c->ProcessResend();
|
||||
@ -71,7 +71,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
buf->len = 65536;
|
||||
},
|
||||
[](uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) {
|
||||
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
|
||||
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data;
|
||||
if (nread < 0 || addr == nullptr) {
|
||||
return;
|
||||
}
|
||||
@ -90,7 +90,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Detach()
|
||||
void EQ::Net::ReliableStreamConnectionManager::Detach()
|
||||
{
|
||||
if (m_attached) {
|
||||
uv_udp_recv_stop(&m_socket);
|
||||
@ -99,11 +99,11 @@ void EQ::Net::DaybreakConnectionManager::Detach()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int port)
|
||||
void EQ::Net::ReliableStreamConnectionManager::Connect(const std::string &addr, int port)
|
||||
{
|
||||
//todo dns resolution
|
||||
|
||||
auto connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, addr, port));
|
||||
auto connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, addr, port));
|
||||
connection->m_self = connection;
|
||||
|
||||
if (m_on_new_connection) {
|
||||
@ -113,7 +113,7 @@ void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int po
|
||||
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Process()
|
||||
void EQ::Net::ReliableStreamConnectionManager::Process()
|
||||
{
|
||||
auto now = Clock::now();
|
||||
auto iter = m_connections.begin();
|
||||
@ -177,7 +177,7 @@ void EQ::Net::DaybreakConnectionManager::Process()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::UpdateDataBudget()
|
||||
void EQ::Net::ReliableStreamConnectionManager::UpdateDataBudget()
|
||||
{
|
||||
auto outgoing_data_rate = m_options.outgoing_data_rate;
|
||||
if (outgoing_data_rate <= 0.0) {
|
||||
@ -196,7 +196,7 @@ void EQ::Net::DaybreakConnectionManager::UpdateDataBudget()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
||||
void EQ::Net::ReliableStreamConnectionManager::ProcessResend()
|
||||
{
|
||||
auto iter = m_connections.begin();
|
||||
while (iter != m_connections.end()) {
|
||||
@ -217,15 +217,15 @@ void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size)
|
||||
void EQ::Net::ReliableStreamConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size)
|
||||
{
|
||||
if (m_options.simulated_in_packet_loss && m_options.simulated_in_packet_loss >= m_rand.Int(0, 100)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < DaybreakHeader::size()) {
|
||||
if (size < ReliableStreamHeader::size()) {
|
||||
if (m_on_error_message) {
|
||||
m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, DaybreakHeader::size()));
|
||||
m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, ReliableStreamHeader::size()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -239,9 +239,9 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
||||
else {
|
||||
if (data[0] == 0 && data[1] == OP_SessionRequest) {
|
||||
StaticPacket p((void*)data, size);
|
||||
auto request = p.GetSerialize<DaybreakConnect>(0);
|
||||
auto request = p.GetSerialize<ReliableStreamConnect>(0);
|
||||
|
||||
connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, request, endpoint, port));
|
||||
connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, request, endpoint, port));
|
||||
connection->m_self = connection;
|
||||
|
||||
if (m_on_new_connection) {
|
||||
@ -262,7 +262,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> EQ::Net::DaybreakConnectionManager::FindConnectionByEndpoint(std::string addr, int port)
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> EQ::Net::ReliableStreamConnectionManager::FindConnectionByEndpoint(std::string addr, int port)
|
||||
{
|
||||
auto p = std::make_pair(addr, port);
|
||||
auto iter = m_connections.find(p);
|
||||
@ -273,9 +273,9 @@ std::shared_ptr<EQ::Net::DaybreakConnection> EQ::Net::DaybreakConnectionManager:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr, int port)
|
||||
void EQ::Net::ReliableStreamConnectionManager::SendDisconnect(const std::string &addr, int port)
|
||||
{
|
||||
DaybreakDisconnect header;
|
||||
ReliableStreamDisconnect header;
|
||||
header.zero = 0;
|
||||
header.opcode = OP_OutOfSession;
|
||||
header.connect_code = 0;
|
||||
@ -300,7 +300,7 @@ void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr,
|
||||
}
|
||||
|
||||
//new connection made as server
|
||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port)
|
||||
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_last_send = Clock::now();
|
||||
@ -327,7 +327,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
}
|
||||
|
||||
//new connection made as client
|
||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port)
|
||||
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_last_send = Clock::now();
|
||||
@ -349,11 +349,11 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnection::~DaybreakConnection()
|
||||
EQ::Net::ReliableStreamConnection::~ReliableStreamConnection()
|
||||
{
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Close()
|
||||
void EQ::Net::ReliableStreamConnection::Close()
|
||||
{
|
||||
if (m_status != StatusDisconnected && m_status != StatusDisconnecting) {
|
||||
FlushBuffer();
|
||||
@ -367,17 +367,17 @@ void EQ::Net::DaybreakConnection::Close()
|
||||
ChangeStatus(StatusDisconnecting);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p)
|
||||
{
|
||||
QueuePacket(p, 0, true);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream)
|
||||
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream)
|
||||
{
|
||||
QueuePacket(p, stream, true);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliable)
|
||||
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream, bool reliable)
|
||||
{
|
||||
if (*(char*)p.Data() == 0) {
|
||||
DynamicPacket packet;
|
||||
@ -390,21 +390,21 @@ void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliab
|
||||
InternalQueuePacket(p, stream, reliable);
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnectionStats EQ::Net::DaybreakConnection::GetStats()
|
||||
EQ::Net::ReliableStreamConnectionStats EQ::Net::ReliableStreamConnection::GetStats()
|
||||
{
|
||||
EQ::Net::DaybreakConnectionStats ret = m_stats;
|
||||
EQ::Net::ReliableStreamConnectionStats ret = m_stats;
|
||||
ret.datarate_remaining = m_outgoing_budget;
|
||||
ret.avg_ping = m_rolling_ping;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ResetStats()
|
||||
void EQ::Net::ReliableStreamConnection::ResetStats()
|
||||
{
|
||||
m_stats.Reset();
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Process()
|
||||
void EQ::Net::ReliableStreamConnection::Process()
|
||||
{
|
||||
try {
|
||||
auto now = Clock::now();
|
||||
@ -422,7 +422,7 @@ void EQ::Net::DaybreakConnection::Process()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
|
||||
{
|
||||
m_last_recv = Clock::now();
|
||||
m_stats.recv_packets++;
|
||||
@ -458,13 +458,13 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
switch (m_encode_passes[i]) {
|
||||
case EncodeCompression:
|
||||
if(temp.GetInt8(0) == 0)
|
||||
Decompress(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
Decompress(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||
else
|
||||
Decompress(temp, 1, temp.Length() - 1);
|
||||
break;
|
||||
case EncodeXOR:
|
||||
if (temp.GetInt8(0) == 0)
|
||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||
else
|
||||
Decode(temp, 1, temp.Length() - 1);
|
||||
break;
|
||||
@ -483,7 +483,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
switch (m_encode_passes[i]) {
|
||||
case EncodeXOR:
|
||||
if (temp.GetInt8(0) == 0)
|
||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||
else
|
||||
Decode(temp, 1, temp.Length() - 1);
|
||||
break;
|
||||
@ -502,7 +502,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessQueue()
|
||||
void EQ::Net::ReliableStreamConnection::ProcessQueue()
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
auto stream = &m_streams[i];
|
||||
@ -521,7 +521,7 @@ void EQ::Net::DaybreakConnection::ProcessQueue()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||
{
|
||||
auto s = &m_streams[stream];
|
||||
auto iter = s->packet_queue.find(seq);
|
||||
@ -532,7 +532,7 @@ void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
|
||||
{
|
||||
auto s = &m_streams[stream];
|
||||
auto iter = s->packet_queue.find(seq);
|
||||
@ -544,7 +544,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
|
||||
{
|
||||
if (p.GetInt8(0) == 0) {
|
||||
if (p.Length() < 2) {
|
||||
@ -628,13 +628,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_SessionRequest:
|
||||
{
|
||||
if (m_status == StatusConnected) {
|
||||
auto request = p.GetSerialize<DaybreakConnect>(0);
|
||||
auto request = p.GetSerialize<ReliableStreamConnect>(0);
|
||||
|
||||
if (NetworkToHost(request.connect_code) != m_connect_code) {
|
||||
return;
|
||||
}
|
||||
|
||||
DaybreakConnectReply reply;
|
||||
ReliableStreamConnectReply reply;
|
||||
reply.zero = 0;
|
||||
reply.opcode = OP_SessionResponse;
|
||||
reply.connect_code = HostToNetwork(m_connect_code);
|
||||
@ -656,13 +656,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_SessionResponse:
|
||||
{
|
||||
if (m_status == StatusConnecting) {
|
||||
auto reply = p.GetSerialize<DaybreakConnectReply>(0);
|
||||
auto reply = p.GetSerialize<ReliableStreamConnectReply>(0);
|
||||
|
||||
if (m_connect_code == reply.connect_code) {
|
||||
m_encode_key = reply.encode_key;
|
||||
m_crc_bytes = reply.crc_bytes;
|
||||
m_encode_passes[0] = (DaybreakEncodeType)reply.encode_pass1;
|
||||
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
|
||||
m_encode_passes[0] = (ReliableStreamEncodeType)reply.encode_pass1;
|
||||
m_encode_passes[1] = (ReliableStreamEncodeType)reply.encode_pass2;
|
||||
m_max_packet_size = reply.max_packet_size;
|
||||
ChangeStatus(StatusConnected);
|
||||
|
||||
@ -686,7 +686,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
return;
|
||||
}
|
||||
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_Packet;
|
||||
auto stream = &m_streams[stream_id];
|
||||
@ -703,7 +703,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
RemoveFromQueue(stream_id, sequence);
|
||||
SendAck(stream_id, stream->sequence_in);
|
||||
stream->sequence_in++;
|
||||
StaticPacket next((char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
|
||||
StaticPacket next((char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size());
|
||||
ProcessDecodedPacket(next);
|
||||
}
|
||||
|
||||
@ -715,7 +715,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_Fragment3:
|
||||
case OP_Fragment4:
|
||||
{
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_Fragment;
|
||||
auto stream = &m_streams[stream_id];
|
||||
@ -735,22 +735,22 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
stream->sequence_in++;
|
||||
|
||||
if (stream->fragment_total_bytes == 0) {
|
||||
auto fragheader = p.GetSerialize<DaybreakReliableFragmentHeader>(0);
|
||||
auto fragheader = p.GetSerialize<ReliableStreamReliableFragmentHeader>(0);
|
||||
stream->fragment_total_bytes = NetworkToHost(fragheader.total_size);
|
||||
stream->fragment_current_bytes = 0;
|
||||
stream->fragment_packet.Reserve(stream->fragment_total_bytes);
|
||||
stream->fragment_packet.PutData(
|
||||
stream->fragment_current_bytes,
|
||||
(char*)p.Data() + DaybreakReliableFragmentHeader::size(), p.Length() - DaybreakReliableFragmentHeader::size());
|
||||
(char*)p.Data() + ReliableStreamReliableFragmentHeader::size(), p.Length() - ReliableStreamReliableFragmentHeader::size());
|
||||
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableFragmentHeader::size());
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableFragmentHeader::size());
|
||||
}
|
||||
else {
|
||||
stream->fragment_packet.PutData(
|
||||
stream->fragment_current_bytes,
|
||||
(char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
|
||||
(char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size());
|
||||
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableHeader::size());
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableHeader::size());
|
||||
|
||||
if (stream->fragment_current_bytes >= stream->fragment_total_bytes) {
|
||||
ProcessDecodedPacket(stream->fragment_packet);
|
||||
@ -769,7 +769,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_Ack3:
|
||||
case OP_Ack4:
|
||||
{
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_Ack;
|
||||
Ack(stream_id, sequence);
|
||||
@ -781,7 +781,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_OutOfOrderAck3:
|
||||
case OP_OutOfOrderAck4:
|
||||
{
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_OutOfOrderAck;
|
||||
OutOfOrderAck(stream_id, sequence);
|
||||
@ -815,13 +815,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
}
|
||||
case OP_SessionStatRequest:
|
||||
{
|
||||
auto request = p.GetSerialize<DaybreakSessionStatRequest>(0);
|
||||
auto request = p.GetSerialize<ReliableStreamSessionStatRequest>(0);
|
||||
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(request.packets_sent);
|
||||
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(request.packets_recv);
|
||||
m_stats.sync_sent_packets = m_stats.sent_packets;
|
||||
m_stats.sync_recv_packets = m_stats.recv_packets;
|
||||
|
||||
DaybreakSessionStatResponse response;
|
||||
ReliableStreamSessionStatResponse response;
|
||||
response.zero = 0;
|
||||
response.opcode = OP_SessionStatResponse;
|
||||
response.timestamp = request.timestamp;
|
||||
@ -836,7 +836,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
break;
|
||||
}
|
||||
case OP_SessionStatResponse: {
|
||||
auto response = p.GetSerialize<DaybreakSessionStatResponse>(0);
|
||||
auto response = p.GetSerialize<ReliableStreamSessionStatResponse>(0);
|
||||
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(response.server_sent);
|
||||
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(response.server_recv);
|
||||
m_stats.sync_sent_packets = m_stats.sent_packets;
|
||||
@ -858,7 +858,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
||||
bool EQ::Net::ReliableStreamConnection::ValidateCRC(Packet &p)
|
||||
{
|
||||
if (m_crc_bytes == 0U) {
|
||||
return true;
|
||||
@ -892,7 +892,7 @@ bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
||||
return false;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::AppendCRC(Packet &p)
|
||||
{
|
||||
if (m_crc_bytes == 0U) {
|
||||
return;
|
||||
@ -911,7 +911,7 @@ void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ChangeStatus(DbProtocolStatus new_status)
|
||||
void EQ::Net::ReliableStreamConnection::ChangeStatus(DbProtocolStatus new_status)
|
||||
{
|
||||
if (m_owner->m_on_connection_state_change) {
|
||||
if (auto self = m_self.lock()) {
|
||||
@ -922,7 +922,7 @@ void EQ::Net::DaybreakConnection::ChangeStatus(DbProtocolStatus new_status)
|
||||
m_status = new_status;
|
||||
}
|
||||
|
||||
bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const
|
||||
bool EQ::Net::ReliableStreamConnection::PacketCanBeEncoded(Packet &p) const
|
||||
{
|
||||
if (p.Length() < 2) {
|
||||
return false;
|
||||
@ -941,7 +941,7 @@ bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Decode(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Decode(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
int key = m_encode_key;
|
||||
char *buffer = (char*)p.Data() + offset;
|
||||
@ -961,7 +961,7 @@ void EQ::Net::DaybreakConnection::Decode(Packet &p, size_t offset, size_t length
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Encode(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Encode(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
int key = m_encode_key;
|
||||
char *buffer = (char*)p.Data() + offset;
|
||||
@ -1050,7 +1050,7 @@ uint32_t Deflate(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t out_
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Decompress(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Decompress(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
if (length < 2) {
|
||||
return;
|
||||
@ -1075,7 +1075,7 @@ void EQ::Net::DaybreakConnection::Decompress(Packet &p, size_t offset, size_t le
|
||||
p.PutData(offset, new_buffer, new_length);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Compress(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
static thread_local uint8_t new_buffer[2048] = { 0 };
|
||||
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
||||
@ -1097,14 +1097,14 @@ void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t leng
|
||||
p.PutData(offset, new_buffer, new_length);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessResend()
|
||||
void EQ::Net::ReliableStreamConnection::ProcessResend()
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
ProcessResend(i);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
|
||||
{
|
||||
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
||||
return;
|
||||
@ -1201,7 +1201,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
|
||||
auto &sp = e.second;
|
||||
auto &p = sp.packet;
|
||||
if (p.Length() >= DaybreakHeader::size()) {
|
||||
if (p.Length() >= ReliableStreamHeader::size()) {
|
||||
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
|
||||
m_stats.resent_fragments++;
|
||||
}
|
||||
@ -1232,7 +1232,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
m_last_ack = now;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::Ack(int stream, uint16_t seq)
|
||||
{
|
||||
auto now = Clock::now();
|
||||
auto s = &m_streams[stream];
|
||||
@ -1259,7 +1259,7 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
||||
m_last_ack = now;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::OutOfOrderAck(int stream, uint16_t seq)
|
||||
{
|
||||
auto now = Clock::now();
|
||||
auto s = &m_streams[stream];
|
||||
@ -1279,15 +1279,15 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
||||
m_last_ack = now;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::UpdateDataBudget(double budget_add)
|
||||
void EQ::Net::ReliableStreamConnection::UpdateDataBudget(double budget_add)
|
||||
{
|
||||
auto outgoing_data_rate = m_owner->m_options.outgoing_data_rate;
|
||||
m_outgoing_budget = EQ::ClampUpper(m_outgoing_budget + budget_add, outgoing_data_rate);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::SendAck(int stream_id, uint16_t seq)
|
||||
{
|
||||
DaybreakReliableHeader ack;
|
||||
ReliableStreamReliableHeader ack;
|
||||
ack.zero = 0;
|
||||
ack.opcode = OP_Ack + stream_id;
|
||||
ack.sequence = HostToNetwork(seq);
|
||||
@ -1298,9 +1298,9 @@ void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
||||
InternalBufferedSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
||||
{
|
||||
DaybreakReliableHeader ack;
|
||||
ReliableStreamReliableHeader ack;
|
||||
ack.zero = 0;
|
||||
ack.opcode = OP_OutOfOrderAck + stream_id;
|
||||
ack.sequence = HostToNetwork(seq);
|
||||
@ -1311,9 +1311,9 @@ void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
||||
InternalBufferedSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendDisconnect()
|
||||
void EQ::Net::ReliableStreamConnection::SendDisconnect()
|
||||
{
|
||||
DaybreakDisconnect disconnect;
|
||||
ReliableStreamDisconnect disconnect;
|
||||
disconnect.zero = 0;
|
||||
disconnect.opcode = OP_SessionDisconnect;
|
||||
disconnect.connect_code = HostToNetwork(m_connect_code);
|
||||
@ -1322,7 +1322,7 @@ void EQ::Net::DaybreakConnection::SendDisconnect()
|
||||
InternalSend(out);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p)
|
||||
{
|
||||
if (p.Length() > 0xFFU) {
|
||||
FlushBuffer();
|
||||
@ -1331,7 +1331,7 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
||||
}
|
||||
|
||||
//we could add this packet to a combined
|
||||
size_t raw_size = DaybreakHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length();
|
||||
size_t raw_size = ReliableStreamHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length();
|
||||
if (raw_size > m_max_packet_size) {
|
||||
FlushBuffer();
|
||||
}
|
||||
@ -1346,9 +1346,9 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendConnect()
|
||||
void EQ::Net::ReliableStreamConnection::SendConnect()
|
||||
{
|
||||
DaybreakConnect connect;
|
||||
ReliableStreamConnect connect;
|
||||
connect.zero = 0;
|
||||
connect.opcode = OP_SessionRequest;
|
||||
connect.protocol_version = HostToNetwork(3U);
|
||||
@ -1361,9 +1361,9 @@ void EQ::Net::DaybreakConnection::SendConnect()
|
||||
InternalSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendKeepAlive()
|
||||
void EQ::Net::ReliableStreamConnection::SendKeepAlive()
|
||||
{
|
||||
DaybreakHeader keep_alive;
|
||||
ReliableStreamHeader keep_alive;
|
||||
keep_alive.zero = 0;
|
||||
keep_alive.opcode = OP_KeepAlive;
|
||||
|
||||
@ -1373,7 +1373,7 @@ void EQ::Net::DaybreakConnection::SendKeepAlive()
|
||||
InternalSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
||||
void EQ::Net::ReliableStreamConnection::InternalSend(Packet &p) {
|
||||
if (m_owner->m_options.outgoing_data_rate > 0.0) {
|
||||
auto new_budget = m_outgoing_budget - (p.Length() / 1024.0);
|
||||
if (new_budget <= 0.0) {
|
||||
@ -1409,14 +1409,14 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
||||
switch (m_encode_passe) {
|
||||
case EncodeCompression:
|
||||
if (out.GetInt8(0) == 0) {
|
||||
Compress(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
||||
Compress(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
|
||||
} else {
|
||||
Compress(out, 1, out.Length() - 1);
|
||||
}
|
||||
break;
|
||||
case EncodeXOR:
|
||||
if (out.GetInt8(0) == 0) {
|
||||
Encode(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
||||
Encode(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
|
||||
} else {
|
||||
Encode(out, 1, out.Length() - 1);
|
||||
}
|
||||
@ -1466,7 +1466,7 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
|
||||
void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
|
||||
{
|
||||
if (!reliable) {
|
||||
auto max_raw_size = 0xFFU - m_crc_bytes;
|
||||
@ -1480,23 +1480,23 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
}
|
||||
|
||||
auto stream = &m_streams[stream_id];
|
||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
|
||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - ReliableStreamReliableHeader::size() - 1; // -1 for compress flag
|
||||
size_t length = p.Length();
|
||||
if (length > max_raw_size) {
|
||||
DaybreakReliableFragmentHeader first_header;
|
||||
ReliableStreamReliableFragmentHeader first_header;
|
||||
first_header.reliable.zero = 0;
|
||||
first_header.reliable.opcode = OP_Fragment + stream_id;
|
||||
first_header.reliable.sequence = HostToNetwork(stream->sequence_out);
|
||||
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
|
||||
|
||||
size_t used = 0;
|
||||
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size() - 1; // -1 for compress flag
|
||||
size_t sublen = m_max_packet_size - m_crc_bytes - ReliableStreamReliableFragmentHeader::size() - 1; // -1 for compress flag
|
||||
DynamicPacket first_packet;
|
||||
first_packet.PutSerialize(0, first_header);
|
||||
first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
||||
first_packet.PutData(ReliableStreamReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
||||
used += sublen;
|
||||
|
||||
DaybreakSentPacket sent;
|
||||
ReliableStreamSentPacket sent;
|
||||
sent.packet.PutPacket(0, first_packet);
|
||||
sent.last_sent = Clock::now();
|
||||
sent.first_sent = Clock::now();
|
||||
@ -1513,22 +1513,22 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
while (used < length) {
|
||||
auto left = length - used;
|
||||
DynamicPacket packet;
|
||||
DaybreakReliableHeader header;
|
||||
ReliableStreamReliableHeader header;
|
||||
header.zero = 0;
|
||||
header.opcode = OP_Fragment + stream_id;
|
||||
header.sequence = HostToNetwork(stream->sequence_out);
|
||||
packet.PutSerialize(0, header);
|
||||
|
||||
if (left > max_raw_size) {
|
||||
packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, max_raw_size);
|
||||
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, max_raw_size);
|
||||
used += max_raw_size;
|
||||
}
|
||||
else {
|
||||
packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, left);
|
||||
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, left);
|
||||
used += left;
|
||||
}
|
||||
|
||||
DaybreakSentPacket sent;
|
||||
ReliableStreamSentPacket sent;
|
||||
sent.packet.PutPacket(0, packet);
|
||||
sent.last_sent = Clock::now();
|
||||
sent.first_sent = Clock::now();
|
||||
@ -1545,14 +1545,14 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
}
|
||||
else {
|
||||
DynamicPacket packet;
|
||||
DaybreakReliableHeader header;
|
||||
ReliableStreamReliableHeader header;
|
||||
header.zero = 0;
|
||||
header.opcode = OP_Packet + stream_id;
|
||||
header.sequence = HostToNetwork(stream->sequence_out);
|
||||
packet.PutSerialize(0, header);
|
||||
packet.PutPacket(DaybreakReliableHeader::size(), p);
|
||||
packet.PutPacket(ReliableStreamReliableHeader::size(), p);
|
||||
|
||||
DaybreakSentPacket sent;
|
||||
ReliableStreamSentPacket sent;
|
||||
sent.packet.PutPacket(0, packet);
|
||||
sent.last_sent = Clock::now();
|
||||
sent.first_sent = Clock::now();
|
||||
@ -1568,7 +1568,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::FlushBuffer()
|
||||
void EQ::Net::ReliableStreamConnection::FlushBuffer()
|
||||
{
|
||||
if (m_buffered_packets.empty()) {
|
||||
return;
|
||||
@ -1595,7 +1595,7 @@ void EQ::Net::DaybreakConnection::FlushBuffer()
|
||||
m_buffered_packets_length = 0;
|
||||
}
|
||||
|
||||
EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t expected, uint16_t actual) const
|
||||
EQ::Net::SequenceOrder EQ::Net::ReliableStreamConnection::CompareSequence(uint16_t expected, uint16_t actual) const
|
||||
{
|
||||
int diff = (int)actual - (int)expected;
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
#include "../random.h"
|
||||
#include "packet.h"
|
||||
#include "daybreak_structs.h"
|
||||
#include "daybreak_pooling.h"
|
||||
#include "reliable_stream_structs.h"
|
||||
#include "reliable_stream_pooling.h"
|
||||
#include <uv.h>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
@ -16,7 +16,7 @@ namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
enum DaybreakProtocolOpcode
|
||||
enum ReliableStreamProtocolOpcode
|
||||
{
|
||||
OP_Padding = 0x00,
|
||||
OP_SessionRequest = 0x01,
|
||||
@ -55,7 +55,7 @@ namespace EQ
|
||||
StatusDisconnected
|
||||
};
|
||||
|
||||
enum DaybreakEncodeType
|
||||
enum ReliableStreamEncodeType
|
||||
{
|
||||
EncodeNone = 0,
|
||||
EncodeCompression = 1,
|
||||
@ -72,9 +72,9 @@ namespace EQ
|
||||
typedef std::chrono::steady_clock::time_point Timestamp;
|
||||
typedef std::chrono::steady_clock Clock;
|
||||
|
||||
struct DaybreakConnectionStats
|
||||
struct ReliableStreamConnectionStats
|
||||
{
|
||||
DaybreakConnectionStats() {
|
||||
ReliableStreamConnectionStats() {
|
||||
recv_bytes = 0;
|
||||
sent_bytes = 0;
|
||||
recv_packets = 0;
|
||||
@ -134,14 +134,14 @@ namespace EQ
|
||||
uint64_t bytes_before_encode;
|
||||
};
|
||||
|
||||
class DaybreakConnectionManager;
|
||||
class DaybreakConnection;
|
||||
class DaybreakConnection
|
||||
class ReliableStreamConnectionManager;
|
||||
class ReliableStreamConnection;
|
||||
class ReliableStreamConnection
|
||||
{
|
||||
public:
|
||||
DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
|
||||
DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port);
|
||||
~DaybreakConnection();
|
||||
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port);
|
||||
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port);
|
||||
~ReliableStreamConnection();
|
||||
|
||||
const std::string& RemoteEndpoint() const { return m_endpoint; }
|
||||
int RemotePort() const { return m_port; }
|
||||
@ -151,23 +151,23 @@ namespace EQ
|
||||
void QueuePacket(Packet &p, int stream);
|
||||
void QueuePacket(Packet &p, int stream, bool reliable);
|
||||
|
||||
DaybreakConnectionStats GetStats();
|
||||
ReliableStreamConnectionStats GetStats();
|
||||
void ResetStats();
|
||||
size_t GetRollingPing() const { return m_rolling_ping; }
|
||||
DbProtocolStatus GetStatus() const { return m_status; }
|
||||
|
||||
const DaybreakEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
||||
const DaybreakConnectionManager* GetManager() const { return m_owner; }
|
||||
DaybreakConnectionManager* GetManager() { return m_owner; }
|
||||
const ReliableStreamEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
||||
const ReliableStreamConnectionManager* GetManager() const { return m_owner; }
|
||||
ReliableStreamConnectionManager* GetManager() { return m_owner; }
|
||||
private:
|
||||
DaybreakConnectionManager *m_owner;
|
||||
ReliableStreamConnectionManager *m_owner;
|
||||
std::string m_endpoint;
|
||||
int m_port;
|
||||
uint32_t m_connect_code;
|
||||
uint32_t m_encode_key;
|
||||
uint32_t m_max_packet_size;
|
||||
uint32_t m_crc_bytes;
|
||||
DaybreakEncodeType m_encode_passes[2];
|
||||
ReliableStreamEncodeType m_encode_passes[2];
|
||||
|
||||
Timestamp m_last_send;
|
||||
Timestamp m_last_recv;
|
||||
@ -176,7 +176,7 @@ namespace EQ
|
||||
std::list<DynamicPacket> m_buffered_packets;
|
||||
size_t m_buffered_packets_length;
|
||||
std::unique_ptr<char[]> m_combined;
|
||||
DaybreakConnectionStats m_stats;
|
||||
ReliableStreamConnectionStats m_stats;
|
||||
Timestamp m_last_session_stats;
|
||||
size_t m_rolling_ping;
|
||||
Timestamp m_close_time;
|
||||
@ -188,7 +188,7 @@ namespace EQ
|
||||
bool m_acked_since_last_resend = false;
|
||||
Timestamp m_last_ack;
|
||||
|
||||
struct DaybreakSentPacket
|
||||
struct ReliableStreamSentPacket
|
||||
{
|
||||
DynamicPacket packet;
|
||||
Timestamp last_sent;
|
||||
@ -197,9 +197,9 @@ namespace EQ
|
||||
size_t resend_delay;
|
||||
};
|
||||
|
||||
struct DaybreakStream
|
||||
struct ReliableStream
|
||||
{
|
||||
DaybreakStream() {
|
||||
ReliableStream() {
|
||||
sequence_in = 0;
|
||||
sequence_out = 0;
|
||||
fragment_current_bytes = 0;
|
||||
@ -214,11 +214,11 @@ namespace EQ
|
||||
uint32_t fragment_current_bytes;
|
||||
uint32_t fragment_total_bytes;
|
||||
|
||||
std::map<uint16_t, DaybreakSentPacket> sent_packets;
|
||||
std::map<uint16_t, ReliableStreamSentPacket> sent_packets;
|
||||
};
|
||||
|
||||
DaybreakStream m_streams[4];
|
||||
std::weak_ptr<DaybreakConnection> m_self;
|
||||
ReliableStream m_streams[4];
|
||||
std::weak_ptr<ReliableStreamConnection> m_self;
|
||||
|
||||
void Process();
|
||||
void ProcessPacket(Packet &p);
|
||||
@ -251,12 +251,12 @@ namespace EQ
|
||||
void FlushBuffer();
|
||||
SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const;
|
||||
|
||||
friend class DaybreakConnectionManager;
|
||||
friend class ReliableStreamConnectionManager;
|
||||
};
|
||||
|
||||
struct DaybreakConnectionManagerOptions
|
||||
struct ReliableStreamConnectionManagerOptions
|
||||
{
|
||||
DaybreakConnectionManagerOptions() {
|
||||
ReliableStreamConnectionManagerOptions() {
|
||||
max_connection_count = 0;
|
||||
keepalive_delay_ms = 9000;
|
||||
resend_delay_ms = 30;
|
||||
@ -268,8 +268,8 @@ namespace EQ
|
||||
connect_stale_ms = 5000;
|
||||
crc_length = 2;
|
||||
max_packet_size = 512;
|
||||
encode_passes[0] = DaybreakEncodeType::EncodeNone;
|
||||
encode_passes[1] = DaybreakEncodeType::EncodeNone;
|
||||
encode_passes[0] = ReliableStreamEncodeType::EncodeNone;
|
||||
encode_passes[1] = ReliableStreamEncodeType::EncodeNone;
|
||||
port = 0;
|
||||
hold_size = 512;
|
||||
hold_length_ms = 50;
|
||||
@ -299,28 +299,28 @@ namespace EQ
|
||||
double tic_rate_hertz;
|
||||
size_t resend_timeout;
|
||||
size_t connection_close_time;
|
||||
DaybreakEncodeType encode_passes[2];
|
||||
ReliableStreamEncodeType encode_passes[2];
|
||||
int port;
|
||||
double outgoing_data_rate;
|
||||
};
|
||||
|
||||
class DaybreakConnectionManager
|
||||
class ReliableStreamConnectionManager
|
||||
{
|
||||
public:
|
||||
DaybreakConnectionManager();
|
||||
DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts);
|
||||
~DaybreakConnectionManager();
|
||||
ReliableStreamConnectionManager();
|
||||
ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts);
|
||||
~ReliableStreamConnectionManager();
|
||||
|
||||
void Connect(const std::string &addr, int port);
|
||||
void Process();
|
||||
void UpdateDataBudget();
|
||||
void ProcessResend();
|
||||
void OnNewConnection(std::function<void(std::shared_ptr<DaybreakConnection>)> func) { m_on_new_connection = func; }
|
||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||
void OnPacketRecv(std::function<void(std::shared_ptr<DaybreakConnection>, const Packet &)> func) { m_on_packet_recv = func; }
|
||||
void OnNewConnection(std::function<void(std::shared_ptr<ReliableStreamConnection>)> func) { m_on_new_connection = func; }
|
||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<ReliableStreamConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||
void OnPacketRecv(std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet &)> func) { m_on_packet_recv = func; }
|
||||
void OnErrorMessage(std::function<void(const std::string&)> func) { m_on_error_message = func; }
|
||||
|
||||
DaybreakConnectionManagerOptions& GetOptions() { return m_options; }
|
||||
ReliableStreamConnectionManagerOptions& GetOptions() { return m_options; }
|
||||
private:
|
||||
void Attach(uv_loop_t *loop);
|
||||
void Detach();
|
||||
@ -329,18 +329,18 @@ namespace EQ
|
||||
uv_timer_t m_timer;
|
||||
uv_udp_t m_socket;
|
||||
uv_loop_t *m_attached;
|
||||
DaybreakConnectionManagerOptions m_options;
|
||||
std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
|
||||
std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||
std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
|
||||
ReliableStreamConnectionManagerOptions m_options;
|
||||
std::function<void(std::shared_ptr<ReliableStreamConnection>)> m_on_new_connection;
|
||||
std::function<void(std::shared_ptr<ReliableStreamConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||
std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet&)> m_on_packet_recv;
|
||||
std::function<void(const std::string&)> m_on_error_message;
|
||||
std::map<std::pair<std::string, int>, std::shared_ptr<DaybreakConnection>> m_connections;
|
||||
std::map<std::pair<std::string, int>, std::shared_ptr<ReliableStreamConnection>> m_connections;
|
||||
|
||||
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
|
||||
std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
|
||||
std::shared_ptr<ReliableStreamConnection> FindConnectionByEndpoint(std::string addr, int port);
|
||||
void SendDisconnect(const std::string &addr, int port);
|
||||
|
||||
friend class DaybreakConnection;
|
||||
friend class ReliableStreamConnection;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@ namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
struct DaybreakHeader
|
||||
struct ReliableStreamHeader
|
||||
{
|
||||
static size_t size() { return 2; }
|
||||
uint8_t zero;
|
||||
@ -22,7 +22,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakConnect
|
||||
struct ReliableStreamConnect
|
||||
{
|
||||
static size_t size() { return 14; }
|
||||
uint8_t zero;
|
||||
@ -42,7 +42,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakConnectReply
|
||||
struct ReliableStreamConnectReply
|
||||
{
|
||||
static size_t size() { return 17; }
|
||||
uint8_t zero;
|
||||
@ -68,7 +68,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakDisconnect
|
||||
struct ReliableStreamDisconnect
|
||||
{
|
||||
static size_t size() { return 8; }
|
||||
uint8_t zero;
|
||||
@ -84,7 +84,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakReliableHeader
|
||||
struct ReliableStreamReliableHeader
|
||||
{
|
||||
static size_t size() { return 4; }
|
||||
uint8_t zero;
|
||||
@ -100,10 +100,10 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakReliableFragmentHeader
|
||||
struct ReliableStreamReliableFragmentHeader
|
||||
{
|
||||
static size_t size() { return 4 + DaybreakReliableHeader::size(); }
|
||||
DaybreakReliableHeader reliable;
|
||||
static size_t size() { return 4 + ReliableStreamReliableHeader::size(); }
|
||||
ReliableStreamReliableHeader reliable;
|
||||
uint32_t total_size;
|
||||
|
||||
template <class Archive>
|
||||
@ -114,7 +114,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakSessionStatRequest
|
||||
struct ReliableStreamSessionStatRequest
|
||||
{
|
||||
static size_t size() { return 40; }
|
||||
uint8_t zero;
|
||||
@ -144,7 +144,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakSessionStatResponse
|
||||
struct ReliableStreamSessionStatResponse
|
||||
{
|
||||
static size_t size() { return 40; }
|
||||
uint8_t zero;
|
||||
@ -6481,7 +6481,7 @@ namespace RoF2
|
||||
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
||||
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
||||
hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0;
|
||||
if (item->EvolvingItem) {
|
||||
if (item->EvolvingItem && packet_type != ItemPacketParcel && packet_type != ItemPacketMerchant) {
|
||||
hdr.instance_id = inst->GetEvolveUniqueID() & 0xFFFFFFFF; //lower dword
|
||||
hdr.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword
|
||||
}
|
||||
@ -6500,6 +6500,7 @@ namespace RoF2
|
||||
|
||||
if (item->EvolvingItem > 0) {
|
||||
RoF2::structs::EvolvingItem_Struct evotop;
|
||||
inst->CalculateEvolveProgression();
|
||||
|
||||
evotop.final_item_id = inst->GetEvolveFinalItemID();
|
||||
evotop.evolve_level = item->EvolvingLevel;
|
||||
|
||||
@ -1059,7 +1059,7 @@ namespace Titanium
|
||||
OUT(spawnid);
|
||||
OUT_str(charname);
|
||||
|
||||
if (emu->race > 473)
|
||||
if (emu->race > 474)
|
||||
eq->race = 1;
|
||||
else
|
||||
OUT(race);
|
||||
@ -1840,7 +1840,7 @@ namespace Titanium
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
|
||||
eq->Race[char_index] = emu_cse->Race;
|
||||
if (eq->Race[char_index] > 473)
|
||||
if (eq->Race[char_index] > 474)
|
||||
eq->Race[char_index] = 1;
|
||||
|
||||
for (int index = 0; index < EQ::textures::materialCount; ++index) {
|
||||
@ -2421,7 +2421,7 @@ namespace Titanium
|
||||
strcpy(eq->title, emu->title);
|
||||
// eq->unknown0274 = emu->unknown0274;
|
||||
eq->helm = emu->helm;
|
||||
if (emu->race > 473)
|
||||
if (emu->race > 474)
|
||||
eq->race = 1;
|
||||
else
|
||||
eq->race = emu->race;
|
||||
|
||||
@ -1,34 +1,14 @@
|
||||
// types
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
#pragma once
|
||||
|
||||
// containers
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
// Lightweight, widely used
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
// utilities
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
|
||||
// fmt
|
||||
#include <fmt/format.h>
|
||||
|
||||
// lua
|
||||
#include "lua.hpp"
|
||||
#include <luabind/luabind.hpp>
|
||||
#include <luabind/object.hpp>
|
||||
|
||||
3779
common/races.cpp
3779
common/races.cpp
File diff suppressed because it is too large
Load Diff
202
common/races.h
202
common/races.h
@ -21,103 +21,7 @@
|
||||
#include "../common/types.h"
|
||||
#include <string>
|
||||
|
||||
namespace Gender {
|
||||
constexpr uint8 Male = 0;
|
||||
constexpr uint8 Female = 1;
|
||||
constexpr uint8 Neuter = 2;
|
||||
}
|
||||
|
||||
//theres a big list straight from the client below.
|
||||
|
||||
#define HUMAN 1
|
||||
#define BARBARIAN 2
|
||||
#define ERUDITE 3
|
||||
#define WOOD_ELF 4
|
||||
#define HIGH_ELF 5
|
||||
#define DARK_ELF 6
|
||||
#define HALF_ELF 7
|
||||
#define DWARF 8
|
||||
#define TROLL 9
|
||||
#define OGRE 10
|
||||
#define HALFLING 11
|
||||
#define GNOME 12
|
||||
#define WEREWOLF 14
|
||||
#define WOLF 42
|
||||
#define BEAR 43
|
||||
#define SKELETON 60
|
||||
#define TIGER 63
|
||||
#define ELEMENTAL 75
|
||||
#define ALLIGATOR 91
|
||||
#define OGGOK_CITIZEN 93
|
||||
#define EYE_OF_ZOMM 108
|
||||
#define WOLF_ELEMENTAL 120
|
||||
#define INVISIBLE_MAN 127
|
||||
#define IKSAR 128
|
||||
#define VAHSHIR 130
|
||||
#define CONTROLLED_BOAT 141
|
||||
#define MINOR_ILL_OBJ 142
|
||||
#define TREE 143
|
||||
#define IKSAR_SKELETON 161
|
||||
#define FROGLOK 330
|
||||
// TODO: check all clients for (BYTE) usage of '/who all' class and remove FROGLOK2, if possible (330 - 74 = 256 .. WORD->BYTE conversion loss...)
|
||||
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
|
||||
#define FAIRY 473
|
||||
#define DRAKKIN 522 // 32768
|
||||
#define EMU_RACE_NPC 131069 // was 65533
|
||||
#define EMU_RACE_PET 131070 // was 65534
|
||||
#define EMU_RACE_UNKNOWN 131071 // was 65535
|
||||
|
||||
|
||||
// player race values
|
||||
#define PLAYER_RACE_UNKNOWN 0
|
||||
#define PLAYER_RACE_HUMAN 1
|
||||
#define PLAYER_RACE_BARBARIAN 2
|
||||
#define PLAYER_RACE_ERUDITE 3
|
||||
#define PLAYER_RACE_WOOD_ELF 4
|
||||
#define PLAYER_RACE_HIGH_ELF 5
|
||||
#define PLAYER_RACE_DARK_ELF 6
|
||||
#define PLAYER_RACE_HALF_ELF 7
|
||||
#define PLAYER_RACE_DWARF 8
|
||||
#define PLAYER_RACE_TROLL 9
|
||||
#define PLAYER_RACE_OGRE 10
|
||||
#define PLAYER_RACE_HALFLING 11
|
||||
#define PLAYER_RACE_GNOME 12
|
||||
#define PLAYER_RACE_IKSAR 13
|
||||
#define PLAYER_RACE_VAHSHIR 14
|
||||
#define PLAYER_RACE_FROGLOK 15
|
||||
#define PLAYER_RACE_DRAKKIN 16
|
||||
|
||||
#define PLAYER_RACE_COUNT 16
|
||||
|
||||
|
||||
#define PLAYER_RACE_EMU_NPC 17
|
||||
#define PLAYER_RACE_EMU_PET 18
|
||||
#define PLAYER_RACE_EMU_COUNT 19
|
||||
|
||||
|
||||
// player race bits
|
||||
#define PLAYER_RACE_UNKNOWN_BIT 0
|
||||
#define PLAYER_RACE_HUMAN_BIT 1
|
||||
#define PLAYER_RACE_BARBARIAN_BIT 2
|
||||
#define PLAYER_RACE_ERUDITE_BIT 4
|
||||
#define PLAYER_RACE_WOOD_ELF_BIT 8
|
||||
#define PLAYER_RACE_HIGH_ELF_BIT 16
|
||||
#define PLAYER_RACE_DARK_ELF_BIT 32
|
||||
#define PLAYER_RACE_HALF_ELF_BIT 64
|
||||
#define PLAYER_RACE_DWARF_BIT 128
|
||||
#define PLAYER_RACE_TROLL_BIT 256
|
||||
#define PLAYER_RACE_OGRE_BIT 512
|
||||
#define PLAYER_RACE_HALFLING_BIT 1024
|
||||
#define PLAYER_RACE_GNOME_BIT 2048
|
||||
#define PLAYER_RACE_IKSAR_BIT 4096
|
||||
#define PLAYER_RACE_VAHSHIR_BIT 8192
|
||||
#define PLAYER_RACE_FROGLOK_BIT 16384
|
||||
#define PLAYER_RACE_DRAKKIN_BIT 32768
|
||||
|
||||
#define PLAYER_RACE_ALL_MASK 65535
|
||||
|
||||
const char* GetRaceIDName(uint16 race_id);
|
||||
const char* GetPlayerRaceName(uint32 player_race_value);
|
||||
const char* GetGenderName(uint32 gender_id);
|
||||
|
||||
bool IsPlayerRace(uint16 race_id);
|
||||
@ -127,25 +31,13 @@ uint32 GetPlayerRaceValue(uint16 race_id);
|
||||
uint16 GetPlayerRaceBit(uint16 race_id);
|
||||
|
||||
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
|
||||
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
|
||||
|
||||
float GetRaceGenderDefaultHeight(int race, int gender);
|
||||
|
||||
// player race-/gender-based model feature validators
|
||||
namespace PlayerAppearance
|
||||
{
|
||||
bool IsValidBeard(uint16 race_id, uint8 gender_id, uint8 beard_value, bool use_luclin = true);
|
||||
bool IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8 beard_color_value, bool use_luclin = true);
|
||||
bool IsValidDetail(uint16 race_id, uint8 gender_id, uint32 detail_value, bool use_luclin = true);
|
||||
bool IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 eye_color_value, bool use_luclin = true);
|
||||
bool IsValidFace(uint16 race_id, uint8 gender_id, uint8 face_value, bool use_luclin = true);
|
||||
bool IsValidHair(uint16 race_id, uint8 gender_id, uint8 hair_value, bool use_luclin = true);
|
||||
bool IsValidHairColor(uint16 race_id, uint8 gender_id, uint8 hair_color_value, bool use_luclin = true);
|
||||
bool IsValidHead(uint16 race_id, uint8 gender_id, uint8 head_value, bool use_luclin = true);
|
||||
bool IsValidHeritage(uint16 race_id, uint8 gender_id, uint32 heritage_value, bool use_luclin = true);
|
||||
bool IsValidTattoo(uint16 race_id, uint8 gender_id, uint32 tattoo_value, bool use_luclin = true);
|
||||
bool IsValidTexture(uint16 race_id, uint8 gender_id, uint8 texture_value, bool use_luclin = true);
|
||||
bool IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_value, bool use_luclin = true);
|
||||
namespace Gender {
|
||||
constexpr uint8 Male = 0;
|
||||
constexpr uint8 Female = 1;
|
||||
constexpr uint8 Neuter = 2;
|
||||
}
|
||||
|
||||
namespace Race {
|
||||
@ -884,8 +776,92 @@ namespace Race {
|
||||
constexpr uint16 Pegasus3 = 732;
|
||||
constexpr uint16 InteractiveObject = 2250;
|
||||
constexpr uint16 Node = 2254;
|
||||
}
|
||||
|
||||
constexpr uint16 ALL_RACES_BITMASK = 65535;
|
||||
namespace RaceBitmask {
|
||||
constexpr uint16 Unknown = 0;
|
||||
constexpr uint16 Human = 1;
|
||||
constexpr uint16 Barbarian = 2;
|
||||
constexpr uint16 Erudite = 4;
|
||||
constexpr uint16 WoodElf = 8;
|
||||
constexpr uint16 HighElf = 16;
|
||||
constexpr uint16 DarkElf = 32;
|
||||
constexpr uint16 HalfElf = 64;
|
||||
constexpr uint16 Dwarf = 128;
|
||||
constexpr uint16 Troll = 256;
|
||||
constexpr uint16 Ogre = 512;
|
||||
constexpr uint16 Halfling = 1024;
|
||||
constexpr uint16 Gnome = 2048;
|
||||
constexpr uint16 Iksar = 4096;
|
||||
constexpr uint16 VahShir = 8192;
|
||||
constexpr uint16 Froglok = 16384;
|
||||
constexpr uint16 Drakkin = 32768;
|
||||
constexpr uint16 All = 65535;
|
||||
}
|
||||
|
||||
namespace RaceIndex {
|
||||
constexpr uint16 Human = 1;
|
||||
constexpr uint16 Barbarian = 2;
|
||||
constexpr uint16 Erudite = 3;
|
||||
constexpr uint16 WoodElf = 4;
|
||||
constexpr uint16 HighElf = 5;
|
||||
constexpr uint16 DarkElf = 6;
|
||||
constexpr uint16 HalfElf = 7;
|
||||
constexpr uint16 Dwarf = 8;
|
||||
constexpr uint16 Troll = 9;
|
||||
constexpr uint16 Ogre = 10;
|
||||
constexpr uint16 Halfling = 11;
|
||||
constexpr uint16 Gnome = 12;
|
||||
constexpr uint16 Iksar = 13;
|
||||
constexpr uint16 VahShir = 14;
|
||||
constexpr uint16 Froglok = 15;
|
||||
constexpr uint16 Drakkin = 16;
|
||||
}
|
||||
|
||||
namespace RaceAppearance {
|
||||
bool IsValidBeard(uint16 race_id, uint8 gender_id, uint8 beard_value, bool use_luclin = true);
|
||||
bool IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8 beard_color_value, bool use_luclin = true);
|
||||
bool IsValidDetail(uint16 race_id, uint8 gender_id, uint32 detail_value, bool use_luclin = true);
|
||||
bool IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 eye_color_value, bool use_luclin = true);
|
||||
bool IsValidFace(uint16 race_id, uint8 gender_id, uint8 face_value, bool use_luclin = true);
|
||||
bool IsValidHair(uint16 race_id, uint8 gender_id, uint8 hair_value, bool use_luclin = true);
|
||||
bool IsValidHairColor(uint16 race_id, uint8 gender_id, uint8 hair_color_value, bool use_luclin = true);
|
||||
bool IsValidHeritage(uint16 race_id, uint8 gender_id, uint32 heritage_value, bool use_luclin = true);
|
||||
bool IsValidTattoo(uint16 race_id, uint8 gender_id, uint32 tattoo_value, bool use_luclin = true);
|
||||
bool IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_value, bool use_luclin = true);
|
||||
|
||||
constexpr int HumanMale = (Race::Human << 8) | Gender::Male;
|
||||
constexpr int HumanFemale = (Race::Human << 8) | Gender::Female;
|
||||
constexpr int BarbarianMale = (Race::Barbarian << 8) | Gender::Male;
|
||||
constexpr int BarbarianFemale = (Race::Barbarian << 8) | Gender::Female;
|
||||
constexpr int EruditeMale = (Race::Erudite << 8) | Gender::Male;
|
||||
constexpr int EruditeFemale = (Race::Erudite << 8) | Gender::Female;
|
||||
constexpr int WoodElfMale = (Race::WoodElf << 8) | Gender::Male;
|
||||
constexpr int WoodElfFemale = (Race::WoodElf << 8) | Gender::Female;
|
||||
constexpr int HighElfMale = (Race::HighElf << 8) | Gender::Male;
|
||||
constexpr int HighElfFemale = (Race::HighElf << 8) | Gender::Female;
|
||||
constexpr int DarkElfMale = (Race::DarkElf << 8) | Gender::Male;
|
||||
constexpr int DarkElfFemale = (Race::DarkElf << 8) | Gender::Female;
|
||||
constexpr int HalfElfMale = (Race::HalfElf << 8) | Gender::Male;
|
||||
constexpr int HalfElfFemale = (Race::HalfElf << 8) | Gender::Female;
|
||||
constexpr int DwarfMale = (Race::Dwarf << 8) | Gender::Male;
|
||||
constexpr int DwarfFemale = (Race::Dwarf << 8) | Gender::Female;
|
||||
constexpr int TrollMale = (Race::Troll << 8) | Gender::Male;
|
||||
constexpr int TrollFemale = (Race::Troll << 8) | Gender::Female;
|
||||
constexpr int OgreMale = (Race::Ogre << 8) | Gender::Male;
|
||||
constexpr int OgreFemale = (Race::Ogre << 8) | Gender::Female;
|
||||
constexpr int HalflingMale = (Race::Halfling << 8) | Gender::Male;
|
||||
constexpr int HalflingFemale = (Race::Halfling << 8) | Gender::Female;
|
||||
constexpr int GnomeMale = (Race::Gnome << 8) | Gender::Male;
|
||||
constexpr int GnomeFemale = (Race::Gnome << 8) | Gender::Female;
|
||||
constexpr int IksarMale = (Race::Iksar << 8) | Gender::Male;
|
||||
constexpr int IksarFemale = (Race::Iksar << 8) | Gender::Female;
|
||||
constexpr int VahShirMale = (Race::VahShir << 8) | Gender::Male;
|
||||
constexpr int VahShirFemale = (Race::VahShir << 8) | Gender::Female;
|
||||
constexpr int FroglokMale = (Race::Froglok2 << 8) | Gender::Male;
|
||||
constexpr int FroglokFemale = (Race::Froglok2 << 8) | Gender::Female;
|
||||
constexpr int DrakkinMale = (Race::Drakkin << 8) | Gender::Male;
|
||||
constexpr int DrakkinFemale = (Race::Drakkin << 8) | Gender::Female;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -30,6 +30,7 @@ public:
|
||||
uint32_t aug_slot_5;
|
||||
uint32_t aug_slot_6;
|
||||
uint32_t quantity;
|
||||
uint32_t evolve_amount;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@ -51,6 +52,7 @@ public:
|
||||
"aug_slot_5",
|
||||
"aug_slot_6",
|
||||
"quantity",
|
||||
"evolve_amount",
|
||||
};
|
||||
}
|
||||
|
||||
@ -68,6 +70,7 @@ public:
|
||||
"aug_slot_5",
|
||||
"aug_slot_6",
|
||||
"quantity",
|
||||
"evolve_amount",
|
||||
};
|
||||
}
|
||||
|
||||
@ -108,17 +111,18 @@ public:
|
||||
{
|
||||
CharacterParcelsContainers e{};
|
||||
|
||||
e.id = 0;
|
||||
e.parcels_id = 0;
|
||||
e.slot_id = 0;
|
||||
e.item_id = 0;
|
||||
e.aug_slot_1 = 0;
|
||||
e.aug_slot_2 = 0;
|
||||
e.aug_slot_3 = 0;
|
||||
e.aug_slot_4 = 0;
|
||||
e.aug_slot_5 = 0;
|
||||
e.aug_slot_6 = 0;
|
||||
e.quantity = 0;
|
||||
e.id = 0;
|
||||
e.parcels_id = 0;
|
||||
e.slot_id = 0;
|
||||
e.item_id = 0;
|
||||
e.aug_slot_1 = 0;
|
||||
e.aug_slot_2 = 0;
|
||||
e.aug_slot_3 = 0;
|
||||
e.aug_slot_4 = 0;
|
||||
e.aug_slot_5 = 0;
|
||||
e.aug_slot_6 = 0;
|
||||
e.quantity = 0;
|
||||
e.evolve_amount = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -155,17 +159,18 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
CharacterParcelsContainers e{};
|
||||
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -209,6 +214,7 @@ public:
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -241,6 +247,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_5));
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -281,6 +288,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_5));
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@ -314,17 +322,18 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CharacterParcelsContainers e{};
|
||||
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -349,17 +358,18 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CharacterParcelsContainers e{};
|
||||
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -445,6 +455,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_5));
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -478,6 +489,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_5));
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ public:
|
||||
uint32_t aug_slot_6;
|
||||
uint32_t slot_id;
|
||||
uint32_t quantity;
|
||||
uint32_t evolve_amount;
|
||||
std::string from_name;
|
||||
std::string note;
|
||||
time_t sent_date;
|
||||
@ -54,6 +55,7 @@ public:
|
||||
"aug_slot_6",
|
||||
"slot_id",
|
||||
"quantity",
|
||||
"evolve_amount",
|
||||
"from_name",
|
||||
"note",
|
||||
"sent_date",
|
||||
@ -74,6 +76,7 @@ public:
|
||||
"aug_slot_6",
|
||||
"slot_id",
|
||||
"quantity",
|
||||
"evolve_amount",
|
||||
"from_name",
|
||||
"note",
|
||||
"UNIX_TIMESTAMP(sent_date)",
|
||||
@ -117,20 +120,21 @@ public:
|
||||
{
|
||||
CharacterParcels e{};
|
||||
|
||||
e.id = 0;
|
||||
e.char_id = 0;
|
||||
e.item_id = 0;
|
||||
e.aug_slot_1 = 0;
|
||||
e.aug_slot_2 = 0;
|
||||
e.aug_slot_3 = 0;
|
||||
e.aug_slot_4 = 0;
|
||||
e.aug_slot_5 = 0;
|
||||
e.aug_slot_6 = 0;
|
||||
e.slot_id = 0;
|
||||
e.quantity = 0;
|
||||
e.from_name = "";
|
||||
e.note = "";
|
||||
e.sent_date = 0;
|
||||
e.id = 0;
|
||||
e.char_id = 0;
|
||||
e.item_id = 0;
|
||||
e.aug_slot_1 = 0;
|
||||
e.aug_slot_2 = 0;
|
||||
e.aug_slot_3 = 0;
|
||||
e.aug_slot_4 = 0;
|
||||
e.aug_slot_5 = 0;
|
||||
e.aug_slot_6 = 0;
|
||||
e.slot_id = 0;
|
||||
e.quantity = 0;
|
||||
e.evolve_amount = 0;
|
||||
e.from_name = "";
|
||||
e.note = "";
|
||||
e.sent_date = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -167,20 +171,21 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
CharacterParcels e{};
|
||||
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.from_name = row[11] ? row[11] : "";
|
||||
e.note = row[12] ? row[12] : "";
|
||||
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||
e.from_name = row[12] ? row[12] : "";
|
||||
e.note = row[13] ? row[13] : "";
|
||||
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -224,9 +229,10 @@ public:
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_6));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.slot_id));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
||||
v.push_back(columns[11] + " = '" + Strings::Escape(e.from_name) + "'");
|
||||
v.push_back(columns[12] + " = '" + Strings::Escape(e.note) + "'");
|
||||
v.push_back(columns[13] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
|
||||
v.push_back(columns[12] + " = '" + Strings::Escape(e.from_name) + "'");
|
||||
v.push_back(columns[13] + " = '" + Strings::Escape(e.note) + "'");
|
||||
v.push_back(columns[14] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -259,6 +265,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.slot_id));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||
@ -302,6 +309,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.slot_id));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||
@ -338,20 +346,21 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CharacterParcels e{};
|
||||
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.from_name = row[11] ? row[11] : "";
|
||||
e.note = row[12] ? row[12] : "";
|
||||
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||
e.from_name = row[12] ? row[12] : "";
|
||||
e.note = row[13] ? row[13] : "";
|
||||
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -376,20 +385,21 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
CharacterParcels e{};
|
||||
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.from_name = row[11] ? row[11] : "";
|
||||
e.note = row[12] ? row[12] : "";
|
||||
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
|
||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||
e.from_name = row[12] ? row[12] : "";
|
||||
e.note = row[13] ? row[13] : "";
|
||||
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -475,6 +485,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.slot_id));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||
@ -511,6 +522,7 @@ public:
|
||||
v.push_back(std::to_string(e.aug_slot_6));
|
||||
v.push_back(std::to_string(e.slot_id));
|
||||
v.push_back(std::to_string(e.quantity));
|
||||
v.push_back(std::to_string(e.evolve_amount));
|
||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||
|
||||
@ -70,6 +70,7 @@ public:
|
||||
int32_t endurance_regen;
|
||||
int32_t shielding;
|
||||
int32_t spell_damage;
|
||||
int32_t heal_amount;
|
||||
int32_t spell_shielding;
|
||||
int32_t strikethrough;
|
||||
int32_t stun_resist;
|
||||
@ -154,6 +155,7 @@ public:
|
||||
"endurance_regen",
|
||||
"shielding",
|
||||
"spell_damage",
|
||||
"heal_amount",
|
||||
"spell_shielding",
|
||||
"strikethrough",
|
||||
"stun_resist",
|
||||
@ -234,6 +236,7 @@ public:
|
||||
"endurance_regen",
|
||||
"shielding",
|
||||
"spell_damage",
|
||||
"heal_amount",
|
||||
"spell_shielding",
|
||||
"strikethrough",
|
||||
"stun_resist",
|
||||
@ -348,6 +351,7 @@ public:
|
||||
e.endurance_regen = 0;
|
||||
e.shielding = 0;
|
||||
e.spell_damage = 0;
|
||||
e.heal_amount = 0;
|
||||
e.spell_shielding = 0;
|
||||
e.strikethrough = 0;
|
||||
e.stun_resist = 0;
|
||||
@ -458,29 +462,30 @@ public:
|
||||
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
|
||||
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
|
||||
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
|
||||
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
|
||||
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -565,29 +570,30 @@ public:
|
||||
v.push_back(columns[48] + " = " + std::to_string(e.endurance_regen));
|
||||
v.push_back(columns[49] + " = " + std::to_string(e.shielding));
|
||||
v.push_back(columns[50] + " = " + std::to_string(e.spell_damage));
|
||||
v.push_back(columns[51] + " = " + std::to_string(e.spell_shielding));
|
||||
v.push_back(columns[52] + " = " + std::to_string(e.strikethrough));
|
||||
v.push_back(columns[53] + " = " + std::to_string(e.stun_resist));
|
||||
v.push_back(columns[54] + " = " + std::to_string(e.backstab));
|
||||
v.push_back(columns[55] + " = " + std::to_string(e.wind));
|
||||
v.push_back(columns[56] + " = " + std::to_string(e.brass));
|
||||
v.push_back(columns[57] + " = " + std::to_string(e.string));
|
||||
v.push_back(columns[58] + " = " + std::to_string(e.percussion));
|
||||
v.push_back(columns[59] + " = " + std::to_string(e.singing));
|
||||
v.push_back(columns[60] + " = " + std::to_string(e.baking));
|
||||
v.push_back(columns[61] + " = " + std::to_string(e.alchemy));
|
||||
v.push_back(columns[62] + " = " + std::to_string(e.tailoring));
|
||||
v.push_back(columns[63] + " = " + std::to_string(e.blacksmithing));
|
||||
v.push_back(columns[64] + " = " + std::to_string(e.fletching));
|
||||
v.push_back(columns[65] + " = " + std::to_string(e.brewing));
|
||||
v.push_back(columns[66] + " = " + std::to_string(e.jewelry));
|
||||
v.push_back(columns[67] + " = " + std::to_string(e.pottery));
|
||||
v.push_back(columns[68] + " = " + std::to_string(e.research));
|
||||
v.push_back(columns[69] + " = " + std::to_string(e.alcohol));
|
||||
v.push_back(columns[70] + " = " + std::to_string(e.fishing));
|
||||
v.push_back(columns[71] + " = " + std::to_string(e.tinkering));
|
||||
v.push_back(columns[72] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||
v.push_back(columns[73] + " = FROM_UNIXTIME(" + (e.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
|
||||
v.push_back(columns[51] + " = " + std::to_string(e.heal_amount));
|
||||
v.push_back(columns[52] + " = " + std::to_string(e.spell_shielding));
|
||||
v.push_back(columns[53] + " = " + std::to_string(e.strikethrough));
|
||||
v.push_back(columns[54] + " = " + std::to_string(e.stun_resist));
|
||||
v.push_back(columns[55] + " = " + std::to_string(e.backstab));
|
||||
v.push_back(columns[56] + " = " + std::to_string(e.wind));
|
||||
v.push_back(columns[57] + " = " + std::to_string(e.brass));
|
||||
v.push_back(columns[58] + " = " + std::to_string(e.string));
|
||||
v.push_back(columns[59] + " = " + std::to_string(e.percussion));
|
||||
v.push_back(columns[60] + " = " + std::to_string(e.singing));
|
||||
v.push_back(columns[61] + " = " + std::to_string(e.baking));
|
||||
v.push_back(columns[62] + " = " + std::to_string(e.alchemy));
|
||||
v.push_back(columns[63] + " = " + std::to_string(e.tailoring));
|
||||
v.push_back(columns[64] + " = " + std::to_string(e.blacksmithing));
|
||||
v.push_back(columns[65] + " = " + std::to_string(e.fletching));
|
||||
v.push_back(columns[66] + " = " + std::to_string(e.brewing));
|
||||
v.push_back(columns[67] + " = " + std::to_string(e.jewelry));
|
||||
v.push_back(columns[68] + " = " + std::to_string(e.pottery));
|
||||
v.push_back(columns[69] + " = " + std::to_string(e.research));
|
||||
v.push_back(columns[70] + " = " + std::to_string(e.alcohol));
|
||||
v.push_back(columns[71] + " = " + std::to_string(e.fishing));
|
||||
v.push_back(columns[72] + " = " + std::to_string(e.tinkering));
|
||||
v.push_back(columns[73] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||
v.push_back(columns[74] + " = FROM_UNIXTIME(" + (e.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -660,6 +666,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
@ -763,6 +770,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
@ -870,29 +878,30 @@ public:
|
||||
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
|
||||
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
|
||||
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
|
||||
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
|
||||
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -968,29 +977,30 @@ public:
|
||||
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
|
||||
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
|
||||
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
|
||||
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
|
||||
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -1116,6 +1126,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
@ -1212,6 +1223,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
|
||||
@ -191,6 +191,22 @@ public:
|
||||
|
||||
return character_ids;
|
||||
}
|
||||
|
||||
static uint32_t GetTotalTimePlayed(Database& db, uint32_t account_id)
|
||||
{
|
||||
auto query = fmt::format(
|
||||
"SELECT SUM(time_played) FROM `character_data` WHERE `account_id` = {}",
|
||||
account_id
|
||||
);
|
||||
|
||||
auto results = db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
||||
|
||||
@ -49,6 +49,7 @@ public:
|
||||
// these are the base definitions for command_subsettings and can be over-ridden by the database
|
||||
std::vector<CommandSubsettingsRepository::CommandSubsettings> static_records = {
|
||||
{.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"},
|
||||
{.parent_command = "find", .sub_command = "account", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaccount"},
|
||||
{.parent_command = "find", .sub_command = "body_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbodytype"},
|
||||
{.parent_command = "find", .sub_command = "bug_category", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbugcategory"},
|
||||
{.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"},
|
||||
@ -142,6 +143,7 @@ public:
|
||||
{.parent_command = "show", .sub_command = "hatelist", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hatelist"},
|
||||
{.parent_command = "show", .sub_command = "inventory", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peekinv"},
|
||||
{.parent_command = "show", .sub_command = "ip_lookup", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "iplookup"},
|
||||
{.parent_command = "show", .sub_command = "keyring", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showkeyring"},
|
||||
{.parent_command = "show", .sub_command = "line_of_sight", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "checklos"},
|
||||
{.parent_command = "show", .sub_command = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"},
|
||||
{.parent_command = "show", .sub_command = "network_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "netstats"},
|
||||
|
||||
@ -619,7 +619,7 @@ RULE_INT(Combat, SneakPullAssistRange, 400, "Modified range of assist for sneak
|
||||
RULE_BOOL(Combat, Classic2HBAnimation, false, "2HB will use the 2 hand piercing animation instead of the overhead slashing animation")
|
||||
RULE_BOOL(Combat, ArcheryConsumesAmmo, true, "Set to false to disable Archery Ammo Consumption")
|
||||
RULE_BOOL(Combat, ThrowingConsumesAmmo, true, "Set to false to disable Throwing Ammo Consumption")
|
||||
RULE_BOOL(Combat, UseLiveRiposteMechanics, false, "Set to true to disable SPA 173 SE_RiposteChance from making those with the effect on them immune to enrage, can longer riposte from a riposte.")
|
||||
RULE_BOOL(Combat, UseLiveRiposteMechanics, false, "Set to true to disable SPA 173 SpellEffect::RiposteChance from making those with the effect on them immune to enrage, can longer riposte from a riposte.")
|
||||
RULE_INT(Combat, FrontalStunImmunityClasses, 0, "Bitmask for Classes than have frontal stun immunity, No Races (0) by default.")
|
||||
RULE_BOOL(Combat, NPCsUseFrontalStunImmunityClasses, false, "Enable or disable NPCs using frontal stun immunity Classes from Combat:FrontalStunImmunityClasses, false by default.")
|
||||
RULE_INT(Combat, FrontalStunImmunityRaces, 512, "Bitmask for Races than have frontal stun immunity, Ogre (512) only by default.")
|
||||
|
||||
@ -51,19 +51,10 @@
|
||||
#include "repositories/inventory_repository.h"
|
||||
#include "repositories/books_repository.h"
|
||||
#include "repositories/sharedbank_repository.h"
|
||||
|
||||
namespace ItemField
|
||||
{
|
||||
enum {
|
||||
source = 0,
|
||||
#define F(x) x,
|
||||
#include "item_fieldlist.h"
|
||||
#undef F
|
||||
updated,
|
||||
minstatus,
|
||||
comment,
|
||||
};
|
||||
}
|
||||
#include "repositories/character_inspect_messages_repository.h"
|
||||
#include "repositories/spells_new_repository.h"
|
||||
#include "repositories/damageshieldtypes_repository.h"
|
||||
#include "repositories/items_repository.h"
|
||||
|
||||
SharedDatabase::SharedDatabase()
|
||||
: Database()
|
||||
@ -131,66 +122,41 @@ bool SharedDatabase::SetGMFlymode(uint32 account_id, uint8 flymode)
|
||||
return a.id > 0;
|
||||
}
|
||||
|
||||
uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
|
||||
uint32 EntitledTime = 0;
|
||||
const std::string query = StringFormat("SELECT `time_played` FROM `character_data` WHERE `account_id` = %u", AccountID);
|
||||
auto results = QueryDatabase(query);
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
EntitledTime += Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
return EntitledTime;
|
||||
}
|
||||
|
||||
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
|
||||
void SharedDatabase::SetMailKey(uint32 character_id, uint32 ip_address, uint32 mail_key)
|
||||
{
|
||||
char mail_key[17];
|
||||
std::string full_mail_key;
|
||||
|
||||
if (RuleB(Chat, EnableMailKeyIPVerification) == true) {
|
||||
sprintf(mail_key, "%08X%08X", IPAddress, MailKey);
|
||||
}
|
||||
else {
|
||||
sprintf(mail_key, "%08X", MailKey);
|
||||
if (RuleB(Chat, EnableMailKeyIPVerification)) {
|
||||
full_mail_key = fmt::format("{:08X}{:08X}", ip_address, mail_key);
|
||||
} else {
|
||||
full_mail_key = fmt::format("{:08X}", mail_key);
|
||||
}
|
||||
|
||||
const std::string query = StringFormat(
|
||||
"UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
||||
mail_key, CharID
|
||||
);
|
||||
auto e = CharacterDataRepository::FindOne(*this, character_id);
|
||||
if (!e.id) {
|
||||
LogError("Failed to find character_id [{}] when setting mailkey", character_id);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, mail_key, results.ErrorMessage().c_str());
|
||||
e.mailkey = full_mail_key;
|
||||
|
||||
if (!CharacterDataRepository::UpdateOne(*this, e)) {
|
||||
LogError("Failed to set mailkey to [{}] for character_id [{}]", full_mail_key, character_id);
|
||||
}
|
||||
}
|
||||
|
||||
SharedDatabase::MailKeys SharedDatabase::GetMailKey(int character_id)
|
||||
SharedDatabase::MailKeys SharedDatabase::GetMailKey(uint32 character_id)
|
||||
{
|
||||
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", character_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return MailKeys{};
|
||||
auto e = CharacterDataRepository::FindOne(*this, character_id);
|
||||
|
||||
if (!e.id) {
|
||||
return MailKeys{ };
|
||||
}
|
||||
|
||||
if (!results.RowCount()) {
|
||||
Log(Logs::General,
|
||||
Logs::ClientLogin,
|
||||
"Error: Mailkey for character id [%i] does not exist or could not be found",
|
||||
character_id
|
||||
);
|
||||
return MailKeys{};
|
||||
}
|
||||
|
||||
auto &row = results.begin();
|
||||
if (row != results.end()) {
|
||||
std::string mail_key = row[0];
|
||||
|
||||
return MailKeys{
|
||||
.mail_key = mail_key.substr(8),
|
||||
.mail_key_full = mail_key
|
||||
};
|
||||
}
|
||||
|
||||
return MailKeys{};
|
||||
return MailKeys{
|
||||
.mail_key = e.mailkey.substr(8),
|
||||
.mail_key_full = e.mailkey
|
||||
};
|
||||
}
|
||||
|
||||
bool SharedDatabase::SaveCursor(
|
||||
@ -457,27 +423,20 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
|
||||
{
|
||||
const auto query = fmt::format("SELECT sharedplat FROM account WHERE id = {}", account_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return 0;
|
||||
}
|
||||
const auto& e = AccountRepository::FindOne(*this, account_id);
|
||||
|
||||
auto row = results.begin();
|
||||
return Strings::ToInt(row[0]);
|
||||
return e.sharedplat;
|
||||
}
|
||||
|
||||
bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
|
||||
const std::string query = StringFormat("UPDATE account SET sharedplat = sharedplat + %i WHERE id = %i", amount_to_add, account_id);
|
||||
const auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
bool SharedDatabase::AddSharedPlatinum(uint32 account_id, int amount)
|
||||
{
|
||||
auto e = AccountRepository::FindOne(*this, account_id);
|
||||
|
||||
return true;
|
||||
e.sharedplat += amount;
|
||||
|
||||
return AccountRepository::UpdateOne(*this, e);
|
||||
}
|
||||
|
||||
bool SharedDatabase::SetStartingItems(
|
||||
@ -944,27 +903,10 @@ void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
|
||||
);
|
||||
}
|
||||
|
||||
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
|
||||
void SharedDatabase::GetItemsCount(int32& item_count, uint32& max_id)
|
||||
{
|
||||
item_count = -1;
|
||||
max_id = 0;
|
||||
|
||||
const std::string query = "SELECT MAX(id), count(*) FROM items";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return;
|
||||
|
||||
auto& row = results.begin();
|
||||
|
||||
if (row[0])
|
||||
max_id = Strings::ToUnsignedInt(row[0]);
|
||||
|
||||
if (row[1])
|
||||
item_count = Strings::ToUnsignedInt(row[1]);
|
||||
max_id = ItemsRepository::GetMaxId(*this);
|
||||
item_count = ItemsRepository::Count(*this);
|
||||
}
|
||||
|
||||
bool SharedDatabase::LoadItems(const std::string &prefix) {
|
||||
@ -994,14 +936,14 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
|
||||
std::string variable_buffer;
|
||||
|
||||
bool disable_attuneable = RuleB(Items, DisableAttuneable);
|
||||
bool disable_bard_focus_effects = RuleB(Items, DisableBardFocusEffects);
|
||||
bool disable_lore = RuleB(Items, DisableLore);
|
||||
bool disable_no_drop = RuleB(Items, DisableNoDrop);
|
||||
bool disable_no_pet = RuleB(Items, DisableNoPet);
|
||||
bool disable_no_rent = RuleB(Items, DisableNoRent);
|
||||
bool disable_no_transfer = RuleB(Items, DisableNoTransfer);
|
||||
bool disable_potion_belt = RuleB(Items, DisablePotionBelt);
|
||||
bool disable_attuneable = RuleB(Items, DisableAttuneable);
|
||||
bool disable_bard_focus_effects = RuleB(Items, DisableBardFocusEffects);
|
||||
bool disable_lore = RuleB(Items, DisableLore);
|
||||
bool disable_no_drop = RuleB(Items, DisableNoDrop);
|
||||
bool disable_no_pet = RuleB(Items, DisableNoPet);
|
||||
bool disable_no_rent = RuleB(Items, DisableNoRent);
|
||||
bool disable_no_transfer = RuleB(Items, DisableNoTransfer);
|
||||
bool disable_potion_belt = RuleB(Items, DisablePotionBelt);
|
||||
bool disable_spell_focus_effects = RuleB(Items, DisableSpellFocusEffects);
|
||||
|
||||
// Old Variable Code
|
||||
@ -1032,206 +974,204 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
|
||||
EQ::ItemData item;
|
||||
|
||||
const std::string query = "SELECT source,"
|
||||
#define F(x) "`"#x"`,"
|
||||
#include "item_fieldlist.h"
|
||||
#undef F
|
||||
"updated, minstatus, comment FROM items ORDER BY id";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
const auto& l = ItemsRepository::All(*this);
|
||||
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
for (const auto& e : l) {
|
||||
memset(&item, 0, sizeof(EQ::ItemData));
|
||||
|
||||
// Unique Identifier
|
||||
item.ID = Strings::ToUnsignedInt(row[ItemField::id]);
|
||||
item.ID = e.id;
|
||||
|
||||
// Minimum Status
|
||||
item.MinStatus = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::minstatus]));
|
||||
item.MinStatus = static_cast<uint8>(e.minstatus);
|
||||
|
||||
// Name, Lore, and Comment
|
||||
strn0cpy(item.Name, row[ItemField::name], sizeof(item.Name));
|
||||
strn0cpy(item.Lore, row[ItemField::lore], sizeof(item.Lore));
|
||||
strn0cpy(item.Comment, row[ItemField::comment], sizeof(item.Comment));
|
||||
strn0cpy(item.Name, e.Name.c_str(), sizeof(item.Name));
|
||||
strn0cpy(item.Lore, e.lore.c_str(), sizeof(item.Lore));
|
||||
strn0cpy(item.Comment, e.comment.c_str(), sizeof(item.Comment));
|
||||
|
||||
// Flags
|
||||
item.ArtifactFlag = Strings::ToBool(row[ItemField::artifactflag]);
|
||||
item.Attuneable = !disable_attuneable && Strings::ToBool(row[ItemField::attuneable]);
|
||||
item.BenefitFlag = Strings::ToBool(row[ItemField::benefitflag]);
|
||||
item.FVNoDrop = Strings::ToBool(row[ItemField::fvnodrop]);
|
||||
item.Magic = Strings::ToBool(row[ItemField::magic]);
|
||||
item.NoDrop = disable_no_drop ? static_cast<uint8>(255) : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::nodrop]));
|
||||
item.NoPet = !disable_no_pet && Strings::ToBool(row[ItemField::nopet]);
|
||||
item.NoRent = disable_no_rent ? static_cast<uint8>(255) : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::norent]));
|
||||
item.NoTransfer = !disable_no_transfer && Strings::ToBool(row[ItemField::notransfer]);
|
||||
item.PendingLoreFlag = Strings::ToBool(row[ItemField::pendingloreflag]);
|
||||
item.QuestItemFlag = Strings::ToBool(row[ItemField::questitemflag]);
|
||||
item.Stackable = Strings::ToBool(row[ItemField::stackable]);
|
||||
item.Tradeskills = Strings::ToBool(row[ItemField::tradeskills]);
|
||||
item.SummonedFlag = Strings::ToBool(row[ItemField::summonedflag]);
|
||||
item.ArtifactFlag = e.artifactflag;
|
||||
item.Attuneable = !disable_attuneable && e.attuneable;
|
||||
item.BenefitFlag = e.benefitflag;
|
||||
item.FVNoDrop = e.fvnodrop;
|
||||
item.Magic = e.magic;
|
||||
item.NoDrop = disable_no_drop ? std::numeric_limits<uint8>::max() : e.nodrop;
|
||||
item.NoPet = !disable_no_pet && e.nopet;
|
||||
item.NoRent = disable_no_rent ? std::numeric_limits<uint8>::max() : e.norent;
|
||||
item.NoTransfer = !disable_no_transfer && e.notransfer;
|
||||
item.PendingLoreFlag = e.pendingloreflag;
|
||||
item.QuestItemFlag = e.questitemflag;
|
||||
item.Stackable = e.stackable;
|
||||
item.Tradeskills = e.tradeskills;
|
||||
item.SummonedFlag = e.summonedflag;
|
||||
|
||||
// Lore
|
||||
item.LoreGroup = disable_lore ? 0 : Strings::ToInt(row[ItemField::loregroup]);
|
||||
item.LoreFlag = !disable_lore && item.LoreGroup != 0;
|
||||
item.LoreGroup = disable_lore ? 0 : e.loregroup;
|
||||
item.LoreFlag = !disable_lore && item.LoreGroup != 0;
|
||||
|
||||
// Type
|
||||
item.AugType = Strings::ToUnsignedInt(row[ItemField::augtype]);
|
||||
item.ItemType = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::itemtype]));
|
||||
item.SubType = Strings::ToInt(row[ItemField::subtype]);
|
||||
item.AugType = e.augtype;
|
||||
item.ItemType = static_cast<uint8>(e.itemtype);
|
||||
item.SubType = e.subtype;
|
||||
|
||||
// Miscellaneous
|
||||
item.ExpendableArrow = static_cast<uint16>(Strings::ToUnsignedInt(row[ItemField::expendablearrow]));
|
||||
item.Light = static_cast<int8>(Strings::ToInt(row[ItemField::light]));
|
||||
item.MaxCharges = static_cast<int16>(Strings::ToInt(row[ItemField::maxcharges]));
|
||||
item.Size = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::size]));
|
||||
item.StackSize = static_cast<int16>(Strings::ToInt(row[ItemField::stacksize]));
|
||||
item.Weight = Strings::ToInt(row[ItemField::weight]);
|
||||
item.ExpendableArrow = e.expendablearrow;
|
||||
item.Light = EQ::Clamp(e.light, -128, 127);
|
||||
item.MaxCharges = e.maxcharges;
|
||||
item.Size = static_cast<uint8>(e.size);
|
||||
item.StackSize = e.stacksize;
|
||||
item.Weight = e.weight;
|
||||
|
||||
// Potion Belt
|
||||
item.PotionBelt = !disable_potion_belt && Strings::ToBool(row[ItemField::potionbelt]);
|
||||
item.PotionBeltSlots = disable_potion_belt ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::potionbeltslots]));
|
||||
item.PotionBelt = !disable_potion_belt && e.potionbelt;
|
||||
item.PotionBeltSlots = disable_potion_belt ? 0 : static_cast<uint8>(e.potionbeltslots);
|
||||
|
||||
// Merchant
|
||||
item.Favor = Strings::ToUnsignedInt(row[ItemField::favor]);
|
||||
item.GuildFavor = Strings::ToUnsignedInt(row[ItemField::guildfavor]);
|
||||
item.Price = Strings::ToUnsignedInt(row[ItemField::price]);
|
||||
item.SellRate = Strings::ToFloat(row[ItemField::sellrate]);
|
||||
item.Favor = e.favor;
|
||||
item.GuildFavor = e.guildfavor;
|
||||
item.Price = e.price;
|
||||
item.SellRate = e.sellrate;
|
||||
|
||||
// Display
|
||||
item.Color = Strings::ToUnsignedInt(row[ItemField::color]);
|
||||
item.EliteMaterial = Strings::ToUnsignedInt(row[ItemField::elitematerial]);
|
||||
item.HerosForgeModel = Strings::ToUnsignedInt(row[ItemField::herosforgemodel]);
|
||||
item.Icon = Strings::ToUnsignedInt(row[ItemField::icon]);
|
||||
strn0cpy(item.IDFile, row[ItemField::idfile], sizeof(item.IDFile));
|
||||
item.Material = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::material]));
|
||||
item.Color = e.color;
|
||||
item.EliteMaterial = e.elitematerial;
|
||||
item.HerosForgeModel = e.herosforgemodel;
|
||||
item.Icon = e.icon;
|
||||
strn0cpy(item.IDFile, e.idfile.c_str(), sizeof(item.IDFile));
|
||||
item.Material = e.material;
|
||||
|
||||
// Resists
|
||||
item.CR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::cr]), -128, 127));
|
||||
item.DR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::dr]), -128, 127));
|
||||
item.FR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::fr]), -128, 127));
|
||||
item.MR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::mr]), -128, 127));
|
||||
item.PR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::pr]), -128, 127));
|
||||
item.SVCorruption = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::svcorruption]), -128, 127));
|
||||
item.CR = EQ::Clamp(e.cr, -128, 127);
|
||||
item.DR = EQ::Clamp(e.dr, -128, 127);
|
||||
item.FR = EQ::Clamp(e.fr, -128, 127);
|
||||
item.MR = EQ::Clamp(e.mr, -128, 127);
|
||||
item.PR = EQ::Clamp(e.pr, -128, 127);
|
||||
item.SVCorruption = EQ::Clamp(e.svcorruption, -128, 127);
|
||||
|
||||
// Heroic Resists
|
||||
item.HeroicCR = Strings::ToInt(row[ItemField::heroic_cr]);
|
||||
item.HeroicDR = Strings::ToInt(row[ItemField::heroic_dr]);
|
||||
item.HeroicFR = Strings::ToInt(row[ItemField::heroic_fr]);
|
||||
item.HeroicMR = Strings::ToInt(row[ItemField::heroic_mr]);
|
||||
item.HeroicPR = Strings::ToInt(row[ItemField::heroic_pr]);
|
||||
item.HeroicSVCorrup = Strings::ToInt(row[ItemField::heroic_svcorrup]);
|
||||
item.HeroicCR = e.heroic_cr;
|
||||
item.HeroicDR = e.heroic_dr;
|
||||
item.HeroicFR = e.heroic_fr;
|
||||
item.HeroicMR = e.heroic_mr;
|
||||
item.HeroicPR = e.heroic_pr;
|
||||
item.HeroicSVCorrup = e.heroic_svcorrup;
|
||||
|
||||
// Stats
|
||||
item.AAgi = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::aagi]), -128, 127));
|
||||
item.ACha = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::acha]), -128, 127));
|
||||
item.ADex = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::adex]), -128, 127));
|
||||
item.AInt = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::aint]), -128, 127));
|
||||
item.ASta = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::asta]), -128, 127));
|
||||
item.AStr = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::astr]), -128, 127));
|
||||
item.AWis = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::awis]), -128, 127));
|
||||
item.AAgi = EQ::Clamp(e.aagi, -128, 127);
|
||||
item.ACha = EQ::Clamp(e.acha, -128, 127);
|
||||
item.ADex = EQ::Clamp(e.adex, -128, 127);
|
||||
item.AInt = EQ::Clamp(e.aint, -128, 127);
|
||||
item.ASta = EQ::Clamp(e.asta, -128, 127);
|
||||
item.AStr = EQ::Clamp(e.astr, -128, 127);
|
||||
item.AWis = EQ::Clamp(e.awis, -128, 127);
|
||||
|
||||
// Heroic Stats
|
||||
item.HeroicAgi = Strings::ToInt(row[ItemField::heroic_agi]);
|
||||
item.HeroicCha = Strings::ToInt(row[ItemField::heroic_cha]);
|
||||
item.HeroicDex = Strings::ToInt(row[ItemField::heroic_dex]);
|
||||
item.HeroicInt = Strings::ToInt(row[ItemField::heroic_int]);
|
||||
item.HeroicSta = Strings::ToInt(row[ItemField::heroic_sta]);
|
||||
item.HeroicStr = Strings::ToInt(row[ItemField::heroic_str]);
|
||||
item.HeroicWis = Strings::ToInt(row[ItemField::heroic_wis]);
|
||||
item.HeroicAgi = e.heroic_agi;
|
||||
item.HeroicCha = e.heroic_cha;
|
||||
item.HeroicDex = e.heroic_dex;
|
||||
item.HeroicInt = e.heroic_int;
|
||||
item.HeroicSta = e.heroic_sta;
|
||||
item.HeroicStr = e.heroic_str;
|
||||
item.HeroicWis = e.heroic_wis;
|
||||
|
||||
// Health, Mana, and Endurance
|
||||
item.HP = Strings::ToInt(row[ItemField::hp]);
|
||||
item.Regen = Strings::ToInt(row[ItemField::regen]);
|
||||
item.Mana = Strings::ToInt(row[ItemField::mana]);
|
||||
item.ManaRegen = Strings::ToInt(row[ItemField::manaregen]);
|
||||
item.Endur = Strings::ToInt(row[ItemField::endur]);
|
||||
item.EnduranceRegen = Strings::ToInt(row[ItemField::enduranceregen]);
|
||||
item.HP = e.hp;
|
||||
item.Regen = e.regen;
|
||||
item.Mana = e.mana;
|
||||
item.ManaRegen = e.manaregen;
|
||||
item.Endur = e.endur;
|
||||
item.EnduranceRegen = e.enduranceregen;
|
||||
|
||||
// Bane Damage
|
||||
item.BaneDmgAmt = Strings::ToInt(row[ItemField::banedmgamt]);
|
||||
item.BaneDmgBody = Strings::ToUnsignedInt(row[ItemField::banedmgbody]);
|
||||
item.BaneDmgRace = Strings::ToUnsignedInt(row[ItemField::banedmgrace]);
|
||||
item.BaneDmgRaceAmt = Strings::ToUnsignedInt(row[ItemField::banedmgraceamt]);
|
||||
item.BaneDmgAmt = e.banedmgamt;
|
||||
item.BaneDmgBody = e.banedmgbody;
|
||||
item.BaneDmgRace = e.banedmgrace;
|
||||
item.BaneDmgRaceAmt = e.banedmgraceamt;
|
||||
|
||||
// Elemental Damage
|
||||
item.ElemDmgType = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::elemdmgtype]));
|
||||
item.ElemDmgAmt = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::elemdmgamt]));
|
||||
item.ElemDmgType = static_cast<uint8>(e.elemdmgtype);
|
||||
item.ElemDmgAmt = static_cast<uint8>(e.elemdmgamt);
|
||||
|
||||
// Combat
|
||||
item.BackstabDmg = Strings::ToUnsignedInt(row[ItemField::backstabdmg]);
|
||||
item.Damage = Strings::ToUnsignedInt(row[ItemField::damage]);
|
||||
item.Delay = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::delay]));
|
||||
item.Range = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::range]));
|
||||
item.BackstabDmg = e.backstabdmg;
|
||||
item.Damage = e.damage;
|
||||
item.Delay = static_cast<uint8>(e.delay);
|
||||
item.Range = static_cast<uint8>(e.range_);
|
||||
|
||||
// Combat Stats
|
||||
item.AC = Strings::ToInt(row[ItemField::ac]);
|
||||
item.Accuracy = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::accuracy]), -128, 127));
|
||||
item.Attack = Strings::ToInt(row[ItemField::attack]);
|
||||
item.Avoidance = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::avoidance]), -128, 127));
|
||||
item.Clairvoyance = Strings::ToUnsignedInt(row[ItemField::clairvoyance]);
|
||||
item.CombatEffects = Strings::IsNumber(row[ItemField::combateffects]) ? static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::combateffects]), -128, 127)) : 0;
|
||||
item.DamageShield = Strings::ToInt(row[ItemField::damageshield]);
|
||||
item.DotShielding = Strings::ToInt(row[ItemField::dotshielding]);
|
||||
item.DSMitigation = Strings::ToUnsignedInt(row[ItemField::dsmitigation]);
|
||||
item.Haste = Strings::ToInt(row[ItemField::haste]);
|
||||
item.HealAmt = Strings::ToInt(row[ItemField::healamt]);
|
||||
item.Purity = Strings::ToUnsignedInt(row[ItemField::purity]);
|
||||
item.Shielding = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::shielding]), -128, 127));
|
||||
item.SpellDmg = Strings::ToInt(row[ItemField::spelldmg]);
|
||||
item.SpellShield = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::spellshield]), -128, 127));
|
||||
item.StrikeThrough = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::strikethrough]), -128, 127));
|
||||
item.StunResist = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::stunresist]), -128, 127));
|
||||
item.AC = e.ac;
|
||||
item.Accuracy = EQ::Clamp(e.accuracy, -128, 127);
|
||||
item.Attack = e.attack;
|
||||
item.Avoidance = EQ::Clamp(e.avoidance, -128, 127);
|
||||
item.Clairvoyance = e.clairvoyance;
|
||||
item.CombatEffects = Strings::IsNumber(e.combateffects) ? static_cast<int8>(EQ::Clamp(Strings::ToInt(e.combateffects), -128, 127)) : 0;
|
||||
item.DamageShield = e.damageshield;
|
||||
item.DotShielding = e.dotshielding;
|
||||
item.DSMitigation = e.dsmitigation;
|
||||
item.Haste = e.haste;
|
||||
item.HealAmt = e.healamt;
|
||||
item.Purity = e.purity;
|
||||
item.Shielding = EQ::Clamp(e.shielding, -128, 127);
|
||||
item.SpellDmg = e.spelldmg;
|
||||
item.SpellShield = EQ::Clamp(e.spellshield, -128, 127);
|
||||
item.StrikeThrough = EQ::Clamp(e.strikethrough, -128, 127);
|
||||
item.StunResist = EQ::Clamp(e.stunresist, -128, 127);
|
||||
|
||||
// Restrictions
|
||||
item.AugRestrict = Strings::ToUnsignedInt(row[ItemField::augrestrict]);
|
||||
item.Classes = Strings::ToUnsignedInt(row[ItemField::classes]);
|
||||
item.Deity = Strings::ToUnsignedInt(row[ItemField::deity]);
|
||||
item.ItemClass = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::itemclass]));
|
||||
item.Races = Strings::ToUnsignedInt(row[ItemField::races]);
|
||||
item.RecLevel = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::reclevel]));
|
||||
item.RecSkill = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::recskill]));
|
||||
item.ReqLevel = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::reqlevel]));
|
||||
item.Slots = Strings::ToUnsignedInt(row[ItemField::slots]);
|
||||
item.AugRestrict = e.augrestrict;
|
||||
item.Classes = e.classes;
|
||||
item.Deity = e.deity;
|
||||
item.ItemClass = static_cast<uint8>(e.itemclass);
|
||||
item.Races = e.races;
|
||||
item.RecLevel = static_cast<uint8>(e.reclevel);
|
||||
item.RecSkill = static_cast<uint8>(e.recskill);
|
||||
item.ReqLevel = static_cast<uint8>(e.reqlevel);
|
||||
item.Slots = e.slots;
|
||||
|
||||
// Skill Modifier
|
||||
item.SkillModValue = Strings::ToInt(row[ItemField::skillmodvalue]);
|
||||
item.SkillModMax = Strings::ToInt(row[ItemField::skillmodmax]);
|
||||
item.SkillModType = Strings::ToUnsignedInt(row[ItemField::skillmodtype]);
|
||||
item.SkillModValue = e.skillmodvalue;
|
||||
item.SkillModMax = e.skillmodmax;
|
||||
item.SkillModType = e.skillmodtype;
|
||||
|
||||
// Extra Damage Skill
|
||||
item.ExtraDmgSkill = Strings::ToInt(row[ItemField::extradmgskill]);
|
||||
item.ExtraDmgAmt = Strings::ToInt(row[ItemField::extradmgamt]);
|
||||
item.ExtraDmgSkill = e.extradmgskill;
|
||||
item.ExtraDmgAmt = e.extradmgamt;
|
||||
|
||||
// Bard
|
||||
item.BardType = Strings::ToUnsignedInt(row[ItemField::bardtype]);
|
||||
item.BardValue = Strings::ToInt(row[ItemField::bardvalue]);
|
||||
item.BardType = e.bardtype;
|
||||
item.BardValue = e.bardvalue;
|
||||
|
||||
// Faction
|
||||
item.FactionAmt1 = Strings::ToInt(row[ItemField::factionamt1]);
|
||||
item.FactionMod1 = Strings::ToInt(row[ItemField::factionmod1]);
|
||||
item.FactionAmt2 = Strings::ToInt(row[ItemField::factionamt2]);
|
||||
item.FactionMod2 = Strings::ToInt(row[ItemField::factionmod2]);
|
||||
item.FactionAmt3 = Strings::ToInt(row[ItemField::factionamt3]);
|
||||
item.FactionMod3 = Strings::ToInt(row[ItemField::factionmod3]);
|
||||
item.FactionAmt4 = Strings::ToInt(row[ItemField::factionamt4]);
|
||||
item.FactionMod4 = Strings::ToInt(row[ItemField::factionmod4]);
|
||||
item.FactionAmt1 = e.factionamt1;
|
||||
item.FactionMod1 = e.factionmod1;
|
||||
item.FactionAmt2 = e.factionamt2;
|
||||
item.FactionMod2 = e.factionmod2;
|
||||
item.FactionAmt3 = e.factionamt3;
|
||||
item.FactionMod3 = e.factionmod3;
|
||||
item.FactionAmt4 = e.factionamt4;
|
||||
item.FactionMod4 = e.factionmod4;
|
||||
|
||||
// Augment
|
||||
item.AugDistiller = Strings::ToUnsignedInt(row[ItemField::augdistiller]);
|
||||
item.AugSlotType[0] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot1type]));
|
||||
item.AugSlotVisible[0] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot1visible]));
|
||||
item.AugSlotType[1] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot2type]));
|
||||
item.AugSlotVisible[1] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot2visible]));
|
||||
item.AugSlotType[2] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot3type]));
|
||||
item.AugSlotVisible[2] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot3visible]));
|
||||
item.AugSlotType[3] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot4type]));
|
||||
item.AugSlotVisible[3] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot4visible]));
|
||||
item.AugSlotType[4] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot5type]));
|
||||
item.AugSlotVisible[4] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot5visible]));
|
||||
item.AugSlotType[5] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot6type]));
|
||||
item.AugSlotVisible[5] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot6visible]));
|
||||
// Augment Distiller
|
||||
item.AugDistiller = e.augdistiller;
|
||||
|
||||
// Augment Slots
|
||||
item.AugSlotType[0] = static_cast<uint8>(e.augslot1type);
|
||||
item.AugSlotVisible[0] = static_cast<uint8>(e.augslot1visible);
|
||||
item.AugSlotType[1] = static_cast<uint8>(e.augslot2type);
|
||||
item.AugSlotVisible[1] = static_cast<uint8>(e.augslot2visible);
|
||||
item.AugSlotType[2] = static_cast<uint8>(e.augslot3type);
|
||||
item.AugSlotVisible[2] = static_cast<uint8>(e.augslot3visible);
|
||||
item.AugSlotType[3] = static_cast<uint8>(e.augslot4type);
|
||||
item.AugSlotVisible[3] = static_cast<uint8>(e.augslot4visible);
|
||||
item.AugSlotType[4] = static_cast<uint8>(e.augslot5type);
|
||||
item.AugSlotVisible[4] = static_cast<uint8>(e.augslot5visible);
|
||||
item.AugSlotType[5] = static_cast<uint8>(e.augslot6type);
|
||||
item.AugSlotVisible[5] = static_cast<uint8>(e.augslot6visible);
|
||||
|
||||
// Augment Unknowns
|
||||
for (uint8 i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
|
||||
@ -1239,79 +1179,79 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
}
|
||||
|
||||
// LDoN
|
||||
item.LDoNTheme = Strings::ToUnsignedInt(row[ItemField::ldontheme]);
|
||||
item.LDoNPrice = Strings::ToUnsignedInt(row[ItemField::ldonprice]);
|
||||
item.LDoNSellBackRate = Strings::ToUnsignedInt(row[ItemField::ldonsellbackrate]);
|
||||
item.LDoNSold = Strings::ToUnsignedInt(row[ItemField::ldonsold]);
|
||||
item.PointType = Strings::ToUnsignedInt(row[ItemField::pointtype]);
|
||||
item.LDoNTheme = e.ldontheme;
|
||||
item.LDoNPrice = e.ldonprice;
|
||||
item.LDoNSellBackRate = e.ldonsellbackrate;
|
||||
item.LDoNSold = e.ldonsold;
|
||||
item.PointType = e.pointtype;
|
||||
|
||||
// Bag
|
||||
item.BagSize = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bagsize]));
|
||||
item.BagSlots = static_cast<uint8>(EQ::Clamp(Strings::ToInt(row[ItemField::bagslots]), 0, static_cast<int>(EQ::invbag::SLOT_COUNT)));
|
||||
item.BagType = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bagtype]));
|
||||
item.BagWR = static_cast<uint8>(EQ::Clamp(Strings::ToInt(row[ItemField::bagwr]), 0, 100));
|
||||
item.BagSize = static_cast<uint8>(e.bagsize);
|
||||
item.BagSlots = EQ::Clamp(e.bagslots, 0, static_cast<int>(EQ::invbag::SLOT_COUNT));
|
||||
item.BagType = static_cast<uint8>(e.bagtype);
|
||||
item.BagWR = EQ::Clamp(e.bagwr, 0, 100);
|
||||
|
||||
// Bard Effect
|
||||
item.Bard.Effect = disable_bard_focus_effects ? 0 : Strings::ToInt(row[ItemField::bardeffect]);
|
||||
item.Bard.Type = disable_bard_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bardtype]));
|
||||
item.Bard.Level = disable_bard_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bardlevel]));
|
||||
item.Bard.Level2 = disable_bard_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bardlevel2]));
|
||||
item.Bard.Effect = disable_bard_focus_effects ? 0 : e.bardeffect;
|
||||
item.Bard.Type = disable_bard_focus_effects ? 0 : static_cast<uint8>(e.bardtype);
|
||||
item.Bard.Level = disable_bard_focus_effects ? 0 : static_cast<uint8>(e.bardlevel);
|
||||
item.Bard.Level2 = disable_bard_focus_effects ? 0 : static_cast<uint8>(e.bardlevel2);
|
||||
|
||||
// Book
|
||||
item.Book = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::book]));
|
||||
item.BookType = Strings::ToUnsignedInt(row[ItemField::booktype]);
|
||||
item.Book = static_cast<uint8>(e.book);
|
||||
item.BookType = e.booktype;
|
||||
|
||||
// Click Effect
|
||||
item.CastTime = Strings::ToUnsignedInt(row[ItemField::casttime]);
|
||||
item.CastTime_ = Strings::ToInt(row[ItemField::casttime_]);
|
||||
item.Click.Effect = Strings::ToInt(row[ItemField::clickeffect]);
|
||||
item.Click.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::clicktype]));
|
||||
item.Click.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::clicklevel]));
|
||||
item.Click.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::clicklevel2]));
|
||||
strn0cpy(item.ClickName, row[ItemField::clickname], sizeof(item.ClickName));
|
||||
item.RecastDelay = Strings::ToUnsignedInt(row[ItemField::recastdelay]);
|
||||
item.RecastType = Strings::ToInt(row[ItemField::recasttype]);
|
||||
item.CastTime = e.casttime;
|
||||
item.CastTime_ = e.casttime_;
|
||||
item.Click.Effect = e.clickeffect;
|
||||
item.Click.Type = static_cast<uint8>(e.clicktype);
|
||||
item.Click.Level = static_cast<uint8>(e.clicklevel);
|
||||
item.Click.Level2 = static_cast<uint8>(e.clicklevel2);
|
||||
strn0cpy(item.ClickName, e.clickname.c_str(), sizeof(item.ClickName));
|
||||
item.RecastDelay = e.recastdelay;
|
||||
item.RecastType = e.recasttype;
|
||||
|
||||
// Focus Effect
|
||||
item.Focus.Effect = disable_spell_focus_effects ? 0 : Strings::ToInt(row[ItemField::focuseffect]);
|
||||
item.Focus.Type = disable_spell_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::focustype]));
|
||||
item.Focus.Level = disable_spell_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::focuslevel]));
|
||||
item.Focus.Level2 = disable_spell_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::focuslevel2]));
|
||||
strn0cpy(item.FocusName, disable_spell_focus_effects ? "" : row[ItemField::focusname], sizeof(item.FocusName));
|
||||
item.Focus.Effect = disable_spell_focus_effects ? 0 : e.focuseffect;
|
||||
item.Focus.Type = disable_spell_focus_effects ? 0 : static_cast<uint8>(e.focustype);
|
||||
item.Focus.Level = disable_spell_focus_effects ? 0 : static_cast<uint8>(e.focuslevel);
|
||||
item.Focus.Level2 = disable_spell_focus_effects ? 0 : static_cast<uint8>(e.focuslevel2);
|
||||
strn0cpy(item.FocusName, disable_spell_focus_effects ? "" : e.focusname.c_str(), sizeof(item.FocusName));
|
||||
|
||||
// Proc Effect
|
||||
item.Proc.Effect = Strings::ToInt(row[ItemField::proceffect]);
|
||||
item.Proc.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::proctype]));
|
||||
item.Proc.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::proclevel]));
|
||||
item.Proc.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::proclevel2]));
|
||||
strn0cpy(item.ProcName, row[ItemField::procname], sizeof(item.ProcName));
|
||||
item.ProcRate = Strings::ToInt(row[ItemField::procrate]);
|
||||
item.Proc.Effect = e.proceffect;
|
||||
item.Proc.Type = static_cast<uint8>(e.proctype);
|
||||
item.Proc.Level = static_cast<uint8>(e.proclevel);
|
||||
item.Proc.Level2 = static_cast<uint8>(e.proclevel2);
|
||||
strn0cpy(item.ProcName, e.procname.c_str(), sizeof(item.ProcName));
|
||||
item.ProcRate = e.procrate;
|
||||
|
||||
// Scroll Effect
|
||||
item.Scroll.Effect = Strings::ToInt(row[ItemField::scrolleffect]);
|
||||
item.Scroll.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::scrolltype]));
|
||||
item.Scroll.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::scrolllevel]));
|
||||
item.Scroll.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::scrolllevel2]));
|
||||
strn0cpy(item.ScrollName, row[ItemField::scrollname], sizeof(item.ScrollName));
|
||||
item.Scroll.Effect = e.scrolleffect;
|
||||
item.Scroll.Type = static_cast<uint8>(e.scrolltype);
|
||||
item.Scroll.Level = static_cast<uint8>(e.scrolllevel);
|
||||
item.Scroll.Level2 = static_cast<uint8>(e.scrolllevel2);
|
||||
strn0cpy(item.ScrollName, e.scrollname.c_str(), sizeof(item.ScrollName));
|
||||
|
||||
// Worn Effect
|
||||
item.Worn.Effect = Strings::ToInt(row[ItemField::worneffect]);
|
||||
item.Worn.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::worntype]));
|
||||
item.Worn.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::wornlevel]));
|
||||
item.Worn.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::wornlevel2]));
|
||||
strn0cpy(item.WornName, row[ItemField::wornname], sizeof(item.WornName));
|
||||
item.Worn.Effect = e.worneffect;
|
||||
item.Worn.Type = static_cast<uint8>(e.worntype);
|
||||
item.Worn.Level = static_cast<uint8>(e.wornlevel);
|
||||
item.Worn.Level2 = static_cast<uint8>(e.wornlevel2);
|
||||
strn0cpy(item.WornName, e.wornname.c_str(), sizeof(item.WornName));
|
||||
|
||||
// Evolving Item
|
||||
item.EvolvingID = Strings::ToUnsignedInt(row[ItemField::evoid]);
|
||||
item.EvolvingItem = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::evoitem]));
|
||||
item.EvolvingLevel = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::evolvinglevel]));
|
||||
item.EvolvingMax = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::evomax]));
|
||||
item.EvolvingID = e.evoid;
|
||||
item.EvolvingItem = static_cast<uint8>(e.evoitem);
|
||||
item.EvolvingLevel = static_cast<uint8>(e.evolvinglevel);
|
||||
item.EvolvingMax = static_cast<uint8>(e.evomax);
|
||||
|
||||
// Scripting
|
||||
item.CharmFileID = Strings::IsNumber(row[ItemField::charmfileid]) ? Strings::ToUnsignedInt(row[ItemField::charmfileid]) : 0;
|
||||
strn0cpy(item.CharmFile, row[ItemField::charmfile], sizeof(item.CharmFile));
|
||||
strn0cpy(item.Filename, row[ItemField::filename], sizeof(item.Filename));
|
||||
item.ScriptFileID = Strings::ToUnsignedInt(row[ItemField::scriptfileid]);
|
||||
item.CharmFileID = Strings::IsNumber(e.charmfileid) ? Strings::ToUnsignedInt(e.charmfileid) : 0;
|
||||
strn0cpy(item.CharmFile, e.charmfile.c_str(), sizeof(item.CharmFile));
|
||||
strn0cpy(item.Filename, e.filename.c_str(), sizeof(item.Filename));
|
||||
item.ScriptFileID = e.scriptfileid;
|
||||
|
||||
try {
|
||||
hash.insert(item.ID, item);
|
||||
@ -1673,20 +1613,17 @@ bool SharedDatabase::GetCommandSubSettings(std::vector<CommandSubsettingsReposit
|
||||
return true;
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID) {
|
||||
const std::string query = StringFormat("SELECT `spellid`, `type` FROM `damageshieldtypes` WHERE `spellid` > 0 "
|
||||
"AND `spellid` <= %i", iMaxSpellID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* s)
|
||||
{
|
||||
const auto& l = DamageshieldtypesRepository::All(*this);
|
||||
|
||||
for(auto& row = results.begin(); row != results.end(); ++row) {
|
||||
const int spellID = Strings::ToInt(row[0]);
|
||||
if((spellID > 0) && (spellID <= iMaxSpellID))
|
||||
sp[spellID].damage_shield_type = Strings::ToUnsignedInt(row[1]);
|
||||
}
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
s[e.spellid].damage_shield_type = e.type;
|
||||
}
|
||||
}
|
||||
|
||||
const EvolveInfo* SharedDatabase::GetEvolveInfo(uint32 loregroup) {
|
||||
@ -1903,21 +1840,32 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
||||
sp[tempid].damage_shield_type = 0;
|
||||
}
|
||||
|
||||
LoadDamageShieldTypes(sp, max_spells);
|
||||
LoadDamageShieldTypes(sp);
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
|
||||
const std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
|
||||
auto results = QueryDatabase(query);
|
||||
memset(message, '\0', sizeof(InspectMessage_Struct));
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
memcpy(message, row[0], sizeof(InspectMessage_Struct));
|
||||
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* s)
|
||||
{
|
||||
const auto& e = CharacterInspectMessagesRepository::FindOne(*this, character_id);
|
||||
|
||||
memset(s, '\0', sizeof(InspectMessage_Struct));
|
||||
|
||||
if (!e.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(s, e.inspect_message.c_str(), sizeof(InspectMessage_Struct));
|
||||
}
|
||||
|
||||
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
|
||||
const std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, Strings::Escape(message->text).c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* s)
|
||||
{
|
||||
auto e = CharacterInspectMessagesRepository::NewEntity();
|
||||
|
||||
e.id = character_id;
|
||||
e.inspect_message = s->text;
|
||||
|
||||
if (!CharacterInspectMessagesRepository::ReplaceOne(*this, e)) {
|
||||
LogError("Failed to save character inspect message of [{}] for character_id [{}]", s->text, character_id);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SharedDatabase::GetSpellsCount()
|
||||
@ -1938,18 +1886,7 @@ uint32 SharedDatabase::GetSpellsCount()
|
||||
|
||||
uint32 SharedDatabase::GetItemsCount()
|
||||
{
|
||||
auto results = QueryDatabase("SELECT count(*) FROM items");
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& row = results.begin();
|
||||
|
||||
if (row[0]) {
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ItemsRepository::Count(*this);
|
||||
}
|
||||
|
||||
void SharedDatabase::SetSharedItemsCount(uint32 shared_items_count)
|
||||
|
||||
@ -76,21 +76,20 @@ public:
|
||||
uint8 GetGMSpeed(uint32 account_id);
|
||||
bool SetHideMe(uint32 account_id, uint8 hideme);
|
||||
int DeleteStalePlayerCorpses();
|
||||
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct *message);
|
||||
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct *message);
|
||||
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* s);
|
||||
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* s);
|
||||
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
|
||||
bool UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected);
|
||||
bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned);
|
||||
bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings);
|
||||
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
|
||||
bool SetGMInvul(uint32 account_id, bool gminvul);
|
||||
bool SetGMFlymode(uint32 account_id, uint8 flymode);
|
||||
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
||||
void SetMailKey(uint32 character_id, uint32 ip_address, uint32 mail_key);
|
||||
struct MailKeys {
|
||||
std::string mail_key;
|
||||
std::string mail_key_full;
|
||||
};
|
||||
MailKeys GetMailKey(int character_id);
|
||||
MailKeys GetMailKey(uint32 character_id);
|
||||
bool SaveCursor(
|
||||
uint32 char_id,
|
||||
std::list<EQ::ItemInstance *>::const_iterator &start,
|
||||
@ -104,7 +103,7 @@ public:
|
||||
bool VerifyInventory(uint32 account_id, int16 slot_id, const EQ::ItemInstance *inst);
|
||||
bool GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is_charid);
|
||||
int32 GetSharedPlatinum(uint32 account_id);
|
||||
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
|
||||
bool AddSharedPlatinum(uint32 account_id, int amount);
|
||||
bool GetInventory(Client* c);
|
||||
bool GetInventory(uint32 account_id, char *name, EQ::InventoryProfile *inv); // deprecated
|
||||
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
|
||||
@ -158,7 +157,7 @@ public:
|
||||
);
|
||||
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0);
|
||||
|
||||
void GetItemsCount(int32 &item_count, uint32 &max_id);
|
||||
void GetItemsCount(int32& item_count, uint32& max_id);
|
||||
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
|
||||
bool LoadItems(const std::string &prefix);
|
||||
const EQ::ItemData *IterateItems(uint32 *id) const;
|
||||
@ -173,7 +172,7 @@ public:
|
||||
int GetMaxSpellID();
|
||||
bool LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp);
|
||||
void LoadSpells(void *data, int max_spells);
|
||||
void LoadDamageShieldTypes(SPDat_Spell_Struct *sp, int32 iMaxSpellID);
|
||||
void LoadDamageShieldTypes(SPDat_Spell_Struct* s);
|
||||
uint32 GetSharedSpellsCount() { return m_shared_spells_count; }
|
||||
uint32 GetSpellsCount();
|
||||
|
||||
|
||||
830
common/spdat.cpp
830
common/spdat.cpp
File diff suppressed because it is too large
Load Diff
1063
common/spdat.h
1063
common/spdat.h
File diff suppressed because it is too large
Load Diff
@ -358,6 +358,7 @@ bool RequiresStackCheck(uint16 spell_type) {
|
||||
case BotSpellTypes::CompleteHeal:
|
||||
case BotSpellTypes::PetCompleteHeals:
|
||||
case BotSpellTypes::GroupCompleteHeals:
|
||||
case BotSpellTypes::Resurrect:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
|
||||
@ -313,6 +313,12 @@ std::string Strings::Commify(const std::string &number)
|
||||
|
||||
auto string_length = static_cast<int>(number.length());
|
||||
|
||||
if (string_length == 3) {
|
||||
return number;
|
||||
} else if (string_length == 4 && number.starts_with("-")) {
|
||||
return number;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (i = string_length - 3; i >= 0; i -= 3) {
|
||||
if (i > 0) {
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "23.8.1-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "23.10.3-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9325
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9328
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||
#define CUSTOM_BINARY_DATABASE_VERSION 0
|
||||
|
||||
|
||||
20
hc/eq.cpp
20
hc/eq.cpp
@ -33,7 +33,7 @@ EverQuest::EverQuest(const std::string &host, int port, const std::string &user,
|
||||
}
|
||||
else {
|
||||
m_host = addr;
|
||||
m_login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_login_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
|
||||
m_login_connection_manager->OnNewConnection(std::bind(&EverQuest::LoginOnNewConnection, this, std::placeholders::_1));
|
||||
m_login_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::LoginOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
@ -48,13 +48,13 @@ EverQuest::~EverQuest()
|
||||
{
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void EverQuest::LoginOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_login_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting...");
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Login connected.");
|
||||
@ -70,14 +70,14 @@ void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::Day
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_login_connection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
|
||||
void EverQuest::LoginOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet & p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
@ -251,20 +251,20 @@ void EverQuest::LoginDisableReconnect()
|
||||
|
||||
void EverQuest::ConnectToWorld()
|
||||
{
|
||||
m_world_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_world_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
m_world_connection_manager->OnNewConnection(std::bind(&EverQuest::WorldOnNewConnection, this, std::placeholders::_1));
|
||||
m_world_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::WorldOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_world_connection_manager->OnPacketRecv(std::bind(&EverQuest::WorldOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
m_world_connection_manager->Connect(m_host, 9000);
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void EverQuest::WorldOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_world_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting to world...");
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "World connected.");
|
||||
@ -278,14 +278,14 @@ void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::Day
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_world_connection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
|
||||
void EverQuest::WorldOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet & p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
|
||||
26
hc/eq.h
26
hc/eq.h
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "../common/event/timer.h"
|
||||
#include <openssl/des.h>
|
||||
#include <string>
|
||||
@ -26,10 +26,10 @@ public:
|
||||
|
||||
private:
|
||||
//Login
|
||||
void LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void LoginOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
|
||||
void LoginSendSessionReady();
|
||||
void LoginSendLogin();
|
||||
@ -41,25 +41,25 @@ private:
|
||||
|
||||
void LoginDisableReconnect();
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_login_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_login_connection;
|
||||
std::map<uint32_t, WorldServer> m_world_servers;
|
||||
|
||||
//World
|
||||
void ConnectToWorld();
|
||||
|
||||
void WorldOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void WorldOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
|
||||
void WorldSendClientAuth();
|
||||
void WorldSendEnterWorld(const std::string &character);
|
||||
|
||||
void WorldProcessCharacterSelect(const EQ::Net::Packet &p);
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_world_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_world_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_world_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_world_connection;
|
||||
|
||||
//Variables
|
||||
std::string m_host;
|
||||
|
||||
10
hc/login.cpp
10
hc/login.cpp
@ -26,7 +26,7 @@ LoginConnection::LoginConnection(const std::string &username, const std::string
|
||||
m_host_port = host_port;
|
||||
m_server = server;
|
||||
|
||||
m_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
|
||||
m_connection_manager->OnNewConnection(std::bind(&LoginConnection::OnNewConnection, this, std::placeholders::_1));
|
||||
m_connection_manager->OnConnectionStateChange(std::bind(&LoginConnection::OnStatusChangeActive, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
@ -39,13 +39,13 @@ LoginConnection::~LoginConnection()
|
||||
{
|
||||
}
|
||||
|
||||
void LoginConnection::OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void LoginConnection::OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting...");
|
||||
}
|
||||
|
||||
void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Login connected.");
|
||||
@ -61,7 +61,7 @@ void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConn
|
||||
}
|
||||
}
|
||||
|
||||
void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_key.clear();
|
||||
@ -70,7 +70,7 @@ void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakCo
|
||||
}
|
||||
}
|
||||
|
||||
void LoginConnection::OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
|
||||
void LoginConnection::OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
|
||||
14
hc/login.h
14
hc/login.h
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "../common/event/timer.h"
|
||||
#include <map>
|
||||
|
||||
@ -23,10 +23,10 @@ public:
|
||||
|
||||
~LoginConnection();
|
||||
private:
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
void Kill();
|
||||
void Start();
|
||||
|
||||
@ -38,8 +38,8 @@ private:
|
||||
void ProcessServerPacketList(const EQ::Net::Packet &p);
|
||||
void ProcessServerPlayResponse(const EQ::Net::Packet &p);
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_connection;
|
||||
bool m_connecting;
|
||||
std::unique_ptr<EQ::Timer> m_connect_timer;
|
||||
|
||||
|
||||
10
hc/world.cpp
10
hc/world.cpp
@ -8,7 +8,7 @@ WorldConnection::WorldConnection(const std::string &key, uint32_t dbid, const st
|
||||
m_key = key;
|
||||
m_dbid = dbid;
|
||||
|
||||
m_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
m_connection_manager->OnNewConnection(std::bind(&WorldConnection::OnNewConnection, this, std::placeholders::_1));
|
||||
m_connection_manager->OnConnectionStateChange(std::bind(&WorldConnection::OnStatusChangeActive, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_connection_manager->OnPacketRecv(std::bind(&WorldConnection::OnPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
@ -18,13 +18,13 @@ WorldConnection::WorldConnection(const std::string &key, uint32_t dbid, const st
|
||||
WorldConnection::~WorldConnection() {
|
||||
}
|
||||
|
||||
void WorldConnection::OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void WorldConnection::OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting to world...");
|
||||
}
|
||||
|
||||
void WorldConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void WorldConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "World connected.");
|
||||
@ -38,14 +38,14 @@ void WorldConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConn
|
||||
}
|
||||
}
|
||||
|
||||
void WorldConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void WorldConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_connection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldConnection::OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
|
||||
void WorldConnection::OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Packet in:\n{0}", p.ToString());
|
||||
|
||||
14
hc/world.h
14
hc/world.h
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "../common/event/timer.h"
|
||||
#include <map>
|
||||
|
||||
@ -10,17 +10,17 @@ public:
|
||||
WorldConnection(const std::string &key, uint32_t dbid, const std::string &host);
|
||||
~WorldConnection();
|
||||
private:
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
void Kill();
|
||||
void Start();
|
||||
|
||||
void SendClientAuth();
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_connection;
|
||||
bool m_connecting;
|
||||
std::unique_ptr<EQ::Timer> m_connect_timer;
|
||||
|
||||
|
||||
@ -124,18 +124,18 @@ uint64 AccountManagement::CheckExternalLoginserverUserCredentials(LoginAccountCo
|
||||
bool running = true;
|
||||
uint32 ret = 0;
|
||||
|
||||
EQ::Net::DaybreakConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn;
|
||||
EQ::Net::ReliableStreamConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> conn;
|
||||
|
||||
mgr.OnNewConnection(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> connection) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> connection) {
|
||||
conn = connection;
|
||||
}
|
||||
);
|
||||
|
||||
mgr.OnConnectionStateChange(
|
||||
[&](
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
) {
|
||||
@ -152,7 +152,7 @@ uint64 AccountManagement::CheckExternalLoginserverUserCredentials(LoginAccountCo
|
||||
);
|
||||
|
||||
mgr.OnPacketRecv(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p) {
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
case 0x0017: //OP_ChatMessage
|
||||
@ -250,18 +250,18 @@ uint64 AccountManagement::HealthCheckUserLogin()
|
||||
bool running = true;
|
||||
uint64 ret = 0;
|
||||
|
||||
EQ::Net::DaybreakConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> c;
|
||||
EQ::Net::ReliableStreamConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> c;
|
||||
|
||||
mgr.OnNewConnection(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> connection) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> connection) {
|
||||
c = connection;
|
||||
}
|
||||
);
|
||||
|
||||
mgr.OnConnectionStateChange(
|
||||
[&](
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
) {
|
||||
@ -278,7 +278,7 @@ uint64 AccountManagement::HealthCheckUserLogin()
|
||||
);
|
||||
|
||||
mgr.OnPacketRecv(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p) {
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
case 0x0017: //OP_ChatMessage
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include "../common/random.h"
|
||||
#include "../common/eq_stream_intf.h"
|
||||
#include "../common/net/dns.h"
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "login_types.h"
|
||||
#include "../common/repositories/login_accounts_repository.h"
|
||||
#include <memory>
|
||||
@ -54,8 +54,8 @@ private:
|
||||
unsigned int m_selected_play_server_id;
|
||||
unsigned int m_play_sequence_id;
|
||||
std::string m_key;
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_login_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_login_connection;
|
||||
LoginBaseMessage m_login_base_message;
|
||||
std::string m_stored_username;
|
||||
std::string m_stored_password;
|
||||
|
||||
@ -31,7 +31,7 @@ public:
|
||||
inline void DefaultLoginServerName(const std::string &v) { m_default_loginserver_name = v; }
|
||||
inline std::string GetDefaultLoginServerName() const { return m_default_loginserver_name; }
|
||||
inline bool IsShowPlayerCountEnabled() const { return m_show_player_count; }
|
||||
inline void SetShowPlayerCount(bool show_player_count) { show_player_count = show_player_count; }
|
||||
inline void SetShowPlayerCount(bool show_player_count) { m_show_player_count = show_player_count; }
|
||||
inline bool IsWorldDevTestServersListBottom() const { return m_world_dev_list_bottom; }
|
||||
inline void SetWorldDevTestServersListBottom(bool list_bottom) { m_world_dev_list_bottom = list_bottom; }
|
||||
inline bool IsWorldSpecialCharacterStartListBottom() const { return m_special_char_list_bottom; }
|
||||
|
||||
@ -155,7 +155,11 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
auto *res = (UsertoWorldResponseLegacy *) packet.Data();
|
||||
|
||||
LogDebug("Trying to find client with user id of [{}]", res->lsaccountid);
|
||||
Client *c = server.client_manager->GetClient(res->lsaccountid, "eqemu");
|
||||
std::string db_loginserver = "local";
|
||||
if (std::getenv("LSPX")) {
|
||||
db_loginserver = "eqemu";
|
||||
}
|
||||
Client *c = server.client_manager->GetClient(res->lsaccountid, db_loginserver);
|
||||
if (c) {
|
||||
LogDebug(
|
||||
"Found client with user id of [{}] and account name of [{}]",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "23.8.1",
|
||||
"version": "23.10.3",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
@ -35,4 +35,4 @@ IF(UNIX)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
ENDIF(UNIX)
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ../../Bin)
|
||||
SET(LIBRARY_OUTPUT_PATH ../../bin)
|
||||
|
||||
@ -469,11 +469,11 @@ static void ProcessCommandIgnore(Client *c, std::string Ignoree) {
|
||||
Clientlist::Clientlist(int ChatPort) {
|
||||
EQStreamManagerInterfaceOptions chat_opts(ChatPort, false, false);
|
||||
chat_opts.opcode_size = 1;
|
||||
chat_opts.daybreak_options.stale_connection_ms = 600000;
|
||||
chat_opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
chat_opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
chat_opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
chat_opts.daybreak_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
chat_opts.reliable_stream_options.stale_connection_ms = 600000;
|
||||
chat_opts.reliable_stream_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
chat_opts.reliable_stream_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
chat_opts.reliable_stream_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
chat_opts.reliable_stream_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
|
||||
chatsf = new EQ::Net::EQStreamManager(chat_opts);
|
||||
|
||||
|
||||
@ -14,15 +14,15 @@ perl utils/scripts/build/tag-version.pl
|
||||
|
||||
mkdir -p build && cd build && \
|
||||
cmake -DEQEMU_BUILD_TESTS=ON \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DEQEMU_BUILD_STATIC=ON \
|
||||
-DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_LUA=ON \
|
||||
-DEQEMU_BUILD_PERL=ON \
|
||||
-DCMAKE_CXX_FLAGS:STRING="-O1 -g -Wno-everything" \
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-O1 -g -Wno-everything" \
|
||||
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-g -Wno-everything" \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-G 'Unix Makefiles' \
|
||||
.. && make -j$((`nproc`-12))
|
||||
.. && make -j$((`nproc`-2))
|
||||
|
||||
curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
|
||||
./bin/tests
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
module should-release
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.5
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/google/go-github/v41 v41.0.0
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
golang.org/x/oauth2 v0.27.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.3.2 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@ -1,23 +1,22 @@
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg=
|
||||
github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -27,5 +26,4 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
|
||||
@ -985,7 +985,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
safe_delete(outapp);
|
||||
|
||||
// set mailkey - used for duration of character session
|
||||
int mail_key = EQ::Random::Instance()->Int(1, INT_MAX);
|
||||
uint32 mail_key = EQ::Random::Instance()->Int(1, INT_MAX);
|
||||
|
||||
database.SetMailKey(charid, GetIP(), mail_key);
|
||||
if (UCSServerAvailable_) {
|
||||
@ -1019,8 +1019,16 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::string ucs_addr = config->GetUCSHost();
|
||||
if (cle && cle->IsLocalClient()) {
|
||||
const char* local_addr = config->LocalAddress.c_str();
|
||||
if (local_addr[0]) {
|
||||
ucs_addr = local_addr;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||
config->GetUCSHost(),
|
||||
ucs_addr,
|
||||
config->GetUCSPort(),
|
||||
config->ShortName,
|
||||
GetCharName(),
|
||||
@ -1046,7 +1054,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||
config->GetUCSHost(),
|
||||
ucs_addr,
|
||||
config->GetUCSPort(),
|
||||
config->ShortName,
|
||||
GetCharName(),
|
||||
@ -2076,10 +2084,10 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
classtemp = cc->class_ - 1;
|
||||
racetemp = cc->race - 1;
|
||||
// these have non sequential race numbers so they need to be mapped
|
||||
if (cc->race == FROGLOK) racetemp = 14;
|
||||
if (cc->race == VAHSHIR) racetemp = 13;
|
||||
if (cc->race == IKSAR) racetemp = 12;
|
||||
if (cc->race == DRAKKIN) racetemp = 15;
|
||||
if (cc->race == Race::Froglok2) racetemp = 14;
|
||||
if (cc->race == Race::VahShir) racetemp = 13;
|
||||
if (cc->race == Race::Iksar) racetemp = 12;
|
||||
if (cc->race == Race::Drakkin) racetemp = 15;
|
||||
|
||||
// if out of range looking it up in the table would crash stuff
|
||||
// so we return from these
|
||||
@ -2186,43 +2194,43 @@ void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
|
||||
{
|
||||
switch( pp->race )
|
||||
{
|
||||
case BARBARIAN:
|
||||
case DWARF:
|
||||
case ERUDITE:
|
||||
case HALF_ELF:
|
||||
case HIGH_ELF:
|
||||
case HUMAN:
|
||||
case OGRE:
|
||||
case TROLL:
|
||||
case DRAKKIN: //Drakkin are supposed to get a starting AA Skill
|
||||
case Race::Barbarian:
|
||||
case Race::Dwarf:
|
||||
case Race::Erudite:
|
||||
case Race::HalfElf:
|
||||
case Race::HighElf:
|
||||
case Race::Human:
|
||||
case Race::Ogre:
|
||||
case Race::Troll:
|
||||
case Race::Drakkin: //Drakkin are supposed to get a starting AA Skill
|
||||
{
|
||||
// No Race Specific Skills
|
||||
break;
|
||||
}
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
{
|
||||
pp->skills[EQ::skills::SkillHide] = 50;
|
||||
break;
|
||||
}
|
||||
case FROGLOK:
|
||||
case Race::Froglok2:
|
||||
{
|
||||
if (RuleI(Skills, SwimmingStartValue) < 125) {
|
||||
pp->skills[EQ::skills::SkillSwimming] = 125;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
{
|
||||
pp->skills[EQ::skills::SkillTinkering] = 50;
|
||||
break;
|
||||
}
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
{
|
||||
pp->skills[EQ::skills::SkillHide] = 50;
|
||||
pp->skills[EQ::skills::SkillSneak] = 50;
|
||||
break;
|
||||
}
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
{
|
||||
pp->skills[EQ::skills::SkillForage] = 50;
|
||||
if (RuleI(Skills, SwimmingStartValue) < 100) {
|
||||
@ -2230,13 +2238,13 @@ void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WOOD_ELF:
|
||||
case Race::WoodElf:
|
||||
{
|
||||
pp->skills[EQ::skills::SkillForage] = 50;
|
||||
pp->skills[EQ::skills::SkillHide] = 50;
|
||||
break;
|
||||
}
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
{
|
||||
pp->skills[EQ::skills::SkillSafeFall] = 50;
|
||||
pp->skills[EQ::skills::SkillSneak] = 50;
|
||||
|
||||
@ -281,62 +281,107 @@ ClientListEntry* ClientList::FindCLEByCharacterID(uint32 iCharID) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* iName) {
|
||||
void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* search_criteria)
|
||||
{
|
||||
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
||||
int x = 0, y = 0;
|
||||
int namestrlen = iName == 0 ? 0 : strlen(iName);
|
||||
bool addnewline = false;
|
||||
char newline[3];
|
||||
if (connection->IsConsole())
|
||||
strcpy(newline, "\r\n");
|
||||
else
|
||||
strcpy(newline, "^");
|
||||
|
||||
auto out = fmt::memory_buffer();
|
||||
int found_count = 0;
|
||||
int total_count = 0;
|
||||
int name_length = search_criteria ? strlen(search_criteria) : 0;
|
||||
|
||||
const char* new_line = connection->IsConsole() ? "\r\n" : "^";
|
||||
bool add_new_line = false;
|
||||
|
||||
std::string message;
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
while (iterator.MoreElements()) {
|
||||
ClientListEntry* cle = iterator.GetData();
|
||||
if (admin >= cle->Admin() && (iName == 0 || namestrlen == 0 || strncasecmp(cle->name(), iName, namestrlen) == 0 || strncasecmp(cle->AccountName(), iName, namestrlen) == 0 || strncasecmp(cle->LSName(), iName, namestrlen) == 0)) {
|
||||
struct in_addr in;
|
||||
in.s_addr = cle->GetIP();
|
||||
if (addnewline) {
|
||||
fmt::format_to(std::back_inserter(out), fmt::runtime(newline));
|
||||
|
||||
struct in_addr in;
|
||||
in.s_addr = cle->GetIP();
|
||||
|
||||
if (
|
||||
admin >= cle->Admin() &&
|
||||
(
|
||||
!search_criteria ||
|
||||
Strings::Contains(std::string(inet_ntoa(in)), search_criteria) ||
|
||||
Strings::Contains(cle->name(), search_criteria) == 0 ||
|
||||
Strings::Contains(cle->AccountName(), search_criteria) == 0 ||
|
||||
Strings::Contains(cle->LSName(), search_criteria) == 0
|
||||
)
|
||||
) {
|
||||
if (add_new_line) {
|
||||
message += new_line;
|
||||
}
|
||||
fmt::format_to(std::back_inserter(out), "ID: {} Acc# {} AccName: {} IP: {}", cle->GetID(), cle->AccountID(), cle->AccountName(), inet_ntoa(in));
|
||||
fmt::format_to(std::back_inserter(out), "{} Stale: {} Online: {} Admin: {}", newline, cle->GetStaleCounter(), static_cast<int>(cle->Online()), cle->Admin());
|
||||
if (cle->LSID())
|
||||
fmt::format_to(std::back_inserter(out), "{} LSID: {} LSName: {} WorldAdmin: {}", newline, cle->LSID(), cle->LSName(), cle->WorldAdmin());
|
||||
if (cle->CharID())
|
||||
fmt::format_to(std::back_inserter(out), "{} CharID: {} CharName: {} Zone: {} ({})", newline, cle->CharID(), cle->name(), ZoneName(cle->zone()), cle->zone());
|
||||
if (out.size() >= 3072) {
|
||||
|
||||
message += fmt::format(
|
||||
"Account: {} ({}) | IP: {} | Admin: {}",
|
||||
cle->AccountName(),
|
||||
cle->AccountID(),
|
||||
inet_ntoa(in),
|
||||
cle->Admin()
|
||||
);
|
||||
|
||||
if (cle->CharID()) {
|
||||
message += fmt::format(
|
||||
"{}Character: {} ({}) | Zone: {} ({})",
|
||||
new_line,
|
||||
cle->name(),
|
||||
cle->CharID(),
|
||||
ZoneLongName(cle->zone()),
|
||||
cle->zone()
|
||||
);
|
||||
}
|
||||
|
||||
if (message.size() >= 3072) {
|
||||
connection->SendEmoteMessageRaw(
|
||||
to,
|
||||
0,
|
||||
AccountStatus::Player,
|
||||
Chat::NPCQuestSay,
|
||||
out.data()
|
||||
message.c_str()
|
||||
);
|
||||
addnewline = false;
|
||||
out.clear();
|
||||
message.clear();
|
||||
add_new_line = false;
|
||||
} else {
|
||||
addnewline = true;
|
||||
add_new_line = true;
|
||||
}
|
||||
y++;
|
||||
|
||||
found_count++;
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
x++;
|
||||
total_count++;
|
||||
}
|
||||
fmt::format_to(std::back_inserter(out), "{}{} CLEs in memory. {} CLEs listed. numplayers = {}.", newline, x, y, numplayers);
|
||||
|
||||
message += fmt::format(
|
||||
"{}{}Player Count: {}",
|
||||
new_line,
|
||||
(
|
||||
found_count != total_count ?
|
||||
fmt::format(
|
||||
"Total: {} CLE{} | Found: {} CLE{} | ",
|
||||
total_count,
|
||||
(total_count != 1 ? "s" : ""),
|
||||
found_count,
|
||||
(found_count != 1 ? "s" : "")
|
||||
) :
|
||||
""
|
||||
),
|
||||
numplayers
|
||||
);
|
||||
|
||||
connection->SendEmoteMessageRaw(
|
||||
to,
|
||||
0,
|
||||
AccountStatus::Player,
|
||||
Chat::NPCQuestSay,
|
||||
out.data()
|
||||
message.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void ClientList::CLEAdd(
|
||||
uint32 login_server_id,
|
||||
const char *login_server_name,
|
||||
@ -598,7 +643,7 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S
|
||||
whomlen = strlen(whom->whom);
|
||||
|
||||
if (whom->wrace == 0x001A) { // 0x001A is the old Froglok race number and is sent by the client for /who all froglok
|
||||
whom->wrace = FROGLOK; // This is what EQEmu uses for the Froglok Race number.
|
||||
whom->wrace = Race::Froglok2; // This is what EQEmu uses for the Froglok Race number.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ public:
|
||||
void SendClientVersionSummary(const char *Name);
|
||||
void SendLFGMatches(ServerLFGMatchesRequest_Struct *LFGMatchesRequest);
|
||||
void ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct* whom, WorldTCPConnection* connection);
|
||||
void SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* iName = 0);
|
||||
void SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* search_criteria = 0);
|
||||
|
||||
bool SendPacket(const char* to, ServerPacket* pack);
|
||||
|
||||
|
||||
@ -333,11 +333,11 @@ int main(int argc, char **argv)
|
||||
WorldBoot::CheckForPossibleConfigurationIssues();
|
||||
|
||||
EQStreamManagerInterfaceOptions opts(9000, false, false);
|
||||
opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
opts.daybreak_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
opts.daybreak_options.outgoing_data_rate = RuleR(Network, ClientDataRate);
|
||||
opts.reliable_stream_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.reliable_stream_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.reliable_stream_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
opts.reliable_stream_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
opts.reliable_stream_options.outgoing_data_rate = RuleR(Network, ClientDataRate);
|
||||
|
||||
EQ::Net::EQStreamManager eqsm(opts);
|
||||
|
||||
|
||||
@ -732,6 +732,12 @@ void WorldDatabase::SetTitaniumDefaultStartZone(PlayerProfile_Struct* in_pp, Cha
|
||||
in_pp->binds[0].zone_id = Zones::SHARVAHL; // sharvahl
|
||||
break;
|
||||
}
|
||||
case StartZoneIndex::RatheMtn:
|
||||
{
|
||||
in_pp->zone_id = Zones::RATHEMTN; // rathemtn
|
||||
in_pp->binds[0].zone_id = Zones::RATHEMTN; // rathemtn
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -895,9 +901,13 @@ bool WorldDatabase::GetCharSelInventory(
|
||||
inst->SetCustomDataString(e.custom_data);
|
||||
}
|
||||
|
||||
inst->SetOrnamentIcon(e.ornament_icon);
|
||||
inst->SetOrnamentationIDFile(e.ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(e.ornament_hero_model);
|
||||
if (e.ornament_icon != 0 || e.ornament_idfile != 0 || e.ornament_hero_model != 0) {
|
||||
inst->SetOrnamentIcon(e.ornament_icon);
|
||||
inst->SetOrnamentationIDFile(e.ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(e.ornament_hero_model);
|
||||
} else if (item->HerosForgeModel > 0) {
|
||||
inst->SetOrnamentHeroModel(item->HerosForgeModel);
|
||||
}
|
||||
|
||||
inv->PutItem(e.slot_id, *inst);
|
||||
|
||||
|
||||
@ -483,6 +483,7 @@ INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
# precompiled headers
|
||||
IF (EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/app-pch.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/std-pch.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ./pch/pch.h)
|
||||
ENDIF()
|
||||
|
||||
@ -501,7 +502,7 @@ if (EQEMU_BUILD_STATIC AND PERL_LIBRARY)
|
||||
endif()
|
||||
|
||||
# link zone against common libraries
|
||||
target_link_libraries(zone PRIVATE ${ZONE_LIBS} lua_zone perl_zone gm_commands_zone)
|
||||
target_link_libraries(zone PRIVATE lua_zone perl_zone gm_commands_zone ${ZONE_LIBS})
|
||||
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
|
||||
22
zone/aa.cpp
22
zone/aa.cpp
@ -82,7 +82,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
|
||||
for (int x = 0; x < MAX_SWARM_PETS; x++)
|
||||
{
|
||||
if (spells[spell_id].effect_id[x] == SE_TemporaryPets)
|
||||
if (spells[spell_id].effect_id[x] == SpellEffect::TemporaryPets)
|
||||
{
|
||||
pet.count = spells[spell_id].base_value[x];
|
||||
pet.duration = spells[spell_id].max_value[x];
|
||||
@ -1376,7 +1376,7 @@ int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) {
|
||||
}
|
||||
|
||||
for(auto &effect : rank->effects) {
|
||||
if(effect.effect_id == SE_HastenedAASkill && effect.limit_value == ability_in->id) {
|
||||
if(effect.effect_id == SpellEffect::HastenedAASkill && effect.limit_value == ability_in->id) {
|
||||
total_reduction += effect.base_value;
|
||||
}
|
||||
}
|
||||
@ -1619,7 +1619,7 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank)
|
||||
|
||||
auto race = GetPlayerRaceValue(GetBaseRace());
|
||||
|
||||
race = race > PLAYER_RACE_COUNT ? Race::Human : race;
|
||||
race = race > RaceIndex::Drakkin ? Race::Human : race;
|
||||
|
||||
if (!(a->races & (1 << (race - 1)))) {
|
||||
return false;
|
||||
@ -1949,7 +1949,7 @@ void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ab
|
||||
|
||||
Instructions for how to make the AA - assuming a basic level of knowledge of how AA's work.
|
||||
- aa_abilities table : Create new ability with a hotkey, type 3, zero charges
|
||||
- aa_ranks table : [Disabled rank] First rank, should have a cost > 0 (this is what you buy), Set hotkeys, MUST SET A SPELL CONTAINING EFFECT SE_Buy_AA_Rank(SPA 472), set a short recast timer.
|
||||
- aa_ranks table : [Disabled rank] First rank, should have a cost > 0 (this is what you buy), Set hotkeys, MUST SET A SPELL CONTAINING EFFECT SpellEffect::Buy_AA_Rank(SPA 472), set a short recast timer.
|
||||
[Enabled rank] Second rank, should have a cost = 0, Set hotkeys, Set any valid spell ID you want (it has to exist but does nothing), set a short recast timer.
|
||||
*Recommend if doing custom, just make the hotkey titled 'Toggle <Ability Name>' and use for both.
|
||||
|
||||
@ -1969,7 +1969,7 @@ void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ab
|
||||
|
||||
*/
|
||||
|
||||
bool enable_next_rank = IsEffectInSpell(rank.spell, SE_Buy_AA_Rank);
|
||||
bool enable_next_rank = IsEffectInSpell(rank.spell, SpellEffect::Buy_AA_Rank);
|
||||
|
||||
if (enable_next_rank) {
|
||||
|
||||
@ -1980,7 +1980,7 @@ void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ab
|
||||
AA::Rank *rank_next = zone->GetAlternateAdvancementRank(rank.next_id);
|
||||
|
||||
//Add checks for any special cases for toggle.
|
||||
if (rank_next && IsEffectinAlternateAdvancementRankEffects(*rank_next, SE_Weapon_Stance)) {
|
||||
if (rank_next && IsEffectinAlternateAdvancementRankEffects(*rank_next, SpellEffect::Weapon_Stance)) {
|
||||
weaponstance.aabonus_enabled = true;
|
||||
ApplyWeaponsStance();
|
||||
}
|
||||
@ -1994,7 +1994,7 @@ void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ab
|
||||
Message(Chat::Spells, "You disable an ability."); //Message live gives you. Should come from spell.
|
||||
|
||||
//Add checks for any special cases for toggle.
|
||||
if (IsEffectinAlternateAdvancementRankEffects(rank, SE_Weapon_Stance)) {
|
||||
if (IsEffectinAlternateAdvancementRankEffects(rank, SpellEffect::Weapon_Stance)) {
|
||||
weaponstance.aabonus_enabled = false;
|
||||
BuffFadeBySpellID(weaponstance.aabonus_buff_spell_id);
|
||||
}
|
||||
@ -2005,8 +2005,8 @@ void Client::TogglePassiveAlternativeAdvancement(const AA::Rank &rank, uint32 ab
|
||||
bool Client::UseTogglePassiveHotkey(const AA::Rank &rank) {
|
||||
|
||||
/*
|
||||
Disabled rank needs a rank spell containing the SE_Buy_AA_Rank effect to return true.
|
||||
Enabled rank checks to see if the prior rank contains a rank spell with SE_Buy_AA_Rank, if so true.
|
||||
Disabled rank needs a rank spell containing the SpellEffect::Buy_AA_Rank effect to return true.
|
||||
Enabled rank checks to see if the prior rank contains a rank spell with SpellEffect::Buy_AA_Rank, if so true.
|
||||
|
||||
Note: On live the enabled rank is Expendable with Charge 1.
|
||||
|
||||
@ -2014,13 +2014,13 @@ bool Client::UseTogglePassiveHotkey(const AA::Rank &rank) {
|
||||
*/
|
||||
|
||||
|
||||
if (IsEffectInSpell(rank.spell, SE_Buy_AA_Rank)) {//Checked when is Disabled.
|
||||
if (IsEffectInSpell(rank.spell, SpellEffect::Buy_AA_Rank)) {//Checked when is Disabled.
|
||||
return true;
|
||||
}
|
||||
else if (rank.prev_id != -1) {//Check when effect is Enabled.
|
||||
AA::Rank *rank_prev = zone->GetAlternateAdvancementRank(rank.prev_id);
|
||||
|
||||
if (rank_prev && IsEffectInSpell(rank_prev->spell, SE_Buy_AA_Rank)) {
|
||||
if (rank_prev && IsEffectInSpell(rank_prev->spell, SpellEffect::Buy_AA_Rank)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
134
zone/aggro.cpp
134
zone/aggro.cpp
@ -1377,132 +1377,132 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool is_proc)
|
||||
|
||||
for (int o = 0; o < EFFECT_COUNT; o++) {
|
||||
switch (spells[spell_id].effect_id[o]) {
|
||||
case SE_CurrentHPOnce:
|
||||
case SE_CurrentHP: {
|
||||
case SpellEffect::CurrentHPOnce:
|
||||
case SpellEffect::CurrentHP: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if(val < 0) {
|
||||
aggro_amount -= val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_MovementSpeed: {
|
||||
case SpellEffect::MovementSpeed: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if (val < 0) {
|
||||
aggro_amount += default_aggro;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_AttackSpeed:
|
||||
case SE_AttackSpeed2:
|
||||
case SE_AttackSpeed3: {
|
||||
case SpellEffect::AttackSpeed:
|
||||
case SpellEffect::AttackSpeed2:
|
||||
case SpellEffect::AttackSpeed3: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if (val < 100) {
|
||||
aggro_amount += default_aggro;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_Stun:
|
||||
case SE_Blind:
|
||||
case SE_Mez:
|
||||
case SE_Charm:
|
||||
case SE_Fear:
|
||||
case SE_Fearstun:
|
||||
case SpellEffect::Stun:
|
||||
case SpellEffect::Blind:
|
||||
case SpellEffect::Mez:
|
||||
case SpellEffect::Charm:
|
||||
case SpellEffect::Fear:
|
||||
case SpellEffect::Fearstun:
|
||||
aggro_amount += default_aggro;
|
||||
break;
|
||||
case SE_Root:
|
||||
case SpellEffect::Root:
|
||||
aggro_amount += 10;
|
||||
break;
|
||||
case SE_ACv2:
|
||||
case SE_ArmorClass: {
|
||||
case SpellEffect::ACv2:
|
||||
case SpellEffect::ArmorClass: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if (val < 0) {
|
||||
aggro_amount += default_aggro;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_ATK:
|
||||
case SE_ResistMagic:
|
||||
case SE_ResistFire:
|
||||
case SE_ResistCold:
|
||||
case SE_ResistPoison:
|
||||
case SE_ResistDisease:
|
||||
case SE_STR:
|
||||
case SE_STA:
|
||||
case SE_DEX:
|
||||
case SE_AGI:
|
||||
case SE_INT:
|
||||
case SE_WIS:
|
||||
case SE_CHA: {
|
||||
case SpellEffect::ATK:
|
||||
case SpellEffect::ResistMagic:
|
||||
case SpellEffect::ResistFire:
|
||||
case SpellEffect::ResistCold:
|
||||
case SpellEffect::ResistPoison:
|
||||
case SpellEffect::ResistDisease:
|
||||
case SpellEffect::STR:
|
||||
case SpellEffect::STA:
|
||||
case SpellEffect::DEX:
|
||||
case SpellEffect::AGI:
|
||||
case SpellEffect::INT:
|
||||
case SpellEffect::WIS:
|
||||
case SpellEffect::CHA: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if (val < 0) {
|
||||
aggro_amount += 10;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_ResistAll: {
|
||||
case SpellEffect::ResistAll: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if (val < 0) {
|
||||
aggro_amount += 50;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_AllStats: {
|
||||
case SpellEffect::AllStats: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if (val < 0) {
|
||||
aggro_amount += 70;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_BardAEDot:
|
||||
case SpellEffect::BardAEDot:
|
||||
aggro_amount += 10;
|
||||
break;
|
||||
case SE_SpinTarget:
|
||||
case SE_Amnesia:
|
||||
case SE_Silence:
|
||||
case SE_Destroy:
|
||||
case SpellEffect::SpinTarget:
|
||||
case SpellEffect::Amnesia:
|
||||
case SpellEffect::Silence:
|
||||
case SpellEffect::Destroy:
|
||||
aggro_amount += default_aggro;
|
||||
break;
|
||||
// unsure -- leave them this for now
|
||||
case SE_Harmony:
|
||||
case SE_CastingLevel:
|
||||
case SE_MeleeMitigation:
|
||||
case SE_CriticalHitChance:
|
||||
case SE_AvoidMeleeChance:
|
||||
case SE_RiposteChance:
|
||||
case SE_DodgeChance:
|
||||
case SE_ParryChance:
|
||||
case SE_DualWieldChance:
|
||||
case SE_DoubleAttackChance:
|
||||
case SE_MeleeSkillCheck:
|
||||
case SE_HitChance:
|
||||
case SE_DamageModifier:
|
||||
case SE_MinDamageModifier:
|
||||
case SE_IncreaseBlockChance:
|
||||
case SE_Accuracy:
|
||||
case SE_DamageShield:
|
||||
case SE_SpellDamageShield:
|
||||
case SE_ReverseDS: {
|
||||
case SpellEffect::Harmony:
|
||||
case SpellEffect::CastingLevel:
|
||||
case SpellEffect::MeleeMitigation:
|
||||
case SpellEffect::CriticalHitChance:
|
||||
case SpellEffect::AvoidMeleeChance:
|
||||
case SpellEffect::RiposteChance:
|
||||
case SpellEffect::DodgeChance:
|
||||
case SpellEffect::ParryChance:
|
||||
case SpellEffect::DualWieldChance:
|
||||
case SpellEffect::DoubleAttackChance:
|
||||
case SpellEffect::MeleeSkillCheck:
|
||||
case SpellEffect::HitChance:
|
||||
case SpellEffect::DamageModifier:
|
||||
case SpellEffect::MinDamageModifier:
|
||||
case SpellEffect::IncreaseBlockChance:
|
||||
case SpellEffect::Accuracy:
|
||||
case SpellEffect::DamageShield:
|
||||
case SpellEffect::SpellDamageShield:
|
||||
case SpellEffect::ReverseDS: {
|
||||
aggro_amount += mob_level * 2;
|
||||
break;
|
||||
}
|
||||
// unsure -- leave them this for now
|
||||
case SE_CurrentMana:
|
||||
case SE_ManaRegen_v2:
|
||||
case SE_ManaPool:
|
||||
case SE_CurrentEndurance: {
|
||||
case SpellEffect::CurrentMana:
|
||||
case SpellEffect::ManaRegen_v2:
|
||||
case SpellEffect::ManaPool:
|
||||
case SpellEffect::CurrentEndurance: {
|
||||
int64 val = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
if (val < 0) {
|
||||
aggro_amount -= val * 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_CancelMagic:
|
||||
case SE_DispelDetrimental:
|
||||
case SE_DispelBeneficial:
|
||||
case SpellEffect::CancelMagic:
|
||||
case SpellEffect::DispelDetrimental:
|
||||
case SpellEffect::DispelBeneficial:
|
||||
dispel = true;
|
||||
break;
|
||||
case SE_ReduceHate:
|
||||
case SE_InstantHate:
|
||||
case SpellEffect::ReduceHate:
|
||||
case SpellEffect::InstantHate:
|
||||
non_modified_aggro = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base_value[o], spells[spell_id].max_value[o], mob_level, spell_id);
|
||||
break;
|
||||
}
|
||||
@ -1549,8 +1549,8 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possib
|
||||
|
||||
for (int o = 0; o < EFFECT_COUNT; o++) {
|
||||
switch (spells[spell_id].effect_id[o]) {
|
||||
case SE_CurrentHP:
|
||||
case SE_PercentalHeal:
|
||||
case SpellEffect::CurrentHP:
|
||||
case SpellEffect::PercentalHeal:
|
||||
{
|
||||
if (heal_possible == 0) {
|
||||
AggroAmount += 1;
|
||||
@ -1572,12 +1572,12 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possib
|
||||
AggroAmount += std::max(val, (int64)1);
|
||||
break;
|
||||
}
|
||||
case SE_Rune:
|
||||
case SpellEffect::Rune:
|
||||
AggroAmount += CalcSpellEffectValue_formula(spells[spell_id].formula[o],
|
||||
spells[spell_id].base_value[o], spells[spell_id].max_value[o], GetLevel(), spell_id) * 2;
|
||||
ignore_default_buff = true;
|
||||
break;
|
||||
case SE_HealOverTime:
|
||||
case SpellEffect::HealOverTime:
|
||||
AggroAmount += 10;
|
||||
ignore_default_buff = true;
|
||||
break;
|
||||
|
||||
@ -82,7 +82,7 @@ Json::Value ApiGetPacketStatistics(EQ::Net::WebsocketServerConnection *connectio
|
||||
auto connection = client->Connection();
|
||||
auto opts = connection->GetManager()->GetOptions();
|
||||
auto eqs_stats = connection->GetStats();
|
||||
auto &stats = eqs_stats.DaybreakStats;
|
||||
auto &stats = eqs_stats.ReliableStreamStats;
|
||||
auto now = EQ::Net::Clock::now();
|
||||
auto sec_since_stats_reset = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
now - stats.created
|
||||
|
||||
@ -179,7 +179,7 @@ int Mob::compute_tohit(EQ::skills::SkillType skillinuse)
|
||||
//SYNC WITH: tune.cpp, mob.h TuneGetTotalToHit
|
||||
int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod)
|
||||
{
|
||||
if (chance_mod >= 10000) // override for stuff like SE_SkillAttack
|
||||
if (chance_mod >= 10000) // override for stuff like SpellEffect::SkillAttack
|
||||
return -1;
|
||||
|
||||
// calculate attacker's accuracy
|
||||
@ -209,7 +209,7 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod)
|
||||
if (atkhit_bonus)
|
||||
accuracy += round(static_cast<double>(accuracy) * static_cast<double>(atkhit_bonus) * 0.0001);
|
||||
|
||||
// 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus
|
||||
// 216 Melee Accuracy Amt aka SpellEffect::Accuracy -- flat bonus
|
||||
accuracy += itembonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
aabonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
spellbonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
@ -224,7 +224,7 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod)
|
||||
if (spellbonuses.HitChanceEffect[EQ::skills::HIGHEST_SKILL + 1] >= 10000)
|
||||
return -1;
|
||||
|
||||
// 184 Accuracy % aka SE_HitChance -- percentage increase
|
||||
// 184 Accuracy % aka SpellEffect::HitChance -- percentage increase
|
||||
auto hit_bonus = itembonuses.HitChanceEffect[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
aabonuses.HitChanceEffect[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
spellbonuses.HitChanceEffect[EQ::skills::HIGHEST_SKILL + 1] +
|
||||
@ -285,7 +285,7 @@ int Mob::compute_defense()
|
||||
}
|
||||
|
||||
|
||||
//516 SE_AC_Mitigation_Max_Percent
|
||||
//516 SpellEffect::AC_Mitigation_Max_Percent
|
||||
auto ac_bonus = itembonuses.AC_Mitigation_Max_Percent + aabonuses.AC_Mitigation_Max_Percent + spellbonuses.AC_Mitigation_Max_Percent;
|
||||
if (ac_bonus) {
|
||||
defense += round(static_cast<double>(defense) * static_cast<double>(ac_bonus) * 0.0001);
|
||||
@ -315,15 +315,15 @@ int Mob::GetTotalDefense()
|
||||
if (evasion_bonus >= 10000)
|
||||
return -1;
|
||||
|
||||
// 515 SE_AC_Avoidance_Max_Percent
|
||||
// 515 SpellEffect::AC_Avoidance_Max_Percent
|
||||
auto ac_aviodance_bonus = itembonuses.AC_Avoidance_Max_Percent + aabonuses.AC_Avoidance_Max_Percent + spellbonuses.AC_Avoidance_Max_Percent;
|
||||
if (ac_aviodance_bonus)
|
||||
avoidance += round(static_cast<double>(avoidance) * static_cast<double>(ac_aviodance_bonus) * 0.0001);
|
||||
|
||||
// 172 Evasion aka SE_AvoidMeleeChance
|
||||
// 172 Evasion aka SpellEffect::AvoidMeleeChance
|
||||
evasion_bonus += itembonuses.AvoidMeleeChanceEffect + aabonuses.AvoidMeleeChanceEffect; // item bonus here isn't mod2 avoidance
|
||||
|
||||
// 215 Pet Avoidance % aka SE_PetAvoidance
|
||||
// 215 Pet Avoidance % aka SpellEffect::PetAvoidance
|
||||
evasion_bonus += GetPetAvoidanceBonusFromOwner();
|
||||
|
||||
// Evasion is a percentage bonus according to AA descriptions
|
||||
@ -401,8 +401,8 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
||||
*/
|
||||
|
||||
/* Order according to current (SoF+?) dev quotes:
|
||||
* https://forums.daybreakgames.com/eq/index.php?threads/test-update-06-10-15.223510/page-2#post-3261772
|
||||
* https://forums.daybreakgames.com/eq/index.php?threads/test-update-06-10-15.223510/page-2#post-3268227
|
||||
* https://web.archive.org/web/20250816014133/https://forums.everquest.com/index.php?threads/test-update-06-10-15.223510/page-2#post-3261772
|
||||
* https://web.archive.org/web/20250816014133/https://forums.everquest.com/index.php?threads/test-update-06-10-15.223510/page-2#post-3268227
|
||||
* Riposte 50, hDEX, must have weapon/fists, doesn't work on archery/throwing
|
||||
* Block 25, hDEX, works on archery/throwing, behind block done here if back to attacker base1 is chance
|
||||
* Parry 45, hDEX, doesn't work on throwing/archery, must be facing target
|
||||
@ -461,7 +461,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
||||
}
|
||||
|
||||
/* Heroic Strikethrough Implementation per Dev Quotes (2018):
|
||||
* https://forums.daybreakgames.com/eq/index.php?threads/illusions-benefit-neza-10-dodge.246757/#post-3622670
|
||||
* https://web.archive.org/web/20250816014810/https://forums.everquest.com/index.php?threads/illusions-benefit-neza-10-dodge.246757/#post-3622670
|
||||
* Step1 = HeroicStrikethrough(NPC)
|
||||
* Step2 = HeroicAgility / 25
|
||||
* Step3 = MIN( Step1, Step2 )
|
||||
@ -896,7 +896,7 @@ int Mob::GetClassRaceACBonus()
|
||||
ac_bonus = 16;
|
||||
}
|
||||
|
||||
if (GetRace() == IKSAR)
|
||||
if (GetRace() == Race::Iksar)
|
||||
ac_bonus += EQ::Clamp(static_cast<int>(level), 10, 35);
|
||||
|
||||
return ac_bonus;
|
||||
@ -1917,7 +1917,7 @@ bool Client::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::Skil
|
||||
dead = true;
|
||||
|
||||
if (m_pet && m_pet->IsCharmed()) {
|
||||
m_pet->BuffFadeByEffect(SE_Charm);
|
||||
m_pet->BuffFadeByEffect(SpellEffect::Charm);
|
||||
}
|
||||
|
||||
if (GetMerc()) {
|
||||
@ -3039,6 +3039,25 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
||||
DispatchZoneControllerEvent(EVENT_DEATH_ZONE, owner_or_self, export_string, 0, &args);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_DEATH_ZONE)) {
|
||||
const auto& export_string = fmt::format(
|
||||
"{} {} {} {} {} {} {} {} {}",
|
||||
killer_mob ? killer_mob->GetID() : 0,
|
||||
damage,
|
||||
spell,
|
||||
static_cast<int>(attack_skill),
|
||||
entity_id,
|
||||
m_combat_record.GetStartTime(),
|
||||
m_combat_record.GetEndTime(),
|
||||
m_combat_record.GetDamageReceived(),
|
||||
m_combat_record.GetHealingReceived()
|
||||
);
|
||||
|
||||
std::vector<std::any> args = { corpse, this, owner_or_self };
|
||||
|
||||
parse->EventZone(EVENT_DEATH_ZONE, zone, export_string, 0, &args);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3395,7 +3414,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
uint8 Mob::GetWeaponDamageBonus(const EQ::ItemData *weapon, bool offhand)
|
||||
{
|
||||
// dev quote with old and new formulas
|
||||
// https://forums.daybreakgames.com/eq/index.php?threads/test-update-09-17-15.226618/page-5#post-3326194
|
||||
// https://web.archive.org/web/20250816013618/https://forums.everquest.com/index.php?threads/test-update-09-17-15.226618/page-5#post-3326194
|
||||
//
|
||||
// We assume that the level check is done before calling this function and sinister strikes is checked before
|
||||
// calling for offhand DB
|
||||
@ -3526,7 +3545,7 @@ int Mob::GetHandToHandDelay(void)
|
||||
int iksar = 0;
|
||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 46)
|
||||
epic = 280;
|
||||
else if (GetRace() == IKSAR)
|
||||
else if (GetRace() == Race::Iksar)
|
||||
iksar = 1;
|
||||
// the delay bonus from the monk epic scales up to a skill of 280
|
||||
if (epic >= skill)
|
||||
@ -3567,8 +3586,8 @@ int Mob::GetHandToHandDelay(void)
|
||||
return 16;
|
||||
int level = GetLevel();
|
||||
if (level > 62)
|
||||
return GetRace() == IKSAR ? 21 : 20;
|
||||
return GetRace() == IKSAR ? mnk_iks_delay[level] : mnk_hum_delay[level];
|
||||
return GetRace() == Race::Iksar ? 21 : 20;
|
||||
return GetRace() == Race::Iksar ? mnk_iks_delay[level] : mnk_hum_delay[level];
|
||||
}
|
||||
else if (GetClass() == Class::Beastlord) {
|
||||
int level = GetLevel();
|
||||
@ -3659,7 +3678,7 @@ int64 Mob::ReduceDamage(int64 damage)
|
||||
return DMG_RUNE;
|
||||
|
||||
if (spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] && spellbonuses.MeleeRune[SBIndex::RUNE_BUFFSLOT] >= 0)
|
||||
damage = RuneAbsorb(damage, SE_Rune);
|
||||
damage = RuneAbsorb(damage, SpellEffect::Rune);
|
||||
|
||||
if (damage < 1)
|
||||
return DMG_RUNE;
|
||||
@ -3786,10 +3805,10 @@ int64 Mob::AffectMagicalDamage(int64 damage, uint16 spell_id, const bool iBuffTi
|
||||
|
||||
//Regular runes absorb spell damage (except dots) - Confirmed on live.
|
||||
if (spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] && spellbonuses.MeleeRune[SBIndex::RUNE_BUFFSLOT] >= 0)
|
||||
damage = RuneAbsorb(damage, SE_Rune);
|
||||
damage = RuneAbsorb(damage, SpellEffect::Rune);
|
||||
|
||||
if (spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_AMOUNT] && spellbonuses.AbsorbMagicAtt[SBIndex::RUNE_BUFFSLOT] >= 0)
|
||||
damage = RuneAbsorb(damage, SE_AbsorbMagicAtt);
|
||||
damage = RuneAbsorb(damage, SpellEffect::AbsorbMagicAtt);
|
||||
|
||||
if (damage < 1)
|
||||
return 0;
|
||||
@ -4094,11 +4113,11 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
if (IsPet()) {
|
||||
Mob *owner = GetOwner();
|
||||
if (owner && owner->IsClient()) {
|
||||
if (GetPetOrder() == SPO_Sit) {
|
||||
if (GetPetOrder() == PetOrder::Sit) {
|
||||
SetPetOrder(GetPreviousPetOrder());
|
||||
}
|
||||
// fix GUI sit button to be unpressed and stop sitting regen
|
||||
owner->CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
owner->CastToClient()->SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
SetAppearance(eaStanding);
|
||||
}
|
||||
}
|
||||
@ -4128,12 +4147,12 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
if (IsClient() && !pet->IsPetStop()) {
|
||||
// if pet was sitting his new mode is previous setting of
|
||||
// follow or guard after the battle (live verified)
|
||||
if (pet->GetPetOrder() == SPO_Sit) {
|
||||
if (pet->GetPetOrder() == PetOrder::Sit) {
|
||||
pet->SetPetOrder(pet->GetPreviousPetOrder());
|
||||
}
|
||||
|
||||
// fix GUI sit button to be unpressed and stop sitting regen
|
||||
CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
CastToClient()->SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
pet->SetAppearance(eaStanding);
|
||||
}
|
||||
|
||||
@ -4155,7 +4174,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
damage = ReduceDamage(damage);
|
||||
LogCombat("Melee Damage reduced to [{}]", damage);
|
||||
damage = ReduceAllDamage(damage);
|
||||
TryTriggerThreshHold(damage, SE_TriggerMeleeThreshold, attacker);
|
||||
TryTriggerThreshHold(damage, SpellEffect::TriggerMeleeThreshold, attacker);
|
||||
|
||||
CheckNumHitsRemaining(NumHit::IncomingHitSuccess);
|
||||
}
|
||||
@ -4180,7 +4199,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
Message(263, "%s tries to cast on YOU, but YOUR magical skin absorbs the spell.", attacker->GetCleanName());
|
||||
}
|
||||
damage = ReduceAllDamage(damage);
|
||||
TryTriggerThreshHold(damage, SE_TriggerSpellThreshold, attacker);
|
||||
TryTriggerThreshHold(damage, SpellEffect::TriggerSpellThreshold, attacker);
|
||||
}
|
||||
|
||||
if (IsClient() && CastToClient()->sneaking) {
|
||||
@ -4295,7 +4314,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
GetCleanName(), /* Message1 */
|
||||
attacker->GetCleanName() /* Message2 */
|
||||
);
|
||||
BuffFadeByEffect(SE_Mez);
|
||||
BuffFadeByEffect(SpellEffect::Mez);
|
||||
}
|
||||
|
||||
// broken up for readability
|
||||
@ -4380,12 +4399,12 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
int bashsave_roll = zone->random.Int(0, 100);
|
||||
if (bashsave_roll > 98 || bashsave_roll > (55 - stunbash_chance)) {
|
||||
// did stun -- roll other resists
|
||||
// SE_FrontalStunResist description says any angle now a days
|
||||
// SpellEffect::FrontalStunResist description says any angle now a days
|
||||
int stun_resist2 = spellbonuses.FrontalStunResist + itembonuses.FrontalStunResist +
|
||||
aabonuses.FrontalStunResist;
|
||||
if (zone->random.Int(1, 100) > stun_resist2) {
|
||||
// stun resist 2 failed
|
||||
// time to check SE_StunResist and mod2 stun resist
|
||||
// time to check SpellEffect::StunResist and mod2 stun resist
|
||||
int stun_resist =
|
||||
spellbonuses.StunResist + itembonuses.StunResist + aabonuses.StunResist;
|
||||
if (zone->random.Int(0, 100) >= stun_resist) {
|
||||
@ -5649,7 +5668,7 @@ void Mob::DoRiposte(Mob *defender)
|
||||
defender->itembonuses.DoubleRiposte;
|
||||
|
||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
LogCombat("Preforming a double riposted from SE_DoubleRiposte ([{}] percent chance)", DoubleRipChance);
|
||||
LogCombat("Preforming a double riposted from SpellEffect::DoubleRiposte ([{}] percent chance)", DoubleRipChance);
|
||||
defender->Attack(this, EQ::invslot::slotPrimary, true);
|
||||
if (HasDied())
|
||||
return;
|
||||
@ -5660,7 +5679,7 @@ void Mob::DoRiposte(Mob *defender)
|
||||
|
||||
// Live AA - Double Riposte
|
||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||
LogCombat("Preforming a double riposted from SE_GiveDoubleRiposte base1 == 0 ([{}] percent chance)", DoubleRipChance);
|
||||
LogCombat("Preforming a double riposted from SpellEffect::GiveDoubleRiposte base1 == 0 ([{}] percent chance)", DoubleRipChance);
|
||||
defender->Attack(this, EQ::invslot::slotPrimary, true);
|
||||
if (HasDied())
|
||||
return;
|
||||
@ -6008,12 +6027,12 @@ void Mob::TrySkillProc(Mob *on, EQ::skills::SkillType skill, uint16 ReuseTime, b
|
||||
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
|
||||
if (spells[base_spell_id].effect_id[i] == SE_SkillProcAttempt || spells[base_spell_id].effect_id[i] == SE_SkillProcSuccess) {
|
||||
if (spells[base_spell_id].effect_id[i] == SpellEffect::SkillProcAttempt || spells[base_spell_id].effect_id[i] == SpellEffect::SkillProcSuccess) {
|
||||
proc_spell_id = spells[base_spell_id].base_value[i];
|
||||
ProcMod = static_cast<float>(spells[base_spell_id].limit_value[i]);
|
||||
}
|
||||
|
||||
else if (spells[base_spell_id].effect_id[i] == SE_LimitToSkill && spells[base_spell_id].base_value[i] <= EQ::skills::HIGHEST_SKILL) {
|
||||
else if (spells[base_spell_id].effect_id[i] == SpellEffect::LimitToSkill && spells[base_spell_id].base_value[i] <= EQ::skills::HIGHEST_SKILL) {
|
||||
if (CanProc && spells[base_spell_id].base_value[i] == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
if (zone->random.Roll(final_chance)) {
|
||||
@ -6052,12 +6071,12 @@ void Mob::TrySkillProc(Mob *on, EQ::skills::SkillType skill, uint16 ReuseTime, b
|
||||
ProcMod = 0;
|
||||
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
if (spells[base_spell_id].effect_id[i] == SE_SkillProcAttempt || spells[base_spell_id].effect_id[i] == SE_SkillProcSuccess) {
|
||||
if (spells[base_spell_id].effect_id[i] == SpellEffect::SkillProcAttempt || spells[base_spell_id].effect_id[i] == SpellEffect::SkillProcSuccess) {
|
||||
proc_spell_id = spells[base_spell_id].base_value[i];
|
||||
ProcMod = static_cast<float>(spells[base_spell_id].limit_value[i]);
|
||||
}
|
||||
|
||||
else if (spells[base_spell_id].effect_id[i] == SE_LimitToSkill && spells[base_spell_id].base_value[i] <= EQ::skills::HIGHEST_SKILL) {
|
||||
else if (spells[base_spell_id].effect_id[i] == SpellEffect::LimitToSkill && spells[base_spell_id].base_value[i] <= EQ::skills::HIGHEST_SKILL) {
|
||||
|
||||
if (CanProc && spells[base_spell_id].base_value[i] == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
@ -6114,11 +6133,11 @@ void Mob::TrySkillProc(Mob *on, EQ::skills::SkillType skill, uint16 ReuseTime, b
|
||||
limit_value = effect.limit_value;
|
||||
slot = effect.slot;
|
||||
|
||||
if (effect_id == SE_SkillProcAttempt || effect_id == SE_SkillProcSuccess) {
|
||||
if (effect_id == SpellEffect::SkillProcAttempt || effect_id == SpellEffect::SkillProcSuccess) {
|
||||
proc_spell_id = base_value;
|
||||
ProcMod = static_cast<float>(limit_value);
|
||||
}
|
||||
else if (effect_id == SE_LimitToSkill && base_value <= EQ::skills::HIGHEST_SKILL) {
|
||||
else if (effect_id == SpellEffect::LimitToSkill && base_value <= EQ::skills::HIGHEST_SKILL) {
|
||||
|
||||
if (CanProc && base_value == skill && IsValidSpell(proc_spell_id)) {
|
||||
float final_chance = chance * (ProcMod / 100.0f);
|
||||
@ -6281,7 +6300,7 @@ bool Mob::TryRootFadeByDamage(int buffslot, Mob* attacker) {
|
||||
int32 Mob::RuneAbsorb(int64 damage, uint16 type)
|
||||
{
|
||||
uint32 buff_max = GetMaxTotalSlots();
|
||||
if (type == SE_Rune) {
|
||||
if (type == SpellEffect::Rune) {
|
||||
for (uint32 slot = 0; slot < buff_max; slot++) {
|
||||
if (slot == spellbonuses.MeleeRune[SBIndex::RUNE_BUFFSLOT] && spellbonuses.MeleeRune[SBIndex::RUNE_AMOUNT] && buffs[slot].melee_rune && IsValidSpell(buffs[slot].spellid)) {
|
||||
int melee_rune_left = buffs[slot].melee_rune;
|
||||
@ -6525,7 +6544,7 @@ void Mob::DoShieldDamageOnShielderSpellEffect(Mob* shield_target, int64 hit_dama
|
||||
return;
|
||||
}
|
||||
/*
|
||||
SPA 463 SE_SHIELD_TARGET
|
||||
SPA 463 SpellEffect::SHIELD_TARGET
|
||||
|
||||
Live description: "Shields your target, taking a percentage of their damage".
|
||||
Only example spell on live is an NPC who uses it during a raid event "Laurion's Song" expansion. SPA 54492 'Guardian Stance' Described as 100% Melee Shielding
|
||||
@ -6577,7 +6596,7 @@ void Mob::CommonBreakInvisibleFromCombat()
|
||||
CancelSneakHide();
|
||||
|
||||
if (spellbonuses.NegateIfCombat) {
|
||||
BuffFadeByEffect(SE_NegateIfCombat);
|
||||
BuffFadeByEffect(SpellEffect::NegateIfCombat);
|
||||
}
|
||||
|
||||
hidden = false;
|
||||
|
||||
1434
zone/bonuses.cpp
1434
zone/bonuses.cpp
File diff suppressed because it is too large
Load Diff
297
zone/bot.cpp
297
zone/bot.cpp
@ -99,7 +99,7 @@ Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm
|
||||
SetPullingFlag(false);
|
||||
SetReturningFlag(false);
|
||||
SetIsUsingItemClick(false);
|
||||
m_previous_pet_order = SPO_Guard;
|
||||
m_previous_pet_order = PetOrder::Guard;
|
||||
|
||||
rest_timer.Disable();
|
||||
m_ping_timer.Disable();
|
||||
@ -232,7 +232,7 @@ Bot::Bot(
|
||||
SetPullingFlag(false);
|
||||
SetReturningFlag(false);
|
||||
SetIsUsingItemClick(false);
|
||||
m_previous_pet_order = SPO_Guard;
|
||||
m_previous_pet_order = PetOrder::Guard;
|
||||
|
||||
rest_timer.Disable();
|
||||
m_ping_timer.Disable();
|
||||
@ -296,8 +296,8 @@ Bot::Bot(
|
||||
|
||||
for (int x1 = 0; x1 < EFFECT_COUNT; x1++) {
|
||||
switch (spell.effect_id[x1]) {
|
||||
case SE_IllusionCopy:
|
||||
case SE_Illusion: {
|
||||
case SpellEffect::IllusionCopy:
|
||||
case SpellEffect::Illusion: {
|
||||
if (GetIllusionBlock()) {
|
||||
break;
|
||||
}
|
||||
@ -317,7 +317,7 @@ Bot::Bot(
|
||||
);
|
||||
} else if (spell.base_value[x1] == -2) // WTF IS THIS
|
||||
{
|
||||
if (GetRace() == IKSAR || GetRace() == VAHSHIR || GetRace() <= GNOME) {
|
||||
if (GetRace() == Race::Iksar || GetRace() == Race::VahShir || GetRace() <= Race::Gnome) {
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = GetGender(),
|
||||
@ -346,27 +346,27 @@ Bot::Bot(
|
||||
}
|
||||
|
||||
switch (spell.base_value[x1]) {
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
SendAppearancePacket(AppearanceType::Size, 9);
|
||||
break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
SendAppearancePacket(AppearanceType::Size, 8);
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case BARBARIAN:
|
||||
case Race::VahShir:
|
||||
case Race::Barbarian:
|
||||
SendAppearancePacket(AppearanceType::Size, 7);
|
||||
break;
|
||||
case HALF_ELF:
|
||||
case WOOD_ELF:
|
||||
case DARK_ELF:
|
||||
case FROGLOK:
|
||||
case Race::HalfElf:
|
||||
case Race::WoodElf:
|
||||
case Race::DarkElf:
|
||||
case Race::Froglok2:
|
||||
SendAppearancePacket(AppearanceType::Size, 5);
|
||||
break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
SendAppearancePacket(AppearanceType::Size, 4);
|
||||
break;
|
||||
case HALFLING:
|
||||
case GNOME:
|
||||
case Race::Halfling:
|
||||
case Race::Gnome:
|
||||
SendAppearancePacket(AppearanceType::Size, 3);
|
||||
break;
|
||||
default:
|
||||
@ -375,63 +375,63 @@ Bot::Bot(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_Silence:
|
||||
case SpellEffect::Silence:
|
||||
{
|
||||
Silence(true);
|
||||
break;
|
||||
}
|
||||
case SE_Amnesia:
|
||||
case SpellEffect::Amnesia:
|
||||
{
|
||||
Amnesia(true);
|
||||
break;
|
||||
}
|
||||
case SE_DivineAura:
|
||||
case SpellEffect::DivineAura:
|
||||
{
|
||||
invulnerable = true;
|
||||
break;
|
||||
}
|
||||
case SE_Invisibility2:
|
||||
case SE_Invisibility:
|
||||
case SpellEffect::Invisibility2:
|
||||
case SpellEffect::Invisibility:
|
||||
{
|
||||
invisible = true;
|
||||
SendAppearancePacket(AppearanceType::Invisibility, 1);
|
||||
break;
|
||||
}
|
||||
case SE_Levitate:
|
||||
case SpellEffect::Levitate:
|
||||
{
|
||||
if (!zone->CanLevitate())
|
||||
{
|
||||
SendAppearancePacket(AppearanceType::FlyMode, 0);
|
||||
BuffFadeByEffect(SE_Levitate);
|
||||
BuffFadeByEffect(SpellEffect::Levitate);
|
||||
}
|
||||
else {
|
||||
SendAppearancePacket(AppearanceType::FlyMode, 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_InvisVsUndead2:
|
||||
case SE_InvisVsUndead:
|
||||
case SpellEffect::InvisVsUndead2:
|
||||
case SpellEffect::InvisVsUndead:
|
||||
{
|
||||
invisible_undead = true;
|
||||
break;
|
||||
}
|
||||
case SE_InvisVsAnimals:
|
||||
case SpellEffect::InvisVsAnimals:
|
||||
{
|
||||
invisible_animals = true;
|
||||
break;
|
||||
}
|
||||
case SE_AddMeleeProc:
|
||||
case SE_WeaponProc:
|
||||
case SpellEffect::AddMeleeProc:
|
||||
case SpellEffect::WeaponProc:
|
||||
{
|
||||
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, buffs[j1].casterlevel);
|
||||
break;
|
||||
}
|
||||
case SE_DefensiveProc:
|
||||
case SpellEffect::DefensiveProc:
|
||||
{
|
||||
AddDefensiveProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid);
|
||||
break;
|
||||
}
|
||||
case SE_RangedProc:
|
||||
case SpellEffect::RangedProc:
|
||||
{
|
||||
AddRangedProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid);
|
||||
break;
|
||||
@ -457,10 +457,10 @@ Bot::Bot(
|
||||
int resurrection_sickness_spell_id = (
|
||||
RuleB(Bots, OldRaceRezEffects) &&
|
||||
(
|
||||
GetRace() == BARBARIAN ||
|
||||
GetRace() == DWARF ||
|
||||
GetRace() == TROLL ||
|
||||
GetRace() == OGRE
|
||||
GetRace() == Race::Barbarian ||
|
||||
GetRace() == Race::Dwarf ||
|
||||
GetRace() == Race::Troll ||
|
||||
GetRace() == Race::Ogre
|
||||
) ?
|
||||
RuleI(Bots, OldResurrectionSicknessSpell) :
|
||||
RuleI(Bots, ResurrectionSicknessSpell)
|
||||
@ -955,9 +955,9 @@ void Bot::GenerateBaseStats()
|
||||
float BotSize = GetSize();
|
||||
|
||||
switch(GetRace()) {
|
||||
case HUMAN: // Humans have no race bonus
|
||||
case Race::Human: // Humans have no race bonus
|
||||
break;
|
||||
case BARBARIAN:
|
||||
case Race::Barbarian:
|
||||
Strength += 28;
|
||||
Stamina += 20;
|
||||
Agility += 7;
|
||||
@ -968,7 +968,7 @@ void Bot::GenerateBaseStats()
|
||||
BotSize = 7.0;
|
||||
ColdResist += 10;
|
||||
break;
|
||||
case ERUDITE:
|
||||
case Race::Erudite:
|
||||
Strength -= 15;
|
||||
Stamina -= 5;
|
||||
Agility -= 5;
|
||||
@ -979,7 +979,7 @@ void Bot::GenerateBaseStats()
|
||||
MagicResist += 5;
|
||||
DiseaseResist -= 5;
|
||||
break;
|
||||
case WOOD_ELF:
|
||||
case Race::WoodElf:
|
||||
Strength -= 10;
|
||||
Stamina -= 10;
|
||||
Agility += 20;
|
||||
@ -987,7 +987,7 @@ void Bot::GenerateBaseStats()
|
||||
Wisdom += 5;
|
||||
BotSize = 5.0;
|
||||
break;
|
||||
case HIGH_ELF:
|
||||
case Race::HighElf:
|
||||
Strength -= 20;
|
||||
Stamina -= 10;
|
||||
Agility += 10;
|
||||
@ -996,7 +996,7 @@ void Bot::GenerateBaseStats()
|
||||
Intelligence += 12;
|
||||
Charisma += 5;
|
||||
break;
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
Strength -= 15;
|
||||
Stamina -= 10;
|
||||
Agility += 15;
|
||||
@ -1005,7 +1005,7 @@ void Bot::GenerateBaseStats()
|
||||
Charisma -= 15;
|
||||
BotSize = 5.0;
|
||||
break;
|
||||
case HALF_ELF:
|
||||
case Race::HalfElf:
|
||||
Strength -= 5;
|
||||
Stamina -= 5;
|
||||
Agility += 15;
|
||||
@ -1013,7 +1013,7 @@ void Bot::GenerateBaseStats()
|
||||
Wisdom -= 15;
|
||||
BotSize = 5.5;
|
||||
break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
Strength += 15;
|
||||
Stamina += 15;
|
||||
Agility -= 5;
|
||||
@ -1025,7 +1025,7 @@ void Bot::GenerateBaseStats()
|
||||
MagicResist -= 5;
|
||||
PoisonResist += 5;
|
||||
break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
Strength += 33;
|
||||
Stamina += 34;
|
||||
Agility += 8;
|
||||
@ -1035,7 +1035,7 @@ void Bot::GenerateBaseStats()
|
||||
BotSize = 8.0;
|
||||
FireResist -= 20;
|
||||
break;
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
Strength += 55;
|
||||
Stamina += 77;
|
||||
Agility -= 5;
|
||||
@ -1045,7 +1045,7 @@ void Bot::GenerateBaseStats()
|
||||
Charisma -= 38;
|
||||
BotSize = 9.0;
|
||||
break;
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
Strength -= 5;
|
||||
Agility += 20;
|
||||
Dexterity += 15;
|
||||
@ -1056,7 +1056,7 @@ void Bot::GenerateBaseStats()
|
||||
PoisonResist += 5;
|
||||
DiseaseResist += 5;
|
||||
break;
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
Strength -= 15;
|
||||
Stamina -= 5;
|
||||
Agility += 10;
|
||||
@ -1066,7 +1066,7 @@ void Bot::GenerateBaseStats()
|
||||
Charisma -= 15;
|
||||
BotSize = 3.0;
|
||||
break;
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
Strength -= 5;
|
||||
Stamina -= 5;
|
||||
Agility += 15;
|
||||
@ -1076,7 +1076,7 @@ void Bot::GenerateBaseStats()
|
||||
MagicResist -= 5;
|
||||
FireResist -= 5;
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
Strength += 15;
|
||||
Agility += 15;
|
||||
Dexterity -= 5;
|
||||
@ -1087,7 +1087,7 @@ void Bot::GenerateBaseStats()
|
||||
MagicResist -= 5;
|
||||
FireResist -= 5;
|
||||
break;
|
||||
case FROGLOK:
|
||||
case Race::Froglok2:
|
||||
Strength -= 5;
|
||||
Stamina += 5;
|
||||
Agility += 25;
|
||||
@ -1097,7 +1097,7 @@ void Bot::GenerateBaseStats()
|
||||
MagicResist -= 5;
|
||||
FireResist -= 5;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
case Race::Drakkin:
|
||||
Strength -= 5;
|
||||
Stamina += 5;
|
||||
Agility += 10;
|
||||
@ -1140,7 +1140,7 @@ void Bot::GenerateBaseStats()
|
||||
void Bot::GenerateAppearance() {
|
||||
// Randomize facial appearance
|
||||
int iFace = 0;
|
||||
if (GetRace() == BARBARIAN) // Barbarian w/Tatoo
|
||||
if (GetRace() == Race::Barbarian) // Barbarian w/Tatoo
|
||||
{
|
||||
iFace = zone->random.Int(0, 79);
|
||||
}
|
||||
@ -1152,13 +1152,13 @@ void Bot::GenerateAppearance() {
|
||||
int iHair = 0;
|
||||
int iBeard = 0;
|
||||
int iBeardColor = 1;
|
||||
if (GetRace() == DRAKKIN) {
|
||||
if (GetRace() == Race::Drakkin) {
|
||||
iHair = zone->random.Int(0, 8);
|
||||
iBeard = zone->random.Int(0, 11);
|
||||
iBeardColor = zone->random.Int(0, 3);
|
||||
} else if (GetGender()) {
|
||||
iHair = zone->random.Int(0, 2);
|
||||
if (GetRace() == DWARF && zone->random.Int(1, 100) < 50) {
|
||||
if (GetRace() == Race::Dwarf && zone->random.Int(1, 100) < 50) {
|
||||
iFace += 10;
|
||||
}
|
||||
} else {
|
||||
@ -1168,7 +1168,7 @@ void Bot::GenerateAppearance() {
|
||||
}
|
||||
|
||||
int iHairColor = 0;
|
||||
if (GetRace() == DRAKKIN) {
|
||||
if (GetRace() == Race::Drakkin) {
|
||||
iHairColor = zone->random.Int(0, 3);
|
||||
} else {
|
||||
iHairColor = zone->random.Int(0, 19);
|
||||
@ -1176,7 +1176,7 @@ void Bot::GenerateAppearance() {
|
||||
|
||||
auto iEyeColor1 = (uint8)zone->random.Int(0, 9);
|
||||
uint8 iEyeColor2 = 0;
|
||||
if (GetRace() == DRAKKIN) {
|
||||
if (GetRace() == Race::Drakkin) {
|
||||
iEyeColor1 = iEyeColor2 = (uint8)zone->random.Int(0, 11);
|
||||
} else if (zone->random.Int(1, 100) > 96) {
|
||||
iEyeColor2 = zone->random.Int(0, 9);
|
||||
@ -1187,7 +1187,7 @@ void Bot::GenerateAppearance() {
|
||||
int iHeritage = 0;
|
||||
int iTattoo = 0;
|
||||
int iDetails = 0;
|
||||
if (GetRace() == DRAKKIN) {
|
||||
if (GetRace() == Race::Drakkin) {
|
||||
iHeritage = zone->random.Int(0, 6);
|
||||
iTattoo = zone->random.Int(0, 7);
|
||||
iDetails = zone->random.Int(0, 7);
|
||||
@ -1527,7 +1527,7 @@ bool Bot::LoadPet()
|
||||
auto my_buffs = GetBuffs();
|
||||
if (buffs_max && my_buffs) {
|
||||
for (int index = 0; index < buffs_max; ++index) {
|
||||
if (IsEffectInSpell(my_buffs[index].spellid, SE_Familiar)) {
|
||||
if (IsEffectInSpell(my_buffs[index].spellid, SpellEffect::Familiar)) {
|
||||
MakePet(my_buffs[index].spellid, spells[my_buffs[index].spellid].teleport_zone);
|
||||
return true;
|
||||
}
|
||||
@ -2313,7 +2313,7 @@ void Bot::AI_Process()
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
|
||||
@ -2569,7 +2569,7 @@ void Bot::DoOutOfCombatChecks(Client* bot_owner, Mob* follow_mob, float leash_di
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
}
|
||||
@ -3198,7 +3198,7 @@ bool Bot::IsValidTarget(
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
}
|
||||
@ -3233,7 +3233,7 @@ Mob* Bot::GetBotTarget(Client* bot_owner)
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
}
|
||||
@ -3269,7 +3269,7 @@ bool Bot::ReturningFlagChecks(Client* bot_owner, Mob* leash_owner, float fm_dist
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
|
||||
if (HasControllablePet(BotAnimEmpathy::BackOff)) {
|
||||
@ -3313,7 +3313,7 @@ bool Bot::PullingFlagChecks(Client* bot_owner) {
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
|
||||
@ -3494,7 +3494,7 @@ Client* Bot::SetLeashOwner(Client* bot_owner, Group* bot_group, Raid* raid, uint
|
||||
|
||||
void Bot::SetOwnerTarget(Client* bot_owner) {
|
||||
if (GetPet() && (PULLING_BOT || RETURNING_BOT)) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
}
|
||||
|
||||
SetAttackFlag(false);
|
||||
@ -3533,7 +3533,7 @@ void Bot::BotPullerProcess(Client* bot_owner, Raid* raid) {
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
|
||||
@ -3562,7 +3562,7 @@ void Bot::BotPullerProcess(Client* bot_owner, Raid* raid) {
|
||||
if (HasControllablePet(BotAnimEmpathy::Guard)) {
|
||||
m_previous_pet_order = GetPet()->GetPetOrder();
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(GetPosition());
|
||||
GetPet()->SetPetOrder(SPO_Guard);
|
||||
GetPet()->SetPetOrder(PetOrder::Guard);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3578,7 +3578,7 @@ void Bot::Depop() {
|
||||
|
||||
if (bot_pet) {
|
||||
if (bot_pet->Charmed()) {
|
||||
bot_pet->BuffFadeByEffect(SE_Charm);
|
||||
bot_pet->BuffFadeByEffect(SpellEffect::Charm);
|
||||
}
|
||||
else {
|
||||
bot_pet->Depop();
|
||||
@ -5404,9 +5404,9 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
|
||||
case Class::Paladin:
|
||||
{
|
||||
bool is_large_race = (
|
||||
GetBaseRace() == OGRE ||
|
||||
GetBaseRace() == TROLL ||
|
||||
GetBaseRace() == BARBARIAN
|
||||
GetBaseRace() == Race::Ogre ||
|
||||
GetBaseRace() == Race::Troll ||
|
||||
GetBaseRace() == Race::Barbarian
|
||||
);
|
||||
bool has_bash_skill = GetSkill(EQ::skills::SkillBash) > 0;
|
||||
bool has_shield_in_secondary =
|
||||
@ -5974,7 +5974,7 @@ bool Bot::SpellOnTarget(
|
||||
|
||||
if (spelltar->IsPet()) {
|
||||
for (int i = 0; i < EFFECT_COUNT; ++i) {
|
||||
if (spells[spell_id].effect_id[i] == SE_Illusion) {
|
||||
if (spells[spell_id].effect_id[i] == SpellEffect::Illusion) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -6214,7 +6214,7 @@ bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spe
|
||||
|
||||
if (!noGroupSpell) {
|
||||
for (Mob* m : GetBuffTargets(spellTarget)) {
|
||||
if (IsEffectInSpell(thespell, SE_AbsorbMagicAtt) || IsEffectInSpell(thespell, SE_Rune)) {
|
||||
if (IsEffectInSpell(thespell, SpellEffect::AbsorbMagicAtt) || IsEffectInSpell(thespell, SpellEffect::Rune)) {
|
||||
for (int i = 0; i < m->GetMaxTotalSlots(); i++) {
|
||||
uint32 buff_count = m->GetMaxTotalSlots();
|
||||
|
||||
@ -7831,7 +7831,7 @@ bool Bot::GetNeedsCured(Mob *tar) {
|
||||
bool need_cured = false;
|
||||
|
||||
if (tar) {
|
||||
if (tar->FindType(SE_PoisonCounter) || tar->FindType(SE_DiseaseCounter) || tar->FindType(SE_CurseCounter) || tar->FindType(SE_CorruptionCounter)) {
|
||||
if (tar->FindType(SpellEffect::PoisonCounter) || tar->FindType(SpellEffect::DiseaseCounter) || tar->FindType(SpellEffect::CurseCounter) || tar->FindType(SpellEffect::CorruptionCounter)) {
|
||||
uint32 buff_count = tar->GetMaxTotalSlots();
|
||||
|
||||
for (unsigned int j = 0; j < buff_count; j++) {
|
||||
@ -8616,7 +8616,7 @@ void Bot::Escape()
|
||||
}
|
||||
|
||||
void Bot::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls, bool calculate_speed) {
|
||||
BuffFadeByEffect(SE_Levitate);
|
||||
BuffFadeByEffect(SpellEffect::Levitate);
|
||||
if (CheckLosFN(target_x, target_y, target_z, 6.0f) || ignore_los) {
|
||||
auto p = new EQApplicationPacket(OP_Fling, sizeof(fling_struct));
|
||||
auto* f = (fling_struct*) p->pBuffer;
|
||||
@ -9553,9 +9553,9 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spell_type, bool precheck
|
||||
|
||||
if (spells[spell_id].target_type == ST_Self && tar != this) {
|
||||
if (
|
||||
!IsEffectInSpell(spell_id, SE_SummonCorpse) ||
|
||||
!IsEffectInSpell(spell_id, SpellEffect::SummonCorpse) ||
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_SummonCorpse) &&
|
||||
IsEffectInSpell(spell_id, SpellEffect::SummonCorpse) &&
|
||||
!RuleB(Bots, AllowCommandedSummonCorpse)
|
||||
)
|
||||
) {
|
||||
@ -9610,14 +9610,9 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spell_type, bool precheck
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!BotHasEnoughMana(spell_id) &&
|
||||
(
|
||||
!RuleB(Bots, FinishBuffing) ||
|
||||
IsEngaged() ||
|
||||
IsBotBuffSpellType(spell_type)
|
||||
)
|
||||
) {
|
||||
bool is_mana_exempt = RuleB(Bots, FinishBuffing) && !IsEngaged() && IsBotBuffSpellType(spell_type);
|
||||
|
||||
if (!BotHasEnoughMana(spell_id) && !is_mana_exempt) {
|
||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of {} due to !BotHasEnoughMana.'", GetCleanName(), GetSpellName(spell_id));
|
||||
return false;
|
||||
}
|
||||
@ -9672,7 +9667,7 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spell_type, bool precheck
|
||||
|
||||
if (
|
||||
!zone->CanLevitate() &&
|
||||
IsEffectInSpell(spell_id, SE_Levitate)
|
||||
IsEffectInSpell(spell_id, SpellEffect::Levitate)
|
||||
) {
|
||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of {} due to !CanLevitate.'", GetCleanName(), GetSpellName(spell_id));
|
||||
return false;
|
||||
@ -9912,8 +9907,8 @@ bool Bot::CanCastSpellType(uint16 spell_type, uint16 spell_id, Mob* tar) {
|
||||
spell_type != BotSpellTypes::Succor
|
||||
) &&
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_Teleport) ||
|
||||
IsEffectInSpell(spell_id, SE_Succor)
|
||||
IsEffectInSpell(spell_id, SpellEffect::Teleport) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::Succor)
|
||||
)
|
||||
) {
|
||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of {} on {} due to Teleport.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName());
|
||||
@ -9923,7 +9918,7 @@ bool Bot::CanCastSpellType(uint16 spell_type, uint16 spell_id, Mob* tar) {
|
||||
if (
|
||||
tar->IsPet() &&
|
||||
!RuleB(Bots, CanCastIllusionsOnPets) &&
|
||||
IsEffectInSpell(spell_id, SE_Illusion)
|
||||
IsEffectInSpell(spell_id, SpellEffect::Illusion)
|
||||
) {
|
||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of {} on {} due to PetSE_Illusion.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName());
|
||||
return false;
|
||||
@ -9967,13 +9962,13 @@ bool Bot::CanCastSpellType(uint16 spell_type, uint16 spell_id, Mob* tar) {
|
||||
tar->IsBot() &&
|
||||
(tar->GetLevel() >= tar->CastToBot()->GetStopMeleeLevel()) &&
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_AttackSpeed) ||
|
||||
IsEffectInSpell(spell_id, SE_ReverseDS)
|
||||
IsEffectInSpell(spell_id, SpellEffect::AttackSpeed) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::ReverseDS)
|
||||
) ||
|
||||
(
|
||||
SpellEffectsCount(spell_id) == 1 &&
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_ATK) || IsEffectInSpell(spell_id, SE_STR)
|
||||
IsEffectInSpell(spell_id, SpellEffect::ATK) || IsEffectInSpell(spell_id, SpellEffect::STR)
|
||||
)
|
||||
)
|
||||
) {
|
||||
@ -9983,11 +9978,11 @@ bool Bot::CanCastSpellType(uint16 spell_type, uint16 spell_id, Mob* tar) {
|
||||
break;
|
||||
case Archetype::Melee:
|
||||
if (
|
||||
IsEffectInSpell(spell_id, SE_IncreaseSpellHaste) ||
|
||||
IsEffectInSpell(spell_id, SE_ManaPool) ||
|
||||
IsEffectInSpell(spell_id, SE_CastingLevel) ||
|
||||
IsEffectInSpell(spell_id, SE_ManaRegen_v2) ||
|
||||
IsEffectInSpell(spell_id, SE_CurrentMana)
|
||||
IsEffectInSpell(spell_id, SpellEffect::IncreaseSpellHaste) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::ManaPool) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::CastingLevel) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::ManaRegen_v2) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::CurrentMana)
|
||||
) {
|
||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of {} on {} due to Archetype::Melee.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName());
|
||||
return false;
|
||||
@ -10002,8 +9997,8 @@ bool Bot::CanCastSpellType(uint16 spell_type, uint16 spell_id, Mob* tar) {
|
||||
// Differences for each type
|
||||
if (spell_type != BotSpellTypes::InCombatBuff) {
|
||||
if (
|
||||
IsEffectInSpell(spell_id, SE_AbsorbMagicAtt) ||
|
||||
IsEffectInSpell(spell_id, SE_Rune)
|
||||
IsEffectInSpell(spell_id, SpellEffect::AbsorbMagicAtt) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::Rune)
|
||||
) {
|
||||
for (int i = 0; i < tar->GetMaxTotalSlots(); i++) {
|
||||
uint32 buff_count = tar->GetMaxTotalSlots();
|
||||
@ -10031,14 +10026,14 @@ bool Bot::CanCastSpellType(uint16 spell_type, uint16 spell_id, Mob* tar) {
|
||||
tar->IsBot() &&
|
||||
(tar->GetLevel() >= tar->CastToBot()->GetStopMeleeLevel()) &&
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_AttackSpeed) ||
|
||||
IsEffectInSpell(spell_id, SE_ReverseDS)
|
||||
IsEffectInSpell(spell_id, SpellEffect::AttackSpeed) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::ReverseDS)
|
||||
) ||
|
||||
(
|
||||
SpellEffectsCount(spell_id) == 1 &&
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_ATK) ||
|
||||
IsEffectInSpell(spell_id, SE_STR)
|
||||
IsEffectInSpell(spell_id, SpellEffect::ATK) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::STR)
|
||||
)
|
||||
)
|
||||
) {
|
||||
@ -10048,11 +10043,11 @@ bool Bot::CanCastSpellType(uint16 spell_type, uint16 spell_id, Mob* tar) {
|
||||
break;
|
||||
case Archetype::Melee:
|
||||
if (
|
||||
IsEffectInSpell(spell_id, SE_IncreaseSpellHaste) ||
|
||||
IsEffectInSpell(spell_id, SE_ManaPool) ||
|
||||
IsEffectInSpell(spell_id, SE_CastingLevel) ||
|
||||
IsEffectInSpell(spell_id, SE_ManaRegen_v2) ||
|
||||
IsEffectInSpell(spell_id, SE_CurrentMana)
|
||||
IsEffectInSpell(spell_id, SpellEffect::IncreaseSpellHaste) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::ManaPool) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::CastingLevel) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::ManaRegen_v2) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::CurrentMana)
|
||||
) {
|
||||
LogBotSpellChecksDetail("{} says, 'Cancelling cast of {} on {} due to Archetype::Melee.'", GetCleanName(), GetSpellName(spell_id), tar->GetCleanName());
|
||||
return false;
|
||||
@ -10334,7 +10329,7 @@ bool Bot::IsValidMezTarget(Mob* owner, Mob* npc, uint16 spell_id) {
|
||||
auto npc_buffs = npc->GetBuffs();
|
||||
|
||||
for (int i = 0; i < buff_count; i++) {
|
||||
if (IsDetrimentalSpell(npc_buffs[i].spellid) && IsEffectInSpell(npc_buffs[i].spellid, SE_CurrentHP)) {
|
||||
if (IsDetrimentalSpell(npc_buffs[i].spellid) && IsEffectInSpell(npc_buffs[i].spellid, SpellEffect::CurrentHP)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -11689,7 +11684,7 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
return false;
|
||||
case BotSpellTypes::Root:
|
||||
case BotSpellTypes::AERoot:
|
||||
if (IsDetrimentalSpell(spell_id) && IsEffectInSpell(spell_id, SE_Root)) {
|
||||
if (IsDetrimentalSpell(spell_id) && IsEffectInSpell(spell_id, SpellEffect::Root)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -11723,7 +11718,7 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::Pet:
|
||||
if (IsSummonPetSpell(spell_id) || IsEffectInSpell(spell_id, SE_TemporaryPets)) {
|
||||
if (IsSummonPetSpell(spell_id) || IsEffectInSpell(spell_id, SpellEffect::TemporaryPets)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -11737,7 +11732,7 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
return false;
|
||||
case BotSpellTypes::Snare:
|
||||
case BotSpellTypes::AESnare:
|
||||
if (IsDetrimentalSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)) {
|
||||
if (IsDetrimentalSpell(spell_id) && IsEffectInSpell(spell_id, SpellEffect::MovementSpeed)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -11811,7 +11806,7 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::Resurrect:
|
||||
if (IsEffectInSpell(spell_id, SE_Revive)) {
|
||||
if (IsEffectInSpell(spell_id, SpellEffect::Revive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -11916,14 +11911,14 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
return false;
|
||||
case BotSpellTypes::ResistBuffs:
|
||||
case BotSpellTypes::PetResistBuffs:
|
||||
if (IsResistanceBuffSpell(spell_id) && !IsEffectInSpell(spell_id, SE_DamageShield)) {
|
||||
if (IsResistanceBuffSpell(spell_id) && !IsEffectInSpell(spell_id, SpellEffect::DamageShield)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::DamageShields:
|
||||
case BotSpellTypes::PetDamageShields:
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_DamageShield)) {
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SpellEffect::DamageShield)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -11931,7 +11926,7 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
case BotSpellTypes::Teleport:
|
||||
if (
|
||||
IsBeneficialSpell(spell_id) &&
|
||||
(IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Translocate))
|
||||
(IsEffectInSpell(spell_id, SpellEffect::Teleport) || IsEffectInSpell(spell_id, SpellEffect::Translocate))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -11947,40 +11942,40 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
case BotSpellTypes::Succor:
|
||||
if (
|
||||
IsBeneficialSpell(spell_id) &&
|
||||
IsEffectInSpell(spell_id, SE_Succor)
|
||||
IsEffectInSpell(spell_id, SpellEffect::Succor)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::BindAffinity:
|
||||
if (IsEffectInSpell(spell_id, SE_BindAffinity)) {
|
||||
if (IsEffectInSpell(spell_id, SpellEffect::BindAffinity)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::Identify:
|
||||
if (IsEffectInSpell(spell_id, SE_Identify)) {
|
||||
if (IsEffectInSpell(spell_id, SpellEffect::Identify)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::Levitate:
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_Levitate)) {
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SpellEffect::Levitate)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::Rune:
|
||||
if (IsBeneficialSpell(spell_id) &&
|
||||
(IsEffectInSpell(spell_id, SE_AbsorbMagicAtt) || IsEffectInSpell(spell_id, SE_Rune))
|
||||
(IsEffectInSpell(spell_id, SpellEffect::AbsorbMagicAtt) || IsEffectInSpell(spell_id, SpellEffect::Rune))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::WaterBreathing:
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_WaterBreathing)) {
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SpellEffect::WaterBreathing)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -11988,7 +11983,7 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
case BotSpellTypes::Size:
|
||||
if (
|
||||
IsBeneficialSpell(spell_id) &&
|
||||
(IsEffectInSpell(spell_id, SE_ModelSize) || IsEffectInSpell(spell_id, SE_ChangeHeight))
|
||||
(IsEffectInSpell(spell_id, SpellEffect::ModelSize) || IsEffectInSpell(spell_id, SpellEffect::ChangeHeight))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -11996,14 +11991,14 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
return false;
|
||||
case BotSpellTypes::Invisibility:
|
||||
if (IsBeneficialSpell(spell_id) &&
|
||||
(IsEffectInSpell(spell_id, SE_SeeInvis) ||IsInvisibleSpell(spell_id))
|
||||
(IsEffectInSpell(spell_id, SpellEffect::SeeInvis) ||IsInvisibleSpell(spell_id))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::MovementSpeed:
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)) {
|
||||
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SpellEffect::MovementSpeed)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -12012,10 +12007,10 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
if (
|
||||
IsBeneficialSpell(spell_id) &&
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_GateToHomeCity) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::GateToHomeCity) ||
|
||||
(
|
||||
teleport_zone.compare("") &&
|
||||
(IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Translocate))
|
||||
(IsEffectInSpell(spell_id, SpellEffect::Teleport) || IsEffectInSpell(spell_id, SpellEffect::Translocate))
|
||||
)
|
||||
)
|
||||
) {
|
||||
@ -12024,7 +12019,7 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) {
|
||||
|
||||
return false;
|
||||
case BotSpellTypes::SummonCorpse:
|
||||
if (IsEffectInSpell(spell_id, SE_SummonCorpse)) {
|
||||
if (IsEffectInSpell(spell_id, SpellEffect::SummonCorpse)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -12515,15 +12510,15 @@ bool Bot::IsValidSpellTypeSubType(uint16 spell_type, uint16 sub_type, uint16 spe
|
||||
|
||||
break;
|
||||
case CommandedSubTypes::SeeInvis:
|
||||
if (IsEffectInSpell(spell_id, SE_SeeInvis)) {
|
||||
if (IsEffectInSpell(spell_id, SpellEffect::SeeInvis)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CommandedSubTypes::Invis:
|
||||
if (
|
||||
IsEffectInSpell(spell_id, SE_Invisibility) ||
|
||||
IsEffectInSpell(spell_id, SE_Invisibility2)
|
||||
IsEffectInSpell(spell_id, SpellEffect::Invisibility) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::Invisibility2)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -12531,8 +12526,8 @@ bool Bot::IsValidSpellTypeSubType(uint16 spell_type, uint16 sub_type, uint16 spe
|
||||
break;
|
||||
case CommandedSubTypes::InvisUndead:
|
||||
if (
|
||||
IsEffectInSpell(spell_id, SE_InvisVsUndead) ||
|
||||
IsEffectInSpell(spell_id, SE_InvisVsUndead2)
|
||||
IsEffectInSpell(spell_id, SpellEffect::InvisVsUndead) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::InvisVsUndead2)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -12540,8 +12535,8 @@ bool Bot::IsValidSpellTypeSubType(uint16 spell_type, uint16 sub_type, uint16 spe
|
||||
break;
|
||||
case CommandedSubTypes::InvisAnimals:
|
||||
if (
|
||||
IsEffectInSpell(spell_id, SE_InvisVsAnimals) ||
|
||||
IsEffectInSpell(spell_id, SE_ImprovedInvisAnimals)
|
||||
IsEffectInSpell(spell_id, SpellEffect::InvisVsAnimals) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::ImprovedInvisAnimals)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -12550,13 +12545,13 @@ bool Bot::IsValidSpellTypeSubType(uint16 spell_type, uint16 sub_type, uint16 spe
|
||||
case CommandedSubTypes::Shrink:
|
||||
if (
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_ModelSize) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ModelSize), GetLevel()) < 100
|
||||
IsEffectInSpell(spell_id, SpellEffect::ModelSize) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SpellEffect::ModelSize), GetLevel()) < 100
|
||||
)
|
||||
||
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_ChangeHeight) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ChangeHeight), GetLevel()) < 100
|
||||
IsEffectInSpell(spell_id, SpellEffect::ChangeHeight) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SpellEffect::ChangeHeight), GetLevel()) < 100
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
@ -12566,13 +12561,13 @@ bool Bot::IsValidSpellTypeSubType(uint16 spell_type, uint16 sub_type, uint16 spe
|
||||
case CommandedSubTypes::Grow:
|
||||
if (
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_ModelSize) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ModelSize), GetLevel()) > 100
|
||||
IsEffectInSpell(spell_id, SpellEffect::ModelSize) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SpellEffect::ModelSize), GetLevel()) > 100
|
||||
)
|
||||
||
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_ChangeHeight) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ChangeHeight), GetLevel()) > 100
|
||||
IsEffectInSpell(spell_id, SpellEffect::ChangeHeight) &&
|
||||
CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SpellEffect::ChangeHeight), GetLevel()) > 100
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
@ -12582,7 +12577,7 @@ bool Bot::IsValidSpellTypeSubType(uint16 spell_type, uint16 sub_type, uint16 spe
|
||||
case CommandedSubTypes::Selo:
|
||||
if (
|
||||
IsBeneficialSpell(spell_id) &&
|
||||
IsEffectInSpell(spell_id, SE_MovementSpeed) &&
|
||||
IsEffectInSpell(spell_id, SpellEffect::MovementSpeed) &&
|
||||
IsBardSong(spell_id)
|
||||
) {
|
||||
return true;
|
||||
@ -13352,7 +13347,7 @@ bool Bot::IsImmuneToBotSpell(uint16 spell_id, Mob* caster) {
|
||||
|
||||
if (!GetSpecialAbility(SpecialAbility::MesmerizeImmunity) && IsMesmerizeSpell(spell_id)) {
|
||||
// check max level for spell
|
||||
effect_index = GetSpellEffectIndex(spell_id, SE_Mez);
|
||||
effect_index = GetSpellEffectIndex(spell_id, SpellEffect::Mez);
|
||||
assert(effect_index >= 0);
|
||||
// NPCs get to ignore the max level
|
||||
if (
|
||||
@ -13364,13 +13359,13 @@ bool Bot::IsImmuneToBotSpell(uint16 spell_id, Mob* caster) {
|
||||
}
|
||||
|
||||
// slow and haste spells
|
||||
if (GetSpecialAbility(SpecialAbility::SlowImmunity) && IsEffectInSpell(spell_id, SE_AttackSpeed)) {
|
||||
if (GetSpecialAbility(SpecialAbility::SlowImmunity) && IsEffectInSpell(spell_id, SpellEffect::AttackSpeed)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// client vs client fear
|
||||
if (!GetSpecialAbility(SpecialAbility::FearImmunity) && IsEffectInSpell(spell_id, SE_Fear)) {
|
||||
effect_index = GetSpellEffectIndex(spell_id, SE_Fear);
|
||||
if (!GetSpecialAbility(SpecialAbility::FearImmunity) && IsEffectInSpell(spell_id, SpellEffect::Fear)) {
|
||||
effect_index = GetSpellEffectIndex(spell_id, SpellEffect::Fear);
|
||||
|
||||
if (IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false)) {
|
||||
LogSpells("Clients cannot fear eachother!");
|
||||
@ -13394,7 +13389,7 @@ bool Bot::IsImmuneToBotSpell(uint16 spell_id, Mob* caster) {
|
||||
//let npcs cast whatever charm on anyone
|
||||
if (!caster->IsNPC()) {
|
||||
// check level limit of charm spell
|
||||
effect_index = GetSpellEffectIndex(spell_id, SE_Charm);
|
||||
effect_index = GetSpellEffectIndex(spell_id, SpellEffect::Charm);
|
||||
assert(effect_index >= 0);
|
||||
if (GetLevel() > spells[spell_id].max_value[effect_index] && spells[spell_id].max_value[effect_index] != 0) {
|
||||
return true;
|
||||
@ -13405,8 +13400,8 @@ bool Bot::IsImmuneToBotSpell(uint16 spell_id, Mob* caster) {
|
||||
if (
|
||||
GetSpecialAbility(SpecialAbility::SnareImmunity) &&
|
||||
(
|
||||
IsEffectInSpell(spell_id, SE_Root) ||
|
||||
IsEffectInSpell(spell_id, SE_MovementSpeed)
|
||||
IsEffectInSpell(spell_id, SpellEffect::Root) ||
|
||||
IsEffectInSpell(spell_id, SpellEffect::MovementSpeed)
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
@ -13461,6 +13456,6 @@ bool Bot::HasControllablePet(uint8 ranks_required) {
|
||||
}
|
||||
|
||||
return GetClass() != Class::Enchanter ||
|
||||
GetPet()->GetPetType() != petAnimation ||
|
||||
GetPet()->GetPetType() != PetType::Animation ||
|
||||
GetAA(aaAnimationEmpathy) >= ranks_required;
|
||||
}
|
||||
|
||||
@ -46,9 +46,9 @@ void bot_command_beard_color(Client *c, const Seperator *sep)
|
||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
||||
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != Race::Dwarf)
|
||||
fail_type = AFT_GenderRace;
|
||||
else if (!PlayerAppearance::IsValidBeardColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
else if (!RaceAppearance::IsValidBeardColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
fail_type = AFT_Value;
|
||||
else
|
||||
my_bot->SetBeardColor(uvalue);
|
||||
@ -83,9 +83,9 @@ void bot_command_beard_style(Client *c, const Seperator *sep)
|
||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
||||
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != Race::Dwarf)
|
||||
fail_type = AFT_GenderRace;
|
||||
else if (!PlayerAppearance::IsValidBeard(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
else if (!RaceAppearance::IsValidBeard(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
fail_type = AFT_Value;
|
||||
else
|
||||
my_bot->SetBeard(uvalue);
|
||||
@ -122,9 +122,9 @@ void bot_command_details(Client *c, const Seperator *sep)
|
||||
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (my_bot->GetRace() != DRAKKIN)
|
||||
if (my_bot->GetRace() != Race::Drakkin)
|
||||
fail_type = AFT_Race;
|
||||
else if (!PlayerAppearance::IsValidDetail(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
else if (!RaceAppearance::IsValidDetail(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
fail_type = AFT_Value;
|
||||
else
|
||||
my_bot->SetDrakkinDetails(uvalue);
|
||||
@ -281,7 +281,7 @@ void bot_command_eyes(Client *c, const Seperator *sep)
|
||||
// eye_bias = 2;
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (!PlayerAppearance::IsValidEyeColor(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||
if (!RaceAppearance::IsValidEyeColor(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||
fail_type = AFT_Value;
|
||||
}
|
||||
else {
|
||||
@ -328,12 +328,12 @@ void bot_command_face(Client *c, const Seperator *sep)
|
||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (!PlayerAppearance::IsValidFace(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||
if (!RaceAppearance::IsValidFace(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||
fail_type = AFT_Value;
|
||||
}
|
||||
else {
|
||||
uint8 old_woad = 0;
|
||||
if (my_bot->GetRace() == BARBARIAN)
|
||||
if (my_bot->GetRace() == Race::Barbarian)
|
||||
old_woad = ((my_bot->GetLuclinFace() / 10) * 10);
|
||||
my_bot->SetLuclinFace((old_woad + uvalue));
|
||||
}
|
||||
@ -368,7 +368,7 @@ void bot_command_hair_color(Client *c, const Seperator *sep)
|
||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (!PlayerAppearance::IsValidHairColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
if (!RaceAppearance::IsValidHairColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
fail_type = AFT_Value;
|
||||
else
|
||||
my_bot->SetHairColor(uvalue);
|
||||
@ -403,7 +403,7 @@ void bot_command_hairstyle(Client *c, const Seperator *sep)
|
||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (!PlayerAppearance::IsValidHair(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
if (!RaceAppearance::IsValidHair(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
fail_type = AFT_Value;
|
||||
else
|
||||
my_bot->SetHairStyle(uvalue);
|
||||
@ -440,9 +440,9 @@ void bot_command_heritage(Client *c, const Seperator *sep)
|
||||
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (my_bot->GetRace() != DRAKKIN)
|
||||
if (my_bot->GetRace() != Race::Drakkin)
|
||||
fail_type = AFT_Race;
|
||||
else if (!PlayerAppearance::IsValidHeritage(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
else if (!RaceAppearance::IsValidHeritage(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
fail_type = AFT_Value;
|
||||
else
|
||||
my_bot->SetDrakkinHeritage(uvalue);
|
||||
@ -479,9 +479,9 @@ void bot_command_tattoo(Client *c, const Seperator *sep)
|
||||
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (my_bot->GetRace() != DRAKKIN)
|
||||
if (my_bot->GetRace() != Race::Drakkin)
|
||||
fail_type = AFT_Race;
|
||||
else if (!PlayerAppearance::IsValidTattoo(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
else if (!RaceAppearance::IsValidTattoo(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||
fail_type = AFT_Value;
|
||||
else
|
||||
my_bot->SetDrakkinTattoo(uvalue);
|
||||
@ -516,10 +516,10 @@ void bot_command_woad(Client *c, const Seperator *sep)
|
||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||
|
||||
auto fail_type = AFT_None;
|
||||
if (my_bot->GetRace() != BARBARIAN) {
|
||||
if (my_bot->GetRace() != Race::Barbarian) {
|
||||
fail_type = AFT_Race;
|
||||
}
|
||||
else if (!PlayerAppearance::IsValidWoad(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||
else if (!RaceAppearance::IsValidWoad(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||
fail_type = AFT_Value;
|
||||
}
|
||||
else {
|
||||
|
||||
@ -455,13 +455,13 @@ void bot_command_follow_distance(Client *c, const Seperator *sep)
|
||||
fmt::format("- You must use a value between 1 and {}.", RuleI(Bots, MaxFollowDistance))
|
||||
};
|
||||
p.example_format = { fmt::format("{} [reset]/[set [value]] [actionable]", sep->arg[0]) };
|
||||
p.examples_one = {
|
||||
"To set all bots to follow at a distance of 25:",
|
||||
fmt::format("{} set 25 spawned", sep->arg[0])
|
||||
p.examples_one = {
|
||||
"To set all bots to follow at a distance of 25:",
|
||||
fmt::format("{} set 25 spawned", sep->arg[0])
|
||||
};
|
||||
p.examples_two = {
|
||||
"To check the curret following distance of all bots:",
|
||||
fmt::format("{} current spawned", sep->arg[0])
|
||||
p.examples_two = {
|
||||
"To check the curret following distance of all bots:",
|
||||
fmt::format("{} current spawned", sep->arg[0])
|
||||
};
|
||||
p.examples_three =
|
||||
{
|
||||
@ -470,10 +470,10 @@ void bot_command_follow_distance(Client *c, const Seperator *sep)
|
||||
"{} reset byclass {}",
|
||||
sep->arg[0],
|
||||
Class::Wizard
|
||||
)
|
||||
)
|
||||
};
|
||||
p.actionables = { "target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned" };
|
||||
|
||||
|
||||
std::string popup_text = c->SendBotCommandHelpWindow(p);
|
||||
popup_text = DialogueWindow::Table(popup_text);
|
||||
|
||||
@ -483,7 +483,7 @@ void bot_command_follow_distance(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type2;
|
||||
|
||||
|
||||
uint32 bfd = RuleI(Bots, DefaultFollowDistance);
|
||||
bool set_flag = false;
|
||||
bool current_check = false;
|
||||
@ -862,7 +862,7 @@ void bot_command_report(Client *c, const Seperator *sep)
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationmembers | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
@ -1057,7 +1057,7 @@ void bot_command_stance(Client *c, const Seperator *sep)
|
||||
BotCommandHelpParams p;
|
||||
|
||||
p.description = { "Change a bot's stance to control the way it behaves." };
|
||||
p.notes =
|
||||
p.notes =
|
||||
{
|
||||
"- Changing a stance will reset all settings to match that stance type.",
|
||||
"- Any changes made will only save to that stance for future use.",
|
||||
@ -1122,29 +1122,29 @@ void bot_command_stance(Client *c, const Seperator *sep)
|
||||
Stance::AEBurn
|
||||
)
|
||||
};
|
||||
p.example_format =
|
||||
p.example_format =
|
||||
{ fmt::format( "{} [current | value]", sep->arg[0]) };
|
||||
p.examples_one =
|
||||
{
|
||||
"To set all bots to BurnAE:",
|
||||
p.examples_one =
|
||||
{
|
||||
"To set all bots to BurnAE:",
|
||||
fmt::format("{} {} spawned {}",
|
||||
sep->arg[0],
|
||||
Stance::Aggressive,
|
||||
Class::ShadowKnight
|
||||
)
|
||||
};
|
||||
p.examples_two =
|
||||
{
|
||||
"To set all Shadowknights to Aggressive:",
|
||||
p.examples_two =
|
||||
{
|
||||
"To set all Shadowknights to Aggressive:",
|
||||
fmt::format("{} {} byclass {}",
|
||||
sep->arg[0],
|
||||
Stance::Aggressive,
|
||||
Class::ShadowKnight
|
||||
)
|
||||
};
|
||||
p.examples_three = {
|
||||
"To check the current stances of all bots:",
|
||||
fmt::format("{} current spawned", sep->arg[0])
|
||||
p.examples_three = {
|
||||
"To check the current stances of all bots:",
|
||||
fmt::format("{} current spawned", sep->arg[0])
|
||||
};
|
||||
|
||||
p.actionables = { "target, byname, ownergroup, ownerraid, targetgroup, namesgroup, healrotationtargets, mmr, byclass, byrace, spawned" };
|
||||
@ -1239,7 +1239,7 @@ void bot_command_stance(Client *c, const Seperator *sep)
|
||||
database.botdb.LoadBotSettings(bot_iter);
|
||||
|
||||
if (
|
||||
(bot_iter->GetClass() == Class::Warrior || bot_iter->GetClass() == Class::Paladin || bot_iter->GetClass() == Class::ShadowKnight) &&
|
||||
(bot_iter->GetClass() == Class::Warrior || bot_iter->GetClass() == Class::Paladin || bot_iter->GetClass() == Class::ShadowKnight) &&
|
||||
(bot_iter->GetBotStance() == Stance::Aggressive)
|
||||
) {
|
||||
bot_iter->SetTaunting(true);
|
||||
@ -1255,7 +1255,7 @@ void bot_command_stance(Client *c, const Seperator *sep)
|
||||
bot_iter->GetPet()->CastToNPC()->SetTaunting(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bot_iter->Save();
|
||||
++success_count;
|
||||
}
|
||||
@ -1431,7 +1431,7 @@ void bot_command_summon(Client *c, const Seperator *sep)
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | ownerraid | targetgroup | namesgroup | healrotationtargets | mmr | byclass | byrace | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
@ -1550,7 +1550,7 @@ void bot_command_toggle_ranged(Client *c, const Seperator *sep)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
int ab_arg = 1;
|
||||
@ -1712,7 +1712,7 @@ void bot_command_toggle_helm(Client *c, const Seperator *sep)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
int ab_arg = 1;
|
||||
|
||||
@ -245,7 +245,7 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep)
|
||||
|
||||
if (pet_type == 6 && RuleI(Bots, RequiredMagicianEpicPetItemID) > 0) {
|
||||
bool has_item = bot_iter->HasBotItem(RuleI(Bots, RequiredMagicianEpicPetItemID)) != INVALID_INDEX;
|
||||
|
||||
|
||||
if (!has_item) {
|
||||
c->Message(
|
||||
Chat::Say,
|
||||
@ -257,7 +257,7 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep)
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (current_check) {
|
||||
@ -313,7 +313,7 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsEffectInSpell(s.SpellId, SE_SummonPet)) {
|
||||
if (!IsEffectInSpell(s.SpellId, SpellEffect::SummonPet)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -401,7 +401,7 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (success_count == 1 && first_found) {
|
||||
c->Message(
|
||||
Chat::Green,
|
||||
|
||||
@ -40,7 +40,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 chance, uint16 spell_type, uint16 sub_targ
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
!IsCommandedSpell() &&
|
||||
zone->random.Int(0, 100) > chance
|
||||
@ -240,7 +240,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 chance, uint16 spell_type, uint16 sub_targ
|
||||
tar->GetCleanName()
|
||||
).c_str()
|
||||
);
|
||||
|
||||
|
||||
InterruptSpell();
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ bool Bot::BotCastMez(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spel
|
||||
if (AIDoSpellCast(s.SpellIndex, tar, s.ManaCost)) {
|
||||
if (BotSpellTypeUsesTargetSettings(spell_type)) {
|
||||
SetCastedSpellType(UINT16_MAX);
|
||||
|
||||
|
||||
if (!IsCommandedSpell()) {
|
||||
SetBotSpellRecastTimer(spell_type, tar, true);
|
||||
}
|
||||
@ -384,7 +384,7 @@ bool Bot::BotCastPet(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spel
|
||||
int familiar_buff_slot = -1;
|
||||
if (buffs_max && my_buffs) {
|
||||
for (int index = 0; index < buffs_max; ++index) {
|
||||
if (IsEffectInSpell(my_buffs[index].spellid, SE_Familiar)) {
|
||||
if (IsEffectInSpell(my_buffs[index].spellid, SpellEffect::Familiar)) {
|
||||
MakePet(my_buffs[index].spellid, spells[my_buffs[index].spellid].teleport_zone);
|
||||
familiar_buff_slot = index;
|
||||
break;
|
||||
@ -445,11 +445,11 @@ bool Bot::BotCastNuke(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe
|
||||
}
|
||||
|
||||
if (
|
||||
!tar->GetSpecialAbility(SpecialAbility::StunImmunity) &&
|
||||
!tar->GetSpecialAbility(SpecialAbility::StunImmunity) &&
|
||||
(
|
||||
IsCommandedSpell() ||
|
||||
IsCommandedSpell() ||
|
||||
(!tar->IsStunned() && (zone->random.Int(1, 100) <= stun_chance))
|
||||
)
|
||||
)
|
||||
) {
|
||||
bot_spell = GetBestBotSpellForStunByTargetType(this, ST_TargetOptional, spell_type, IsAEBotSpellType(spell_type), tar);
|
||||
}
|
||||
@ -1173,7 +1173,7 @@ BotSpell Bot::GetBestBotSpellForVeryFastHeal(Bot* caster, Mob* tar, uint16 spell
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CurrentHP);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::CurrentHP);
|
||||
|
||||
for (auto bot_spell_list_itr : bot_spell_list) {
|
||||
if (
|
||||
@ -1198,7 +1198,7 @@ BotSpell Bot::GetBestBotSpellForFastHeal(Bot* caster, Mob* tar, uint16 spell_typ
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CurrentHP);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::CurrentHP);
|
||||
|
||||
for (auto bot_spell_list_itr : bot_spell_list) {
|
||||
if (IsFastHealSpell(bot_spell_list_itr.SpellId) && caster->CastChecks(bot_spell_list_itr.SpellId, tar, spell_type)) {
|
||||
@ -1222,7 +1222,7 @@ BotSpell Bot::GetBestBotSpellForHealOverTime(Bot* caster, Mob* tar, uint16 spell
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_HealOverTime);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::HealOverTime);
|
||||
|
||||
for (auto bot_spell_list_itr : bot_spell_list) {
|
||||
if (IsHealOverTimeSpell(bot_spell_list_itr.SpellId) && caster->CastChecks(bot_spell_list_itr.SpellId, tar, spell_type)) {
|
||||
@ -1278,7 +1278,7 @@ BotSpell Bot::GetBestBotSpellForRegularSingleTargetHeal(Bot* caster, Mob* tar, u
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CurrentHP);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::CurrentHP);
|
||||
|
||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||
if (IsRegularSingleTargetHealSpell(bot_spell_list_itr->SpellId) && caster->CastChecks(bot_spell_list_itr->SpellId, tar, spell_type)) {
|
||||
@ -1302,7 +1302,7 @@ BotSpell Bot::GetFirstBotSpellForSingleTargetHeal(Bot* caster, Mob* tar, uint16
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CurrentHP);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::CurrentHP);
|
||||
|
||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||
if (IsRegularSingleTargetHealSpell(bot_spell_list_itr->SpellId) && caster->CastChecks(bot_spell_list_itr->SpellId, tar, spell_type)) {
|
||||
@ -1329,7 +1329,7 @@ BotSpell Bot::GetBestBotSpellForGroupHeal(Bot* caster, Mob* tar, uint16 spell_ty
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CurrentHP);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::CurrentHP);
|
||||
int target_count = 0;
|
||||
int required_count = caster->GetSpellTypeAEOrGroupTargetCount(spell_type);
|
||||
|
||||
@ -1367,7 +1367,7 @@ BotSpell Bot::GetBestBotSpellForGroupHealOverTime(Bot* caster, Mob* tar, uint16
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_HealOverTime);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::HealOverTime);
|
||||
int target_count = 0;
|
||||
int required_count = caster->GetSpellTypeAEOrGroupTargetCount(spell_type);
|
||||
|
||||
@ -1405,7 +1405,7 @@ BotSpell Bot::GetBestBotSpellForGroupCompleteHeal(Bot* caster, Mob* tar, uint16
|
||||
return result;
|
||||
}
|
||||
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_CompleteHeal);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::CompleteHeal);
|
||||
int target_count = 0;
|
||||
int required_count = caster->GetSpellTypeAEOrGroupTargetCount(spell_type);
|
||||
|
||||
@ -1440,7 +1440,7 @@ BotSpell Bot::GetBestBotSpellForMez(Bot* caster, uint16 spell_type) {
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_Mez);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::Mez);
|
||||
|
||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||
if (
|
||||
@ -1548,7 +1548,7 @@ BotSpell Bot::GetBestBotMagicianPetSpell(Bot* caster, uint16 spell_type) {
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_SummonPet);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::SummonPet);
|
||||
std::string pet_type = GetBotMagicianPetType(caster);
|
||||
|
||||
for(std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||
@ -1638,7 +1638,7 @@ std::string Bot::GetBotMagicianPetType(Bot* caster) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsEffectInSpell(s.SpellId, SE_SummonPet)) {
|
||||
if (!IsEffectInSpell(s.SpellId, SpellEffect::SummonPet)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1683,7 +1683,7 @@ std::string Bot::GetBotMagicianPetType(Bot* caster) {
|
||||
if (bot_level >= water_min_level) {
|
||||
result = std::string("SumWater");
|
||||
}
|
||||
|
||||
|
||||
found = true;
|
||||
break;
|
||||
case SumFire:
|
||||
@ -1730,7 +1730,7 @@ BotSpell Bot::GetBestBotSpellForNukeByTargetType(Bot* caster, SpellTargetType ta
|
||||
}
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffectAndTargetType(caster, spell_type, SE_CurrentHP, target_type);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffectAndTargetType(caster, spell_type, SpellEffect::CurrentHP, target_type);
|
||||
|
||||
for(std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||
if (IsPureNukeSpell(bot_spell_list_itr->SpellId) || IsDamageSpell(bot_spell_list_itr->SpellId)) {
|
||||
@ -1777,7 +1777,7 @@ BotSpell Bot::GetBestBotSpellForStunByTargetType(Bot* caster, SpellTargetType ta
|
||||
|
||||
if (caster)
|
||||
{
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffectAndTargetType(caster, spell_type, SE_Stun, target_type);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffectAndTargetType(caster, spell_type, SpellEffect::Stun, target_type);
|
||||
|
||||
for(std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr)
|
||||
{
|
||||
@ -1835,7 +1835,7 @@ BotSpell Bot::GetBestBotWizardNukeSpellByTargetResists(Bot* caster, Mob* target,
|
||||
}
|
||||
|
||||
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffectAndTargetType(caster, spell_type, SE_CurrentHP, ST_Target);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffectAndTargetType(caster, spell_type, SpellEffect::CurrentHP, ST_Target);
|
||||
|
||||
BotSpell first_wizard_magic_nuke_spell_found;
|
||||
first_wizard_magic_nuke_spell_found.SpellId = 0;
|
||||
@ -1855,32 +1855,32 @@ BotSpell Bot::GetBestBotWizardNukeSpellByTargetResists(Bot* caster, Mob* target,
|
||||
}
|
||||
else if (!select_lure_nuke && IsPureNukeSpell(bot_spell_list_itr->SpellId)) {
|
||||
if (
|
||||
((target->GetMR() < target->GetCR()) || (target->GetMR() < target->GetFR())) &&
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_MAGIC) &&
|
||||
((target->GetMR() < target->GetCR()) || (target->GetMR() < target->GetFR())) &&
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_MAGIC) &&
|
||||
(spells[bot_spell_list_itr->SpellId].resist_difficulty > lure_resis_value) &&
|
||||
caster->CastChecks(bot_spell_list_itr->SpellId, target, spell_type)
|
||||
) {
|
||||
spell_selected = true;
|
||||
}
|
||||
else if (
|
||||
((target->GetCR() < target->GetMR()) || (target->GetCR() < target->GetFR())) &&
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_COLD) &&
|
||||
(spells[bot_spell_list_itr->SpellId].resist_difficulty > lure_resis_value) &&
|
||||
((target->GetCR() < target->GetMR()) || (target->GetCR() < target->GetFR())) &&
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_COLD) &&
|
||||
(spells[bot_spell_list_itr->SpellId].resist_difficulty > lure_resis_value) &&
|
||||
caster->CastChecks(bot_spell_list_itr->SpellId, target, spell_type)
|
||||
) {
|
||||
spell_selected = true;
|
||||
}
|
||||
else if (
|
||||
((target->GetFR() < target->GetCR()) || (target->GetFR() < target->GetMR())) &&
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_FIRE) &&
|
||||
(spells[bot_spell_list_itr->SpellId].resist_difficulty > lure_resis_value) &&
|
||||
((target->GetFR() < target->GetCR()) || (target->GetFR() < target->GetMR())) &&
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_FIRE) &&
|
||||
(spells[bot_spell_list_itr->SpellId].resist_difficulty > lure_resis_value) &&
|
||||
caster->CastChecks(bot_spell_list_itr->SpellId, target, spell_type)
|
||||
) {
|
||||
spell_selected = true;
|
||||
}
|
||||
else if (
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_MAGIC) &&
|
||||
(spells[bot_spell_list_itr->SpellId].resist_difficulty > lure_resis_value) &&
|
||||
(GetSpellResistType(bot_spell_list_itr->SpellId) == RESIST_MAGIC) &&
|
||||
(spells[bot_spell_list_itr->SpellId].resist_difficulty > lure_resis_value) &&
|
||||
caster->CastChecks(bot_spell_list_itr->SpellId, target, spell_type)
|
||||
) {
|
||||
first_wizard_magic_nuke_spell_found.SpellId = bot_spell_list_itr->SpellId;
|
||||
@ -1998,11 +1998,11 @@ BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* caster, Mob *tar, uint16 spell
|
||||
if (
|
||||
(bot_spell_list[i].type == BotSpellTypes::Debuff || IsResistDebuffSpell(bot_spell_list[i].spellid)) &&
|
||||
(
|
||||
(needs_magic_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistMagic) || IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistAll))) ||
|
||||
(needs_cold_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistCold) || IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistAll))) ||
|
||||
(needs_fire_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistFire) || IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistAll))) ||
|
||||
(needs_poison_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistPoison) || IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistAll))) ||
|
||||
(needs_disease_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistDisease) || IsEffectInSpell(bot_spell_list[i].spellid, SE_ResistAll)))
|
||||
(needs_magic_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistMagic) || IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistAll))) ||
|
||||
(needs_cold_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistCold) || IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistAll))) ||
|
||||
(needs_fire_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistFire) || IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistAll))) ||
|
||||
(needs_poison_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistPoison) || IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistAll))) ||
|
||||
(needs_disease_resist_debuff && (IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistDisease) || IsEffectInSpell(bot_spell_list[i].spellid, SpellEffect::ResistAll)))
|
||||
) &&
|
||||
!tar->IsImmuneToSpell(bot_spell_list[i].spellid, caster) &&
|
||||
tar->CanBuffStack(bot_spell_list[i].spellid, caster->GetLevel(), true) >= 0 &&
|
||||
@ -2033,7 +2033,7 @@ BotSpell Bot::GetBestBotSpellForCure(Bot* caster, Mob* tar, uint16 spell_type) {
|
||||
|
||||
if (caster) {
|
||||
std::vector<BotSpell_wPriority> bot_spell_list_itr = GetPrioritizedBotSpellsBySpellType(caster, spell_type, tar);
|
||||
|
||||
|
||||
if (IsGroupBotSpellType(spell_type)) {
|
||||
int count_needs_cured = 0;
|
||||
uint16 count_poisoned = 0;
|
||||
@ -2049,16 +2049,16 @@ BotSpell Bot::GetBestBotSpellForCure(Bot* caster, Mob* tar, uint16 spell_type) {
|
||||
for (Mob* m : (IsGroupBotSpellType(spell_type) ? caster->GetSpellTargetList() : caster->GetSpellTargetList(true))) {
|
||||
if (caster->GetNeedsCured(m)) {
|
||||
if (caster->CastChecks(itr->SpellId, m, spell_type, true, IsGroupBotSpellType(spell_type))) {
|
||||
if (m->FindType(SE_PoisonCounter)) {
|
||||
if (m->FindType(SpellEffect::PoisonCounter)) {
|
||||
++count_poisoned;
|
||||
}
|
||||
if (m->FindType(SE_DiseaseCounter)) {
|
||||
if (m->FindType(SpellEffect::DiseaseCounter)) {
|
||||
++count_diseased;
|
||||
}
|
||||
if (m->FindType(SE_CurseCounter)) {
|
||||
if (m->FindType(SpellEffect::CurseCounter)) {
|
||||
++count_cursed;
|
||||
}
|
||||
if (m->FindType(SE_CorruptionCounter)) {
|
||||
if (m->FindType(SpellEffect::CorruptionCounter)) {
|
||||
++count_corrupted;
|
||||
}
|
||||
}
|
||||
@ -2066,10 +2066,10 @@ BotSpell Bot::GetBestBotSpellForCure(Bot* caster, Mob* tar, uint16 spell_type) {
|
||||
}
|
||||
|
||||
if (
|
||||
(count_poisoned >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SE_PoisonCounter)) ||
|
||||
(count_diseased >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SE_DiseaseCounter)) ||
|
||||
(count_cursed >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SE_CurseCounter)) ||
|
||||
(count_corrupted >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SE_CorruptionCounter))
|
||||
(count_poisoned >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SpellEffect::PoisonCounter)) ||
|
||||
(count_diseased >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SpellEffect::DiseaseCounter)) ||
|
||||
(count_cursed >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SpellEffect::CurseCounter)) ||
|
||||
(count_corrupted >= caster->GetSpellTypeAEOrGroupTargetCount(spell_type) && IsEffectInSpell(itr->SpellId, SpellEffect::CorruptionCounter))
|
||||
) {
|
||||
result.SpellId = itr->SpellId;
|
||||
result.SpellIndex = itr->SpellIndex;
|
||||
@ -2086,10 +2086,10 @@ BotSpell Bot::GetBestBotSpellForCure(Bot* caster, Mob* tar, uint16 spell_type) {
|
||||
}
|
||||
|
||||
if (
|
||||
tar->FindType(SE_PoisonCounter) && IsEffectInSpell(itr->SpellId, SE_PoisonCounter) ||
|
||||
tar->FindType(SE_DiseaseCounter) && IsEffectInSpell(itr->SpellId, SE_DiseaseCounter) ||
|
||||
tar->FindType(SE_CurseCounter) && IsEffectInSpell(itr->SpellId, SE_CurseCounter) ||
|
||||
tar->FindType(SE_CorruptionCounter) && IsEffectInSpell(itr->SpellId, SE_CorruptionCounter)
|
||||
tar->FindType(SpellEffect::PoisonCounter) && IsEffectInSpell(itr->SpellId, SpellEffect::PoisonCounter) ||
|
||||
tar->FindType(SpellEffect::DiseaseCounter) && IsEffectInSpell(itr->SpellId, SpellEffect::DiseaseCounter) ||
|
||||
tar->FindType(SpellEffect::CurseCounter) && IsEffectInSpell(itr->SpellId, SpellEffect::CurseCounter) ||
|
||||
tar->FindType(SpellEffect::CorruptionCounter) && IsEffectInSpell(itr->SpellId, SpellEffect::CorruptionCounter)
|
||||
) {
|
||||
result.SpellId = itr->SpellId;
|
||||
result.SpellIndex = itr->SpellIndex;
|
||||
@ -2146,13 +2146,13 @@ uint8 Bot::GetChanceToCastBySpellType(uint16 spell_type)
|
||||
case BotSpellTypes::Dispel:
|
||||
return RuleI(Bots, PercentChanceToCastDispel);
|
||||
case BotSpellTypes::InCombatBuff:
|
||||
return RuleI(Bots, PercentChanceToCastInCombatBuff);
|
||||
return RuleI(Bots, PercentChanceToCastInCombatBuff);
|
||||
case BotSpellTypes::HateLine:
|
||||
return RuleI(Bots, PercentChanceToCastHateLine);
|
||||
case BotSpellTypes::Mez:
|
||||
return RuleI(Bots, PercentChanceToCastMez);
|
||||
return RuleI(Bots, PercentChanceToCastMez);
|
||||
case BotSpellTypes::Slow:
|
||||
return RuleI(Bots, PercentChanceToCastSlow);
|
||||
return RuleI(Bots, PercentChanceToCastSlow);
|
||||
case BotSpellTypes::Debuff:
|
||||
return RuleI(Bots, PercentChanceToCastDebuff);
|
||||
case BotSpellTypes::Cure:
|
||||
@ -2161,7 +2161,7 @@ uint8 Bot::GetChanceToCastBySpellType(uint16 spell_type)
|
||||
case BotSpellTypes::GroupCures:
|
||||
return RuleI(Bots, PercentChanceToCastGroupCure);
|
||||
case BotSpellTypes::HateRedux:
|
||||
return RuleI(Bots, PercentChanceToCastHateRedux);
|
||||
return RuleI(Bots, PercentChanceToCastHateRedux);
|
||||
case BotSpellTypes::Fear:
|
||||
return RuleI(Bots, PercentChanceToCastFear);
|
||||
case BotSpellTypes::RegularHeal:
|
||||
@ -2758,8 +2758,8 @@ bool Bot::IsValidSpellRange(uint16 spell_id, Mob* tar) {
|
||||
) {
|
||||
range = GetAOERange(spell_id);
|
||||
}
|
||||
|
||||
if (RuleB(Bots, EnableBotTGB) && IsTGBCompatibleSpell(spell_id) && IsGroupSpell(spell_id)) {
|
||||
|
||||
if (RuleB(Bots, EnableBotTGB) && IsTGBCompatibleSpell(spell_id) && IsGroupSpell(spell_id)) {
|
||||
range = spells[spell_id].aoe_range;
|
||||
}
|
||||
|
||||
@ -2838,7 +2838,7 @@ BotSpell Bot::GetBestBotSpellForRez(Bot* caster, Mob* target, uint16 spell_type)
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_Revive);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::Revive);
|
||||
|
||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||
if (
|
||||
@ -2865,7 +2865,7 @@ BotSpell Bot::GetBestBotSpellForCharm(Bot* caster, Mob* target, uint16 spell_typ
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (caster) {
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_Charm);
|
||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SpellEffect::Charm);
|
||||
|
||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||
if (
|
||||
|
||||
@ -1391,7 +1391,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
}
|
||||
case ChatChannel_Shout: { /* Shout */
|
||||
Mob *sender = this;
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SpellEffect::VoiceGraft))
|
||||
sender = GetPet();
|
||||
|
||||
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
||||
@ -1429,7 +1429,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
else if(!RuleB(Chat, ServerWideAuction)) {
|
||||
Mob *sender = this;
|
||||
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SpellEffect::VoiceGraft))
|
||||
sender = GetPet();
|
||||
|
||||
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
||||
@ -1476,7 +1476,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
{
|
||||
Mob *sender = this;
|
||||
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SpellEffect::VoiceGraft))
|
||||
sender = GetPet();
|
||||
|
||||
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
||||
@ -1606,7 +1606,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
}
|
||||
|
||||
Mob* sender = this;
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SE_VoiceGraft)) {
|
||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SpellEffect::VoiceGraft)) {
|
||||
sender = GetPet();
|
||||
}
|
||||
|
||||
@ -4780,9 +4780,21 @@ bool Client::KeyRingClear()
|
||||
);
|
||||
}
|
||||
|
||||
void Client::KeyRingList()
|
||||
void Client::KeyRingList(Client* c)
|
||||
{
|
||||
Message(Chat::LightBlue, "Keys on Keyring:");
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string message = "Keys on Keyring:";
|
||||
if (c != this) {
|
||||
message = fmt::format(
|
||||
"Keys on Keyring for {}:",
|
||||
GetCleanName()
|
||||
);
|
||||
}
|
||||
|
||||
c->Message(Chat::LightBlue, message.c_str());
|
||||
|
||||
const EQ::ItemData *item = nullptr;
|
||||
|
||||
@ -4795,7 +4807,7 @@ void Client::KeyRingList()
|
||||
item->Name
|
||||
);
|
||||
|
||||
Message(Chat::LightBlue, item_string.c_str());
|
||||
c->Message(Chat::LightBlue, item_string.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6403,17 +6415,17 @@ void Client::SuspendMinion(int value)
|
||||
// TODO: These pet command states need to be synced ...
|
||||
// Will just fix them for now
|
||||
if (m_ClientVersionBit & EQ::versions::maskUFAndLater) {
|
||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Stop, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Regroup, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Follow, PetButtonState::On);
|
||||
SetPetCommandState(PetButton::Guard, PetButtonState::Off);
|
||||
// Taunt saved on client side for logging on with pet
|
||||
// In our db for when we zone.
|
||||
SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOCUS, 0);
|
||||
SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||
SetPetCommandState(PetButton::Hold, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::GreaterHold, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Focus, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::SpellHold, PetButtonState::Off);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -6894,9 +6906,9 @@ void Client::CheckLDoNHail(NPC* n)
|
||||
|
||||
auto pet = GetPet();
|
||||
if (pet) {
|
||||
if (pet->GetPetType() == petCharmed) {
|
||||
pet->BuffFadeByEffect(SE_Charm);
|
||||
} else if (pet->GetPetType() == petNPCFollow) {
|
||||
if (pet->GetPetType() == PetType::Charmed) {
|
||||
pet->BuffFadeByEffect(SpellEffect::Charm);
|
||||
} else if (pet->GetPetType() == PetType::Follow) {
|
||||
pet->SetOwnerID(0);
|
||||
} else {
|
||||
pet->Depop();
|
||||
@ -8433,7 +8445,7 @@ void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction)
|
||||
merchant->SayString(zone->random.Int(WONT_SELL_DEEDS1, WONT_SELL_DEEDS6));
|
||||
} else if (lowestvalue == fmod.race_mod) { // race biggest
|
||||
// Non-standard race (ex. illusioned to wolf)
|
||||
if (GetRace() > PLAYER_RACE_COUNT) {
|
||||
if (!IsPlayerRace(GetRace())) {
|
||||
messageid = zone->random.Int(1, 3); // these aren't sequential StringIDs :(
|
||||
switch (messageid) {
|
||||
case 1:
|
||||
@ -9438,12 +9450,15 @@ void Client::ProcessAggroMeter()
|
||||
}
|
||||
}
|
||||
|
||||
void Client::SetPetCommandState(int button, int state)
|
||||
void Client::SetPetCommandState(uint8 button, uint8 state)
|
||||
{
|
||||
auto app = new EQApplicationPacket(OP_PetCommandState, sizeof(PetCommandState_Struct));
|
||||
auto pcs = (PetCommandState_Struct *)app->pBuffer;
|
||||
pcs->button_id = button;
|
||||
pcs->state = state;
|
||||
|
||||
auto s = (PetCommandState_Struct*) app->pBuffer;
|
||||
|
||||
s->button_id = button;
|
||||
s->state = state;
|
||||
|
||||
FastQueuePacket(&app);
|
||||
}
|
||||
|
||||
@ -10643,7 +10658,7 @@ void Client::MovePCDynamicZone(const std::string& zone_name, int zone_version, b
|
||||
}
|
||||
|
||||
void Client::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls, bool calculate_speed) {
|
||||
BuffFadeByEffect(SE_Levitate);
|
||||
BuffFadeByEffect(SpellEffect::Levitate);
|
||||
if (CheckLosFN(target_x, target_y, target_z, 6.0f) || ignore_los) {
|
||||
auto p = new EQApplicationPacket(OP_Fling, sizeof(fling_struct));
|
||||
auto* f = (fling_struct*) p->pBuffer;
|
||||
@ -10708,7 +10723,7 @@ std::vector<int> Client::GetLearnableDisciplines(uint8 min_level, uint8 max_leve
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RuleB(Spells, UseCHAScribeHack) && spells[spell_id].effect_id[EFFECT_COUNT - 1] == SE_CHA) {
|
||||
if (RuleB(Spells, UseCHAScribeHack) && spells[spell_id].effect_id[EFFECT_COUNT - 1] == SpellEffect::CHA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -10779,7 +10794,7 @@ std::vector<int> Client::GetScribeableSpells(uint8 min_level, uint8 max_level) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RuleB(Spells, UseCHAScribeHack) && spells[spell_id].effect_id[EFFECT_COUNT - 1] == SE_CHA) {
|
||||
if (RuleB(Spells, UseCHAScribeHack) && spells[spell_id].effect_id[EFFECT_COUNT - 1] == SpellEffect::CHA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -11421,7 +11436,7 @@ void Client::SummonBaggedItems(uint32 bag_item_id, const std::vector<LootItem>&
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: maybe some common functions for SE_SummonItem and SE_SummonItemIntoBag
|
||||
// todo: maybe some common functions for SpellEffect::SummonItem and SpellEffect::SummonItemIntoBag
|
||||
|
||||
const EQ::ItemData* bag_item = database.GetItem(bag_item_id);
|
||||
if (!bag_item)
|
||||
|
||||
@ -326,12 +326,13 @@ public:
|
||||
void TraderStartTrader(const EQApplicationPacket *app);
|
||||
// void TraderPriceUpdate(const EQApplicationPacket *app);
|
||||
uint8 WithCustomer(uint16 NewCustomer);
|
||||
std::vector<uint32> GetKeyRing() { return keyring; }
|
||||
void KeyRingLoad();
|
||||
bool KeyRingAdd(uint32 item_id);
|
||||
bool KeyRingCheck(uint32 item_id);
|
||||
bool KeyRingClear();
|
||||
bool KeyRingRemove(uint32 item_id);
|
||||
void KeyRingList();
|
||||
void KeyRingList(Client* c = nullptr);
|
||||
bool IsNameChangeAllowed();
|
||||
void InvokeChangeNameWindow(bool immediate = true);
|
||||
bool ClearNameChange();
|
||||
@ -523,7 +524,7 @@ public:
|
||||
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
||||
void ReloadExpansionProfileSetting();
|
||||
|
||||
void SetPetCommandState(int button, int state);
|
||||
void SetPetCommandState(uint8 button, uint8 state);
|
||||
|
||||
bool AutoAttackEnabled() const { return auto_attack; }
|
||||
bool AutoFireEnabled() const { return auto_fire; }
|
||||
|
||||
@ -693,7 +693,7 @@ int64 Client::CalcManaRegen(bool bCombat)
|
||||
}
|
||||
|
||||
regen += aabonuses.ManaRegen;
|
||||
// add in + 1 bonus for SE_CompleteHeal, but we don't do anything for it yet?
|
||||
// add in + 1 bonus for SpellEffect::CompleteHeal, but we don't do anything for it yet?
|
||||
|
||||
int item_bonus = itembonuses.ManaRegen; // this is capped already
|
||||
item_bonus += itembonuses.heroic_mana_regen;
|
||||
@ -1011,52 +1011,52 @@ int32 Client::CalcMR()
|
||||
{
|
||||
//racial bases
|
||||
switch (GetBaseRace()) {
|
||||
case HUMAN:
|
||||
case Race::Human:
|
||||
MR = 25;
|
||||
break;
|
||||
case BARBARIAN:
|
||||
case Race::Barbarian:
|
||||
MR = 25;
|
||||
break;
|
||||
case ERUDITE:
|
||||
case Race::Erudite:
|
||||
MR = 30;
|
||||
break;
|
||||
case WOOD_ELF:
|
||||
case Race::WoodElf:
|
||||
MR = 25;
|
||||
break;
|
||||
case HIGH_ELF:
|
||||
case Race::HighElf:
|
||||
MR = 25;
|
||||
break;
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
MR = 25;
|
||||
break;
|
||||
case HALF_ELF:
|
||||
case Race::HalfElf:
|
||||
MR = 25;
|
||||
break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
MR = 30;
|
||||
break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
MR = 25;
|
||||
break;
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
MR = 25;
|
||||
break;
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
MR = 25;
|
||||
break;
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
MR = 25;
|
||||
break;
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
MR = 25;
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
MR = 25;
|
||||
break;
|
||||
case FROGLOK:
|
||||
case Race::Froglok2:
|
||||
MR = 30;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
case Race::Drakkin:
|
||||
{
|
||||
MR = 25;
|
||||
if (GetDrakkinHeritage() == 2)
|
||||
@ -1085,52 +1085,52 @@ int32 Client::CalcFR()
|
||||
{
|
||||
//racial bases
|
||||
switch (GetBaseRace()) {
|
||||
case HUMAN:
|
||||
case Race::Human:
|
||||
FR = 25;
|
||||
break;
|
||||
case BARBARIAN:
|
||||
case Race::Barbarian:
|
||||
FR = 25;
|
||||
break;
|
||||
case ERUDITE:
|
||||
case Race::Erudite:
|
||||
FR = 25;
|
||||
break;
|
||||
case WOOD_ELF:
|
||||
case Race::WoodElf:
|
||||
FR = 25;
|
||||
break;
|
||||
case HIGH_ELF:
|
||||
case Race::HighElf:
|
||||
FR = 25;
|
||||
break;
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
FR = 25;
|
||||
break;
|
||||
case HALF_ELF:
|
||||
case Race::HalfElf:
|
||||
FR = 25;
|
||||
break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
FR = 25;
|
||||
break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
FR = 5;
|
||||
break;
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
FR = 25;
|
||||
break;
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
FR = 25;
|
||||
break;
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
FR = 25;
|
||||
break;
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
FR = 30;
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
FR = 25;
|
||||
break;
|
||||
case FROGLOK:
|
||||
case Race::Froglok2:
|
||||
FR = 25;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
case Race::Drakkin:
|
||||
{
|
||||
FR = 25;
|
||||
if (GetDrakkinHeritage() == 0)
|
||||
@ -1171,52 +1171,52 @@ int32 Client::CalcDR()
|
||||
{
|
||||
//racial bases
|
||||
switch (GetBaseRace()) {
|
||||
case HUMAN:
|
||||
case Race::Human:
|
||||
DR = 15;
|
||||
break;
|
||||
case BARBARIAN:
|
||||
case Race::Barbarian:
|
||||
DR = 15;
|
||||
break;
|
||||
case ERUDITE:
|
||||
case Race::Erudite:
|
||||
DR = 10;
|
||||
break;
|
||||
case WOOD_ELF:
|
||||
case Race::WoodElf:
|
||||
DR = 15;
|
||||
break;
|
||||
case HIGH_ELF:
|
||||
case Race::HighElf:
|
||||
DR = 15;
|
||||
break;
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
DR = 15;
|
||||
break;
|
||||
case HALF_ELF:
|
||||
case Race::HalfElf:
|
||||
DR = 15;
|
||||
break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
DR = 15;
|
||||
break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
DR = 15;
|
||||
break;
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
DR = 15;
|
||||
break;
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
DR = 20;
|
||||
break;
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
DR = 15;
|
||||
break;
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
DR = 15;
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
DR = 15;
|
||||
break;
|
||||
case FROGLOK:
|
||||
case Race::Froglok2:
|
||||
DR = 15;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
case Race::Drakkin:
|
||||
{
|
||||
DR = 15;
|
||||
if (GetDrakkinHeritage() == 1)
|
||||
@ -1263,52 +1263,52 @@ int32 Client::CalcPR()
|
||||
{
|
||||
//racial bases
|
||||
switch (GetBaseRace()) {
|
||||
case HUMAN:
|
||||
case Race::Human:
|
||||
PR = 15;
|
||||
break;
|
||||
case BARBARIAN:
|
||||
case Race::Barbarian:
|
||||
PR = 15;
|
||||
break;
|
||||
case ERUDITE:
|
||||
case Race::Erudite:
|
||||
PR = 15;
|
||||
break;
|
||||
case WOOD_ELF:
|
||||
case Race::WoodElf:
|
||||
PR = 15;
|
||||
break;
|
||||
case HIGH_ELF:
|
||||
case Race::HighElf:
|
||||
PR = 15;
|
||||
break;
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
PR = 15;
|
||||
break;
|
||||
case HALF_ELF:
|
||||
case Race::HalfElf:
|
||||
PR = 15;
|
||||
break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
PR = 20;
|
||||
break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
PR = 15;
|
||||
break;
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
PR = 15;
|
||||
break;
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
PR = 20;
|
||||
break;
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
PR = 15;
|
||||
break;
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
PR = 15;
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
PR = 15;
|
||||
break;
|
||||
case FROGLOK:
|
||||
case Race::Froglok2:
|
||||
PR = 30;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
case Race::Drakkin:
|
||||
{
|
||||
PR = 15;
|
||||
if (GetDrakkinHeritage() == 3)
|
||||
@ -1355,52 +1355,52 @@ int32 Client::CalcCR()
|
||||
{
|
||||
//racial bases
|
||||
switch (GetBaseRace()) {
|
||||
case HUMAN:
|
||||
case Race::Human:
|
||||
CR = 25;
|
||||
break;
|
||||
case BARBARIAN:
|
||||
case Race::Barbarian:
|
||||
CR = 35;
|
||||
break;
|
||||
case ERUDITE:
|
||||
case Race::Erudite:
|
||||
CR = 25;
|
||||
break;
|
||||
case WOOD_ELF:
|
||||
case Race::WoodElf:
|
||||
CR = 25;
|
||||
break;
|
||||
case HIGH_ELF:
|
||||
case Race::HighElf:
|
||||
CR = 25;
|
||||
break;
|
||||
case DARK_ELF:
|
||||
case Race::DarkElf:
|
||||
CR = 25;
|
||||
break;
|
||||
case HALF_ELF:
|
||||
case Race::HalfElf:
|
||||
CR = 25;
|
||||
break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
CR = 25;
|
||||
break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
CR = 25;
|
||||
break;
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
CR = 25;
|
||||
break;
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
CR = 25;
|
||||
break;
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
CR = 25;
|
||||
break;
|
||||
case IKSAR:
|
||||
case Race::Iksar:
|
||||
CR = 15;
|
||||
break;
|
||||
case VAHSHIR:
|
||||
case Race::VahShir:
|
||||
CR = 25;
|
||||
break;
|
||||
case FROGLOK:
|
||||
case Race::Froglok2:
|
||||
CR = 25;
|
||||
break;
|
||||
case DRAKKIN:
|
||||
case Race::Drakkin:
|
||||
{
|
||||
CR = 25;
|
||||
if (GetDrakkinHeritage() == 4)
|
||||
@ -1482,24 +1482,24 @@ uint32 Mob::GetInstrumentMod(uint16 spell_id)
|
||||
Bard Spell Effects
|
||||
|
||||
Mod uses the highest bonus from either of these for each instrument
|
||||
SPA 179 SE_AllInstrumentMod is used for instrument spellbonus.______Mod. This applies to ALL instrument mods (Puretones Discipline)
|
||||
SPA 260 SE_AddSingingMod is used for instrument spellbonus.______Mod. This applies to indiviual instrument mods. (Instrument mastery AA)
|
||||
SPA 179 SpellEffect::AllInstrumentMod is used for instrument spellbonus.______Mod. This applies to ALL instrument mods (Puretones Discipline)
|
||||
SPA 260 SpellEffect::AddSingingMod is used for instrument spellbonus.______Mod. This applies to indiviual instrument mods. (Instrument mastery AA)
|
||||
-Example usage: From AA a value of 4 = 40%
|
||||
|
||||
SPA 118 SE_Amplification is a stackable singing mod, on live it exists as both spell and AA bonus (stackable)
|
||||
SPA 118 SpellEffect::Amplification is a stackable singing mod, on live it exists as both spell and AA bonus (stackable)
|
||||
- Live Behavior: Amplifcation can be modified by singing mods and amplification itself, thus on the second cast of Amplification you will recieve
|
||||
the mod from the first cast, this continues until you reach the song mod cap.
|
||||
|
||||
SPA 261 SE_SongModCap raises song focus cap (No longer used on live)
|
||||
SPA 270 SE_BardSongRange increase range of beneficial bard songs (Sionachie's Crescendo)
|
||||
SPA 261 SpellEffect::SongModCap raises song focus cap (No longer used on live)
|
||||
SPA 270 SpellEffect::BardSongRange increase range of beneficial bard songs (Sionachie's Crescendo)
|
||||
|
||||
SPA 413 SE_FcBaseEffects focus effect that replaced item instrument mods
|
||||
SPA 413 SpellEffect::FcBaseEffects focus effect that replaced item instrument mods
|
||||
|
||||
Issues 10-15-21:
|
||||
Bonuses are not applied, unless song is stopped and restarted due to pulse keeping it continues. -> Need to recode songs to recast when duration ends.
|
||||
|
||||
Formula Live Bards:
|
||||
mod = (10 + (aabonus.____Mod [SPA 260 AA Instrument Mastery]) + (SE_FcBaseEffect[SPA 413])/10 + (spellbonus.______Mod [SPA 179 Puretone Disc]) + (Amplication [SPA 118])/10
|
||||
mod = (10 + (aabonus.____Mod [SPA 260 AA Instrument Mastery]) + (SpellEffect::FcBaseEffect[SPA 413])/10 + (spellbonus.______Mod [SPA 179 Puretone Disc]) + (Amplication [SPA 118])/10
|
||||
|
||||
TODO: Spell Table Fields that need to be implemented
|
||||
Field 225 //float base_effects_focus_slope; // -- BASE_EFFECTS_FOCUS_SLOPE
|
||||
@ -1567,7 +1567,7 @@ uint32 Mob::GetInstrumentMod(uint16 spell_id)
|
||||
else
|
||||
effectmod = spellbonuses.singingMod;
|
||||
if (IsBardSong(spell_id))
|
||||
effectmod += aabonuses.singingMod + (spellbonuses.Amplification + itembonuses.Amplification + aabonuses.Amplification); //SPA 118 SE_Amplification
|
||||
effectmod += aabonuses.singingMod + (spellbonuses.Amplification + itembonuses.Amplification + aabonuses.Amplification); //SPA 118 SpellEffect::Amplification
|
||||
break;
|
||||
default:
|
||||
effectmod = 10;
|
||||
@ -1584,7 +1584,7 @@ uint32 Mob::GetInstrumentMod(uint16 spell_id)
|
||||
|
||||
if (effectmodcap) {
|
||||
|
||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap; //SPA 261 SE_SongModCap (not used on live)
|
||||
effectmodcap += aabonuses.songModCap + spellbonuses.songModCap + itembonuses.songModCap; //SPA 261 SpellEffect::SongModCap (not used on live)
|
||||
|
||||
//Incase a negative modifier is used.
|
||||
if (effectmodcap <= 0) {
|
||||
|
||||
@ -671,7 +671,7 @@ void Client::CompleteConnect()
|
||||
|
||||
for (int x1 = 0; x1 < EFFECT_COUNT; x1++) {
|
||||
switch (spell.effect_id[x1]) {
|
||||
case SE_Illusion: {
|
||||
case SpellEffect::Illusion: {
|
||||
if (GetIllusionBlock()) {
|
||||
break;
|
||||
}
|
||||
@ -682,41 +682,41 @@ void Client::CompleteConnect()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_SummonHorse: {
|
||||
case SpellEffect::SummonHorse: {
|
||||
if (RuleB(Character, PreventMountsFromZoning) || !zone->CanCastOutdoor()) {
|
||||
BuffFadeByEffect(SE_SummonHorse);
|
||||
BuffFadeByEffect(SpellEffect::SummonHorse);
|
||||
} else {
|
||||
SummonHorse(buffs[j1].spellid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SE_Silence:
|
||||
case SpellEffect::Silence:
|
||||
{
|
||||
Silence(true);
|
||||
break;
|
||||
}
|
||||
case SE_Amnesia:
|
||||
case SpellEffect::Amnesia:
|
||||
{
|
||||
Amnesia(true);
|
||||
break;
|
||||
}
|
||||
case SE_DivineAura:
|
||||
case SpellEffect::DivineAura:
|
||||
{
|
||||
invulnerable = true;
|
||||
break;
|
||||
}
|
||||
case SE_Invisibility2:
|
||||
case SE_Invisibility:
|
||||
case SpellEffect::Invisibility2:
|
||||
case SpellEffect::Invisibility:
|
||||
{
|
||||
SendAppearancePacket(AppearanceType::Invisibility, Invisibility::Invisible);
|
||||
break;
|
||||
}
|
||||
case SE_Levitate:
|
||||
case SpellEffect::Levitate:
|
||||
{
|
||||
if (!zone->CanLevitate()) {
|
||||
if (!GetGM()) {
|
||||
SendAppearancePacket(AppearanceType::FlyMode, 0);
|
||||
BuffFadeByEffect(SE_Levitate);
|
||||
BuffFadeByEffect(SpellEffect::Levitate);
|
||||
Message(Chat::Red, "You can't levitate in this zone.");
|
||||
break;
|
||||
}
|
||||
@ -737,18 +737,18 @@ void Client::CompleteConnect()
|
||||
|
||||
break;
|
||||
}
|
||||
case SE_AddMeleeProc:
|
||||
case SE_WeaponProc:
|
||||
case SpellEffect::AddMeleeProc:
|
||||
case SpellEffect::WeaponProc:
|
||||
{
|
||||
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, buffs[j1].casterlevel, GetSpellProcLimitTimer(buffs[j1].spellid, ProcType::MELEE_PROC));
|
||||
break;
|
||||
}
|
||||
case SE_DefensiveProc:
|
||||
case SpellEffect::DefensiveProc:
|
||||
{
|
||||
AddDefensiveProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, GetSpellProcLimitTimer(buffs[j1].spellid, ProcType::DEFENSIVE_PROC));
|
||||
break;
|
||||
}
|
||||
case SE_RangedProc:
|
||||
case SpellEffect::RangedProc:
|
||||
{
|
||||
AddRangedProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].limit_value[x1], buffs[j1].spellid, GetSpellProcLimitTimer(buffs[j1].spellid, ProcType::RANGED_PROC));
|
||||
break;
|
||||
@ -795,6 +795,11 @@ void Client::CompleteConnect()
|
||||
parse->EventPlayer(EVENT_ENTER_ZONE, this, "", 0);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_ENTER_ZONE)) {
|
||||
std::vector<std::any> args = { this };
|
||||
parse->EventZone(EVENT_ENTER_ZONE, zone, "", 0, &args);
|
||||
}
|
||||
|
||||
DeleteEntityVariable(SEE_BUFFS_FLAG);
|
||||
|
||||
// the way that the client deals with positions during the initial spawn struct
|
||||
@ -950,17 +955,17 @@ void Client::CompleteConnect()
|
||||
// TODO: load these states
|
||||
// We at least will set them to the correct state for now
|
||||
if (m_ClientVersionBit & EQ::versions::maskUFAndLater && GetPet()) {
|
||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Stop, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Regroup, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Follow, PetButtonState::On);
|
||||
SetPetCommandState(PetButton::Guard, PetButtonState::Off);
|
||||
// Taunt saved on client side for logging on with pet
|
||||
// In our db for when we zone.
|
||||
SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOCUS, 0);
|
||||
SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||
SetPetCommandState(PetButton::Hold, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::GreaterHold, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Focus, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::SpellHold, PetButtonState::Off);
|
||||
}
|
||||
|
||||
database.LoadAuras(this); // this ends up spawning them so probably safer to load this later (here)
|
||||
@ -1510,23 +1515,23 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
|
||||
switch (race)
|
||||
{
|
||||
case OGRE:
|
||||
case Race::Ogre:
|
||||
size = 9; break;
|
||||
case TROLL:
|
||||
case Race::Troll:
|
||||
size = 8; break;
|
||||
case VAHSHIR: case BARBARIAN:
|
||||
case Race::VahShir: case Race::Barbarian:
|
||||
size = 7; break;
|
||||
case HUMAN: case HIGH_ELF: case ERUDITE: case IKSAR: case DRAKKIN:
|
||||
case Race::Human: case Race::HighElf: case Race::Erudite: case Race::Iksar: case Race::Drakkin:
|
||||
size = 6; break;
|
||||
case HALF_ELF:
|
||||
case Race::HalfElf:
|
||||
size = 5.5; break;
|
||||
case WOOD_ELF: case DARK_ELF: case FROGLOK:
|
||||
case Race::WoodElf: case Race::DarkElf: case Race::Froglok2:
|
||||
size = 5; break;
|
||||
case DWARF:
|
||||
case Race::Dwarf:
|
||||
size = 4; break;
|
||||
case HALFLING:
|
||||
case Race::Halfling:
|
||||
size = 3.5; break;
|
||||
case GNOME:
|
||||
case Race::Gnome:
|
||||
size = 3; break;
|
||||
default:
|
||||
size = 0;
|
||||
@ -1708,7 +1713,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if (zone->IsPVPZone())
|
||||
m_pp.pvp = 1;
|
||||
/* Time entitled on Account: Move to account */
|
||||
m_pp.timeentitledonaccount = database.GetTotalTimeEntitledOnAccount(AccountID()) / 1440;
|
||||
m_pp.timeentitledonaccount = CharacterDataRepository::GetTotalTimePlayed(database, AccountID()) / 1440;
|
||||
/* Reset rest timer if the durations have been lowered in the database */
|
||||
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
|
||||
m_pp.RestTimer = 0;
|
||||
@ -4254,7 +4259,7 @@ void Client::Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app)
|
||||
|
||||
uint16 SpellID = m->GetSpellIDFromSlot(brrs->SlotID);
|
||||
|
||||
if (SpellID && (GetGM() || ((IsBeneficialSpell(SpellID) || IsEffectInSpell(SpellID, SE_BindSight)) && !spells[SpellID].no_remove))) {
|
||||
if (SpellID && (GetGM() || ((IsBeneficialSpell(SpellID) || IsEffectInSpell(SpellID, SpellEffect::BindSight)) && !spells[SpellID].no_remove))) {
|
||||
m->BuffFadeBySlot(brrs->SlotID, true);
|
||||
}
|
||||
}
|
||||
@ -4709,6 +4714,12 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app)
|
||||
quest_return = parse->EventPlayer(EVENT_CLICK_DOOR, this, std::to_string(cd->doorid), 0, &args);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_CLICK_DOOR)) {
|
||||
std::vector<std::any> args = { currentdoor, this };
|
||||
|
||||
quest_return = parse->EventZone(EVENT_CLICK_DOOR, zone, std::to_string(cd->doorid), 0, &args);
|
||||
}
|
||||
|
||||
if (quest_return == 0) {
|
||||
currentdoor->HandleClick(this, 0);
|
||||
}
|
||||
@ -4741,6 +4752,11 @@ void Client::Handle_OP_ClickObject(const EQApplicationPacket *app)
|
||||
parse->EventPlayer(EVENT_CLICK_OBJECT, this, std::to_string(click_object->drop_id), GetID(), &args);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_CLICK_OBJECT)) {
|
||||
std::vector<std::any> args = { object, this };
|
||||
parse->EventZone(EVENT_CLICK_OBJECT, zone, std::to_string(click_object->drop_id), GetID(), &args);
|
||||
}
|
||||
|
||||
if (IsDevToolsEnabled()) {
|
||||
SetObjectToolEntityId(entity->GetID());
|
||||
ObjectManipulation::CommandHeader(this);
|
||||
@ -4967,9 +4983,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
m_Proximity = glm::vec3(cx, cy, cz);
|
||||
}
|
||||
|
||||
/* Update internal state */
|
||||
m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading));
|
||||
|
||||
if (RuleB(Skills, TrackingAutoRefreshSkillUps) && IsTracking() && ((m_Position.x != cx) || (m_Position.y != cy))) {
|
||||
if (zone->random.Real(0, 100) < 70)//should be good
|
||||
CheckIncreaseSkill(EQ::skills::SkillTracking, nullptr, -20);
|
||||
@ -5003,6 +5016,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
rewind_timer.Start(30000, true);
|
||||
}
|
||||
|
||||
glm::vec4 prevDelta = m_Delta; // SetMoving clears m_Delta
|
||||
SetMoving(!(cy == m_Position.y && cx == m_Position.x));
|
||||
|
||||
if (RuleB(Character, EnableAutoAFK)) {
|
||||
@ -5017,12 +5031,13 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
|
||||
CheckSendBulkNpcPositions();
|
||||
|
||||
int32 new_animation = ppu->animation;
|
||||
|
||||
/* Update internal server position from what the client has sent */
|
||||
m_Position.x = cx;
|
||||
m_Position.y = cy;
|
||||
m_Position.z = cz;
|
||||
glm::vec4 prevPosition = m_Position;
|
||||
m_Position = glm::vec4(cx, cy, cz, new_heading);
|
||||
m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading));
|
||||
int32 prevAnimation = ppu->animation;
|
||||
animation = ppu->animation;
|
||||
bool positionUpdated = m_Position != prevPosition || m_Delta != prevDelta || m_Delta != glm::vec4(0.0f) || prevAnimation != animation;
|
||||
|
||||
/* Visual Debugging */
|
||||
if (RuleB(Character, OPClientUpdateVisualDebug)) {
|
||||
@ -5032,11 +5047,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
/* Only feed real time updates when client is moving */
|
||||
if (IsMoving() || new_heading != m_Position.w || new_animation != animation) {
|
||||
|
||||
animation = ppu->animation;
|
||||
m_Position.w = new_heading;
|
||||
|
||||
if (positionUpdated) {
|
||||
/* Broadcast update to other clients */
|
||||
static EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct *position_update = (PlayerPositionUpdateServer_Struct *) outapp.pBuffer;
|
||||
@ -5049,7 +5060,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
entity_list.QueueCloseClients(this, &outapp, true, RuleI(Range, ClientPositionUpdates), nullptr, true);
|
||||
}
|
||||
|
||||
|
||||
/* Always send position updates to group - send when beyond normal ClientPositionUpdate range */
|
||||
Group *group = GetGroup();
|
||||
Raid *raid = GetRaid();
|
||||
@ -5068,14 +5078,13 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
// Dismount horses when entering water
|
||||
if (GetHorseId() && RuleB(Character, DismountWater)) {
|
||||
SetHorseId(0);
|
||||
BuffFadeByEffect(SE_SummonHorse);
|
||||
BuffFadeByEffect(SpellEffect::SummonHorse);
|
||||
}
|
||||
}
|
||||
CheckRegionTypeChanges();
|
||||
}
|
||||
|
||||
CheckVirtualZoneLines();
|
||||
|
||||
}
|
||||
|
||||
void Client::Handle_OP_CombatAbility(const EQApplicationPacket *app)
|
||||
@ -7979,7 +7988,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app)
|
||||
|
||||
if ((Admin() < RuleI(Guild, PlayerCreationRequiredStatus)) ||
|
||||
(GetLevel() < RuleI(Guild, PlayerCreationRequiredLevel)) ||
|
||||
(database.GetTotalTimeEntitledOnAccount(AccountID()) < (unsigned int)RuleI(Guild, PlayerCreationRequiredTime)))
|
||||
(CharacterDataRepository::GetTotalTimePlayed(database, AccountID()) < (unsigned int)RuleI(Guild, PlayerCreationRequiredTime)))
|
||||
{
|
||||
Message(Chat::Red, "Your status, level or time playing on this account are insufficient to use this feature.");
|
||||
return;
|
||||
@ -9773,7 +9782,7 @@ void Client::Handle_OP_Jump(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_OP_KeyRing(const EQApplicationPacket *app)
|
||||
{
|
||||
KeyRingList();
|
||||
KeyRingList(this);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_KickPlayers(const EQApplicationPacket *app)
|
||||
@ -11064,6 +11073,7 @@ void Client::Handle_OP_PDeletePetition(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != sizeof(PetCommand_Struct)) {
|
||||
@ -11254,7 +11264,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
// eqlive ignores this command
|
||||
// we could just remove the charm
|
||||
// and continue
|
||||
mypet->BuffFadeByEffect(SE_Charm);
|
||||
mypet->BuffFadeByEffect(SpellEffect::Charm);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@ -11721,7 +11731,6 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Client::Handle_OP_Petition(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size <= 1)
|
||||
@ -12042,6 +12051,11 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
|
||||
parse->EventPlayer(EVENT_POPUP_RESPONSE, this, std::to_string(popup_response->popupid), 0);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_POPUP_RESPONSE)) {
|
||||
std::vector<std::any> args = { this };
|
||||
parse->EventZone(EVENT_POPUP_RESPONSE, zone, std::to_string(popup_response->popupid), 0, &args);
|
||||
}
|
||||
|
||||
auto t = GetTarget();
|
||||
if (t) {
|
||||
parse->EventBotMercNPC(EVENT_POPUP_RESPONSE, t, this, [&]() { return std::to_string(popup_response->popupid); });
|
||||
@ -13973,7 +13987,7 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app)
|
||||
Recast is 3 minutes.
|
||||
|
||||
For custom use cases, Mob::ShieldAbility can be used in quests with all parameters being altered. This functional
|
||||
is also used for SPA 201 SE_PetShield, which functions in a simalar manner with pet shielding owner.
|
||||
is also used for SPA 201 SpellEffect::PetShield, which functions in a simalar manner with pet shielding owner.
|
||||
|
||||
Note: If either the shielder or the shield target die all variables are reset on both.
|
||||
|
||||
@ -15735,7 +15749,7 @@ void Client::Handle_OP_TradeSkillRecipeInspect(const EQApplicationPacket* app)
|
||||
const auto& v = TradeskillRecipeEntriesRepository::GetWhere(
|
||||
content_db,
|
||||
fmt::format(
|
||||
"`recipe_id` = {} AND `componentcount` = 0 AND `successcount` > 0 LIMIT 1",
|
||||
"`recipe_id` = {} AND `componentcount` = 0 AND `successcount` > 0 ORDER BY `id` ASC LIMIT 1",
|
||||
s->recipe_id
|
||||
)
|
||||
);
|
||||
@ -16804,6 +16818,7 @@ void Client::RecordStats()
|
||||
r.endurance_regen = GetEnduranceRegen() - GetSpellBonuses().EnduranceRegen;
|
||||
r.shielding = GetShielding() - GetSpellBonuses().MeleeMitigation;
|
||||
r.spell_damage = GetSpellDmg() - GetSpellBonuses().SpellDmg;
|
||||
r.heal_amount = GetHealAmt() - GetSpellBonuses().HealAmt;
|
||||
r.spell_shielding = GetSpellShield() - GetSpellBonuses().SpellShield;
|
||||
r.strikethrough = GetStrikeThrough() - GetSpellBonuses().StrikeThrough;
|
||||
r.stun_resist = GetStunResist() - GetSpellBonuses().StunResist;
|
||||
|
||||
@ -561,6 +561,10 @@ bool Client::Process() {
|
||||
{
|
||||
ItemTimerCheck();
|
||||
}
|
||||
|
||||
if (m_clear_wearchange_cache_timer.Check()) {
|
||||
m_last_seen_wearchange.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1567,7 +1571,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
|
||||
if (from_bucket == &m_pp.platinum_shared)
|
||||
amount_to_add = 0 - amount_to_take;
|
||||
|
||||
database.SetSharedPlatinum(AccountID(),amount_to_add);
|
||||
database.AddSharedPlatinum(AccountID(),amount_to_add);
|
||||
}
|
||||
}
|
||||
else{
|
||||
@ -1644,7 +1648,7 @@ void Client::OPGMTraining(const EQApplicationPacket *app)
|
||||
//#pragma GCC push_options
|
||||
//#pragma GCC optimize ("O0")
|
||||
for (int sk = EQ::skills::Skill1HBlunt; sk <= EQ::skills::HIGHEST_SKILL; ++sk) {
|
||||
if (sk == EQ::skills::SkillTinkering && GetRace() != GNOME) {
|
||||
if (sk == EQ::skills::SkillTinkering && GetRace() != Race::Gnome) {
|
||||
gmtrain->skills[sk] = 0; //Non gnomes can't tinker!
|
||||
} else {
|
||||
gmtrain->skills[sk] = GetMaxSkillAfterSpecializationRules((EQ::skills::SkillType)sk, MaxSkill((EQ::skills::SkillType)sk, GetClass(), RuleI(Character, MaxLevel)));
|
||||
|
||||
210
zone/common.h
210
zone/common.h
@ -3,6 +3,7 @@
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/emu_constants.h"
|
||||
|
||||
#include <cereal/cereal.hpp>
|
||||
|
||||
@ -45,55 +46,6 @@ namespace Archetype {
|
||||
//Maximum distance from a zone point if zone was specified
|
||||
#define ZONEPOINT_ZONE_RANGE 40000.0f
|
||||
|
||||
// Defines based on the RoF2 Client
|
||||
#define PET_HEALTHREPORT 0 // 0x00 - /pet health or Pet Window
|
||||
#define PET_LEADER 1 // 0x01 - /pet leader or Pet Window
|
||||
#define PET_ATTACK 2 // 0x02 - /pet attack or Pet Window
|
||||
#define PET_QATTACK 3 // 0x03 - /pet qattack or Pet Window
|
||||
#define PET_FOLLOWME 4 // 0x04 - /pet follow or Pet Window
|
||||
#define PET_GUARDHERE 5 // 0x05 - /pet guard or Pet Window
|
||||
#define PET_SIT 6 // 0x06 - /pet sit or Pet Window
|
||||
#define PET_SITDOWN 7 // 0x07 - /pet sit on
|
||||
#define PET_STANDUP 8 // 0x08 - /pet sit off
|
||||
#define PET_STOP 9 // 0x09 - /pet stop or Pet Window - Not implemented
|
||||
#define PET_STOP_ON 10 // 0x0a - /pet stop on - Not implemented
|
||||
#define PET_STOP_OFF 11 // 0x0b - /pet stop off - Not implemented
|
||||
#define PET_TAUNT 12 // 0x0c - /pet taunt or Pet Window
|
||||
#define PET_TAUNT_ON 13 // 0x0d - /pet taunt on
|
||||
#define PET_TAUNT_OFF 14 // 0x0e - /pet taunt off
|
||||
#define PET_HOLD 15 // 0x0f - /pet hold or Pet Window, won't add to hate list unless attacking
|
||||
#define PET_HOLD_ON 16 // 0x10 - /pet hold on
|
||||
#define PET_HOLD_OFF 17 // 0x11 - /pet hold off
|
||||
#define PET_GHOLD 18 // 0x12 - /pet ghold, will never add to hate list unless told to
|
||||
#define PET_GHOLD_ON 19 // 0x13 - /pet ghold on
|
||||
#define PET_GHOLD_OFF 20 // 0x14 - /pet ghold off
|
||||
#define PET_SPELLHOLD 21 // 0x15 - /pet no cast or /pet spellhold or Pet Window
|
||||
#define PET_SPELLHOLD_ON 22 // 0x16 - /pet spellhold on
|
||||
#define PET_SPELLHOLD_OFF 23 // 0x17 - /pet spellhold off
|
||||
#define PET_FOCUS 24 // 0x18 - /pet focus or Pet Window
|
||||
#define PET_FOCUS_ON 25 // 0x19 - /pet focus on
|
||||
#define PET_FOCUS_OFF 26 // 0x1a - /pet focus off
|
||||
#define PET_FEIGN 27 // 0x1b - /pet feign
|
||||
#define PET_BACKOFF 28 // 0x1c - /pet back off
|
||||
#define PET_GETLOST 29 // 0x1d - /pet get lost
|
||||
#define PET_GUARDME 30 // 0x1e - Same as /pet follow, but different message in older clients - define not from client /pet target in modern clients but doesn't send packet
|
||||
#define PET_REGROUP 31 // 0x1f - /pet regroup, acts like classic hold. Stops attack and moves back to guard/you but doesn't clear hate list
|
||||
#define PET_REGROUP_ON 32 // 0x20 - /pet regroup on, turns on regroup
|
||||
#define PET_REGROUP_OFF 33 // 0x21 - /pet regroup off, turns off regroup
|
||||
#define PET_MAXCOMMANDS PET_REGROUP_OFF + 1
|
||||
|
||||
// can change the state of these buttons with a packet
|
||||
#define PET_BUTTON_SIT 0
|
||||
#define PET_BUTTON_STOP 1
|
||||
#define PET_BUTTON_REGROUP 2
|
||||
#define PET_BUTTON_FOLLOW 3
|
||||
#define PET_BUTTON_GUARD 4
|
||||
#define PET_BUTTON_TAUNT 5
|
||||
#define PET_BUTTON_HOLD 6
|
||||
#define PET_BUTTON_GHOLD 7
|
||||
#define PET_BUTTON_FOCUS 8
|
||||
#define PET_BUTTON_SPELLHOLD 9
|
||||
|
||||
#define AURA_HARDCAP 2
|
||||
#define WEAPON_STANCE_TYPE_MAX 2
|
||||
|
||||
@ -101,50 +53,50 @@ namespace Archetype {
|
||||
#define SHIELD_ABILITY_RECAST_TIME 180
|
||||
|
||||
typedef enum { //focus types
|
||||
focusSpellHaste = 1, //@Fc, SPA: 127, SE_IncreaseSpellHaste, On Caster, cast time mod pct, base: pct
|
||||
focusSpellDuration, //@Fc, SPA: 128, SE_IncreaseSpellDuration, On Caster, spell duration mod pct, base: pct
|
||||
focusRange, //@Fc, SPA: 129, SE_IncreaseRange, On Caster, spell range mod pct, base: pct
|
||||
focusReagentCost, //@Fc, SPA: 131, SE_ReduceReagentCost, On Caster, do not consume reagent pct chance, base: min pct, limit: max pct
|
||||
focusManaCost, //@Fc, SPA: 132, SE_ReduceManaCost, On Caster, reduce mana cost by pct, base: min pct, limt: max pct
|
||||
focusImprovedHeal, //@Fc, SPA: 125, SE_ImprovedHeal, On Caster, spell healing mod pct, base: min pct, limit: max pct
|
||||
focusImprovedDamage, //@Fc, SPA: 124, SE_ImprovedDamage, On Caster, spell damage mod pct, base: min pct, limit: max pct
|
||||
focusImprovedDamage2, //@Fc, SPA: 461, SE_ImprovedDamage2, On Caster, spell damage mod pct, base: min pct, limit: max pct
|
||||
focusFcDamagePctCrit, //@Fc, SPA: 302, SE_FcDamagePctCrit, On Caster, spell damage mod pct, base: min pct, limit: max pct
|
||||
focusPetPower, //@Fc, SPA: 167, SE_PetPowerIncrease, On Caster, pet power mod, base: value
|
||||
focusResistRate, //@Fc, SPA: 126, SE_SpellResistReduction, On Caster, casted spell resist mod pct, base: min pct, limit: max pct
|
||||
focusSpellHateMod, //@Fc, SPA: 130, SE_SpellHateMod, On Caster, spell hate mod pct, base: min pct, limit: max pct
|
||||
focusTriggerOnCast, //@Fc, SPA: 339, SE_TriggerOnCast, On Caster, cast on spell use, base: chance pct limit: spellid
|
||||
focusSpellVulnerability, //@Fc, SPA: 296, SE_FcSpellVulnerability, On Target, spell damage taken mod pct, base: min pct, limit: max pct
|
||||
focusFcSpellDamagePctIncomingPC, //@Fc, SPA: 483, SE_Fc_Spell_Damage_Pct_IncomingPC, On Target, spell damage taken mod pct, base: min pct, limit: max pct
|
||||
focusTwincast, //@Fc, SPA: 399, SE_FcTwincast, On Caster, chance cast spell twice, base: chance pct
|
||||
focusSympatheticProc, //@Fc, SPA: 383, SE_SympatheticProc, On Caster, cast on spell use, base: variable proc chance on cast time, limit: spellid
|
||||
focusFcDamageAmt, //@Fc, SPA: 286, SE_FcDamageAmt, On Caster, spell damage mod flat amt, base: amt
|
||||
focusFcDamageAmt2, //@Fc, SPA: 462, SE_FcDamageAmt2, On Caster, spell damage mod flat amt, base: amt
|
||||
focusFcDamageAmtCrit, //@Fc, SPA: 303, SE_FFcDamageAmtCrit, On Caster, spell damage mod flat amt, base: amt
|
||||
focusSpellDurByTic, //@Fc, SPA: 287, SE_SpellDurationIncByTic, On Caster, spell buff duration mod, base: tics
|
||||
focusSwarmPetDuration, //@Fc, SPA: 398, SE_SwarmPetDuration, On Caster, swarm pet duration mod, base: milliseconds
|
||||
focusReduceRecastTime, //@Fc, SPA: 310, SE_ReduceReuseTimer, On Caster, disc reuse time mod, base: milliseconds
|
||||
focusBlockNextSpell, //@Fc, SPA: 335, SE_BlockNextSpellFocus, On Caster, chance to block next spell, base: chance
|
||||
focusFcHealPctIncoming, //@Fc, SPA: 393, SE_FcHealPctIncoming, On Target, heal received mod pct, base: pct
|
||||
focusFcDamageAmtIncoming, //@Fc, SPA: 297, SE_FcDamageAmtIncoming, On Target, damage taken flat amt, base: amt
|
||||
focusFcSpellDamageAmtIncomingPC, //@Fc, SPA: 484, SE_Fc_Spell_Damage_Amt_IncomingPC, On Target, damage taken flat amt, base: amt
|
||||
focusFcCastSpellOnLand, //@Fc, SPA: 481, SE_Fc_Cast_Spell_On_Land, On Target, cast spell if hit by spell, base: chance pct, limit: spellid
|
||||
focusFcHealAmtIncoming, //@Fc, SPA: 394, SE_FcHealAmtIncoming, On Target, heal received mod flat amt, base: amt
|
||||
focusFcBaseEffects, //@Fc, SPA: 413, SE_FcBaseEffects, On Caster, base spell effectiveness mod pct, base: pct
|
||||
focusIncreaseNumHits, //@Fc, SPA: 421, SE_FcIncreaseNumHits, On Caster, numhits mod flat amt, base: amt
|
||||
focusFcLimitUse, //@Fc, SPA: 420, SE_FcLimitUse, On Caster, numhits mod pct, base: pct
|
||||
focusFcMute, //@Fc, SPA: 357, SE_FcMute, On Caster, prevents spell casting, base: chance pct
|
||||
focusFcTimerRefresh, //@Fc, SPA: 389, SE_FcTimerRefresh, On Caster, reset spell recast timer, base: 1
|
||||
focusFcTimerLockout, //@Fc, SPA: 390, SE_FcTimerLockout, On Caster, set a spell to be on recast timer, base: recast duration milliseconds
|
||||
focusFcStunTimeMod, //@Fc, SPA: 133, SE_FcStunTimeMod, On Caster, stun time mod pct, base: chance pct
|
||||
focusFcResistIncoming, //@Fc, SPA: 510, SE_Fc_Resist_Incoming, On Target, resist modifier, base: amt
|
||||
focusFcAmplifyMod, //@Fc, SPA: 507, SE_Fc_Amplify_Mod, On Caster, damage-heal-dot mod pct, base: pct
|
||||
focusFcAmplifyAmt, //@Fc, SPA: 508, SE_Fc_Amplify_Amt, On Caster, damage-heal-dot mod flat amt, base: amt
|
||||
focusFcCastTimeMod2, //@Fc, SPA: 500, SE_Fc_CastTimeMod2, On Caster, cast time mod pct, base: pct
|
||||
focusFcCastTimeAmt, //@Fc, SPA: 501, SE_Fc_CastTimeAmt, On Caster, cast time mod flat amt, base: milliseconds
|
||||
focusFcHealPctCritIncoming, //@Fc, SPA: 395, SE_FcHealPctCritIncoming, On Target, spell healing mod pct, base: pct
|
||||
focusFcHealAmt, //@Fc, SPA: 392, SE_FcHealAmt, On Caster, spell healing mod flat amt, base: amt
|
||||
focusFcHealAmtCrit, //@Fc, SPA: 396, SE_FcHealAmtCrit, On Caster, spell healing mod flat amt, base: amt
|
||||
focusSpellHaste = 1, //@Fc, SPA: 127, SpellEffect::IncreaseSpellHaste, On Caster, cast time mod pct, base: pct
|
||||
focusSpellDuration, //@Fc, SPA: 128, SpellEffect::IncreaseSpellDuration, On Caster, spell duration mod pct, base: pct
|
||||
focusRange, //@Fc, SPA: 129, SpellEffect::IncreaseRange, On Caster, spell range mod pct, base: pct
|
||||
focusReagentCost, //@Fc, SPA: 131, SpellEffect::ReduceReagentCost, On Caster, do not consume reagent pct chance, base: min pct, limit: max pct
|
||||
focusManaCost, //@Fc, SPA: 132, SpellEffect::ReduceManaCost, On Caster, reduce mana cost by pct, base: min pct, limt: max pct
|
||||
focusImprovedHeal, //@Fc, SPA: 125, SpellEffect::ImprovedHeal, On Caster, spell healing mod pct, base: min pct, limit: max pct
|
||||
focusImprovedDamage, //@Fc, SPA: 124, SpellEffect::ImprovedDamage, On Caster, spell damage mod pct, base: min pct, limit: max pct
|
||||
focusImprovedDamage2, //@Fc, SPA: 461, SpellEffect::ImprovedDamage2, On Caster, spell damage mod pct, base: min pct, limit: max pct
|
||||
focusFcDamagePctCrit, //@Fc, SPA: 302, SpellEffect::FcDamagePctCrit, On Caster, spell damage mod pct, base: min pct, limit: max pct
|
||||
focusPetPower, //@Fc, SPA: 167, SpellEffect::PetPowerIncrease, On Caster, pet power mod, base: value
|
||||
focusResistRate, //@Fc, SPA: 126, SpellEffect::SpellResistReduction, On Caster, casted spell resist mod pct, base: min pct, limit: max pct
|
||||
focusSpellHateMod, //@Fc, SPA: 130, SpellEffect::SpellHateMod, On Caster, spell hate mod pct, base: min pct, limit: max pct
|
||||
focusTriggerOnCast, //@Fc, SPA: 339, SpellEffect::TriggerOnCast, On Caster, cast on spell use, base: chance pct limit: spellid
|
||||
focusSpellVulnerability, //@Fc, SPA: 296, SpellEffect::FcSpellVulnerability, On Target, spell damage taken mod pct, base: min pct, limit: max pct
|
||||
focusFcSpellDamagePctIncomingPC, //@Fc, SPA: 483, SpellEffect::Fc_Spell_Damage_Pct_IncomingPC, On Target, spell damage taken mod pct, base: min pct, limit: max pct
|
||||
focusTwincast, //@Fc, SPA: 399, SpellEffect::FcTwincast, On Caster, chance cast spell twice, base: chance pct
|
||||
focusSympatheticProc, //@Fc, SPA: 383, SpellEffect::SympatheticProc, On Caster, cast on spell use, base: variable proc chance on cast time, limit: spellid
|
||||
focusFcDamageAmt, //@Fc, SPA: 286, SpellEffect::FcDamageAmt, On Caster, spell damage mod flat amt, base: amt
|
||||
focusFcDamageAmt2, //@Fc, SPA: 462, SpellEffect::FcDamageAmt2, On Caster, spell damage mod flat amt, base: amt
|
||||
focusFcDamageAmtCrit, //@Fc, SPA: 303, SpellEffect::FFcDamageAmtCrit, On Caster, spell damage mod flat amt, base: amt
|
||||
focusSpellDurByTic, //@Fc, SPA: 287, SpellEffect::SpellDurationIncByTic, On Caster, spell buff duration mod, base: tics
|
||||
focusSwarmPetDuration, //@Fc, SPA: 398, SpellEffect::SwarmPetDuration, On Caster, swarm pet duration mod, base: milliseconds
|
||||
focusReduceRecastTime, //@Fc, SPA: 310, SpellEffect::ReduceReuseTimer, On Caster, disc reuse time mod, base: milliseconds
|
||||
focusBlockNextSpell, //@Fc, SPA: 335, SpellEffect::BlockNextSpellFocus, On Caster, chance to block next spell, base: chance
|
||||
focusFcHealPctIncoming, //@Fc, SPA: 393, SpellEffect::FcHealPctIncoming, On Target, heal received mod pct, base: pct
|
||||
focusFcDamageAmtIncoming, //@Fc, SPA: 297, SpellEffect::FcDamageAmtIncoming, On Target, damage taken flat amt, base: amt
|
||||
focusFcSpellDamageAmtIncomingPC, //@Fc, SPA: 484, SpellEffect::Fc_Spell_Damage_Amt_IncomingPC, On Target, damage taken flat amt, base: amt
|
||||
focusFcCastSpellOnLand, //@Fc, SPA: 481, SpellEffect::Fc_Cast_Spell_On_Land, On Target, cast spell if hit by spell, base: chance pct, limit: spellid
|
||||
focusFcHealAmtIncoming, //@Fc, SPA: 394, SpellEffect::FcHealAmtIncoming, On Target, heal received mod flat amt, base: amt
|
||||
focusFcBaseEffects, //@Fc, SPA: 413, SpellEffect::FcBaseEffects, On Caster, base spell effectiveness mod pct, base: pct
|
||||
focusIncreaseNumHits, //@Fc, SPA: 421, SpellEffect::FcIncreaseNumHits, On Caster, numhits mod flat amt, base: amt
|
||||
focusFcLimitUse, //@Fc, SPA: 420, SpellEffect::FcLimitUse, On Caster, numhits mod pct, base: pct
|
||||
focusFcMute, //@Fc, SPA: 357, SpellEffect::FcMute, On Caster, prevents spell casting, base: chance pct
|
||||
focusFcTimerRefresh, //@Fc, SPA: 389, SpellEffect::FcTimerRefresh, On Caster, reset spell recast timer, base: 1
|
||||
focusFcTimerLockout, //@Fc, SPA: 390, SpellEffect::FcTimerLockout, On Caster, set a spell to be on recast timer, base: recast duration milliseconds
|
||||
focusFcStunTimeMod, //@Fc, SPA: 133, SpellEffect::FcStunTimeMod, On Caster, stun time mod pct, base: chance pct
|
||||
focusFcResistIncoming, //@Fc, SPA: 510, SpellEffect::Fc_Resist_Incoming, On Target, resist modifier, base: amt
|
||||
focusFcAmplifyMod, //@Fc, SPA: 507, SpellEffect::Fc_Amplify_Mod, On Caster, damage-heal-dot mod pct, base: pct
|
||||
focusFcAmplifyAmt, //@Fc, SPA: 508, SpellEffect::Fc_Amplify_Amt, On Caster, damage-heal-dot mod flat amt, base: amt
|
||||
focusFcCastTimeMod2, //@Fc, SPA: 500, SpellEffect::Fc_CastTimeMod2, On Caster, cast time mod pct, base: pct
|
||||
focusFcCastTimeAmt, //@Fc, SPA: 501, SpellEffect::Fc_CastTimeAmt, On Caster, cast time mod flat amt, base: milliseconds
|
||||
focusFcHealPctCritIncoming, //@Fc, SPA: 395, SpellEffect::FcHealPctCritIncoming, On Target, spell healing mod pct, base: pct
|
||||
focusFcHealAmt, //@Fc, SPA: 392, SpellEffect::FcHealAmt, On Caster, spell healing mod flat amt, base: amt
|
||||
focusFcHealAmtCrit, //@Fc, SPA: 396, SpellEffect::FcHealAmtCrit, On Caster, spell healing mod flat amt, base: amt
|
||||
} focusType; //Any new FocusType needs to be added to the Mob::IsFocus function
|
||||
#define HIGHEST_FOCUS focusFcHealAmtCrit //Should always be last focusType in enum
|
||||
|
||||
@ -617,7 +569,7 @@ struct StatBonuses {
|
||||
uint8 TradeSkillMastery; // Allow number of tradeskills to exceed 200 skill.
|
||||
int16 NoBreakAESneak; // Percent value
|
||||
int16 FeignedCastOnChance; // Percent Value
|
||||
bool PetCommands[PET_MAXCOMMANDS]; // SPA 267
|
||||
bool PetCommands[PetCommand::Max]; // SPA 267
|
||||
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
||||
int GrantForage; // affects max skill of forage as well as granting non-forage classes forage
|
||||
int aura_slots;
|
||||
@ -781,16 +733,6 @@ enum {
|
||||
GridRandomPath
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
petFamiliar, //only listens to /pet get lost
|
||||
petAnimation, //does not listen to any commands
|
||||
petOther,
|
||||
petCharmed,
|
||||
petNPCFollow,
|
||||
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
||||
petNone = 0xFF // not a pet
|
||||
} PetType;
|
||||
|
||||
typedef enum {
|
||||
SingleTarget, // causes effect to spell_target
|
||||
AETarget, // causes effect in aerange of target + target
|
||||
@ -912,6 +854,66 @@ struct DataBucketCache
|
||||
uint32_t bucket_expires;
|
||||
};
|
||||
|
||||
// Defines based on the RoF2 Client
|
||||
#define PET_HEALTHREPORT 0 // 0x00 - /pet health or Pet Window
|
||||
#define PET_LEADER 1 // 0x01 - /pet leader or Pet Window
|
||||
#define PET_ATTACK 2 // 0x02 - /pet attack or Pet Window
|
||||
#define PET_QATTACK 3 // 0x03 - /pet qattack or Pet Window
|
||||
#define PET_FOLLOWME 4 // 0x04 - /pet follow or Pet Window
|
||||
#define PET_GUARDHERE 5 // 0x05 - /pet guard or Pet Window
|
||||
#define PET_SIT 6 // 0x06 - /pet sit or Pet Window
|
||||
#define PET_SITDOWN 7 // 0x07 - /pet sit on
|
||||
#define PET_STANDUP 8 // 0x08 - /pet sit off
|
||||
#define PET_STOP 9 // 0x09 - /pet stop or Pet Window - Not implemented
|
||||
#define PET_STOP_ON 10 // 0x0a - /pet stop on - Not implemented
|
||||
#define PET_STOP_OFF 11 // 0x0b - /pet stop off - Not implemented
|
||||
#define PET_TAUNT 12 // 0x0c - /pet taunt or Pet Window
|
||||
#define PET_TAUNT_ON 13 // 0x0d - /pet taunt on
|
||||
#define PET_TAUNT_OFF 14 // 0x0e - /pet taunt off
|
||||
#define PET_HOLD 15 // 0x0f - /pet hold or Pet Window, won't add to hate list unless attacking
|
||||
#define PET_HOLD_ON 16 // 0x10 - /pet hold on
|
||||
#define PET_HOLD_OFF 17 // 0x11 - /pet hold off
|
||||
#define PET_GHOLD 18 // 0x12 - /pet ghold, will never add to hate list unless told to
|
||||
#define PET_GHOLD_ON 19 // 0x13 - /pet ghold on
|
||||
#define PET_GHOLD_OFF 20 // 0x14 - /pet ghold off
|
||||
#define PET_SPELLHOLD 21 // 0x15 - /pet no cast or /pet spellhold or Pet Window
|
||||
#define PET_SPELLHOLD_ON 22 // 0x16 - /pet spellhold on
|
||||
#define PET_SPELLHOLD_OFF 23 // 0x17 - /pet spellhold off
|
||||
#define PET_FOCUS 24 // 0x18 - /pet focus or Pet Window
|
||||
#define PET_FOCUS_ON 25 // 0x19 - /pet focus on
|
||||
#define PET_FOCUS_OFF 26 // 0x1a - /pet focus off
|
||||
#define PET_FEIGN 27 // 0x1b - /pet feign
|
||||
#define PET_BACKOFF 28 // 0x1c - /pet back off
|
||||
#define PET_GETLOST 29 // 0x1d - /pet get lost
|
||||
#define PET_GUARDME 30 // 0x1e - Same as /pet follow, but different message in older clients - define not from client /pet target in modern clients but doesn't send packet
|
||||
#define PET_REGROUP 31 // 0x1f - /pet regroup, acts like classic hold. Stops attack and moves back to guard/you but doesn't clear hate list
|
||||
#define PET_REGROUP_ON 32 // 0x20 - /pet regroup on, turns on regroup
|
||||
#define PET_REGROUP_OFF 33 // 0x21 - /pet regroup off, turns off regroup
|
||||
#define PET_MAXCOMMANDS PET_REGROUP_OFF + 1
|
||||
|
||||
// can change the state of these buttons with a packet
|
||||
#define PET_BUTTON_SIT 0
|
||||
#define PET_BUTTON_STOP 1
|
||||
#define PET_BUTTON_REGROUP 2
|
||||
#define PET_BUTTON_FOLLOW 3
|
||||
#define PET_BUTTON_GUARD 4
|
||||
#define PET_BUTTON_TAUNT 5
|
||||
#define PET_BUTTON_HOLD 6
|
||||
#define PET_BUTTON_GHOLD 7
|
||||
#define PET_BUTTON_FOCUS 8
|
||||
#define PET_BUTTON_SPELLHOLD 9
|
||||
|
||||
enum eStandingPetOrder { SPO_Follow, SPO_Sit, SPO_Guard, SPO_FeignDeath };
|
||||
|
||||
typedef enum {
|
||||
petFamiliar, //only listens to /pet get lost
|
||||
petAnimation, //does not listen to any commands
|
||||
petOther,
|
||||
petCharmed,
|
||||
petNPCFollow,
|
||||
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
||||
petNone = 0xFF // not a pet
|
||||
} PetTypeOld;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -1586,6 +1586,21 @@ void Corpse::LootCorpseItem(Client *c, const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_LOOT_ZONE)) {
|
||||
const auto &export_string = fmt::format(
|
||||
"{} {} {} {}",
|
||||
inst->GetItem()->ID,
|
||||
inst->GetCharges(),
|
||||
EntityList::RemoveNumbers(corpse_name),
|
||||
GetID()
|
||||
);
|
||||
|
||||
std::vector<std::any> args = {inst, this, c};
|
||||
if (parse->EventZone(EVENT_LOOT_ZONE, zone, export_string, 0, &args) != 0) {
|
||||
prevent_loot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (inst && PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::LOOT_ITEM) && !IsPlayerCorpse()) {
|
||||
auto e = PlayerEvent::LootItemEvent{
|
||||
.item_id = inst->GetItem()->ID,
|
||||
|
||||
@ -263,7 +263,7 @@ int64 Mob::GetActDoTDamage(uint16 spell_id, int64 value, Mob* target, bool from_
|
||||
chance += itembonuses.CriticalDoTChance + spellbonuses.CriticalDoTChance + aabonuses.CriticalDoTChance;
|
||||
|
||||
if (spellbonuses.CriticalDotDecay)
|
||||
chance += GetDecayEffectValue(spell_id, SE_CriticalDotDecay);
|
||||
chance += GetDecayEffectValue(spell_id, SpellEffect::CriticalDotDecay);
|
||||
|
||||
if (spells[spell_id].override_crit_chance > 0 && chance > spells[spell_id].override_crit_chance)
|
||||
chance = spells[spell_id].override_crit_chance;
|
||||
@ -429,14 +429,14 @@ int64 Mob::GetActSpellHealing(uint16 spell_id, int64 value, Mob* target, bool fr
|
||||
critical_chance += itembonuses.CriticalHealChance + spellbonuses.CriticalHealChance + aabonuses.CriticalHealChance;
|
||||
|
||||
if (spellbonuses.CriticalHealDecay) {
|
||||
critical_chance += GetDecayEffectValue(spell_id, SE_CriticalHealDecay);
|
||||
critical_chance += GetDecayEffectValue(spell_id, SpellEffect::CriticalHealDecay);
|
||||
}
|
||||
}
|
||||
else {
|
||||
critical_chance = itembonuses.CriticalHealOverTime + spellbonuses.CriticalHealOverTime + aabonuses.CriticalHealOverTime;
|
||||
|
||||
if (spellbonuses.CriticalRegenDecay) {
|
||||
critical_chance += GetDecayEffectValue(spell_id, SE_CriticalRegenDecay);
|
||||
critical_chance += GetDecayEffectValue(spell_id, SpellEffect::CriticalRegenDecay);
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,7 +596,7 @@ int32 Mob::GetActSpellCost(uint16 spell_id, int32 cost)
|
||||
if (buffs[buffSlot].spellid == 0 || buffs[buffSlot].spellid >= SPDAT_RECORDS)
|
||||
continue;
|
||||
|
||||
if(IsEffectInSpell(buffs[buffSlot].spellid, SE_ReduceManaCost)) {
|
||||
if(IsEffectInSpell(buffs[buffSlot].spellid, SpellEffect::ReduceManaCost)) {
|
||||
if(CalcFocusEffect(focusManaCost, buffs[buffSlot].spellid, spell_id) == 100)
|
||||
cost = 1;
|
||||
}
|
||||
@ -1105,8 +1105,8 @@ void EntityList::AESpell(
|
||||
IsTargetableAESpell(spell_id) &&
|
||||
is_detrimental_spell &&
|
||||
!is_npc &&
|
||||
!IsEffectInSpell(spell_id, SE_Lull) &&
|
||||
!IsEffectInSpell(spell_id, SE_Mez)
|
||||
!IsEffectInSpell(spell_id, SpellEffect::Lull) &&
|
||||
!IsEffectInSpell(spell_id, SpellEffect::Mez)
|
||||
) {
|
||||
max_targets_allowed = RuleI(Spells, TargetedAOEMaxTargets);
|
||||
} else if (
|
||||
|
||||
@ -207,6 +207,9 @@ const char* QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_AA_LOSS",
|
||||
"EVENT_SPELL_BLOCKED",
|
||||
"EVENT_READ_ITEM",
|
||||
"EVENT_PET_COMMAND",
|
||||
"EVENT_CHARM_START",
|
||||
"EVENT_CHARM_END",
|
||||
|
||||
// Add new events before these or Lua crashes
|
||||
"EVENT_SPELL_EFFECT_BOT",
|
||||
@ -222,6 +225,8 @@ PerlembParser::PerlembParser() : perl(nullptr)
|
||||
global_bot_quest_status_ = questUnloaded;
|
||||
merc_quest_status_ = questUnloaded;
|
||||
global_merc_quest_status_ = questUnloaded;
|
||||
zone_quest_status_ = questUnloaded;
|
||||
global_zone_quest_status_ = questUnloaded;
|
||||
}
|
||||
|
||||
PerlembParser::~PerlembParser()
|
||||
@ -265,6 +270,8 @@ void PerlembParser::ReloadQuests()
|
||||
global_bot_quest_status_ = questUnloaded;
|
||||
merc_quest_status_ = questUnloaded;
|
||||
global_merc_quest_status_ = questUnloaded;
|
||||
zone_quest_status_ = questUnloaded;
|
||||
global_zone_quest_status_ = questUnloaded;
|
||||
|
||||
item_quest_status_.clear();
|
||||
spell_quest_status_.clear();
|
||||
@ -278,6 +285,7 @@ int PerlembParser::EventCommon(
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
uint32 extra_data,
|
||||
bool is_global,
|
||||
std::vector<std::any>* extra_pointers
|
||||
@ -287,52 +295,22 @@ int PerlembParser::EventCommon(
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_player_quest = false;
|
||||
bool is_global_player_quest = false;
|
||||
bool is_global_npc_quest = false;
|
||||
bool is_bot_quest = false;
|
||||
bool is_global_bot_quest = false;
|
||||
bool is_merc_quest = false;
|
||||
bool is_global_merc_quest = false;
|
||||
bool is_item_quest = false;
|
||||
bool is_spell_quest = false;
|
||||
|
||||
std::string package_name;
|
||||
|
||||
GetQuestTypes(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
QuestType quest_type = GetQuestTypes(
|
||||
event_id,
|
||||
npc_mob,
|
||||
inst,
|
||||
mob,
|
||||
zone,
|
||||
is_global
|
||||
);
|
||||
|
||||
GetQuestPackageName(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
package_name,
|
||||
std::string package_name = GetQuestPackageName(
|
||||
quest_type,
|
||||
event_id,
|
||||
object_id,
|
||||
data,
|
||||
npc_mob,
|
||||
inst,
|
||||
is_global
|
||||
inst
|
||||
);
|
||||
|
||||
const std::string& sub_name = QuestEventSubroutines[event_id];
|
||||
@ -348,15 +326,7 @@ int PerlembParser::EventCommon(
|
||||
/* Check for QGlobal export event enable */
|
||||
if (parse->perl_event_export_settings[event_id].qglobals) {
|
||||
ExportQGlobals(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
quest_type,
|
||||
package_name,
|
||||
npc_mob,
|
||||
mob,
|
||||
@ -367,15 +337,7 @@ int PerlembParser::EventCommon(
|
||||
/* Check for Mob export event enable */
|
||||
if (parse->perl_event_export_settings[event_id].mob) {
|
||||
ExportMobVariables(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
quest_type,
|
||||
package_name,
|
||||
mob,
|
||||
npc_mob
|
||||
@ -397,19 +359,24 @@ int PerlembParser::EventCommon(
|
||||
ExportEventVariables(package_name, event_id, object_id, data, npc_mob, inst, mob, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
if (is_player_quest || is_global_player_quest) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, nullptr);
|
||||
} else if (is_bot_quest || is_global_bot_quest || is_merc_quest || is_global_merc_quest) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, nullptr);
|
||||
} else if (is_item_quest) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, inst, nullptr);
|
||||
} else if (is_spell_quest) {
|
||||
if (quest_type == QuestType::Player || quest_type == QuestType::PlayerGlobal) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, nullptr, nullptr);
|
||||
} else if (
|
||||
quest_type == QuestType::Bot ||
|
||||
quest_type == QuestType::BotGlobal ||
|
||||
quest_type == QuestType::Merc ||
|
||||
quest_type == QuestType::MercGlobal
|
||||
) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, nullptr, nullptr);
|
||||
} else if (quest_type == QuestType::Item || quest_type == QuestType::ItemGlobal) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, inst, nullptr, nullptr);
|
||||
} else if (quest_type == QuestType::Spell || quest_type == QuestType::SpellGlobal) {
|
||||
if (mob) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, spell);
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, spell, nullptr);
|
||||
} else {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, spell);
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, spell, nullptr);
|
||||
}
|
||||
} else {
|
||||
} else if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
return SendCommands(
|
||||
package_name.c_str(),
|
||||
QuestEventSubroutines[event_id],
|
||||
@ -417,8 +384,20 @@ int PerlembParser::EventCommon(
|
||||
npc_mob,
|
||||
mob,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
} else if (quest_type == QuestType::Zone || quest_type == QuestType::ZoneGlobal) {
|
||||
return SendCommands(
|
||||
package_name.c_str(),
|
||||
QuestEventSubroutines[event_id],
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
zone
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,6 +418,7 @@ int PerlembParser::EventNPC(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -462,6 +442,7 @@ int PerlembParser::EventGlobalNPC(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
@ -484,6 +465,7 @@ int PerlembParser::EventPlayer(
|
||||
nullptr,
|
||||
nullptr,
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -506,6 +488,7 @@ int PerlembParser::EventGlobalPlayer(
|
||||
nullptr,
|
||||
nullptr,
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
@ -534,6 +517,7 @@ int PerlembParser::EventItem(
|
||||
inst,
|
||||
nullptr,
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -558,6 +542,7 @@ int PerlembParser::EventSpell(
|
||||
nullptr,
|
||||
&spells[spell_id],
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -1006,7 +991,8 @@ int PerlembParser::SendCommands(
|
||||
Mob* other,
|
||||
Mob* mob,
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Zone* zone
|
||||
)
|
||||
{
|
||||
if (!perl) {
|
||||
@ -1014,12 +1000,22 @@ int PerlembParser::SendCommands(
|
||||
}
|
||||
|
||||
int ret_value = 0;
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = other;
|
||||
q.questitem = inst;
|
||||
q.questspell = spell;
|
||||
|
||||
if (mob && mob->IsClient()) {
|
||||
quest_manager.StartQuest(other, mob->CastToClient(), inst, spell);
|
||||
} else {
|
||||
quest_manager.StartQuest(other);
|
||||
q.initiator = mob->CastToClient();
|
||||
}
|
||||
|
||||
if (zone) {
|
||||
q.zone = zone;
|
||||
}
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
try {
|
||||
perl->eval(fmt::format("package {};", prefix).c_str());
|
||||
|
||||
@ -1033,7 +1029,8 @@ int PerlembParser::SendCommands(
|
||||
"merc",
|
||||
"npc",
|
||||
"questitem",
|
||||
"spell"
|
||||
"spell",
|
||||
"zone"
|
||||
};
|
||||
|
||||
for (const auto& suffix : suffixes) {
|
||||
@ -1058,21 +1055,23 @@ int PerlembParser::SendCommands(
|
||||
sv_setsv(client, _empty_sv);
|
||||
}
|
||||
|
||||
if (other->IsBot()) {
|
||||
Bot* b = quest_manager.GetBot();
|
||||
buf = fmt::format("{}::bot", prefix);
|
||||
SV* bot = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(bot, "Bot", b);
|
||||
} else if (other->IsMerc()) {
|
||||
Merc* m = quest_manager.GetMerc();
|
||||
buf = fmt::format("{}::merc", prefix);
|
||||
SV* merc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(merc, "Merc", m);
|
||||
} else if (other->IsNPC()) {
|
||||
NPC* n = quest_manager.GetNPC();
|
||||
buf = fmt::format("{}::npc", prefix);
|
||||
SV* npc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(npc, "NPC", n);
|
||||
if (other) {
|
||||
if (other->IsBot()) {
|
||||
Bot* b = quest_manager.GetBot();
|
||||
buf = fmt::format("{}::bot", prefix);
|
||||
SV* bot = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(bot, "Bot", b);
|
||||
} else if (other->IsMerc()) {
|
||||
Merc* m = quest_manager.GetMerc();
|
||||
buf = fmt::format("{}::merc", prefix);
|
||||
SV* merc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(merc, "Merc", m);
|
||||
} else if (other->IsNPC()) {
|
||||
NPC* n = quest_manager.GetNPC();
|
||||
buf = fmt::format("{}::npc", prefix);
|
||||
SV* npc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(npc, "NPC", n);
|
||||
}
|
||||
}
|
||||
|
||||
//only export QuestItem if it's an inst quest
|
||||
@ -1110,7 +1109,8 @@ int PerlembParser::SendCommands(
|
||||
"merc",
|
||||
"npc",
|
||||
"questitem",
|
||||
"spell"
|
||||
"spell",
|
||||
"zone"
|
||||
};
|
||||
|
||||
for (const auto& suffix : suffixes) {
|
||||
@ -1192,20 +1192,12 @@ void PerlembParser::MapFunctions()
|
||||
#endif // EMBPERL_XS_CLASSES
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestTypes(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
QuestType PerlembParser::GetQuestTypes(
|
||||
QuestEventID event_id,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
bool is_global
|
||||
)
|
||||
{
|
||||
@ -1219,100 +1211,74 @@ void PerlembParser::GetQuestTypes(
|
||||
event_id == EVENT_SPELL_FADE ||
|
||||
event_id == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE
|
||||
) {
|
||||
is_spell_quest = true;
|
||||
return is_global ? QuestType::SpellGlobal : QuestType::Spell;
|
||||
} else {
|
||||
if (npc_mob) {
|
||||
if (!inst) {
|
||||
if (is_global) {
|
||||
if (npc_mob->IsBot()) {
|
||||
is_global_bot_quest = true;
|
||||
} else if (npc_mob->IsMerc()) {
|
||||
is_global_merc_quest = true;
|
||||
}
|
||||
} else {
|
||||
if (npc_mob->IsBot()) {
|
||||
is_bot_quest = true;
|
||||
} else if (npc_mob->IsMerc()) {
|
||||
is_merc_quest = true;
|
||||
}
|
||||
if (npc_mob->IsBot()) {
|
||||
return is_global ? QuestType::BotGlobal : QuestType::Bot;
|
||||
} else if (npc_mob->IsMerc()) {
|
||||
return is_global ? QuestType::MercGlobal : QuestType::Merc;
|
||||
} else if (npc_mob->IsNPC()) {
|
||||
return is_global ? QuestType::NPCGlobal : QuestType::NPC;
|
||||
}
|
||||
} else {
|
||||
is_item_quest = true;
|
||||
return is_global ? QuestType::ItemGlobal : QuestType::Item;
|
||||
}
|
||||
} else if (!npc_mob && mob) {
|
||||
if (!inst) {
|
||||
if (is_global) {
|
||||
if (mob->IsClient()) {
|
||||
is_global_player_quest = true;
|
||||
}
|
||||
} else {
|
||||
if (mob->IsClient()) {
|
||||
is_player_quest = true;
|
||||
}
|
||||
if (mob->IsClient()) {
|
||||
return is_global ? QuestType::PlayerGlobal : QuestType::Player;
|
||||
}
|
||||
} else {
|
||||
is_item_quest = true;
|
||||
return is_global ? QuestType::ItemGlobal : QuestType::Item;
|
||||
}
|
||||
} else if (zone) {
|
||||
return is_global ? QuestType::ZoneGlobal : QuestType::Zone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestPackageName(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
std::string& package_name,
|
||||
std::string PerlembParser::GetQuestPackageName(
|
||||
QuestType quest_type,
|
||||
QuestEventID event_id,
|
||||
uint32 object_id,
|
||||
const char* data,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
bool is_global
|
||||
EQ::ItemInstance* inst
|
||||
)
|
||||
{
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest &&
|
||||
!is_spell_quest
|
||||
) {
|
||||
if (is_global) {
|
||||
is_global_npc_quest = true;
|
||||
package_name = "qst_global_npc";
|
||||
} else {
|
||||
package_name = fmt::format("qst_npc_{}", npc_mob->GetNPCTypeID());
|
||||
}
|
||||
} else if (is_item_quest) {
|
||||
if (quest_type == QuestType::NPC) {
|
||||
return fmt::format("qst_npc_{}", npc_mob->GetNPCTypeID());
|
||||
} else if (quest_type == QuestType::NPCGlobal) {
|
||||
return "qst_global_npc";
|
||||
} else if (quest_type == QuestType::Item || quest_type == QuestType::ItemGlobal) {
|
||||
if (!inst) {
|
||||
return;
|
||||
return "";
|
||||
}
|
||||
|
||||
package_name = fmt::format("qst_item_{}", inst->GetID());
|
||||
} else if (is_player_quest) {
|
||||
package_name = "qst_player";
|
||||
} else if (is_global_player_quest) {
|
||||
package_name = "qst_global_player";
|
||||
} else if (is_bot_quest) {
|
||||
package_name = "qst_bot";
|
||||
} else if (is_global_bot_quest) {
|
||||
package_name = "qst_global_bot";
|
||||
} else if (is_merc_quest) {
|
||||
package_name = "qst_merc";
|
||||
} else if (is_global_merc_quest) {
|
||||
package_name = "qst_global_merc";
|
||||
} else {
|
||||
package_name = fmt::format("qst_spell_{}", object_id);
|
||||
return fmt::format("qst_item_{}", inst->GetID());
|
||||
} else if (quest_type == QuestType::Player) {
|
||||
return "qst_player";
|
||||
} else if (quest_type == QuestType::PlayerGlobal) {
|
||||
return "qst_global_player";
|
||||
} else if (quest_type == QuestType::Bot) {
|
||||
return "qst_bot";
|
||||
} else if (quest_type == QuestType::BotGlobal) {
|
||||
return "qst_global_bot";
|
||||
} else if (quest_type == QuestType::Merc) {
|
||||
return "qst_merc";
|
||||
} else if (quest_type == QuestType::MercGlobal) {
|
||||
return "qst_global_merc";
|
||||
} else if (quest_type == QuestType::Spell || quest_type == QuestType::SpellGlobal) {
|
||||
return fmt::format("qst_spell_{}", object_id);
|
||||
} else if (quest_type == QuestType::Zone) {
|
||||
return "qst_zone";
|
||||
} else if (quest_type == QuestType::ZoneGlobal) {
|
||||
return "qst_global_zone";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void PerlembParser::ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob)
|
||||
@ -1331,15 +1297,7 @@ void PerlembParser::ExportCharID(const std::string& package_name, int& char_id,
|
||||
}
|
||||
|
||||
void PerlembParser::ExportQGlobals(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* npc_mob,
|
||||
Mob* mob,
|
||||
@ -1347,16 +1305,7 @@ void PerlembParser::ExportQGlobals(
|
||||
)
|
||||
{
|
||||
//NPC quest
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest &&
|
||||
!is_spell_quest
|
||||
) {
|
||||
if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
//only export for npcs that are global enabled.
|
||||
if (npc_mob && npc_mob->GetQglobal()) {
|
||||
std::map<std::string, std::string> globhash;
|
||||
@ -1485,15 +1434,7 @@ void PerlembParser::ExportQGlobals(
|
||||
}
|
||||
|
||||
void PerlembParser::ExportMobVariables(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* mob,
|
||||
Mob* npc_mob
|
||||
@ -1511,15 +1452,7 @@ void PerlembParser::ExportMobVariables(
|
||||
ExportVar(package_name.c_str(), "bot_owner_char_id", mob->CastToBot()->GetBotOwnerCharacterID());
|
||||
}
|
||||
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest
|
||||
) {
|
||||
if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
if (mob && mob->IsClient() && npc_mob && npc_mob->IsNPC()) {
|
||||
Client* c = mob->CastToClient();
|
||||
|
||||
@ -1543,16 +1476,7 @@ void PerlembParser::ExportMobVariables(
|
||||
ExportVar(package_name.c_str(), "userid", mob->GetID());
|
||||
}
|
||||
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest &&
|
||||
!is_spell_quest
|
||||
) {
|
||||
if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
if (npc_mob->IsNPC()) {
|
||||
ExportVar(package_name.c_str(), "mname", npc_mob->GetName());
|
||||
ExportVar(package_name.c_str(), "mobid", npc_mob->GetID());
|
||||
@ -1758,10 +1682,14 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "doorid", data);
|
||||
ExportVar(package_name.c_str(), "version", zone->GetInstanceVersion());
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
ExportVar(package_name.c_str(), "door", "Doors", std::any_cast<Doors*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1782,10 +1710,14 @@ void PerlembParser::ExportEventVariables(
|
||||
);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
if (extra_pointers && extra_pointers->size() >= 2) {
|
||||
ExportVar(package_name.c_str(), "corpse", "Corpse", std::any_cast<Corpse*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 3) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(2)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1852,7 +1784,7 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "picked_up_id", data);
|
||||
ExportVar(package_name.c_str(), "picked_up_entity_id", extra_data);
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
ExportVar(
|
||||
package_name.c_str(),
|
||||
"item",
|
||||
@ -1861,6 +1793,10 @@ void PerlembParser::ExportEventVariables(
|
||||
);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1873,6 +1809,11 @@ void PerlembParser::ExportEventVariables(
|
||||
|
||||
case EVENT_POPUP_RESPONSE: {
|
||||
ExportVar(package_name.c_str(), "popupid", data);
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2036,10 +1977,14 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "objectid", data);
|
||||
ExportVar(package_name.c_str(), "clicker_id", extra_data);
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
ExportVar(package_name.c_str(), "object", "Object", std::any_cast<Object*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2115,6 +2060,13 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "killed_npc_id", !killed->IsMerc() && killed->IsNPC() ? killed->GetNPCTypeID() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 3) {
|
||||
Mob* killer = std::any_cast<Mob*>(extra_pointers->at(2));
|
||||
if (killer) {
|
||||
ExportVar(package_name.c_str(), "killer", "Mob", killer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2142,10 +2094,21 @@ void PerlembParser::ExportEventVariables(
|
||||
}
|
||||
|
||||
case EVENT_SPAWN_ZONE: {
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "spawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned", "Mob", mob);
|
||||
if (mob) {
|
||||
ExportVar(package_name.c_str(), "spawned", "Mob", mob);
|
||||
ExportVar(package_name.c_str(), "spawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
NPC* spawn_npc = std::any_cast<NPC*>(extra_pointers->at(0));
|
||||
ExportVar(package_name.c_str(), "spawned", "NPC", spawn_npc);
|
||||
ExportVar(package_name.c_str(), "spawned_bot_id", spawn_npc->IsBot() ? spawn_npc->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", spawn_npc->GetID());
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", spawn_npc->IsNPC() ? spawn_npc->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2386,6 +2349,7 @@ void PerlembParser::ExportEventVariables(
|
||||
}
|
||||
|
||||
case EVENT_DESPAWN: {
|
||||
ExportVar(package_name.c_str(), "despawned", "Mob", npc_mob);
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", npc_mob->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", npc_mob->IsBot() ? npc_mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_merc_id", npc_mob->IsMerc() ? npc_mob->CastToMerc()->GetMercenaryID() : 0);
|
||||
@ -2394,9 +2358,21 @@ void PerlembParser::ExportEventVariables(
|
||||
}
|
||||
|
||||
case EVENT_DESPAWN_ZONE: {
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
if (mob) {
|
||||
ExportVar(package_name.c_str(), "despawned", "Mob", mob);
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
NPC* spawn_npc = std::any_cast<NPC*>(extra_pointers->at(0));
|
||||
ExportVar(package_name.c_str(), "despawned", "NPC", spawn_npc);
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", spawn_npc->IsBot() ? spawn_npc->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", spawn_npc->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_npc_id", spawn_npc->IsNPC() ? spawn_npc->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2551,6 +2527,20 @@ void PerlembParser::ExportEventVariables(
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_ENTER_ZONE: {
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_PET_COMMAND: {
|
||||
ExportVar(package_name.c_str(), "pet_command", extra_data);
|
||||
ExportVar(package_name.c_str(), "pet_command_name", data);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@ -2648,6 +2638,7 @@ int PerlembParser::EventBot(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -2671,6 +2662,7 @@ int PerlembParser::EventGlobalBot(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
@ -2768,6 +2760,7 @@ int PerlembParser::EventMerc(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -2791,6 +2784,127 @@ int PerlembParser::EventGlobalMerc(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
);
|
||||
}
|
||||
|
||||
void PerlembParser::LoadZoneScript(std::string filename)
|
||||
{
|
||||
if (!perl || zone_quest_status_ != questUnloaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
perl->eval_file("qst_zone", filename.c_str());
|
||||
} catch (std::string e) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Error Compiling Zone Quest File [{}] Error [{}]",
|
||||
filename,
|
||||
e
|
||||
)
|
||||
);
|
||||
|
||||
zone_quest_status_ = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
zone_quest_status_ = questLoaded;
|
||||
}
|
||||
|
||||
void PerlembParser::LoadGlobalZoneScript(std::string filename)
|
||||
{
|
||||
if (!perl || global_zone_quest_status_ != questUnloaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
perl->eval_file("qst_global_zone", filename.c_str());
|
||||
} catch (std::string e) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Error Compiling Global Zone Quest File [{}] Error [{}]",
|
||||
filename,
|
||||
e
|
||||
)
|
||||
);
|
||||
|
||||
global_zone_quest_status_ = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
global_zone_quest_status_ = questLoaded;
|
||||
}
|
||||
|
||||
bool PerlembParser::ZoneHasQuestSub(QuestEventID event_id)
|
||||
{
|
||||
if (
|
||||
!perl ||
|
||||
zone_quest_status_ != questLoaded ||
|
||||
event_id >= _LargestEventID
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return perl->SubExists("qst_zone", QuestEventSubroutines[event_id]);
|
||||
}
|
||||
|
||||
bool PerlembParser::GlobalZoneHasQuestSub(QuestEventID event_id)
|
||||
{
|
||||
if (
|
||||
!perl ||
|
||||
global_zone_quest_status_ != questLoaded ||
|
||||
event_id >= _LargestEventID
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return perl->SubExists("qst_global_zone", QuestEventSubroutines[event_id]);
|
||||
}
|
||||
|
||||
int PerlembParser::EventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
return EventCommon(
|
||||
event_id,
|
||||
0,
|
||||
data.c_str(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
zone,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
);
|
||||
}
|
||||
|
||||
int PerlembParser::EventGlobalZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
return EventCommon(
|
||||
event_id,
|
||||
0,
|
||||
data.c_str(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
zone,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
|
||||
@ -41,6 +41,23 @@ typedef enum {
|
||||
questFailedToLoad
|
||||
} PerlQuestStatus;
|
||||
|
||||
enum class QuestType {
|
||||
Bot,
|
||||
BotGlobal,
|
||||
Item,
|
||||
ItemGlobal,
|
||||
Merc,
|
||||
MercGlobal,
|
||||
NPC,
|
||||
NPCGlobal,
|
||||
Player,
|
||||
PlayerGlobal,
|
||||
Spell,
|
||||
SpellGlobal,
|
||||
Zone,
|
||||
ZoneGlobal
|
||||
};
|
||||
|
||||
class PerlembParser : public QuestInterface {
|
||||
public:
|
||||
PerlembParser();
|
||||
@ -136,6 +153,22 @@ public:
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
virtual int EventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
virtual int EventGlobalZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id);
|
||||
virtual bool HasGlobalQuestSub(QuestEventID event_id);
|
||||
virtual bool PlayerHasQuestSub(QuestEventID event_id);
|
||||
@ -146,6 +179,8 @@ public:
|
||||
virtual bool GlobalBotHasQuestSub(QuestEventID event_id);
|
||||
virtual bool MercHasQuestSub(QuestEventID event_id);
|
||||
virtual bool GlobalMercHasQuestSub(QuestEventID event_id);
|
||||
virtual bool ZoneHasQuestSub(QuestEventID event_id);
|
||||
virtual bool GlobalZoneHasQuestSub(QuestEventID event_id);
|
||||
|
||||
virtual void LoadNPCScript(std::string filename, int npc_id);
|
||||
virtual void LoadGlobalNPCScript(std::string filename);
|
||||
@ -157,6 +192,8 @@ public:
|
||||
virtual void LoadGlobalBotScript(std::string filename);
|
||||
virtual void LoadMercScript(std::string filename);
|
||||
virtual void LoadGlobalMercScript(std::string filename);
|
||||
virtual void LoadZoneScript(std::string filename);
|
||||
virtual void LoadGlobalZoneScript(std::string filename);
|
||||
|
||||
virtual void AddVar(std::string name, std::string val);
|
||||
virtual std::string GetVar(std::string name);
|
||||
@ -182,6 +219,7 @@ private:
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
uint32 extra_data,
|
||||
bool is_global,
|
||||
std::vector<std::any>* extra_pointers
|
||||
@ -194,59 +232,34 @@ private:
|
||||
Mob* other,
|
||||
Mob* mob,
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Zone* zone
|
||||
);
|
||||
|
||||
void MapFunctions();
|
||||
|
||||
void GetQuestTypes(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
QuestType GetQuestTypes(
|
||||
QuestEventID event,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
bool is_global
|
||||
);
|
||||
|
||||
void GetQuestPackageName(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
std::string& package_name,
|
||||
std::string GetQuestPackageName(
|
||||
QuestType quest_type,
|
||||
QuestEventID event,
|
||||
uint32 object_id,
|
||||
const char* data,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
bool is_global
|
||||
EQ::ItemInstance* inst
|
||||
);
|
||||
|
||||
void ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob);
|
||||
|
||||
void ExportQGlobals(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* npc_mob,
|
||||
Mob* mob,
|
||||
@ -254,15 +267,7 @@ private:
|
||||
);
|
||||
|
||||
void ExportMobVariables(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* mob,
|
||||
Mob* npc_mob
|
||||
@ -295,6 +300,8 @@ private:
|
||||
PerlQuestStatus global_bot_quest_status_;
|
||||
PerlQuestStatus merc_quest_status_;
|
||||
PerlQuestStatus global_merc_quest_status_;
|
||||
PerlQuestStatus zone_quest_status_;
|
||||
PerlQuestStatus global_zone_quest_status_;
|
||||
|
||||
SV* _empty_sv;
|
||||
|
||||
|
||||
@ -6005,6 +6005,50 @@ bool Perl__handin(perl::reference handin_ref)
|
||||
return quest_manager.handin(handin_map);
|
||||
}
|
||||
|
||||
perl::array Perl__get_paused_timers(Mob* m)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = quest_manager.GetPausedTimers(m);
|
||||
|
||||
if (!l.empty()) {
|
||||
a.reserve(l.size());
|
||||
|
||||
for (const auto& v : l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
perl::array Perl__get_timers(Mob* m)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = quest_manager.GetTimers(m);
|
||||
|
||||
if (!l.empty()) {
|
||||
a.reserve(l.size());
|
||||
|
||||
for (const auto& v: l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
std::string Perl__get_pet_command_name(uint8 pet_command)
|
||||
{
|
||||
return PetCommand::GetName(pet_command);
|
||||
}
|
||||
|
||||
std::string Perl__get_pet_type_name(uint8 pet_type)
|
||||
{
|
||||
return PetType::GetName(pet_type);
|
||||
}
|
||||
|
||||
void perl_register_quest()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@ -6694,6 +6738,9 @@ void perl_register_quest()
|
||||
package.add("getguildidbycharid", &Perl__getguildidbycharid);
|
||||
package.add("getgroupidbycharid", &Perl__getgroupidbycharid);
|
||||
package.add("getinventoryslotname", &Perl__getinventoryslotname);
|
||||
package.add("get_paused_timers", &Perl__get_paused_timers);
|
||||
package.add("get_pet_command_name", &Perl__get_pet_command_name);
|
||||
package.add("get_pet_type_name", &Perl__get_pet_type_name);
|
||||
package.add("getraididbycharid", &Perl__getraididbycharid);
|
||||
package.add("get_race_bitmask", &Perl__get_race_bitmask);
|
||||
package.add("get_recipe_component_item_ids", &Perl__GetRecipeComponentItemIDs);
|
||||
@ -6713,6 +6760,7 @@ void perl_register_quest()
|
||||
package.add("getspellstat", (int(*)(uint32, std::string))&Perl__getspellstat);
|
||||
package.add("getspellstat", (int(*)(uint32, std::string, uint8))&Perl__getspellstat);
|
||||
package.add("getskillname", &Perl__getskillname);
|
||||
package.add("get_timers", &Perl__get_timers);
|
||||
package.add("getlevel", &Perl__getlevel);
|
||||
package.add("getplayerburiedcorpsecount", &Perl__getplayerburiedcorpsecount);
|
||||
package.add("getplayercorpsecount", &Perl__getplayercorpsecount);
|
||||
|
||||
@ -56,8 +56,6 @@ extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern uint32 numclients;
|
||||
|
||||
extern char errorname[32];
|
||||
|
||||
Entity::Entity()
|
||||
{
|
||||
id = 0;
|
||||
@ -743,6 +741,11 @@ void EntityList::AddNPC(NPC *npc, bool send_spawn_packet, bool dont_queue)
|
||||
npc->DispatchZoneControllerEvent(EVENT_SPAWN_ZONE, npc, "", 0, nullptr);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_SPAWN_ZONE)) {
|
||||
std::vector<std::any> args = { npc };
|
||||
parse->EventZone(EVENT_SPAWN_ZONE, zone, "", 0, &args);
|
||||
}
|
||||
|
||||
if (zone->HasMap() && zone->HasWaterMap()) {
|
||||
npc->SetSpawnedInWater(false);
|
||||
if (zone->watermap->InLiquid(npc->GetPosition())) {
|
||||
@ -1386,7 +1389,7 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
|
||||
|
||||
bool is_delayed_packet = (
|
||||
DistanceSquared(client_position, spawn_position) > distance_max ||
|
||||
(spawn->IsClient() && (spawn->GetRace() == MINOR_ILL_OBJ || spawn->GetRace() == TREE))
|
||||
(spawn->IsClient() && (spawn->GetRace() == Race::MinorIllusion || spawn->GetRace() == Race::Tree))
|
||||
);
|
||||
|
||||
if (is_delayed_packet) {
|
||||
@ -1410,7 +1413,7 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
|
||||
*
|
||||
* Illusion races on PCs don't work as a mass spawn
|
||||
* But they will work as an add_spawn AFTER CLIENT_CONNECTED.
|
||||
* if (spawn->IsClient() && (race == MINOR_ILL_OBJ || race == TREE)) {
|
||||
* if (spawn->IsClient() && (race == Race::MinorIllusion || race == Race::Tree)) {
|
||||
* app = new EQApplicationPacket;
|
||||
* spawn->CreateSpawnPacket(app);
|
||||
* client->QueuePacket(app, true, Client::CLIENT_CONNECTED);
|
||||
|
||||
@ -145,6 +145,9 @@ typedef enum {
|
||||
EVENT_AA_LOSS,
|
||||
EVENT_SPELL_BLOCKED,
|
||||
EVENT_READ_ITEM,
|
||||
EVENT_PET_COMMAND,
|
||||
EVENT_CHARM_START,
|
||||
EVENT_CHARM_END,
|
||||
|
||||
// Add new events before these or Lua crashes
|
||||
EVENT_SPELL_EFFECT_BOT,
|
||||
|
||||
14
zone/exp.cpp
14
zone/exp.cpp
@ -130,7 +130,7 @@ uint64 Client::CalcEXP(uint8 consider_level, bool ignore_modifiers) {
|
||||
if (
|
||||
GetClass() == Class::Warrior ||
|
||||
GetClass() == Class::Rogue ||
|
||||
GetBaseRace() == HALFLING
|
||||
GetBaseRace() == Race::Halfling
|
||||
) {
|
||||
total_modifier *= 1.05;
|
||||
}
|
||||
@ -291,7 +291,7 @@ void Client::CalculateStandardAAExp(uint64 &add_aaxp, uint8 conlevel, bool resex
|
||||
// Shouldn't race not affect AA XP?
|
||||
if (RuleB(Character, UseRaceClassExpBonuses))
|
||||
{
|
||||
if (GetBaseRace() == HALFLING) {
|
||||
if (GetBaseRace() == Race::Halfling) {
|
||||
aatotalmod *= 1.05;
|
||||
}
|
||||
|
||||
@ -439,7 +439,7 @@ void Client::CalculateExp(uint64 in_add_exp, uint64 &add_exp, uint64 &add_aaxp,
|
||||
|
||||
if (RuleB(Character, UseRaceClassExpBonuses))
|
||||
{
|
||||
if (GetBaseRace() == HALFLING) {
|
||||
if (GetBaseRace() == Race::Halfling) {
|
||||
totalmod *= 1.05;
|
||||
}
|
||||
|
||||
@ -1057,13 +1057,13 @@ uint32 Client::GetEXPForLevel(uint16 check_level)
|
||||
if(RuleB(Character,UseOldRaceExpPenalties))
|
||||
{
|
||||
float racemod = 1.0;
|
||||
if(GetBaseRace() == TROLL || GetBaseRace() == IKSAR) {
|
||||
if(GetBaseRace() == Race::Troll || GetBaseRace() == Race::Iksar) {
|
||||
racemod = 1.2;
|
||||
} else if(GetBaseRace() == OGRE) {
|
||||
} else if(GetBaseRace() == Race::Ogre) {
|
||||
racemod = 1.15;
|
||||
} else if(GetBaseRace() == BARBARIAN) {
|
||||
} else if(GetBaseRace() == Race::Barbarian) {
|
||||
racemod = 1.05;
|
||||
} else if(GetBaseRace() == HALFLING) {
|
||||
} else if(GetBaseRace() == Race::Halfling) {
|
||||
racemod = 0.95;
|
||||
}
|
||||
|
||||
|
||||
@ -365,7 +365,7 @@ void Mob::CalculateNewFearpoint()
|
||||
// fallback logic if pathing system can't be used
|
||||
bool inliquid = zone->HasWaterMap() && zone->watermap->InLiquid(glm::vec3(GetPosition())) || zone->IsWaterZone(GetZ());
|
||||
bool stay_inliquid = (inliquid && IsNPC() && CastToNPC()->IsUnderwaterOnly());
|
||||
bool levitating = IsClient() && (FindType(SE_Levitate) || flymode != GravityBehavior::Ground);
|
||||
bool levitating = IsClient() && (FindType(SpellEffect::Levitate) || flymode != GravityBehavior::Ground);
|
||||
bool open_outdoor_zone = !zone->CanCastOutdoor() && !zone->IsCity();
|
||||
|
||||
int loop = 0;
|
||||
|
||||
@ -83,7 +83,7 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
feature_changed = "Beard Color";
|
||||
value_changed = f.beardcolor;
|
||||
} else if (is_details) {
|
||||
if (t->GetRace() != DRAKKIN) {
|
||||
if (t->GetRace() != Race::Drakkin) {
|
||||
c->Message(Chat::White, "You must target a Drakkin to use this command.");
|
||||
return;
|
||||
}
|
||||
@ -116,7 +116,7 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
feature_changed = "Helmet Texture";
|
||||
value_changed = helm_texture;
|
||||
} else if (is_heritage) {
|
||||
if (t->GetRace() != DRAKKIN) {
|
||||
if (t->GetRace() != Race::Drakkin) {
|
||||
c->Message(Chat::White, "You must target a Drakkin to use this command.");
|
||||
return;
|
||||
}
|
||||
@ -148,7 +148,7 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
feature_changed = "Size";
|
||||
value_changed = size;
|
||||
} else if (is_tattoo) {
|
||||
if (t->GetRace() != DRAKKIN) {
|
||||
if (t->GetRace() != Race::Drakkin) {
|
||||
c->Message(Chat::White, "You must target a Drakkin to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "../client.h"
|
||||
#include "find/aa.cpp"
|
||||
#include "find/account.cpp"
|
||||
#include "find/body_type.cpp"
|
||||
#include "find/bot.cpp"
|
||||
#include "find/bug_category.cpp"
|
||||
@ -38,6 +39,7 @@ void command_find(Client *c, const Seperator *sep)
|
||||
|
||||
std::vector<Cmd> commands = {
|
||||
Cmd{.cmd = "aa", .u = "aa [Search Criteria]", .fn = FindAA, .a = {"#findaa"}},
|
||||
Cmd{.cmd = "account", .u = "account [Search Criteria]", .fn = FindAccount, .a = {"#findaccount"}},
|
||||
Cmd{.cmd = "body_type", .u = "body_type [Search Criteria]", .fn = FindBodyType, .a = {"#findbodytype"}},
|
||||
Cmd{.cmd = "bug_category", .u = "bug_category [Search Criteria]", .fn = FindBugCategory, .a = {"#findbugcategory"}},
|
||||
Cmd{.cmd = "character", .u = "character [Search Criteria]", .fn = FindCharacter, .a = {"#findcharacter"}},
|
||||
@ -72,7 +74,7 @@ void command_find(Client *c, const Seperator *sep)
|
||||
commands.emplace_back(
|
||||
Cmd{.cmd = "bot", .u = "bot [Search Criteria]", .fn = FindBot, .a = {"#findbot"}}
|
||||
);
|
||||
|
||||
|
||||
std::sort(commands.begin(), commands.end(), [](const Cmd& a, const Cmd& b) {
|
||||
return a.cmd < b.cmd;
|
||||
});
|
||||
|
||||
50
zone/gm_commands/find/account.cpp
Normal file
50
zone/gm_commands/find/account.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "../../client.h"
|
||||
#include "../../common/repositories/account_repository.h"
|
||||
|
||||
void FindAccount(Client *c, const Seperator *sep)
|
||||
{
|
||||
const uint16 arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #find account [Character Name]");
|
||||
c->Message(Chat::White, "Note: Used to print the account ID and name of the account a character belongs to.");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& character_name = sep->arg[2];
|
||||
|
||||
const auto& e = CharacterDataRepository::FindByName(database, character_name);
|
||||
|
||||
if (!e.id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Character '{}' does not exist.",
|
||||
character_name
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
auto a = AccountRepository::FindOne(database, e.account_id);
|
||||
|
||||
if (!a.id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Character '{}' is not attached to an account.",
|
||||
character_name
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Account {} ({}) owns the character {}.",
|
||||
a.name,
|
||||
a.id,
|
||||
character_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
@ -110,6 +110,7 @@ void SendNPCEditSubCommands(Client *c)
|
||||
c->Message(Chat::White, "Usage: #npcedit setanimation [Animation ID] - Sets an NPC's Animation on Spawn (Stored in spawn2 table)");
|
||||
c->Message(Chat::White, "Usage: #npcedit respawntime [Respawn Time] - Sets an NPC's Respawn Timer in Seconds (Stored in spawn2 table)");
|
||||
c->Message(Chat::White, "Usage: #npcedit set_grid [Grid ID] - Sets an NPC's Grid ID");
|
||||
c->Message(Chat::White, "Usage: #npcedit npc_tint_id [NPC Tint ID] - Sets an NPC's Tint ID (0 to 78 for RoF2)");
|
||||
}
|
||||
|
||||
void command_npcedit(Client *c, const Seperator *sep)
|
||||
@ -1836,4 +1837,4 @@ void command_npcedit(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
c->Message(Chat::White, d.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ void command_randomfeatures(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
auto target = c->GetTarget();
|
||||
|
||||
|
||||
if (target->RandomizeFeatures()) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
|
||||
@ -44,6 +44,19 @@ void SetRace(Client *c, const Seperator *sep)
|
||||
}
|
||||
);
|
||||
|
||||
if (race_id == Race::Doug) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} {} been returned to {} base race.",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCYou),
|
||||
c == t ? "have" : "has",
|
||||
c == t ? "your" : "their"
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "show/group_info.cpp"
|
||||
#include "show/hatelist.cpp"
|
||||
#include "show/inventory.cpp"
|
||||
#include "show/keyring.cpp"
|
||||
#include "show/ip_lookup.cpp"
|
||||
#include "show/line_of_sight.cpp"
|
||||
#include "show/network.cpp"
|
||||
@ -78,6 +79,7 @@ void command_show(Client *c, const Seperator *sep)
|
||||
Cmd{.cmd = "hatelist", .u = "hatelist", .fn = ShowHateList, .a = {"#hatelist"}},
|
||||
Cmd{.cmd = "inventory", .u = "inventory", .fn = ShowInventory, .a = {"#peekinv"}},
|
||||
Cmd{.cmd = "ip_lookup", .u = "ip_lookup", .fn = ShowIPLookup, .a = {"#iplookup"}},
|
||||
Cmd{.cmd = "keyring", .u = "keyring", .fn = ShowKeyring, .a = {"#showkeyring"}},
|
||||
Cmd{.cmd = "line_of_sight", .u = "line_of_sight", .fn = ShowLineOfSight, .a = {"#checklos"}},
|
||||
Cmd{.cmd = "network", .u = "network", .fn = ShowNetwork, .a = {"#network"}},
|
||||
Cmd{.cmd = "network_stats", .u = "network_stats", .fn = ShowNetworkStats, .a = {"#netstats"}},
|
||||
|
||||
@ -9,7 +9,7 @@ void ShowIPLookup(Client *c, const Seperator *sep)
|
||||
|
||||
auto pack = new ServerPacket(
|
||||
ServerOP_IPLookup,
|
||||
sizeof(ServerGenericWorldQuery_Struct) + ip_length + 1
|
||||
sizeof(ServerGenericWorldQuery_Struct) + ip_length
|
||||
);
|
||||
|
||||
auto s = (ServerGenericWorldQuery_Struct *) pack->pBuffer;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user