mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 09:06:46 +00:00
Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 158396937a | |||
| fb1467284c | |||
| 14addd4869 | |||
| 0a114fae9a | |||
| 2b224d42ad | |||
| 155ec9ac0d | |||
| 25b4b97c41 | |||
| 839f31b24d | |||
| 20728c31c4 | |||
| c6eb12ac16 | |||
| 34d21d4056 | |||
| d369b47ef4 | |||
| 404f7cada8 | |||
| 823e73336d | |||
| 0da6391be3 | |||
| 0348cb6b8e | |||
| b385a4385f | |||
| 6a9228ed6e | |||
| 8031bf0bcb | |||
| c1584da9cc | |||
| ee6f6f683c | |||
| 60707a14db | |||
| 54050924d8 | |||
| f727c9f75a | |||
| f410c89815 | |||
| 2e575652f6 | |||
| 8e831dce36 | |||
| 040c092795 | |||
| a25952910a | |||
| 66896a3121 | |||
| 4d2418af9d | |||
| 265b32f46f | |||
| 1cde55c535 | |||
| 369b5c2921 | |||
| bcc2e022dc | |||
| 0fef46a6c1 | |||
| b867d40774 | |||
| a489290eba | |||
| 549d731849 | |||
| 68a34565f9 | |||
| c05f951f81 | |||
| dc64561b3c | |||
| cb2aee2713 | |||
| 0730b6b588 | |||
| 826550acac | |||
| b71b3f5be0 | |||
| 1fe79f430c | |||
| e5dabe0afc | |||
| 5720ffbcb6 | |||
| 2b0c778ad1 | |||
| bf39a0540c | |||
| 08c8393988 | |||
| 8c12f7b431 | |||
| 037be84f38 | |||
| 4d355afe9d | |||
| 93eddf603b | |||
| 293f79268d | |||
| 7e35d5aa79 | |||
| f7e4fba584 | |||
| 01a0f906e1 | |||
| 0a11eaa092 | |||
| d0edb93d62 | |||
| 35c3778baf | |||
| abb41840f8 | |||
| cd63047e60 | |||
| 4fe5522212 | |||
| 0ccb18d017 | |||
| e010e41a83 | |||
| 886f80117c |
+80
-9
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: EQEmulator Server Linux CI
|
name: Build Linux
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||||
concurrency:
|
concurrency:
|
||||||
@@ -10,18 +11,88 @@ concurrency:
|
|||||||
volumes:
|
volumes:
|
||||||
- name: cache
|
- name: cache
|
||||||
host:
|
host:
|
||||||
path: /var/lib/cache
|
path: /var/lib/cache-release
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: server-build
|
- name: Build Linux X64
|
||||||
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
|
|
||||||
image: akkadius/eqemu-server:v11
|
image: akkadius/eqemu-server:v11
|
||||||
|
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:
|
commands:
|
||||||
- sudo chown eqemu:eqemu /drone/src/ * -R
|
- ./utils/scripts/build/linux-build.sh
|
||||||
- sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
|
|
||||||
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-O0 -g -DNDEBUG" -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
|
|
||||||
- curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
|
|
||||||
- ./bin/tests
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: cache
|
- name: cache
|
||||||
path: /home/eqemu/.ccache/
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -63,3 +63,11 @@ compile_flags.txt
|
|||||||
|
|
||||||
# vscode generated settings
|
# vscode generated settings
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
# Build pipeline
|
||||||
|
!utils/scripts/build/
|
||||||
|
!utils/scripts/build/should-release/should-release
|
||||||
|
!utils/scripts/build/should-release/should-release.exe
|
||||||
|
|
||||||
|
# CMake Files
|
||||||
|
cmake-build-relwithdebinfo/*
|
||||||
|
|||||||
+747
@@ -0,0 +1,747 @@
|
|||||||
|
## [22.3.0] - 02/06/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add GetAugmentIDsBySlotID & AddItem with table ref Methods. ([#2805](https://github.com/EQEmu/Server/pull/2805)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-29
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* #list now searches without case sensitivity ([#2825](https://github.com/EQEmu/Server/pull/2825)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Remove extraneous else from #weather ([#2819](https://github.com/EQEmu/Server/pull/2819)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix IsUnderwaterOnly crash where npc data references can be stale ([#2830](https://github.com/EQEmu/Server/pull/2830)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Fix command crash with #npcedit weapon when second weapon not passed ni ([#2829](https://github.com/EQEmu/Server/pull/2829)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Fix crash in bot command botdyearmor ([#2832](https://github.com/EQEmu/Server/pull/2832)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### DB Updates
|
||||||
|
|
||||||
|
* Add Windows MySQL path auto detection for users where the path is not found ([#2836](https://github.com/EQEmu/Server/pull/2836)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Doors
|
||||||
|
|
||||||
|
* Have NPCs trigger double doors ([#2821](https://github.com/EQEmu/Server/pull/2821)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Remove door dev tools spam on client controlled doors ([#2824](https://github.com/EQEmu/Server/pull/2824)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Min/Max Status to Merchants ([#2806](https://github.com/EQEmu/Server/pull/2806)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* #reload aa will now refresh the AA table properly for every client when changes are made ([#2814](https://github.com/EQEmu/Server/pull/2814)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
||||||
|
* #reload static should now properly fill the entity_lists for… ([#2815](https://github.com/EQEmu/Server/pull/2815)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
||||||
|
* BuffLevelRestrictions were restricting group buffs if mob targeted ([#2809](https://github.com/EQEmu/Server/pull/2809)) ([noudess](https://github.com/noudess)) 2023-01-29
|
||||||
|
* Fix does_augment_fit_slot method. ([#2817](https://github.com/EQEmu/Server/pull/2817)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-01
|
||||||
|
* Fix NPC ghosting at safe coordinates ([#2823](https://github.com/EQEmu/Server/pull/2823)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
* Fixing % based mob see invis ([#2802](https://github.com/EQEmu/Server/pull/2802)) ([fryguy503](https://github.com/fryguy503)) 2023-01-29
|
||||||
|
* Resolve issue with max buff count being 25 in ROF2. ([#2800](https://github.com/EQEmu/Server/pull/2800)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-28
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Post revert build fix for https://github.com/EQEmu/Server/commit/54050924d81d1f83268fe01f9c2b36fe10626601 ([Akkadius](https://github.com/Akkadius)) 2023-02-01
|
||||||
|
|
||||||
|
### Lua
|
||||||
|
|
||||||
|
* Resolve stoi Exception ([#2736](https://github.com/EQEmu/Server/pull/2736)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Pathing
|
||||||
|
|
||||||
|
* Improvements to handling tight corridors pathing, clipping detection and recovery ([#2826](https://github.com/EQEmu/Server/pull/2826)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Augment Slot support to does_augment_fit ([#2813](https://github.com/EQEmu/Server/pull/2813)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-31
|
||||||
|
* Add EVENT_DAMAGE_GIVEN and EVENT_DAMAGE_TAKEN to Perl/Lua. ([#2804](https://github.com/EQEmu/Server/pull/2804)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||||
|
* Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua. ([#2810](https://github.com/EQEmu/Server/pull/2810)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-30
|
||||||
|
* Add EVENT_TASKACCEPTED to Player scope ([#2822](https://github.com/EQEmu/Server/pull/2822)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
||||||
|
* Add GetItemCooldown to return the time remaining on items… ([#2811](https://github.com/EQEmu/Server/pull/2811)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-30
|
||||||
|
* Add LDoN Methods to Perl/Lua ([#2799](https://github.com/EQEmu/Server/pull/2799)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||||
|
* Add Override Parameters to ScaleNPC() in Perl/Lua. ([#2816](https://github.com/EQEmu/Server/pull/2816)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
||||||
|
* Add rule AlternateAugmentationSealer for using a different bagtype ([#2831](https://github.com/EQEmu/Server/pull/2831)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-06
|
||||||
|
* Default ScaleNPC to always scale. ([#2818](https://github.com/EQEmu/Server/pull/2818)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-06
|
||||||
|
|
||||||
|
### Readme
|
||||||
|
|
||||||
|
* Update build badges with Drone ([Akkadius](https://github.com/Akkadius)) 2023-01-29
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add rule to ignore name filter on chat channel creation. ([#2820](https://github.com/EQEmu/Server/pull/2820)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
||||||
|
* Added rule to bypass level based haste caps ([#2835](https://github.com/EQEmu/Server/pull/2835)) ([jcr4990](https://github.com/jcr4990)) 2023-02-06
|
||||||
|
* Fix rule updates that affected bot booting checks ([#2841](https://github.com/EQEmu/Server/pull/2841)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
* Implement alternate currency rewards ([#2827](https://github.com/EQEmu/Server/pull/2827)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||||
|
|
||||||
|
## [22.2.0] - 01/27/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add EVENT_UNEQUIP_ITEM_BOT & EVENT_EQUIP_ITEM_BOT ([#2796](https://github.com/EQEmu/Server/pull/2796)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-27
|
||||||
|
* ^create and ^viewcombos popup messages fix. ([#2797](https://github.com/EQEmu/Server/pull/2797)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-26
|
||||||
|
|
||||||
|
### Code Cleanup
|
||||||
|
|
||||||
|
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash issue with log formatting during character creation ([#2798](https://github.com/EQEmu/Server/pull/2798)) ([Akkadius](https://github.com/Akkadius)) 2023-01-27
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* ResetItemCooldown added to lua/perl and fix item re-cast times to show properly ([#2793](https://github.com/EQEmu/Server/pull/2793)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-26
|
||||||
|
|
||||||
|
### Git
|
||||||
|
|
||||||
|
* Add CMake Files to .gitignore ([#2792](https://github.com/EQEmu/Server/pull/2792)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-25
|
||||||
|
|
||||||
|
## [22.1.2] - 01/24/2023
|
||||||
|
|
||||||
|
### CI/CD
|
||||||
|
|
||||||
|
* Build / Release Pipeline Changes ([#2788](https://github.com/EQEmu/Server/pull/2788)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
|
||||||
|
|
||||||
|
### Code Cleanup
|
||||||
|
|
||||||
|
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix rarer world crash issue where scheduler database was not available ([#2789](https://github.com/EQEmu/Server/pull/2789)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix nullptr spell in BCSpells::Load() ([#2790](https://github.com/EQEmu/Server/pull/2790)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||||
|
* Remove duplicate logic in GetActSpellHealing reducing HOT criticals ([#2786](https://github.com/EQEmu/Server/pull/2786)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||||
|
|
||||||
|
## [22.1.1] - 01/23/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||||
|
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||||
|
|
||||||
|
## [22.1.0] - 01/22/2023
|
||||||
|
|
||||||
|
This is a first release using the new build system. Changelog entry representative of last year. Subsequent releases will consist of incremental changes since the last release.
|
||||||
|
|
||||||
|
### AA
|
||||||
|
|
||||||
|
* Fix AA tables dump ([#2769](https://github.com/EQEmu/Server/pull/2769)) ([Akkadius](https://github.com/Akkadius)) 2023-01-22
|
||||||
|
|
||||||
|
### Appveyor
|
||||||
|
|
||||||
|
* Remove bots preprocessor ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||||
|
|
||||||
|
### Bot/Merc
|
||||||
|
|
||||||
|
* Cleanup methods, and virtual overrides. ([#2734](https://github.com/EQEmu/Server/pull/2734)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add Bot Command Reloading ([#2773](https://github.com/EQEmu/Server/pull/2773)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||||
|
* Add Bot-specific Spell Settings. ([#2553](https://github.com/EQEmu/Server/pull/2553)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||||
|
* Add Buff support for Bards under AI_IdleCastChecks ([#2590](https://github.com/EQEmu/Server/pull/2590)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-28
|
||||||
|
* Add Data Bucket support to Bot Spell Entries. ([#2505](https://github.com/EQEmu/Server/pull/2505)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
|
||||||
|
* Add EVENT_TRADE Support to Bots. ([#2560](https://github.com/EQEmu/Server/pull/2560)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
||||||
|
* Add Event_Trade Support for ^inventorygive Command ([#2628](https://github.com/EQEmu/Server/pull/2628)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-11
|
||||||
|
* Add Expansion Bitmask Quest APIs. ([#2523](https://github.com/EQEmu/Server/pull/2523)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||||
|
* Add GetBotOwnerByBotID Method ([#2715](https://github.com/EQEmu/Server/pull/2715)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
|
||||||
|
* Add Melee Support for Casting, Cleanup Bot Casting Logic ([#2571](https://github.com/EQEmu/Server/pull/2571)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
||||||
|
* Add Quest API Methods ([#2631](https://github.com/EQEmu/Server/pull/2631)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-12
|
||||||
|
* Add Quest API Support for Limits. ([#2522](https://github.com/EQEmu/Server/pull/2522)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||||
|
* Add Rule Allowing Bots to Equip Any Race Items ([#2578](https://github.com/EQEmu/Server/pull/2578)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-26
|
||||||
|
* Add Support for AA bonuses that were missing. ([#2764](https://github.com/EQEmu/Server/pull/2764)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
||||||
|
* Add Support for Bots to receive Auras, and other AoE Buffs. ([#2586](https://github.com/EQEmu/Server/pull/2586)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
||||||
|
* Add Virtual Override for Bot::Attack ([#2771](https://github.com/EQEmu/Server/pull/2771)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
||||||
|
* Add give/remove saylinks to ^itemuse. ([#2503](https://github.com/EQEmu/Server/pull/2503)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||||
|
* Add support for Bot scripting. ([#2515](https://github.com/EQEmu/Server/pull/2515)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||||
|
* Apply Spells:IgnoreSpellDmgLvlRestriction to bots ([#2024](https://github.com/EQEmu/Server/pull/2024)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
||||||
|
* Bot::PerformTradeWithClient Cleanup. ([#2084](https://github.com/EQEmu/Server/pull/2084)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
|
||||||
|
* Cleanup Bot Spell Functions, reduce reliance on NPC Functions/Attributes ([#2495](https://github.com/EQEmu/Server/pull/2495)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-29
|
||||||
|
* Cleanup Fast Rest Regen ([#2626](https://github.com/EQEmu/Server/pull/2626)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-07
|
||||||
|
* Cleanup Say Event Parse. ([#2557](https://github.com/EQEmu/Server/pull/2557)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
||||||
|
* Cleanup Spell Settings Commands ([#2607](https://github.com/EQEmu/Server/pull/2607)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||||
|
* Cleanup ^inventoryremove, ^inventorylist, and ^list Commands and bot groups. ([#2273](https://github.com/EQEmu/Server/pull/2273)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-03
|
||||||
|
* Cleanup and remove preprocessors. ([#2757](https://github.com/EQEmu/Server/pull/2757)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-20
|
||||||
|
* Cleanup various Bot Spell Focus methods ([#2649](https://github.com/EQEmu/Server/pull/2649)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-16
|
||||||
|
* Convert Load, Save, SaveNew, and Delete to Repositories. ([#2614](https://github.com/EQEmu/Server/pull/2614)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||||
|
* Expanded Bot Spell Settings List. ([#2606](https://github.com/EQEmu/Server/pull/2606)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-03
|
||||||
|
* Fix Bot Spell Type "In Combat Buffs" ([#2711](https://github.com/EQEmu/Server/pull/2711)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-08
|
||||||
|
* Fix Gender not saving as GetBaseGender on BotSave ([#2639](https://github.com/EQEmu/Server/pull/2639)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
|
||||||
|
* Fix Slow Query in QueryNameAvailablity ([#2781](https://github.com/EQEmu/Server/pull/2781)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
|
||||||
|
* Fix ^dyearmor command math. ([#2081](https://github.com/EQEmu/Server/pull/2081)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
||||||
|
* Fix bot spawn when bot id = char_id ([#1984](https://github.com/EQEmu/Server/pull/1984)) ([neckkola](https://github.com/neckkola)) 2022-03-07
|
||||||
|
* Hotfix for possible crash. ([#2539](https://github.com/EQEmu/Server/pull/2539)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Melee Bot Support for Spell Settings Commands ([#2599](https://github.com/EQEmu/Server/pull/2599)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
|
||||||
|
* Move Bot Spell Loading process to constructor from calcbotstats() ([#2583](https://github.com/EQEmu/Server/pull/2583)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
||||||
|
* Optimize inventory loading. ([#2588](https://github.com/EQEmu/Server/pull/2588)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-28
|
||||||
|
* Post pre-processor fixes ([#2770](https://github.com/EQEmu/Server/pull/2770)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||||
|
* Resolve incorrect values on Bot Creation ([#2644](https://github.com/EQEmu/Server/pull/2644)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-14
|
||||||
|
* Restrict Bot Groups from spawning while Feigned. ([#2761](https://github.com/EQEmu/Server/pull/2761)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
|
||||||
|
* Save Bot Toggle Archer Setting between Loads. ([#2612](https://github.com/EQEmu/Server/pull/2612)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||||
|
* Update Bot Heal & Damage methods to more closely match Clients + Bugfixes ([#2045](https://github.com/EQEmu/Server/pull/2045)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-11
|
||||||
|
* Update Bot Logic to ignore ST_TargetsTarget when buffing ([#2584](https://github.com/EQEmu/Server/pull/2584)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
||||||
|
|
||||||
|
### C++20
|
||||||
|
|
||||||
|
* Arithmetic on different enums is deprecated ([#2752](https://github.com/EQEmu/Server/pull/2752)) ([mackal](https://github.com/mackal)) 2023-01-17
|
||||||
|
* Enable C++20 + Fixes + FMT 9.1 ([#2664](https://github.com/EQEmu/Server/pull/2664)) ([Akkadius](https://github.com/Akkadius)) 2022-12-21
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Removed vscode setting ([#2753](https://github.com/EQEmu/Server/pull/2753)) ([xackery](https://github.com/xackery)) 2023-01-17
|
||||||
|
|
||||||
|
### Code Cleanup
|
||||||
|
|
||||||
|
* Add Validation to varchar number item fields. ([#2241](https://github.com/EQEmu/Server/pull/2241)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||||
|
* Cleanup #kick message. ([#2164](https://github.com/EQEmu/Server/pull/2164)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
||||||
|
* Cleanup Haste references and Lua API calls for unsigned to signed. ([#2240](https://github.com/EQEmu/Server/pull/2240)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||||
|
* Cleanup code smells and compiler warnings in common/shareddb ([#2270](https://github.com/EQEmu/Server/pull/2270)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||||
|
* Cleanup magic numbers ([#2662](https://github.com/EQEmu/Server/pull/2662)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-20
|
||||||
|
* Cleanup spell and max level bucket logic. ([#2181](https://github.com/EQEmu/Server/pull/2181)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
||||||
|
* Extra Space in NPC::AISpellsList(). ([#2555](https://github.com/EQEmu/Server/pull/2555)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
||||||
|
* Fix unintended copies in zone/zonedb.cpp by changing auto to auto& ([#2271](https://github.com/EQEmu/Server/pull/2271)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||||
|
* Make use of std::abs where possible. ([#2739](https://github.com/EQEmu/Server/pull/2739)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||||
|
* Merge Client::Attack and Bot::Attack into Mob::Attack ([#2756](https://github.com/EQEmu/Server/pull/2756)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
||||||
|
* Move Client::Undye() to client.cpp from #path Command. ([#2188](https://github.com/EQEmu/Server/pull/2188)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-21
|
||||||
|
* Possible issues with variable/parameter name equality. ([#2161](https://github.com/EQEmu/Server/pull/2161)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
||||||
|
* Quest API push methods using invalid types. ([#2172](https://github.com/EQEmu/Server/pull/2172)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-16
|
||||||
|
* Remove Unused EQEMU_DEPOP_INVALIDATES_CACHE ([#2292](https://github.com/EQEmu/Server/pull/2292)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
||||||
|
* Remove this-> in code where its implied ([#2088](https://github.com/EQEmu/Server/pull/2088)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
|
||||||
|
* Remove unused basic_functions.h ([#2729](https://github.com/EQEmu/Server/pull/2729)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
||||||
|
* Remove unused maxskill.h. ([#2728](https://github.com/EQEmu/Server/pull/2728)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
||||||
|
* Remove unused methods. ([#2171](https://github.com/EQEmu/Server/pull/2171)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
|
||||||
|
* Remove unusued Max Item ID Constant ([#2528](https://github.com/EQEmu/Server/pull/2528)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-08
|
||||||
|
* Remove use of bzero since it is deprecated for memset ([#2295](https://github.com/EQEmu/Server/pull/2295)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
||||||
|
* Resharper Warnings ([#2235](https://github.com/EQEmu/Server/pull/2235)) ([Quintinon](https://github.com/Quintinon)) 2022-06-01
|
||||||
|
* Resolve some warnings in loginserver/world_server.cpp ([#2347](https://github.com/EQEmu/Server/pull/2347)) ([mackal](https://github.com/mackal)) 2022-07-31
|
||||||
|
* Rework Lua QuestReward to not use try/catch blocks ([#2417](https://github.com/EQEmu/Server/pull/2417)) ([mackal](https://github.com/mackal)) 2022-09-03
|
||||||
|
* Send eqstr message in AddAAPoints ([#2507](https://github.com/EQEmu/Server/pull/2507)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||||
|
* Update to EQEmu #2253 to clean up message strings ([#2279](https://github.com/EQEmu/Server/pull/2279)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
||||||
|
* Zone Data Loading Refactor ([#2388](https://github.com/EQEmu/Server/pull/2388)) ([Akkadius](https://github.com/Akkadius)) 2022-09-01
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* #bind Typo. ([#2196](https://github.com/EQEmu/Server/pull/2196)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||||
|
* #ginfo Cleanup. ([#1955](https://github.com/EQEmu/Server/pull/1955)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
|
||||||
|
* #reload Command Overhaul. ([#2162](https://github.com/EQEmu/Server/pull/2162)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
||||||
|
* #reload level_mods could cause Non-Booted zones to crash. ([#2670](https://github.com/EQEmu/Server/pull/2670)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-24
|
||||||
|
* Add #bugs Command. ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Add #feature Command. ([#2142](https://github.com/EQEmu/Server/pull/2142)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Add #findcharacter Command. ([#2692](https://github.com/EQEmu/Server/pull/2692)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
||||||
|
* Add #findrecipe and #viewrecipe Commands. ([#2401](https://github.com/EQEmu/Server/pull/2401)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-31
|
||||||
|
* Add #setanon Command ([#2690](https://github.com/EQEmu/Server/pull/2690)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
||||||
|
* Add #suspendmulti Command. ([#2619](https://github.com/EQEmu/Server/pull/2619)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||||
|
* Add BestZ and Region Data to #loc ([#2245](https://github.com/EQEmu/Server/pull/2245)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-05
|
||||||
|
* Add additional #peqzone functionality. ([#2085](https://github.com/EQEmu/Server/pull/2085)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
|
||||||
|
* Add max_hp back to #modifynpcstat command. ([#2638](https://github.com/EQEmu/Server/pull/2638)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
|
||||||
|
* Adding movespeed to #showstats output ([#2596](https://github.com/EQEmu/Server/pull/2596)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
|
||||||
|
* Bug fix for #logs command. ([#2008](https://github.com/EQEmu/Server/pull/2008)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
|
||||||
|
* Cleanup #ai Command. ([#1980](https://github.com/EQEmu/Server/pull/1980)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
|
||||||
|
* Cleanup #appearanceeffects Command. ([#2777](https://github.com/EQEmu/Server/pull/2777)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||||
|
* Cleanup #attack Command. ([#2103](https://github.com/EQEmu/Server/pull/2103)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||||
|
* Cleanup #ban, #ipban, #flag, #kick, #setlsinfo, and #setpass Commands. ([#2104](https://github.com/EQEmu/Server/pull/2104)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||||
|
* Cleanup #chat Command. ([#2581](https://github.com/EQEmu/Server/pull/2581)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||||
|
* Cleanup #corpsefix Command. ([#2197](https://github.com/EQEmu/Server/pull/2197)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Cleanup #cvs Command. ([#2153](https://github.com/EQEmu/Server/pull/2153)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||||
|
* Cleanup #date Command. ([#2228](https://github.com/EQEmu/Server/pull/2228)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
||||||
|
* Cleanup #dbspawn2 Command. ([#2493](https://github.com/EQEmu/Server/pull/2493)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||||
|
* Cleanup #delacct Command. ([#2567](https://github.com/EQEmu/Server/pull/2567)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Cleanup #depop Command. ([#2536](https://github.com/EQEmu/Server/pull/2536)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Cleanup #depopzone Command. ([#2537](https://github.com/EQEmu/Server/pull/2537)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Cleanup #devtools Command. ([#2538](https://github.com/EQEmu/Server/pull/2538)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Cleanup #doanim Command. ([#2540](https://github.com/EQEmu/Server/pull/2540)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Cleanup #emote Command. ([#2535](https://github.com/EQEmu/Server/pull/2535)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Cleanup #emotesearch and #emoteview Command. ([#2494](https://github.com/EQEmu/Server/pull/2494)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||||
|
* Cleanup #emptyinventory Command. ([#2219](https://github.com/EQEmu/Server/pull/2219)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
|
||||||
|
* Cleanup #findaliases and #help Commands. ([#2204](https://github.com/EQEmu/Server/pull/2204)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Cleanup #findclass and #findrace Commands. ([#2211](https://github.com/EQEmu/Server/pull/2211)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Cleanup #flagedit Command. ([#1968](https://github.com/EQEmu/Server/pull/1968)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Cleanup #freeze and #unfreeze Commands. ([#2102](https://github.com/EQEmu/Server/pull/2102)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||||
|
* Cleanup #gassign Command. ([#2101](https://github.com/EQEmu/Server/pull/2101)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #gearup Command. ([#2589](https://github.com/EQEmu/Server/pull/2589)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||||
|
* Cleanup #getvariable Command. ([#2100](https://github.com/EQEmu/Server/pull/2100)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||||
|
* Cleanup #guild Command ([#2693](https://github.com/EQEmu/Server/pull/2693)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-04
|
||||||
|
* Cleanup #hatelist Command. ([#1976](https://github.com/EQEmu/Server/pull/1976)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Cleanup #heromodel Command. ([#2566](https://github.com/EQEmu/Server/pull/2566)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Cleanup #kill Command. ([#2195](https://github.com/EQEmu/Server/pull/2195)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||||
|
* Cleanup #level Command. ([#2203](https://github.com/EQEmu/Server/pull/2203)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Cleanup #logs Command. ([#1969](https://github.com/EQEmu/Server/pull/1969)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Cleanup #makepet Command. ([#2105](https://github.com/EQEmu/Server/pull/2105)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #modifynpcstat Command. ([#2499](https://github.com/EQEmu/Server/pull/2499)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||||
|
* Cleanup #motd Command. ([#2190](https://github.com/EQEmu/Server/pull/2190)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||||
|
* Cleanup #name Command. ([#1977](https://github.com/EQEmu/Server/pull/1977)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Cleanup #netstats Command. ([#1970](https://github.com/EQEmu/Server/pull/1970)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Cleanup #npcedit Command. ([#2582](https://github.com/EQEmu/Server/pull/2582)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||||
|
* Cleanup #npcedit, #lastname, #title, and #titlesuffix Commands. ([#2215](https://github.com/EQEmu/Server/pull/2215)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
||||||
|
* Cleanup #npceditmass command. ([#1957](https://github.com/EQEmu/Server/pull/1957)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
|
||||||
|
* Cleanup #npcemote Command. ([#2106](https://github.com/EQEmu/Server/pull/2106)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #npcloot Command. ([#1974](https://github.com/EQEmu/Server/pull/1974)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
|
||||||
|
* Cleanup #npcsay and #npcshout Commands. ([#2107](https://github.com/EQEmu/Server/pull/2107)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #npcspecialattk Command. ([#2108](https://github.com/EQEmu/Server/pull/2108)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #npctype_cache Command. ([#2109](https://github.com/EQEmu/Server/pull/2109)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #npctypespawn Command. ([#2110](https://github.com/EQEmu/Server/pull/2110)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #nudge Command. ([#2220](https://github.com/EQEmu/Server/pull/2220)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
|
||||||
|
* Cleanup #oocmute Command. ([#2191](https://github.com/EQEmu/Server/pull/2191)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Cleanup #opcode Command. ([#2547](https://github.com/EQEmu/Server/pull/2547)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||||
|
* Cleanup #profanity Command. ([#2113](https://github.com/EQEmu/Server/pull/2113)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #push Command. ([#2114](https://github.com/EQEmu/Server/pull/2114)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #qglobal Command. ([#2115](https://github.com/EQEmu/Server/pull/2115)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #randomizefeatures Command. ([#2118](https://github.com/EQEmu/Server/pull/2118)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #refreshgroup Command. ([#2119](https://github.com/EQEmu/Server/pull/2119)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadaa Command. ([#2120](https://github.com/EQEmu/Server/pull/2120)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadallrules Command. ([#2121](https://github.com/EQEmu/Server/pull/2121)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadlevelmods Command. ([#2122](https://github.com/EQEmu/Server/pull/2122)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadmerchants Command. ([#2123](https://github.com/EQEmu/Server/pull/2123)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadperlexportsettings Command. ([#2124](https://github.com/EQEmu/Server/pull/2124)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadrulesworld Command. ([#2128](https://github.com/EQEmu/Server/pull/2128)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadstatic Command. ([#2130](https://github.com/EQEmu/Server/pull/2130)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadtitles Command. ([#2125](https://github.com/EQEmu/Server/pull/2125)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadtraps Command. ([#2126](https://github.com/EQEmu/Server/pull/2126)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadworld and #repop Command. ([#2127](https://github.com/EQEmu/Server/pull/2127)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #reloadzps Command. ([#2129](https://github.com/EQEmu/Server/pull/2129)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #resetaa Command. ([#2132](https://github.com/EQEmu/Server/pull/2132)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #resetaa_timer Command. ([#2131](https://github.com/EQEmu/Server/pull/2131)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #resetdisc_timer Command. ([#2133](https://github.com/EQEmu/Server/pull/2133)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #revoke Command. ([#2134](https://github.com/EQEmu/Server/pull/2134)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #roambox Command. ([#2135](https://github.com/EQEmu/Server/pull/2135)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #rules Command. ([#2593](https://github.com/EQEmu/Server/pull/2593)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
|
||||||
|
* Cleanup #save Command. ([#2136](https://github.com/EQEmu/Server/pull/2136)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #scale Command. ([#2591](https://github.com/EQEmu/Server/pull/2591)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
|
||||||
|
* Cleanup #scribespell and #scribespells Commands. ([#2534](https://github.com/EQEmu/Server/pull/2534)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Cleanup #sensetrap Command. ([#2137](https://github.com/EQEmu/Server/pull/2137)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #serverinfo Command. ([#2568](https://github.com/EQEmu/Server/pull/2568)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Cleanup #serverrules Command. ([#2139](https://github.com/EQEmu/Server/pull/2139)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #setlanguage Command. ([#2464](https://github.com/EQEmu/Server/pull/2464)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-13
|
||||||
|
* Cleanup #setskillall Command. ([#1992](https://github.com/EQEmu/Server/pull/1992)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
|
||||||
|
* Cleanup #shownpcgloballoot and #showzonegloballoot Command. ([#2141](https://github.com/EQEmu/Server/pull/2141)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #showskills Command. ([#1994](https://github.com/EQEmu/Server/pull/1994)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
|
||||||
|
* Cleanup #spawneditmass Command. ([#2229](https://github.com/EQEmu/Server/pull/2229)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||||
|
* Cleanup #spawnfix Command. ([#2143](https://github.com/EQEmu/Server/pull/2143)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #spawnstatus Command. ([#2144](https://github.com/EQEmu/Server/pull/2144)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #summon Command. ([#2145](https://github.com/EQEmu/Server/pull/2145)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||||
|
* Cleanup #summonburiedplayercorpse Command. ([#2146](https://github.com/EQEmu/Server/pull/2146)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #suspend Command. ([#2564](https://github.com/EQEmu/Server/pull/2564)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Cleanup #task Command. ([#2071](https://github.com/EQEmu/Server/pull/2071)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-14
|
||||||
|
* Cleanup #time and #timezone Command. ([#2147](https://github.com/EQEmu/Server/pull/2147)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #timers Command. ([#2562](https://github.com/EQEmu/Server/pull/2562)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Cleanup #trapinfo Command. ([#2148](https://github.com/EQEmu/Server/pull/2148)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #ucs Command. ([#2149](https://github.com/EQEmu/Server/pull/2149)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Cleanup #undye and #undyeme Commands. ([#1966](https://github.com/EQEmu/Server/pull/1966)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Cleanup #unscribespell Command. ([#1998](https://github.com/EQEmu/Server/pull/1998)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
|
||||||
|
* Cleanup #untraindisc Command. ([#1996](https://github.com/EQEmu/Server/pull/1996)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
|
||||||
|
* Cleanup #version Command. ([#1967](https://github.com/EQEmu/Server/pull/1967)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Cleanup #worldwide command. ([#2021](https://github.com/EQEmu/Server/pull/2021)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
|
||||||
|
* Cleanup #xtargets Command. ([#2545](https://github.com/EQEmu/Server/pull/2545)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||||
|
* Cleanup #zone and #zoneinstance Commands. ([#2202](https://github.com/EQEmu/Server/pull/2202)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Command Status Reload and Helper Method ([#2377](https://github.com/EQEmu/Server/pull/2377)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
||||||
|
* Consolidate #lock and #unlock Commands into #serverlock. ([#2193](https://github.com/EQEmu/Server/pull/2193)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||||
|
* Fix #copycharacter command crash ([#2446](https://github.com/EQEmu/Server/pull/2446)) ([Akkadius](https://github.com/Akkadius)) 2022-09-25
|
||||||
|
* Fix #killallnpcs from crashing ([#2037](https://github.com/EQEmu/Server/pull/2037)) ([Akkadius](https://github.com/Akkadius)) 2022-03-07
|
||||||
|
* Fix Flymode Command Help Prompt ([#2669](https://github.com/EQEmu/Server/pull/2669)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-23
|
||||||
|
* Fix typos in #ban and #ipban Commands. ([#2209](https://github.com/EQEmu/Server/pull/2209)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
|
||||||
|
* Make #damage require a target ([#2426](https://github.com/EQEmu/Server/pull/2426)) ([hgtw](https://github.com/hgtw)) 2022-09-05
|
||||||
|
* Nested Command Aliases ([#2636](https://github.com/EQEmu/Server/pull/2636)) ([Akkadius](https://github.com/Akkadius)) 2022-12-15
|
||||||
|
* Remove #guildapprove, #guildcreate, and #guildlist Commands ([#2775](https://github.com/EQEmu/Server/pull/2775)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||||
|
* Remove #iteminfo Command. ([#2565](https://github.com/EQEmu/Server/pull/2565)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Remove #profiledump and #profilereset Commands. ([#2546](https://github.com/EQEmu/Server/pull/2546)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||||
|
* Remove #undyeme Command. ([#2776](https://github.com/EQEmu/Server/pull/2776)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||||
|
* Remove unused #bestz and #pf Commands. ([#2112](https://github.com/EQEmu/Server/pull/2112)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Remove unused/broken #deletegraveyard and #setgraveyard Commands. ([#2198](https://github.com/EQEmu/Server/pull/2198)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||||
|
|
||||||
|
### Diawind
|
||||||
|
|
||||||
|
* Plus sign markdown fix ([#2727](https://github.com/EQEmu/Server/pull/2727)) ([Akkadius](https://github.com/Akkadius)) 2023-01-12
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* AA Cap Limit ([#2423](https://github.com/EQEmu/Server/pull/2423)) ([fryguy503](https://github.com/fryguy503)) 2022-10-13
|
||||||
|
* Add "Keeps Sold Items" Flag to NPCs ([#2671](https://github.com/EQEmu/Server/pull/2671)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
||||||
|
* Add Experience Gain Toggle. ([#2676](https://github.com/EQEmu/Server/pull/2676)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-30
|
||||||
|
* Add Guild Chat to Console. ([#2387](https://github.com/EQEmu/Server/pull/2387)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
||||||
|
* Add Hate Override for Heals ([#2485](https://github.com/EQEmu/Server/pull/2485)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-14
|
||||||
|
* Add Rule to Disable Group EXP Modifier. ([#2741](https://github.com/EQEmu/Server/pull/2741)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||||
|
* Add Support for "Show Mine Only" Filters ([#2484](https://github.com/EQEmu/Server/pull/2484)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||||
|
* Add Type 49545 to Spell Resistrictions ([#2436](https://github.com/EQEmu/Server/pull/2436)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
|
||||||
|
* Add humanoid and non-wielded restrictions to pick pocket ([#2276](https://github.com/EQEmu/Server/pull/2276)) ([noudess](https://github.com/noudess)) 2022-07-03
|
||||||
|
* Add player /inspect quest event ([#2508](https://github.com/EQEmu/Server/pull/2508)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||||
|
* Add special ability to block /open ([#2506](https://github.com/EQEmu/Server/pull/2506)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||||
|
* Allow Focus Effects to be Filtered out. ([#2447](https://github.com/EQEmu/Server/pull/2447)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
|
||||||
|
* Allow pets to zone with permanent (buffdurationformula 50) buffs to maintain them through zone transitions ([#2035](https://github.com/EQEmu/Server/pull/2035)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
||||||
|
* Bind Wound and Forage while mounted. ([#2257](https://github.com/EQEmu/Server/pull/2257)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
||||||
|
* Change #scribespells to be aware of spellgroups & ranks ([#2501](https://github.com/EQEmu/Server/pull/2501)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
|
||||||
|
* Change GetSkillDmgAmt to int32 ([#2364](https://github.com/EQEmu/Server/pull/2364)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-10
|
||||||
|
* Change Lifetap Emotes to be filterable. ([#2454](https://github.com/EQEmu/Server/pull/2454)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-29
|
||||||
|
* Change Mana Costs to use Signed Int ([#2384](https://github.com/EQEmu/Server/pull/2384)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-21
|
||||||
|
* Change mana_used to int32 ([#2321](https://github.com/EQEmu/Server/pull/2321)) ([Aeadoin](https://github.com/Aeadoin)) 2022-07-30
|
||||||
|
* Client Checksum Verification (Resubmit old 1678) ([#1922](https://github.com/EQEmu/Server/pull/1922)) ([noudess](https://github.com/noudess)) 2022-03-07
|
||||||
|
* EQ2-style implied targeting for spells. ([#2032](https://github.com/EQEmu/Server/pull/2032)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
||||||
|
* Faction Association ([#2408](https://github.com/EQEmu/Server/pull/2408)) ([mackal](https://github.com/mackal)) 2022-09-03
|
||||||
|
* GM State Change Persistance ([#2328](https://github.com/EQEmu/Server/pull/2328)) ([fryguy503](https://github.com/fryguy503)) 2022-07-31
|
||||||
|
* Implement Heroic Strikethrough to NPCs ([#2395](https://github.com/EQEmu/Server/pull/2395)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-31
|
||||||
|
* Implement OP_CashReward ([#2307](https://github.com/EQEmu/Server/pull/2307)) ([mackal](https://github.com/mackal)) 2022-07-15
|
||||||
|
* Instance Version Specific Experience Modifiers ([#2376](https://github.com/EQEmu/Server/pull/2376)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
||||||
|
* NPCs with bows and arrows do ranged attacks ([#2322](https://github.com/EQEmu/Server/pull/2322)) ([mackal](https://github.com/mackal)) 2022-07-30
|
||||||
|
* Soft Delete Bots on Character Soft Delete ([#2467](https://github.com/EQEmu/Server/pull/2467)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||||
|
* Spell Ranks will now work with AllowSpellMemorizeFromItem Rule ([#2475](https://github.com/EQEmu/Server/pull/2475)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||||
|
* Update HateMod used by SPA 114 to Int32. ([#2428](https://github.com/EQEmu/Server/pull/2428)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-08
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* #npcstats command displaying incorrect faction ([#2710](https://github.com/EQEmu/Server/pull/2710)) ([noudess](https://github.com/noudess)) 2023-01-08
|
||||||
|
* #peqzone no longer bypass Handle_OP_ZoneChange ([#2063](https://github.com/EQEmu/Server/pull/2063)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-19
|
||||||
|
* #scribespells triggered error on mysql keyword rank ([#2779](https://github.com/EQEmu/Server/pull/2779)) ([noudess](https://github.com/noudess)) 2023-01-21
|
||||||
|
* #tune command various fixes ([#2046](https://github.com/EQEmu/Server/pull/2046)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-11
|
||||||
|
* Add Complete Heal Spell back to IsCompleteHealSpell Method ([#2722](https://github.com/EQEmu/Server/pull/2722)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
|
||||||
|
* Add SE_MakeDrunk to avoid error message. ([#2601](https://github.com/EQEmu/Server/pull/2601)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||||
|
* Add omitted function call in UCS ([#2768](https://github.com/EQEmu/Server/pull/2768)) ([Valorith](https://github.com/Valorith)) 2023-01-20
|
||||||
|
* Add required distance to CoTH before aggro wipe ([#2253](https://github.com/EQEmu/Server/pull/2253)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
||||||
|
* Adjustment for nullptr crash ([#2232](https://github.com/EQEmu/Server/pull/2232)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
|
||||||
|
* Alleviate some lag with crosszone/worldwide spell casting. ([#2016](https://github.com/EQEmu/Server/pull/2016)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-21
|
||||||
|
* Allow High Level Spells to be Unmemorized. ([#2641](https://github.com/EQEmu/Server/pull/2641)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
||||||
|
* Allow Songs to be scribed from scrolls ([#2460](https://github.com/EQEmu/Server/pull/2460)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-12
|
||||||
|
* AltCurrencySelectItemReply_Struct was not handled correctly. ([#2702](https://github.com/EQEmu/Server/pull/2702)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-04
|
||||||
|
* Any use of TempName left old clean_name. ([#1946](https://github.com/EQEmu/Server/pull/1946)) ([noudess](https://github.com/noudess)) 2022-01-26
|
||||||
|
* Avoid erase in discord queue range loop ([#2411](https://github.com/EQEmu/Server/pull/2411)) ([hgtw](https://github.com/hgtw)) 2022-09-03
|
||||||
|
* Bandolier didn't recognize source weapon on cursor ([#2026](https://github.com/EQEmu/Server/pull/2026)) ([noudess](https://github.com/noudess)) 2022-03-07
|
||||||
|
* Bard Invisible causing display issues. ([#2067](https://github.com/EQEmu/Server/pull/2067)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-01
|
||||||
|
* Bard update fixes 1 ([#1982](https://github.com/EQEmu/Server/pull/1982)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-09
|
||||||
|
* Bazaar Search MYSQL Error ([#2252](https://github.com/EQEmu/Server/pull/2252)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
|
||||||
|
* Blocked spells max spell id increased ([#2207](https://github.com/EQEmu/Server/pull/2207)) ([Isaaru](https://github.com/Isaaru)) 2022-05-25
|
||||||
|
* Boats should never get FixZ'd ([#2246](https://github.com/EQEmu/Server/pull/2246)) ([noudess](https://github.com/noudess)) 2022-07-02
|
||||||
|
* Clamp Item Ldon Sell Back Rates. ([#2592](https://github.com/EQEmu/Server/pull/2592)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-30
|
||||||
|
* Clear title/suffix bug fix. ([#2068](https://github.com/EQEmu/Server/pull/2068)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
|
||||||
|
* Correct (probably) unintended bitwise AND instead of logical AND ([#2239](https://github.com/EQEmu/Server/pull/2239)) ([Quintinon](https://github.com/Quintinon)) 2022-06-02
|
||||||
|
* Correct type signed/unsigned int when reading item from database in shareddb ([#2269](https://github.com/EQEmu/Server/pull/2269)) ([Quintinon](https://github.com/Quintinon)) 2022-06-15
|
||||||
|
* Data Bucket Permanent Duration String ([#2624](https://github.com/EQEmu/Server/pull/2624)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||||
|
* Delete NpcType Struct returned by Bot::CreateDefaultNPCTypeStructForBot() when unused ([#2267](https://github.com/EQEmu/Server/pull/2267)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
|
||||||
|
* Do not allow /open to be used on traps or auras, causes crash ([#1951](https://github.com/EQEmu/Server/pull/1951)) ([KayenEQ](https://github.com/KayenEQ)) 2022-01-30
|
||||||
|
* Doors::GetSize() Perl Croak Typo. ([#2027](https://github.com/EQEmu/Server/pull/2027)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
|
||||||
|
* EVENT_ENTER_AREA/EVENT_LEAVE_AREA. ([#2698](https://github.com/EQEmu/Server/pull/2698)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
||||||
|
* Edge case AA reset timer issue fixes ([#1995](https://github.com/EQEmu/Server/pull/1995)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-14
|
||||||
|
* Fix #door Save ([#2699](https://github.com/EQEmu/Server/pull/2699)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
||||||
|
* Fix #findaa and GetAAName(). ([#2774](https://github.com/EQEmu/Server/pull/2774)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||||
|
* Fix #zone 0. ([#2691](https://github.com/EQEmu/Server/pull/2691)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||||
|
* Fix Aug Clicks where item has no click effect. ([#2725](https://github.com/EQEmu/Server/pull/2725)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-12
|
||||||
|
* Fix Bot "Failed to Load" Messages. ([#2719](https://github.com/EQEmu/Server/pull/2719)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
|
||||||
|
* Fix Bot Group Loading ([#2780](https://github.com/EQEmu/Server/pull/2780)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
|
||||||
|
* Fix Bot ^spellsettingsadd command ([#2603](https://github.com/EQEmu/Server/pull/2603)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
|
||||||
|
* Fix Duplicate Silent Saylink Messages ([#2386](https://github.com/EQEmu/Server/pull/2386)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
||||||
|
* Fix EntityList::GetBotListByCharacterID() ([#2569](https://github.com/EQEmu/Server/pull/2569)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Fix Flag Updating with SetGMStatus() in Lua. ([#2554](https://github.com/EQEmu/Server/pull/2554)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
||||||
|
* Fix Group XP not working. ([#2748](https://github.com/EQEmu/Server/pull/2748)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
|
||||||
|
* Fix HP Regen Per Second. ([#2206](https://github.com/EQEmu/Server/pull/2206)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-25
|
||||||
|
* Fix IDFile Crash with spaces or invalid data. ([#2597](https://github.com/EQEmu/Server/pull/2597)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||||
|
* Fix IP Exemptions. ([#2189](https://github.com/EQEmu/Server/pull/2189)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
||||||
|
* Fix Instance Repository ([#2598](https://github.com/EQEmu/Server/pull/2598)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||||
|
* Fix Legacy Combat Lua Script ([#2226](https://github.com/EQEmu/Server/pull/2226)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
|
||||||
|
* Fix MovePC in #zone and #zoneinstance Commands. ([#2236](https://github.com/EQEmu/Server/pull/2236)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
||||||
|
* Fix NPC Reference in EVENT_SPAWN ([#2712](https://github.com/EQEmu/Server/pull/2712)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-08
|
||||||
|
* Fix ST_TargetsTarget Spells with Restrictions ([#2746](https://github.com/EQEmu/Server/pull/2746)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
||||||
|
* Fix Silent Saylinks Sending Message to Others. ([#2389](https://github.com/EQEmu/Server/pull/2389)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
||||||
|
* Fix Spell Bucket and Spell Global Logic Checks. ([#2285](https://github.com/EQEmu/Server/pull/2285)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
||||||
|
* Fix Spellinfo Command to work with SpellIDs above int16 ([#2437](https://github.com/EQEmu/Server/pull/2437)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
|
||||||
|
* Fix Strings::Money Missing Conditions. ([#2383](https://github.com/EQEmu/Server/pull/2383)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-21
|
||||||
|
* Fix Swarm Pet Flurry/Rampages Messages ([#2444](https://github.com/EQEmu/Server/pull/2444)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
|
||||||
|
* Fix bot compile locking client on server enter. ([#2210](https://github.com/EQEmu/Server/pull/2210)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
|
||||||
|
* Fix bot guild removal. ([#2194](https://github.com/EQEmu/Server/pull/2194)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||||
|
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||||
|
* Fix bots equipping augments. ([#2772](https://github.com/EQEmu/Server/pull/2772)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||||
|
* Fix case-sensitivity in #suspend Command. ([#2613](https://github.com/EQEmu/Server/pull/2613)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
|
||||||
|
* Fix duplicate and missing messages due to innate in spells ([#2170](https://github.com/EQEmu/Server/pull/2170)) ([noudess](https://github.com/noudess)) 2022-05-20
|
||||||
|
* Fix empty spawned merchants ([#2275](https://github.com/EQEmu/Server/pull/2275)) ([hgtw](https://github.com/hgtw)) 2022-06-28
|
||||||
|
* Fix for Bot command casting ([#1990](https://github.com/EQEmu/Server/pull/1990)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-12
|
||||||
|
* Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs ([#1986](https://github.com/EQEmu/Server/pull/1986)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
|
||||||
|
* Fix for being able to skill up on corspe. ([#2058](https://github.com/EQEmu/Server/pull/2058)) ([noudess](https://github.com/noudess)) 2022-03-19
|
||||||
|
* Fix for castspell command ([#2010](https://github.com/EQEmu/Server/pull/2010)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-18
|
||||||
|
* Fix issue where #advnpcspawn addspawn does not add spawn sometimes. ([#2247](https://github.com/EQEmu/Server/pull/2247)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
|
||||||
|
* Fix issue where you can set your title to titles you don't have. ([#1917](https://github.com/EQEmu/Server/pull/1917)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-30
|
||||||
|
* Fix issue with Bot::LoadAndSpawnAllZonedBots. ([#2733](https://github.com/EQEmu/Server/pull/2733)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||||
|
* Fix issue with mobs summoning PCs into ceilings ([#1921](https://github.com/EQEmu/Server/pull/1921)) ([noudess](https://github.com/noudess)) 2022-01-30
|
||||||
|
* Fix loading world shared task state ([#2398](https://github.com/EQEmu/Server/pull/2398)) ([hgtw](https://github.com/hgtw)) 2022-08-28
|
||||||
|
* Fix luamod GetExperienceForKill return value ([Cole-SoD](https://github.com/Cole-SoD)) 2023-01-12
|
||||||
|
* Fix memory leak in ucs ([#2409](https://github.com/EQEmu/Server/pull/2409)) ([hgtw](https://github.com/hgtw)) 2022-09-03
|
||||||
|
* Fix miscellaneous memory leaks related to EQApplicationPacket and it's pBuffer ([#2262](https://github.com/EQEmu/Server/pull/2262)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||||
|
* Fix null pointer crash on zones that have not booted a zone yet with #reload commands or anything that calls GetZoneDescription ([#2231](https://github.com/EQEmu/Server/pull/2231)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
|
||||||
|
* Fix possible crash in ProcessSpecialAbilities. ([#2630](https://github.com/EQEmu/Server/pull/2630)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||||
|
* Fix possible crash with zone name methods. ([#2055](https://github.com/EQEmu/Server/pull/2055)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
|
||||||
|
* Fix possible issue where variables have the same name. ([#2156](https://github.com/EQEmu/Server/pull/2156)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||||
|
* Fix quest::updatespawntimer() Perl croak. ([#1947](https://github.com/EQEmu/Server/pull/1947)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-26
|
||||||
|
* Fix recipient sound (vtell) on non-player races ([#2066](https://github.com/EQEmu/Server/pull/2066)) ([noudess](https://github.com/noudess)) 2022-04-02
|
||||||
|
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||||
|
* Fix stack leaks in Lua events #2254 ([hgtw](https://github.com/hgtw)) 2022-06-09
|
||||||
|
* Fix trading with bots when in an illusion. ([#2645](https://github.com/EQEmu/Server/pull/2645)) ([nytmyr](https://github.com/nytmyr)) 2022-12-15
|
||||||
|
* Fix two invalid data accesses in zone/client.cpp ([#2238](https://github.com/EQEmu/Server/pull/2238)) ([Quintinon](https://github.com/Quintinon)) 2022-06-07
|
||||||
|
* Fixed Spell Logic for Bot Nukes ([#2481](https://github.com/EQEmu/Server/pull/2481)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||||
|
* Fixed message on promote/demote permissions check. ([#2700](https://github.com/EQEmu/Server/pull/2700)) ([Valorith](https://github.com/Valorith)) 2023-01-02
|
||||||
|
* Fixed several instances of incorrect comparision - & executes after == ([#2025](https://github.com/EQEmu/Server/pull/2025)) ([noudess](https://github.com/noudess)) 2022-03-07
|
||||||
|
* Force NPCs to respect special ability 24 and 50 when set on player pets ([#2059](https://github.com/EQEmu/Server/pull/2059)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-16
|
||||||
|
* Free return value of ZoneDatabase::LoadTraderItemWithCharges() ([#2264](https://github.com/EQEmu/Server/pull/2264)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
|
||||||
|
* Hacker_Str was causing sql errors - Non Escaped ([#2251](https://github.com/EQEmu/Server/pull/2251)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
|
||||||
|
* Handle memory leaks from return value of Client::GetTraderItems() ([#2266](https://github.com/EQEmu/Server/pull/2266)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||||
|
* Handle_OP_AugmentItem could cause Zone crash ([#2750](https://github.com/EQEmu/Server/pull/2750)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
|
||||||
|
* HasPet() Zone Crashes ([#2744](https://github.com/EQEmu/Server/pull/2744)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
||||||
|
* Illusions will now properly display armor to other clients when they zone in. ([#1958](https://github.com/EQEmu/Server/pull/1958)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-04
|
||||||
|
* Instrument Mods should not affect spells that change model size. ([#2072](https://github.com/EQEmu/Server/pull/2072)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-13
|
||||||
|
* Invisible will display as dropped now on air pets when they attack. ([#2042](https://github.com/EQEmu/Server/pull/2042)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
|
||||||
|
* IsDamage test for lifetap was not complete. ([#2213](https://github.com/EQEmu/Server/pull/2213)) ([noudess](https://github.com/noudess)) 2022-05-27
|
||||||
|
* Limit merchant temp item list to zone and instance ([#2346](https://github.com/EQEmu/Server/pull/2346)) ([mackal](https://github.com/mackal)) 2022-07-31
|
||||||
|
* Lua GetBlockNextSpell() no return. ([#2151](https://github.com/EQEmu/Server/pull/2151)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Make Perl TakeMoneyFromPP int64 ([#2158](https://github.com/EQEmu/Server/pull/2158)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||||
|
* Missing break ([#2031](https://github.com/EQEmu/Server/pull/2031)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-04
|
||||||
|
* Move EVENT_SPAWN for adding NPCs back to original spot, also add NPCs… ([#2749](https://github.com/EQEmu/Server/pull/2749)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-17
|
||||||
|
* NPC Constructor was passing hp_regen_per_second out of order to Mob(). ([#2681](https://github.com/EQEmu/Server/pull/2681)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-29
|
||||||
|
* NPC::CountItem and Corpse::CountItem 0 Charge Item Fix. ([#1959](https://github.com/EQEmu/Server/pull/1959)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-04
|
||||||
|
* NPC::GetNPCStat has no default return. ([#2150](https://github.com/EQEmu/Server/pull/2150)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* NPCs were getting weapon proc added twice ([#2277](https://github.com/EQEmu/Server/pull/2277)) ([noudess](https://github.com/noudess)) 2022-07-07
|
||||||
|
* Objects::GetTiltX() and Objects::GetTiltY() Perl Croak Typos. ([#2028](https://github.com/EQEmu/Server/pull/2028)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
|
||||||
|
* PR 1982 ([#1985](https://github.com/EQEmu/Server/pull/1985)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
|
||||||
|
* PR 2032 would lock client on casting fail as written ([#2038](https://github.com/EQEmu/Server/pull/2038)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
|
||||||
|
* Remove StringUtilTest::EscapeStringMemoryTest ([#2310](https://github.com/EQEmu/Server/pull/2310)) ([mackal](https://github.com/mackal)) 2022-07-15
|
||||||
|
* Remove Unnecessary Attack Log ([#2643](https://github.com/EQEmu/Server/pull/2643)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
||||||
|
* Remove unnecessary log messages. ([#2642](https://github.com/EQEmu/Server/pull/2642)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
||||||
|
* Removed Lua Event Argument Dispatch. ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
|
||||||
|
* Resolve Warning due to Virtual Mob Method GetInv() ([#2650](https://github.com/EQEmu/Server/pull/2650)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-19
|
||||||
|
* Resolve XP Calculation Bug introduced w/ recent Rule addition ([#2703](https://github.com/EQEmu/Server/pull/2703)) ([Valorith](https://github.com/Valorith)) 2023-01-07
|
||||||
|
* Resolve logic error in Raid::QueueClients ([#2404](https://github.com/EQEmu/Server/pull/2404)) ([mackal](https://github.com/mackal)) 2022-09-01
|
||||||
|
* Resolve subroutine redefinition due to bot methods. ([#2117](https://github.com/EQEmu/Server/pull/2117)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Restore missing messages for lifetap and dmg spells. ([#2057](https://github.com/EQEmu/Server/pull/2057)) ([noudess](https://github.com/noudess)) 2022-04-14
|
||||||
|
* Shared Memory Faction Association Typo ([#2419](https://github.com/EQEmu/Server/pull/2419)) ([mackal](https://github.com/mackal)) 2022-09-03
|
||||||
|
* Spell Buckets/Globals SQL Escape. ([#2019](https://github.com/EQEmu/Server/pull/2019)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-26
|
||||||
|
* Spell Buckets/Globals did not allow string-based values. ([#2043](https://github.com/EQEmu/Server/pull/2043)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-09
|
||||||
|
* Stop skill ups on Charmed NPCs. ([#2249](https://github.com/EQEmu/Server/pull/2249)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-10
|
||||||
|
* Summon Companion causing pets to warps away. ([#1972](https://github.com/EQEmu/Server/pull/1972)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-08
|
||||||
|
* Touch Of Vinitras was ignoring pet DT rule ([#2469](https://github.com/EQEmu/Server/pull/2469)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-03
|
||||||
|
* Tradeskill Autocombine MinSkill ([#2260](https://github.com/EQEmu/Server/pull/2260)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
||||||
|
* Tradeskill Item 0 Error ([#2256](https://github.com/EQEmu/Server/pull/2256)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
||||||
|
* Zone Flags Regression ([#2760](https://github.com/EQEmu/Server/pull/2760)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
|
||||||
|
* checking casting_spell_slot before its defined is bad ([#2013](https://github.com/EQEmu/Server/pull/2013)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-20
|
||||||
|
* manifest for db version 9176 had incorrect field name ([#2062](https://github.com/EQEmu/Server/pull/2062)) ([noudess](https://github.com/noudess)) 2022-03-19
|
||||||
|
* quest::MovePCInstance() Arguments Fix. ([#2020](https://github.com/EQEmu/Server/pull/2020)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-27
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Add Bazaar portal discs to SQL ([Akkadius](https://github.com/Akkadius)) 2022-09-05
|
||||||
|
* Add discord_webhooks to server tables ([Akkadius](https://github.com/Akkadius)) 2022-07-03
|
||||||
|
* Blocks are nested too deeply. ([#2689](https://github.com/EQEmu/Server/pull/2689)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||||
|
* Cleanup #questerrors Command. ([#2116](https://github.com/EQEmu/Server/pull/2116)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||||
|
* Compiling fails on FMT 9.1 with Bots ([#2665](https://github.com/EQEmu/Server/pull/2665)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-21
|
||||||
|
* Correct database call to point to the content_db connection ([Akkadius](https://github.com/Akkadius)) 2022-06-12
|
||||||
|
* Corrected misnamed Database Query file for Experience Toggle ([#2683](https://github.com/EQEmu/Server/pull/2683)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-31
|
||||||
|
* Faction associations file naming / lock consistency ([Akkadius](https://github.com/Akkadius)) 2022-09-05
|
||||||
|
* Fix DB version merge ([Akkadius](https://github.com/Akkadius)) 2022-05-08
|
||||||
|
* Fix door click crash issue if destination zone doesn't exist ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||||
|
* Fix issue with Bot Loading with 0 Health causing buffs to be lost. ([#2552](https://github.com/EQEmu/Server/pull/2552)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-18
|
||||||
|
* Fix lua mod load path ([Akkadius](https://github.com/Akkadius)) 2022-09-29
|
||||||
|
* Fix merge issue ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
||||||
|
* Fix path load ordering for CLI commands ([Akkadius](https://github.com/Akkadius)) 2022-10-16
|
||||||
|
* Fix potential race for crash dumps (Linux) ([Akkadius](https://github.com/Akkadius)) 2022-07-31
|
||||||
|
* Fix regression caused by #2129 ([Akkadius](https://github.com/Akkadius)) 2022-05-09
|
||||||
|
* Flipped positive / negative values for legacy_combat.lua ([Akkadius](https://github.com/Akkadius)) 2022-06-09
|
||||||
|
* Force collation on conversion script ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
||||||
|
* Instances Repository Fix ([#2576](https://github.com/EQEmu/Server/pull/2576)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||||
|
* Login Server failing to compile on Windows. ([#2758](https://github.com/EQEmu/Server/pull/2758)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
|
||||||
|
* Lua Parser Needs Lua_ItemInst ([#2696](https://github.com/EQEmu/Server/pull/2696)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||||
|
* Make sure we have a proper split size before assuming we can split it ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||||
|
* Move discord_webhooks to state tables because we don't want webhooks being exported ([Akkadius](https://github.com/Akkadius)) 2022-07-03
|
||||||
|
* Possible windows compile fix ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||||
|
* Possible windows compile fix take 2 ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||||
|
* Remove appveyor fetch bots ([Akkadius](https://github.com/Akkadius)) 2023-01-21
|
||||||
|
* Remove expansion field from account for those who have it ([#2357](https://github.com/EQEmu/Server/pull/2357)) ([Akkadius](https://github.com/Akkadius)) 2022-08-01
|
||||||
|
* Resolve Zone Crashing when grouped with Bots. ([#2747](https://github.com/EQEmu/Server/pull/2747)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-16
|
||||||
|
* Resolve issue with Bot Casting after zoning. ([#2617](https://github.com/EQEmu/Server/pull/2617)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||||
|
* Return weather_type_map ([Akkadius](https://github.com/Akkadius)) 2022-10-14
|
||||||
|
* SQL Update ([Akkadius](https://github.com/Akkadius)) 2022-07-31
|
||||||
|
* Shared Memory Protection Fixes ([Akkadius](https://github.com/Akkadius)) 2022-07-27
|
||||||
|
* Windows compile fix take 3 (final) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||||
|
* fix manifest ([Akkadius](https://github.com/Akkadius)) 2022-07-16
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
* Add stack trace in code paths that shouldn't occur ([#2453](https://github.com/EQEmu/Server/pull/2453)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
||||||
|
* Cleanup AI Logging Events ([#2615](https://github.com/EQEmu/Server/pull/2615)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||||
|
* Fix log messages to final damage values ([#2056](https://github.com/EQEmu/Server/pull/2056)) ([noudess](https://github.com/noudess)) 2022-03-14
|
||||||
|
* Fix zoning log typo ([#2478](https://github.com/EQEmu/Server/pull/2478)) ([Akkadius](https://github.com/Akkadius)) 2022-10-11
|
||||||
|
* Force crash logs to always be on regardless of setting ([#2762](https://github.com/EQEmu/Server/pull/2762)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||||
|
* Improvements to GM Say Logging ([#2765](https://github.com/EQEmu/Server/pull/2765)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||||
|
* Logging Improvements ([#2755](https://github.com/EQEmu/Server/pull/2755)) ([Akkadius](https://github.com/Akkadius)) 2023-01-18
|
||||||
|
* More AI Logging Cleanup ([#2616](https://github.com/EQEmu/Server/pull/2616)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-10
|
||||||
|
* Netcode Logging Unify ([#2443](https://github.com/EQEmu/Server/pull/2443)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
||||||
|
* Remove function prefixes ([#2766](https://github.com/EQEmu/Server/pull/2766)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||||
|
* Remove loginserver unhandled error ([#2458](https://github.com/EQEmu/Server/pull/2458)) ([Akkadius](https://github.com/Akkadius)) 2022-09-29
|
||||||
|
* Reset stream so we don't bold the whole line ([Akkadius](https://github.com/Akkadius)) 2023-01-18
|
||||||
|
* Table Injection - Member Variable Cleanup ([#2281](https://github.com/EQEmu/Server/pull/2281)) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||||
|
* Update BUILD_LOGGING=false Blank Aliases ([#2083](https://github.com/EQEmu/Server/pull/2083)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
|
||||||
|
|
||||||
|
### Luamod
|
||||||
|
|
||||||
|
* Add CalcSpellEffectValue_formula to luamods ([#2721](https://github.com/EQEmu/Server/pull/2721)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-11
|
||||||
|
|
||||||
|
### Mercs
|
||||||
|
|
||||||
|
* Add Mercenary Support ([#2745](https://github.com/EQEmu/Server/pull/2745)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-17
|
||||||
|
|
||||||
|
### Optimization
|
||||||
|
|
||||||
|
* Handle channel name filter checks in memory ([#2767](https://github.com/EQEmu/Server/pull/2767)) ([Valorith](https://github.com/Valorith)) 2023-01-20
|
||||||
|
|
||||||
|
### QS
|
||||||
|
|
||||||
|
* Database class name change ([#2743](https://github.com/EQEmu/Server/pull/2743)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add AddAISpellEffect(spell_effect_id, base_value, limit_value, max_value) and RemoveAISpellEffect(spell_effect_id) to Lua. ([#1981](https://github.com/EQEmu/Server/pull/1981)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-09
|
||||||
|
* Add AddItem() to Perl/Lua. ([#2054](https://github.com/EQEmu/Server/pull/2054)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
|
||||||
|
* Add AddPlatinum(), GetCarriedPlatinum() and TakePlatinum() to Perl/Lua. ([#2079](https://github.com/EQEmu/Server/pull/2079)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
||||||
|
* Add Area Damage Methods to Perl/Lua. ([#2549](https://github.com/EQEmu/Server/pull/2549)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||||
|
* Add Augment Slot Type/Visible to GetItemStat ([#2686](https://github.com/EQEmu/Server/pull/2686)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||||
|
* Add Bot Methods to Lua. ([#2731](https://github.com/EQEmu/Server/pull/2731)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
|
||||||
|
* Add Bot::Camp() to Perl/Lua. ([#2718](https://github.com/EQEmu/Server/pull/2718)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
|
||||||
|
* Add BuffCount() Overloads to Perl/Lua. ([#2679](https://github.com/EQEmu/Server/pull/2679)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-29
|
||||||
|
* Add CampAllBots() to Perl/Lua. ([#2732](https://github.com/EQEmu/Server/pull/2732)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
|
||||||
|
* Add Charges/Augment/Attuned Support to Varlink. ([#2685](https://github.com/EQEmu/Server/pull/2685)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||||
|
* Add CheckNameFilter to Perl/Lua. ([#2175](https://github.com/EQEmu/Server/pull/2175)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-20
|
||||||
|
* Add Client Augment Events to Perl/Lua. ([#2735](https://github.com/EQEmu/Server/pull/2735)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||||
|
* Add Client Spell Methods to Perl/Lua. ([#2550](https://github.com/EQEmu/Server/pull/2550)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Add CloneAppearance() to Perl/Lua. ([#2531](https://github.com/EQEmu/Server/pull/2531)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add CopyHateList() to Perl/Lua. ([#2623](https://github.com/EQEmu/Server/pull/2623)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||||
|
* Add Corpse::AddItem overloads for Lua ([#2509](https://github.com/EQEmu/Server/pull/2509)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||||
|
* Add Despawn Events to Perl/Lua. ([#2707](https://github.com/EQEmu/Server/pull/2707)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-07
|
||||||
|
* Add DoAnim Overloads to Perl/Lua. ([#2627](https://github.com/EQEmu/Server/pull/2627)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
|
||||||
|
* Add DoAugmentSlotsMatch() to Perl/Lua. ([#2687](https://github.com/EQEmu/Server/pull/2687)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||||
|
* Add DoesAugmentFit() to Perl/Lua. ([#2688](https://github.com/EQEmu/Server/pull/2688)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||||
|
* Add Door Methods to Perl/Lua. ([#2724](https://github.com/EQEmu/Server/pull/2724)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-12
|
||||||
|
* Add EVENT_AA_BUY and EVENT_AA_GAIN to Perl/Lua. ([#2504](https://github.com/EQEmu/Server/pull/2504)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||||
|
* Add EVENT_BOT_CREATE to Perl/Lua ([#2713](https://github.com/EQEmu/Server/pull/2713)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-09
|
||||||
|
* Add EVENT_CAST_ON exports to EVENT_CAST and EVENT_CAST_BEGIN. ([#2051](https://github.com/EQEmu/Server/pull/2051)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
||||||
|
* Add EVENT_EQUIP_ITEM_CLIENT and EVENT_UNEQUIP_ITEM_CLIENT to Perl/Lua. ([#2015](https://github.com/EQEmu/Server/pull/2015)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-23
|
||||||
|
* Add EVENT_GM_COMMAND to Perl/Lua. ([#2634](https://github.com/EQEmu/Server/pull/2634)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||||
|
* Add EVENT_LEVEL_DOWN to Perl/Lua. ([#2620](https://github.com/EQEmu/Server/pull/2620)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||||
|
* Add EVENT_PAYLOAD to Perl/Lua. ([#2611](https://github.com/EQEmu/Server/pull/2611)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||||
|
* Add EVENT_SKILL_UP & EVENT_LANGUAGE_SKILL_UP to Perl/Lua ([#2076](https://github.com/EQEmu/Server/pull/2076)) ([nytmyr](https://github.com/nytmyr)) 2022-04-25
|
||||||
|
* Add Entity Variable Methods to Perl/Lua. ([#2609](https://github.com/EQEmu/Server/pull/2609)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||||
|
* Add Fling Overloads to Perl/Lua. ([#2622](https://github.com/EQEmu/Server/pull/2622)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||||
|
* Add GetAugmentIDsBySlotID() to Perl/Lua. ([#2673](https://github.com/EQEmu/Server/pull/2673)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
||||||
|
* Add GetAverageLevel() to Perl/Lua. ([#2524](https://github.com/EQEmu/Server/pull/2524)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add GetBotItem() and GetBotItemIDBySlot() to Perl/Lua. ([#2350](https://github.com/EQEmu/Server/pull/2350)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-31
|
||||||
|
* Add GetBotListByCharacterID() to Perl/Lua. ([#2069](https://github.com/EQEmu/Server/pull/2069)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
|
||||||
|
* Add GetBotListByClientName() Class Overload to Perl/Lua. ([#2577](https://github.com/EQEmu/Server/pull/2577)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||||
|
* Add GetBotListByClientName(client_name) to Perl/Lua. ([#2064](https://github.com/EQEmu/Server/pull/2064)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-23
|
||||||
|
* Add GetEnvironmentalDamageName() to Perl/Lua. ([#1964](https://github.com/EQEmu/Server/pull/1964)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||||
|
* Add GetGMStatus() to Perl/Lua. ([#2448](https://github.com/EQEmu/Server/pull/2448)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
|
||||||
|
* Add GetGuildPublicNote() to Perl/Lua. ([#2608](https://github.com/EQEmu/Server/pull/2608)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||||
|
* Add GetHealAmount() and GetSpellDamage() to Perl/Lua. ([#2165](https://github.com/EQEmu/Server/pull/2165)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-11
|
||||||
|
* Add GetLeader() and GetLeaderName() to Perl/Lua. ([#2701](https://github.com/EQEmu/Server/pull/2701)) ([Valorith](https://github.com/Valorith)) 2023-01-04
|
||||||
|
* Add GetLowestLevel() to Perl. ([#2517](https://github.com/EQEmu/Server/pull/2517)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||||
|
* Add GetRandomBot() to Perl/Lua ([#2543](https://github.com/EQEmu/Server/pull/2543)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||||
|
* Add GetRandomClient(), GetRandomMob() and GetRandomNPC() overloads to Perl/Lua. ([#2541](https://github.com/EQEmu/Server/pull/2541)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add GetRandomMob() and GetRandomNPC() to Perl/Lua. ([#2006](https://github.com/EQEmu/Server/pull/2006)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
|
||||||
|
* Add GetSkillDmgAmt() to Perl. ([#2365](https://github.com/EQEmu/Server/pull/2365)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-10
|
||||||
|
* Add GetUltimateOwner() to Perl/Lua. ([#2516](https://github.com/EQEmu/Server/pull/2516)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||||
|
* Add Goto Player Teleport Methods. ([#2379](https://github.com/EQEmu/Server/pull/2379)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
||||||
|
* Add Group/Raid Overloads to Perl/Lua. ([#2587](https://github.com/EQEmu/Server/pull/2587)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||||
|
* Add Group/Raid overloads to Perl/Lua. ([#2526](https://github.com/EQEmu/Server/pull/2526)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add HasBotSpellEntry() to Perl/Lua. ([#2563](https://github.com/EQEmu/Server/pull/2563)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
||||||
|
* Add Hotzone Methods to Perl/Lua. ([#2558](https://github.com/EQEmu/Server/pull/2558)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Add Instance ID/Version exports to EVENT_ZONE. ([#2502](https://github.com/EQEmu/Server/pull/2502)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||||
|
* Add Instance Methods to Perl/Lua. ([#2573](https://github.com/EQEmu/Server/pull/2573)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||||
|
* Add IsAttackAllowed() to Perl/Lua. ([#2672](https://github.com/EQEmu/Server/pull/2672)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
||||||
|
* Add IsRaining() and IsSnowing() to Perl/Lua. ([#2477](https://github.com/EQEmu/Server/pull/2477)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-14
|
||||||
|
* Add IsRareSpawn() to Perl/Lua. ([#2338](https://github.com/EQEmu/Server/pull/2338)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-30
|
||||||
|
* Add Lua handlers for zone controller events ([#2514](https://github.com/EQEmu/Server/pull/2514)) ([hgtw](https://github.com/hgtw)) 2022-11-05
|
||||||
|
* Add Marquee methods to Perl/Lua. ([#2544](https://github.com/EQEmu/Server/pull/2544)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||||
|
* Add MaxSkills() to Perl/Lua. ([#2621](https://github.com/EQEmu/Server/pull/2621)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||||
|
* Add Merchant Events to Perl/Lua. ([#2452](https://github.com/EQEmu/Server/pull/2452)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
|
||||||
|
* Add Mob Hate Methods to Perl/Lua. ([#2548](https://github.com/EQEmu/Server/pull/2548)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||||
|
* Add Overloads to MoveZone Methods in Perl/Lua. ([#2551](https://github.com/EQEmu/Server/pull/2551)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||||
|
* Add Owner methods to Perl/Lua. ([#2542](https://github.com/EQEmu/Server/pull/2542)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add Popup methods to Perl/Lua. ([#2533](https://github.com/EQEmu/Server/pull/2533)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add Proximity Range Methods to Perl/Lua. ([#2572](https://github.com/EQEmu/Server/pull/2572)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||||
|
* Add RandomizeFeature() overloads to Perl/Lua. ([#2532](https://github.com/EQEmu/Server/pull/2532)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add Recipe Methods ([#2393](https://github.com/EQEmu/Server/pull/2393)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-23
|
||||||
|
* Add ResetAlternateAdvancementRank() to Perl/Lua. ([#2510](https://github.com/EQEmu/Server/pull/2510)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||||
|
* Add ResetDecayTimer() to Perl/Lua. ([#2520](https://github.com/EQEmu/Server/pull/2520)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||||
|
* Add SendGMCommand() to Perl/Lua. ([#2527](https://github.com/EQEmu/Server/pull/2527)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add SendPath() to Perl/Lua. ([#2740](https://github.com/EQEmu/Server/pull/2740)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||||
|
* Add SignalAllBotsByOwnerName() to Perl/Lua. ([#2730](https://github.com/EQEmu/Server/pull/2730)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
||||||
|
* Add SplitMoney() with Client splitter to Perl. ([#2525](https://github.com/EQEmu/Server/pull/2525)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||||
|
* Add TaskSelector to Perl/Lua. ([#2177](https://github.com/EQEmu/Server/pull/2177)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
|
||||||
|
* Add Time String to Seconds Method to Perl/Lua. ([#2580](https://github.com/EQEmu/Server/pull/2580)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||||
|
* Add TrackNPC to Perl/Lua. ([#2272](https://github.com/EQEmu/Server/pull/2272)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-29
|
||||||
|
* Add WearChange Overloads to Perl/Lua. ([#2600](https://github.com/EQEmu/Server/pull/2600)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||||
|
* Add Zone Flag Methods to Perl/Lua. ([#2574](https://github.com/EQEmu/Server/pull/2574)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||||
|
* Add apis to end shared tasks ([#2521](https://github.com/EQEmu/Server/pull/2521)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||||
|
* Add caster_id and caster_level export to EVENT_CAST_ON in Perl/Lua. ([#2049](https://github.com/EQEmu/Server/pull/2049)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-11
|
||||||
|
* Add commify to Perl/Lua. ([#2099](https://github.com/EQEmu/Server/pull/2099)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-03
|
||||||
|
* Add inventory->CountItemEquippedByID(item_id) and inventory->HasItemEquippedByID(item_id) to Perl/Lua. ([#1963](https://github.com/EQEmu/Server/pull/1963)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-06
|
||||||
|
* Add missing methods/package.adds to Perl API. ([#2287](https://github.com/EQEmu/Server/pull/2287)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
||||||
|
* Add multiple inventory method short hands to client. ([#2078](https://github.com/EQEmu/Server/pull/2078)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
||||||
|
* Add option to Ignore Mods to CalcEXP ([#2704](https://github.com/EQEmu/Server/pull/2704)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-06
|
||||||
|
* Adjustment to depop_all function. ([#2595](https://github.com/EQEmu/Server/pull/2595)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
|
||||||
|
* Allow CreateInstance to be used without a Client initiator. ([#2399](https://github.com/EQEmu/Server/pull/2399)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-28
|
||||||
|
* Allow EVENT_ZONE to be parsed as non-zero to prevent zoning. ([#2052](https://github.com/EQEmu/Server/pull/2052)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
||||||
|
* Allow scripts to prevent door click ([#2327](https://github.com/EQEmu/Server/pull/2327)) ([hgtw](https://github.com/hgtw)) 2022-07-27
|
||||||
|
* Cleanup Proximity Events ([#2697](https://github.com/EQEmu/Server/pull/2697)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
||||||
|
* Cleanup Signal Methods in Perl/Lua. ([#2604](https://github.com/EQEmu/Server/pull/2604)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||||
|
* Expand Bot quest API functionality. ([#2096](https://github.com/EQEmu/Server/pull/2096)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||||
|
* Expand SaveGuardSpot ([#2258](https://github.com/EQEmu/Server/pull/2258)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
||||||
|
* Export corpse in EVENT_DEATH_COMPLETE ([#2519](https://github.com/EQEmu/Server/pull/2519)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||||
|
* Export killed XYZH to EVENT_DEATH_ZONE in Perl. ([#2050](https://github.com/EQEmu/Server/pull/2050)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
||||||
|
* Fix Lua Door/Object Create Methods. ([#2633](https://github.com/EQEmu/Server/pull/2633)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||||
|
* Fix Perl EVENT_HP double parsing in Spire. ([#2585](https://github.com/EQEmu/Server/pull/2585)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||||
|
* Fix lua task selector count when over max ([#2353](https://github.com/EQEmu/Server/pull/2353)) ([hgtw](https://github.com/hgtw)) 2022-07-31
|
||||||
|
* Fix missing arg in perl set_proximity ([#2291](https://github.com/EQEmu/Server/pull/2291)) ([hgtw](https://github.com/hgtw)) 2022-07-09
|
||||||
|
* Fix parameters in some Perl worldwide methods. ([#2224](https://github.com/EQEmu/Server/pull/2224)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
|
||||||
|
* Let HasQuestSub check encounters ([#2435](https://github.com/EQEmu/Server/pull/2435)) ([hgtw](https://github.com/hgtw)) 2022-09-20
|
||||||
|
* Perl Doors Fix. ([#2288](https://github.com/EQEmu/Server/pull/2288)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
||||||
|
* Perl Money Fixes. ([#2098](https://github.com/EQEmu/Server/pull/2098)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||||
|
* Send delivered task items in trade events ([#2518](https://github.com/EQEmu/Server/pull/2518)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||||
|
* Use Floating Point for CameraEffect Intensity ([#2337](https://github.com/EQEmu/Server/pull/2337)) ([hgtw](https://github.com/hgtw)) 2022-07-31
|
||||||
|
* Use binding library for perl apis ([#2216](https://github.com/EQEmu/Server/pull/2216)) ([hgtw](https://github.com/hgtw)) 2022-07-04
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add Backstab Rules ([#2666](https://github.com/EQEmu/Server/pull/2666)) ([Valorith](https://github.com/Valorith)) 2022-12-21
|
||||||
|
* Add Frontal Stun Immunity Rules. ([#2217](https://github.com/EQEmu/Server/pull/2217)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
|
||||||
|
* Add Keep Level on Death ([#2319](https://github.com/EQEmu/Server/pull/2319)) ([trentdm](https://github.com/trentdm)) 2022-07-30
|
||||||
|
* Add LDoN Loot Count Modifier Rule ([#2694](https://github.com/EQEmu/Server/pull/2694)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
||||||
|
* Add ManaOnDeath and EndurOnDeath ([#2661](https://github.com/EQEmu/Server/pull/2661)) ([fryguy503](https://github.com/fryguy503)) 2022-12-20
|
||||||
|
* Add Rule to Disable NPC Last Names. ([#2227](https://github.com/EQEmu/Server/pull/2227)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||||
|
* Add Rule to Enable Tells with #hideme ([#2358](https://github.com/EQEmu/Server/pull/2358)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-04
|
||||||
|
* Add Rule to allow Assassinate on non-Humanoid body types. ([#2331](https://github.com/EQEmu/Server/pull/2331)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
|
||||||
|
* Add Rule to allow Headshots on non-Humanoid body types. ([#2329](https://github.com/EQEmu/Server/pull/2329)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
|
||||||
|
* Add Rules to disable various item functionalities and cleanup data types. ([#2225](https://github.com/EQEmu/Server/pull/2225)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
||||||
|
* Add Spells:BuffsFadeOnDeath. ([#2200](https://github.com/EQEmu/Server/pull/2200)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Add Spells:IllusionsAlwaysPersist. ([#2199](https://github.com/EQEmu/Server/pull/2199)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||||
|
* Add Toggle for Warrior Shielding ([#2496](https://github.com/EQEmu/Server/pull/2496)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-22
|
||||||
|
* Add adjustment for zone forage. ([#2330](https://github.com/EQEmu/Server/pull/2330)) ([fryguy503](https://github.com/fryguy503)) 2022-07-30
|
||||||
|
* Add rule for NPC Level Based Buff Restrictions. ([#2708](https://github.com/EQEmu/Server/pull/2708)) ([noudess](https://github.com/noudess)) 2023-01-15
|
||||||
|
* Add rule to allow players to permanently save chat channels to database, up to a limit. ([#2706](https://github.com/EQEmu/Server/pull/2706)) ([Valorith](https://github.com/Valorith)) 2023-01-19
|
||||||
|
* Change TradeskillUp Rules to be Floats ([#2674](https://github.com/EQEmu/Server/pull/2674)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-25
|
||||||
|
* Cleanup all unused rules. ([#2184](https://github.com/EQEmu/Server/pull/2184)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||||
|
* Rule Gate Pet Zoning ([#2625](https://github.com/EQEmu/Server/pull/2625)) ([fryguy503](https://github.com/fryguy503)) 2022-12-07
|
||||||
|
* Rule to allow cap on % XP gain per kill ([#2667](https://github.com/EQEmu/Server/pull/2667)) ([Valorith](https://github.com/Valorith)) 2022-12-25
|
||||||
|
* Update logic checks everywhere for FVNoDropFlag. ([#2179](https://github.com/EQEmu/Server/pull/2179)) ([Quintinon](https://github.com/Quintinon)) 2022-07-30
|
||||||
|
|
||||||
|
### SQL
|
||||||
|
|
||||||
|
* Bugs Table Migration (#2602) ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([joligario](https://github.com/joligario)) 2022-12-01
|
||||||
|
* Update 2023_01_15_merc_data.sql ([#2763](https://github.com/EQEmu/Server/pull/2763)) ([joligario](https://github.com/joligario)) 2023-01-20
|
||||||
|
|
||||||
|
### UCS
|
||||||
|
|
||||||
|
* Auto Client Reconnection ([#2154](https://github.com/EQEmu/Server/pull/2154)) ([Akkadius](https://github.com/Akkadius)) 2022-05-08
|
||||||
|
|
||||||
|
### Websocket
|
||||||
|
|
||||||
|
* Fix cpp20/gcc11 compile failure ([#2737](https://github.com/EQEmu/Server/pull/2737)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
|
||||||
|
|
||||||
|
### Zone Flags
|
||||||
|
|
||||||
|
* Use database connection, not content connection ([#2759](https://github.com/EQEmu/Server/pull/2759)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
|
||||||
@@ -23,6 +23,7 @@ IF(MSVC)
|
|||||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
|
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||||
ELSE(MSVC)
|
ELSE(MSVC)
|
||||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# EQEmulator Core Server
|
# EQEmulator Core Server
|
||||||
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
| Drone (Linux x64) | Drone (Windows x64) |
|
||||||
|:---:|:---:|:---:|
|
|:---:|:---:|
|
||||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
version: 1.0.{build}
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
image: Visual Studio 2017
|
|
||||||
configuration: RelWithDebInfo
|
|
||||||
clone_folder: c:\projects\eqemu
|
|
||||||
init:
|
|
||||||
- ps: git config --global core.autocrlf input
|
|
||||||
cache: c:\tools\vcpkg\installed\
|
|
||||||
before_build:
|
|
||||||
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
|
||||||
build:
|
|
||||||
project: C:\projects\eqemu\build\EQEmu.sln
|
|
||||||
parallel: true
|
|
||||||
verbosity: minimal
|
|
||||||
after_build:
|
|
||||||
- cmd: >-
|
|
||||||
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
|
||||||
|
|
||||||
appveyor PushArtifact build_x64-bots.zip
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
version: 1.0.{build}
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
image: Visual Studio 2017
|
|
||||||
configuration: RelWithDebInfo
|
|
||||||
clone_folder: c:\projects\eqemu
|
|
||||||
init:
|
|
||||||
- ps: git config --global core.autocrlf input
|
|
||||||
cache: c:\tools\vcpkg\installed\
|
|
||||||
before_build:
|
|
||||||
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
|
||||||
build:
|
|
||||||
project: C:\projects\eqemu\build\EQEmu.sln
|
|
||||||
parallel: true
|
|
||||||
verbosity: minimal
|
|
||||||
after_build:
|
|
||||||
- cmd: >-
|
|
||||||
7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
|
||||||
|
|
||||||
appveyor PushArtifact build_x64-no-bots.zip
|
|
||||||
+115
-5
@@ -3,13 +3,96 @@
|
|||||||
#include "crash.h"
|
#include "crash.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "process/process.h"
|
#include "process/process.h"
|
||||||
|
#include "http/httplib.h"
|
||||||
|
#include "http/uri.h"
|
||||||
|
#include "json/json.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "eqemu_config.h"
|
||||||
|
#include "serverinfo.h"
|
||||||
|
#include "rulesys.h"
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#if WINDOWS
|
#if WINDOWS
|
||||||
#define popen _popen
|
#define popen _popen
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void SendCrashReport(const std::string &crash_report)
|
||||||
|
{
|
||||||
|
// can configure multiple endpoints if need be
|
||||||
|
std::vector<std::string> endpoints = {
|
||||||
|
"http://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||||
|
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||||
|
};
|
||||||
|
|
||||||
|
auto config = EQEmuConfig::get();
|
||||||
|
for (auto &e: endpoints) {
|
||||||
|
uri u(e);
|
||||||
|
|
||||||
|
std::string base_url = fmt::format("{}://{}", u.get_scheme(), u.get_host());
|
||||||
|
if (u.get_port()) {
|
||||||
|
base_url += fmt::format(":{}", u.get_port());
|
||||||
|
}
|
||||||
|
|
||||||
|
// client
|
||||||
|
httplib::Client r(base_url);
|
||||||
|
r.set_connection_timeout(1, 0);
|
||||||
|
r.set_read_timeout(1, 0);
|
||||||
|
r.set_write_timeout(1, 0);
|
||||||
|
httplib::Headers headers = {
|
||||||
|
{"Content-Type", "application/json"}
|
||||||
|
};
|
||||||
|
|
||||||
|
// os info
|
||||||
|
auto os = EQ::GetOS();
|
||||||
|
auto cpus = EQ::GetCPUs();
|
||||||
|
auto process_id = EQ::GetPID();
|
||||||
|
auto rss = EQ::GetRSS() / 1048576.0;
|
||||||
|
auto uptime = static_cast<uint32>(EQ::GetUptime());
|
||||||
|
|
||||||
|
// payload
|
||||||
|
Json::Value p;
|
||||||
|
p["platform_name"] = GetPlatformName();
|
||||||
|
p["crash_report"] = crash_report;
|
||||||
|
p["server_version"] = CURRENT_VERSION;
|
||||||
|
p["compile_date"] = COMPILE_DATE;
|
||||||
|
p["compile_time"] = COMPILE_TIME;
|
||||||
|
p["server_name"] = config->LongName;
|
||||||
|
p["server_short_name"] = config->ShortName;
|
||||||
|
p["uptime"] = uptime;
|
||||||
|
p["os_machine"] = os.machine;
|
||||||
|
p["os_release"] = os.release;
|
||||||
|
p["os_version"] = os.version;
|
||||||
|
p["os_sysname"] = os.sysname;
|
||||||
|
p["process_id"] = process_id;
|
||||||
|
p["rss_memory"] = rss;
|
||||||
|
p["cpus"] = cpus.size();
|
||||||
|
p["origination_info"] = "";
|
||||||
|
|
||||||
|
if (!LogSys.origination_info.zone_short_name.empty()) {
|
||||||
|
p["origination_info"] = fmt::format(
|
||||||
|
"{} ({}) instance_id [{}]",
|
||||||
|
LogSys.origination_info.zone_short_name,
|
||||||
|
LogSys.origination_info.zone_long_name,
|
||||||
|
LogSys.origination_info.instance_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream payload;
|
||||||
|
payload << p;
|
||||||
|
|
||||||
|
if (auto res = r.Post(e, payload.str(), "application/json")) {
|
||||||
|
if (res->status == 200) {
|
||||||
|
LogInfo("Sent crash report");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogError("Failed to send crash report to [{}]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
||||||
#include "StackWalker.h"
|
#include "StackWalker.h"
|
||||||
@@ -21,22 +104,30 @@ public:
|
|||||||
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
||||||
virtual void OnOutput(LPCSTR szText) {
|
virtual void OnOutput(LPCSTR szText) {
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
for(int i = 0; i < 4096; ++i) {
|
for (int i = 0; i < 4096; ++i) {
|
||||||
if(szText[i] == 0) {
|
if (szText[i] == 0) {
|
||||||
buffer[i] = '\0';
|
buffer[i] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(szText[i] == '\n' || szText[i] == '\r') {
|
if (szText[i] == '\n' || szText[i] == '\r') {
|
||||||
buffer[i] = ' ';
|
buffer[i] = ' ';
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
buffer[i] = szText[i];
|
buffer[i] = szText[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string line = buffer;
|
||||||
|
_lines.push_back(line);
|
||||||
|
|
||||||
Log(Logs::General, Logs::Crash, buffer);
|
Log(Logs::General, Logs::Crash, buffer);
|
||||||
StackWalker::OnOutput(szText);
|
StackWalker::OnOutput(szText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& const GetLines() { return _lines; }
|
||||||
|
private:
|
||||||
|
std::vector<std::string> _lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
@@ -110,7 +201,20 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
|||||||
|
|
||||||
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||||
{
|
{
|
||||||
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
EQEmuStackWalker sw;
|
||||||
|
sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||||
|
|
||||||
|
if (RuleB(Analytics, CrashReporting)) {
|
||||||
|
std::string crash_report;
|
||||||
|
auto& lines = sw.GetLines();
|
||||||
|
|
||||||
|
for (auto& line : lines) {
|
||||||
|
crash_report += line;
|
||||||
|
crash_report += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
SendCrashReport(crash_report);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
@@ -181,12 +285,18 @@ void print_trace()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream input(temp_output_file);
|
std::ifstream input(temp_output_file);
|
||||||
|
std::string crash_report;
|
||||||
for (std::string line; getline(input, line);) {
|
for (std::string line; getline(input, line);) {
|
||||||
LogCrash("{}", line);
|
LogCrash("{}", line);
|
||||||
|
crash_report += fmt::format("{}\n", line);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::remove(temp_output_file.c_str());
|
std::remove(temp_output_file.c_str());
|
||||||
|
|
||||||
|
if (RuleB(Analytics, CrashReporting)) {
|
||||||
|
SendCrashReport(crash_report);
|
||||||
|
}
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -476,10 +476,11 @@ bool Database::CheckDatabaseConversions() {
|
|||||||
CheckDatabaseConvertPPDeblob();
|
CheckDatabaseConvertPPDeblob();
|
||||||
CheckDatabaseConvertCorpseDeblob();
|
CheckDatabaseConvertCorpseDeblob();
|
||||||
|
|
||||||
RuleManager::Instance()->LoadRules(this, "default", false);
|
auto *r = RuleManager::Instance();
|
||||||
|
r->LoadRules(this, "default", false);
|
||||||
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
||||||
LogInfo("Bot tables found but rule not enabled, enabling");
|
LogInfo("Bot tables found but rule not enabled, enabling");
|
||||||
RuleManager::Instance()->SetRule("Bots:Enabled", "true", this, true, true);
|
r->SetRule("Bots:Enabled", "true", this, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run EQEmu Server script (Checks for database updates) */
|
/* Run EQEmu Server script (Checks for database updates) */
|
||||||
|
|||||||
@@ -79,6 +79,8 @@
|
|||||||
#define ANIM_DEATH 0x73
|
#define ANIM_DEATH 0x73
|
||||||
#define ANIM_LOOT 0x69
|
#define ANIM_LOOT 0x69
|
||||||
|
|
||||||
|
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eaStanding = 0,
|
eaStanding = 0,
|
||||||
eaSitting, //1
|
eaSitting, //1
|
||||||
@@ -1026,4 +1028,7 @@ enum ZoningMessage : int8
|
|||||||
ZoneNoExperience = -7
|
ZoneNoExperience = -7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ALT_CURRENCY_ID_RADIANT 4
|
||||||
|
#define ALT_CURRENCY_ID_EBON 5
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 BUFF_COUNT = 25;
|
static const uint32 BUFF_COUNT = 42;
|
||||||
static const uint32 PET_BUFF_COUNT = 30;
|
static const uint32 PET_BUFF_COUNT = 30;
|
||||||
static const uint32 MAX_MERC = 100;
|
static const uint32 MAX_MERC = 100;
|
||||||
static const uint32 MAX_MERC_GRADES = 10;
|
static const uint32 MAX_MERC_GRADES = 10;
|
||||||
@@ -3637,6 +3637,8 @@ struct MerchantList {
|
|||||||
uint32 item;
|
uint32 item;
|
||||||
int16 faction_required;
|
int16 faction_required;
|
||||||
int8 level_required;
|
int8 level_required;
|
||||||
|
uint8 min_status;
|
||||||
|
uint8 max_status;
|
||||||
uint16 alt_currency_cost;
|
uint16 alt_currency_cost;
|
||||||
uint32 classes_required;
|
uint32 classes_required;
|
||||||
uint8 probability;
|
uint8 probability;
|
||||||
@@ -4545,7 +4547,7 @@ struct ItemVerifyReply_Struct {
|
|||||||
struct ItemRecastDelay_Struct {
|
struct ItemRecastDelay_Struct {
|
||||||
/*000*/ uint32 recast_delay; // in seconds
|
/*000*/ uint32 recast_delay; // in seconds
|
||||||
/*004*/ uint32 recast_type;
|
/*004*/ uint32 recast_type;
|
||||||
/*008*/ uint32 unknown008;
|
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -358,14 +358,26 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
|||||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const
|
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon())
|
if (!m_item || !m_item->IsClassCommon()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) {
|
if (
|
||||||
|
(
|
||||||
|
!GetItem(slot) &&
|
||||||
|
m_item->AugSlotVisible[slot]
|
||||||
|
) &&
|
||||||
|
augment_type == -1 ||
|
||||||
|
(
|
||||||
|
m_item->AugSlotType[slot] &&
|
||||||
|
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||||
|
)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ namespace EQ
|
|||||||
//
|
//
|
||||||
bool IsAugmentable() const;
|
bool IsAugmentable() const;
|
||||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||||
int8 AvailableAugmentSlot(int32 augtype) const;
|
int8 AvailableAugmentSlot(int32 augment_type) const;
|
||||||
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
|
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
|
||||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||||
|
|
||||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseMerchantlistRepository {
|
class BaseMerchantlistRepository {
|
||||||
public:
|
public:
|
||||||
struct Merchantlist {
|
struct Merchantlist {
|
||||||
@@ -24,6 +25,8 @@ public:
|
|||||||
int32_t item;
|
int32_t item;
|
||||||
int16_t faction_required;
|
int16_t faction_required;
|
||||||
uint8_t level_required;
|
uint8_t level_required;
|
||||||
|
uint8_t min_status;
|
||||||
|
uint8_t max_status;
|
||||||
uint16_t alt_currency_cost;
|
uint16_t alt_currency_cost;
|
||||||
int32_t classes_required;
|
int32_t classes_required;
|
||||||
int32_t probability;
|
int32_t probability;
|
||||||
@@ -49,6 +52,8 @@ public:
|
|||||||
"item",
|
"item",
|
||||||
"faction_required",
|
"faction_required",
|
||||||
"level_required",
|
"level_required",
|
||||||
|
"min_status",
|
||||||
|
"max_status",
|
||||||
"alt_currency_cost",
|
"alt_currency_cost",
|
||||||
"classes_required",
|
"classes_required",
|
||||||
"probability",
|
"probability",
|
||||||
@@ -70,6 +75,8 @@ public:
|
|||||||
"item",
|
"item",
|
||||||
"faction_required",
|
"faction_required",
|
||||||
"level_required",
|
"level_required",
|
||||||
|
"min_status",
|
||||||
|
"max_status",
|
||||||
"alt_currency_cost",
|
"alt_currency_cost",
|
||||||
"classes_required",
|
"classes_required",
|
||||||
"probability",
|
"probability",
|
||||||
@@ -125,6 +132,8 @@ public:
|
|||||||
e.item = 0;
|
e.item = 0;
|
||||||
e.faction_required = -100;
|
e.faction_required = -100;
|
||||||
e.level_required = 0;
|
e.level_required = 0;
|
||||||
|
e.min_status = 0;
|
||||||
|
e.max_status = 255;
|
||||||
e.alt_currency_cost = 0;
|
e.alt_currency_cost = 0;
|
||||||
e.classes_required = 65535;
|
e.classes_required = 65535;
|
||||||
e.probability = 100;
|
e.probability = 100;
|
||||||
@@ -160,8 +169,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
merchantlist_id
|
merchantlist_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -175,16 +185,18 @@ public:
|
|||||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||||
e.bucket_name = row[8] ? row[8] : "";
|
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.bucket_value = row[9] ? row[9] : "";
|
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
e.bucket_name = row[10] ? row[10] : "";
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
e.bucket_value = row[11] ? row[11] : "";
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.content_flags = row[13] ? row[13] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||||
|
e.content_flags = row[15] ? row[15] : "";
|
||||||
|
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -223,16 +235,18 @@ public:
|
|||||||
v.push_back(columns[2] + " = " + std::to_string(e.item));
|
v.push_back(columns[2] + " = " + std::to_string(e.item));
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.faction_required));
|
v.push_back(columns[3] + " = " + std::to_string(e.faction_required));
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.level_required));
|
v.push_back(columns[4] + " = " + std::to_string(e.level_required));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.alt_currency_cost));
|
v.push_back(columns[5] + " = " + std::to_string(e.min_status));
|
||||||
v.push_back(columns[6] + " = " + std::to_string(e.classes_required));
|
v.push_back(columns[6] + " = " + std::to_string(e.max_status));
|
||||||
v.push_back(columns[7] + " = " + std::to_string(e.probability));
|
v.push_back(columns[7] + " = " + std::to_string(e.alt_currency_cost));
|
||||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.bucket_name) + "'");
|
v.push_back(columns[8] + " = " + std::to_string(e.classes_required));
|
||||||
v.push_back(columns[9] + " = '" + Strings::Escape(e.bucket_value) + "'");
|
v.push_back(columns[9] + " = " + std::to_string(e.probability));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.bucket_comparison));
|
v.push_back(columns[10] + " = '" + Strings::Escape(e.bucket_name) + "'");
|
||||||
v.push_back(columns[11] + " = " + std::to_string(e.min_expansion));
|
v.push_back(columns[11] + " = '" + Strings::Escape(e.bucket_value) + "'");
|
||||||
v.push_back(columns[12] + " = " + std::to_string(e.max_expansion));
|
v.push_back(columns[12] + " = " + std::to_string(e.bucket_comparison));
|
||||||
v.push_back(columns[13] + " = '" + Strings::Escape(e.content_flags) + "'");
|
v.push_back(columns[13] + " = " + std::to_string(e.min_expansion));
|
||||||
v.push_back(columns[14] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
v.push_back(columns[14] + " = " + std::to_string(e.max_expansion));
|
||||||
|
v.push_back(columns[15] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back(columns[16] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -259,6 +273,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.item));
|
v.push_back(std::to_string(e.item));
|
||||||
v.push_back(std::to_string(e.faction_required));
|
v.push_back(std::to_string(e.faction_required));
|
||||||
v.push_back(std::to_string(e.level_required));
|
v.push_back(std::to_string(e.level_required));
|
||||||
|
v.push_back(std::to_string(e.min_status));
|
||||||
|
v.push_back(std::to_string(e.max_status));
|
||||||
v.push_back(std::to_string(e.alt_currency_cost));
|
v.push_back(std::to_string(e.alt_currency_cost));
|
||||||
v.push_back(std::to_string(e.classes_required));
|
v.push_back(std::to_string(e.classes_required));
|
||||||
v.push_back(std::to_string(e.probability));
|
v.push_back(std::to_string(e.probability));
|
||||||
@@ -303,6 +319,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.item));
|
v.push_back(std::to_string(e.item));
|
||||||
v.push_back(std::to_string(e.faction_required));
|
v.push_back(std::to_string(e.faction_required));
|
||||||
v.push_back(std::to_string(e.level_required));
|
v.push_back(std::to_string(e.level_required));
|
||||||
|
v.push_back(std::to_string(e.min_status));
|
||||||
|
v.push_back(std::to_string(e.max_status));
|
||||||
v.push_back(std::to_string(e.alt_currency_cost));
|
v.push_back(std::to_string(e.alt_currency_cost));
|
||||||
v.push_back(std::to_string(e.classes_required));
|
v.push_back(std::to_string(e.classes_required));
|
||||||
v.push_back(std::to_string(e.probability));
|
v.push_back(std::to_string(e.probability));
|
||||||
@@ -351,16 +369,18 @@ public:
|
|||||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||||
e.bucket_name = row[8] ? row[8] : "";
|
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.bucket_value = row[9] ? row[9] : "";
|
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
e.bucket_name = row[10] ? row[10] : "";
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
e.bucket_value = row[11] ? row[11] : "";
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.content_flags = row[13] ? row[13] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||||
|
e.content_flags = row[15] ? row[15] : "";
|
||||||
|
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -390,16 +410,18 @@ public:
|
|||||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||||
e.bucket_name = row[8] ? row[8] : "";
|
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.bucket_value = row[9] ? row[9] : "";
|
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
e.bucket_name = row[10] ? row[10] : "";
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
e.bucket_value = row[11] ? row[11] : "";
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.content_flags = row[13] ? row[13] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||||
|
e.content_flags = row[15] ? row[15] : "";
|
||||||
|
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -385,7 +385,16 @@ void RuleManager::_SaveRule(Database *db, RuleType type, uint16 index) {
|
|||||||
e.rule_value = rule_value;
|
e.rule_value = rule_value;
|
||||||
e.notes = rule_notes;
|
e.notes = rule_notes;
|
||||||
|
|
||||||
RuleValuesRepository::UpdateOne(*db, e);
|
db->QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE rule_values SET rule_value = '{}', notes = '{}' WHERE ruleset_id = {} AND rule_name = '{}'",
|
||||||
|
rule_value,
|
||||||
|
Strings::Escape(rule_notes),
|
||||||
|
e.ruleset_id,
|
||||||
|
e.rule_name
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ RULE_INT(Character, ExperiencePercentCapPerKill, -1, "Caps the percentage of exp
|
|||||||
RULE_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier based on number of players in group, default is true")
|
RULE_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier based on number of players in group, default is true")
|
||||||
RULE_REAL(Character, GroupMemberEXPModifier, 0.2, "Sets the group experience modifier per members between 2 and 5, default is 0.2")
|
RULE_REAL(Character, GroupMemberEXPModifier, 0.2, "Sets the group experience modifier per members between 2 and 5, default is 0.2")
|
||||||
RULE_REAL(Character, FullGroupEXPModifier, 2.16, "Sets the group experience modifier for a full group, default is 2.16")
|
RULE_REAL(Character, FullGroupEXPModifier, 2.16, "Sets the group experience modifier for a full group, default is 2.16")
|
||||||
|
RULE_BOOL(Character, IgnoreLevelBasedHasteCaps, false, "Ignores hard coded level based haste caps.")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Mercs)
|
RULE_CATEGORY(Mercs)
|
||||||
@@ -317,6 +318,7 @@ RULE_BOOL(Map, FixPathingZOnSendTo, false, "Try to repair Z coordinates in the S
|
|||||||
RULE_BOOL(Map, FixZWhenPathing, true, "Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)")
|
RULE_BOOL(Map, FixZWhenPathing, true, "Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)")
|
||||||
RULE_REAL(Map, DistanceCanTravelBeforeAdjustment, 10.0, "Distance a mob can path before FixZ is called, depends on FixZWhenPathing")
|
RULE_REAL(Map, DistanceCanTravelBeforeAdjustment, 10.0, "Distance a mob can path before FixZ is called, depends on FixZWhenPathing")
|
||||||
RULE_BOOL(Map, MobZVisualDebug, false, "Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)")
|
RULE_BOOL(Map, MobZVisualDebug, false, "Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)")
|
||||||
|
RULE_BOOL(Map, MobPathingVisualDebug, false, "Displays nodes in pathing points in realtime to help with visual debugging")
|
||||||
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20, "At runtime in SendTo: maximum change in Z to allow the BestZ code to apply")
|
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20, "At runtime in SendTo: maximum change in Z to allow the BestZ code to apply")
|
||||||
RULE_INT(Map, FindBestZHeightAdjust, 1, "Adds this to the current Z before seeking the best Z position")
|
RULE_INT(Map, FindBestZHeightAdjust, 1, "Adds this to the current Z before seeking the best Z position")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
@@ -583,6 +585,7 @@ RULE_INT(Range, SongMessages, 75, "The packet range in which song messages are s
|
|||||||
RULE_INT(Range, ClientPositionUpdates, 300, "Distance in which the own changed position is communicated to other clients")
|
RULE_INT(Range, ClientPositionUpdates, 300, "Distance in which the own changed position is communicated to other clients")
|
||||||
RULE_INT(Range, CriticalDamage, 80, "The packet range in which critical hit messages are sent")
|
RULE_INT(Range, CriticalDamage, 80, "The packet range in which critical hit messages are sent")
|
||||||
RULE_INT(Range, MobCloseScanDistance, 600, "Close scan distance")
|
RULE_INT(Range, MobCloseScanDistance, 600, "Close scan distance")
|
||||||
|
RULE_INT(Range, MaxDistanceToClickDoors, 100, "Max distance that a client can click a door from (Client says 'You can't reach that' at roughly 25-50 for most doors)")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Bots)
|
RULE_CATEGORY(Bots)
|
||||||
@@ -623,6 +626,7 @@ RULE_BOOL(Chat, EnableVoiceMacros, true, "Enable voice macros")
|
|||||||
RULE_BOOL(Chat, EnableMailKeyIPVerification, true, "Setting whether the authenticity of the client should be verified via its IP address when accessing the InGame mailbox")
|
RULE_BOOL(Chat, EnableMailKeyIPVerification, true, "Setting whether the authenticity of the client should be verified via its IP address when accessing the InGame mailbox")
|
||||||
RULE_BOOL(Chat, EnableAntiSpam, true, "Enable anti-spam system for chat")
|
RULE_BOOL(Chat, EnableAntiSpam, true, "Enable anti-spam system for chat")
|
||||||
RULE_BOOL(Chat, SuppressCommandErrors, false, "Do not suppress command errors by default")
|
RULE_BOOL(Chat, SuppressCommandErrors, false, "Do not suppress command errors by default")
|
||||||
|
RULE_BOOL(Chat, ChannelsIgnoreNameFilter, false, "Ignore name filtering when creating new chat channels")
|
||||||
RULE_INT(Chat, MaxPermanentPlayerChannels, 0, "Maximum number of permanent chat channels a player can make. Default 0.")
|
RULE_INT(Chat, MaxPermanentPlayerChannels, 0, "Maximum number of permanent chat channels a player can make. Default 0.")
|
||||||
RULE_INT(Chat, MinStatusToBypassAntiSpam, 100, "Minimum status to bypass the anti-spam system")
|
RULE_INT(Chat, MinStatusToBypassAntiSpam, 100, "Minimum status to bypass the anti-spam system")
|
||||||
RULE_INT(Chat, MinimumMessagesPerInterval, 4, "Minimum number of chat messages allowed per interval. The karma value is added to this value")
|
RULE_INT(Chat, MinimumMessagesPerInterval, 4, "Minimum number of chat messages allowed per interval. The karma value is added to this value")
|
||||||
@@ -744,6 +748,7 @@ RULE_BOOL(Inventory, DeleteTransformationMold, true, "False if you want mold to
|
|||||||
RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any weapon transformation")
|
RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any weapon transformation")
|
||||||
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
||||||
RULE_BOOL(Inventory, AllowMultipleOfSameAugment, false, "Allows multiple of the same augment to be placed in an item via #augmentitem or MQ2, set to true to allow")
|
RULE_BOOL(Inventory, AllowMultipleOfSameAugment, false, "Allows multiple of the same augment to be placed in an item via #augmentitem or MQ2, set to true to allow")
|
||||||
|
RULE_INT(Inventory, AlternateAugmentationSealer, 53, "Allows RoF+ clients to augment items from a special container type")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Client)
|
RULE_CATEGORY(Client)
|
||||||
@@ -766,6 +771,10 @@ RULE_INT(Faction, DubiouslyFactionMinimum, -500, "Minimum faction for dubiously"
|
|||||||
RULE_INT(Faction, ThreateninglyFactionMinimum, -750, "Minimum faction for threateningly")
|
RULE_INT(Faction, ThreateninglyFactionMinimum, -750, "Minimum faction for threateningly")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
|
RULE_CATEGORY(Analytics)
|
||||||
|
RULE_BOOL(Analytics, CrashReporting, true, "Automatic crash reporting analytics for EQEmu Server developers")
|
||||||
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Logging)
|
RULE_CATEGORY(Logging)
|
||||||
RULE_BOOL(Logging, PrintFileFunctionAndLine, false, "Ex: [World Server] [net.cpp::main:309] Loading variables...")
|
RULE_BOOL(Logging, PrintFileFunctionAndLine, false, "Ex: [World Server] [net.cpp::main:309] Loading variables...")
|
||||||
RULE_BOOL(Logging, WorldGMSayLogging, true, "Relay worldserver logging to zone processes via GM say output")
|
RULE_BOOL(Logging, WorldGMSayLogging, true, "Relay worldserver logging to zone processes via GM say output")
|
||||||
|
|||||||
@@ -143,6 +143,10 @@ bool ServerEventScheduler::ValidateDatabaseConnection()
|
|||||||
// this helps inform decisions to tell all zones to reload their events
|
// this helps inform decisions to tell all zones to reload their events
|
||||||
bool ServerEventScheduler::CheckIfEventsChanged()
|
bool ServerEventScheduler::CheckIfEventsChanged()
|
||||||
{
|
{
|
||||||
|
if (!m_database) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto events = ServerScheduledEventsRepository::GetWhere(*m_database, "deleted_at is null");
|
auto events = ServerScheduledEventsRepository::GetWhere(*m_database, "deleted_at is null");
|
||||||
|
|
||||||
// first check if the size changed, if it did this is the easiest step
|
// first check if the size changed, if it did this is the easiest step
|
||||||
|
|||||||
+6
-2
@@ -721,11 +721,15 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
|
|||||||
inst->SetCharges(charges);
|
inst->SetCharges(charges);
|
||||||
|
|
||||||
if (item->RecastDelay) {
|
if (item->RecastDelay) {
|
||||||
if (timestamps.count(item->RecastType))
|
if (item->RecastType != RECAST_TYPE_UNLINKED_ITEM && timestamps.count(item->RecastType)) {
|
||||||
inst->SetRecastTimestamp(timestamps.at(item->RecastType));
|
inst->SetRecastTimestamp(timestamps.at(item->RecastType));
|
||||||
else
|
} else if (item->RecastType == RECAST_TYPE_UNLINKED_ITEM && timestamps.count(item->ID)) {
|
||||||
|
inst->SetRecastTimestamp(timestamps.at(item->ID));
|
||||||
|
}
|
||||||
|
else {
|
||||||
inst->SetRecastTimestamp(0);
|
inst->SetRecastTimestamp(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (item->IsClassCommon()) {
|
if (item->IsClassCommon()) {
|
||||||
for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
|
for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
|
||||||
|
|||||||
@@ -763,3 +763,23 @@ std::string Strings::Random(size_t length)
|
|||||||
std::generate_n(str.begin(), length, randchar);
|
std::generate_n(str.begin(), length, randchar);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a wrapper for stoi which will return a fallback if the string
|
||||||
|
// fails to cast to a number
|
||||||
|
int Strings::ToInt(const std::string &s, int fallback)
|
||||||
|
{
|
||||||
|
return Strings::IsNumber(s) ? std::stoi(s) : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Strings::RemoveNumbers(std::string s)
|
||||||
|
{
|
||||||
|
int current = 0;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
if (!isdigit(s[i])) {
|
||||||
|
s[current] = s[i];
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.substr(0, current);
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ class Strings {
|
|||||||
public:
|
public:
|
||||||
static bool Contains(std::vector<std::string> container, std::string element);
|
static bool Contains(std::vector<std::string> container, std::string element);
|
||||||
static bool Contains(const std::string& subject, const std::string& search);
|
static bool Contains(const std::string& subject, const std::string& search);
|
||||||
|
static int ToInt(const std::string &s, int fallback = 0);
|
||||||
static bool IsNumber(const std::string &s);
|
static bool IsNumber(const std::string &s);
|
||||||
|
static std::string RemoveNumbers(std::string s);
|
||||||
static bool IsFloat(const std::string &s);
|
static bool IsFloat(const std::string &s);
|
||||||
static const std::string ToLower(std::string s);
|
static const std::string ToLower(std::string s);
|
||||||
static const std::string ToUpper(std::string s);
|
static const std::string ToUpper(std::string s);
|
||||||
|
|||||||
+15
-15
@@ -18,14 +18,22 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _EQEMU_VERSION_H
|
#ifndef EQEMU_VERSION_H
|
||||||
#define _EQEMU_VERSION_H
|
#define EQEMU_VERSION_H
|
||||||
|
|
||||||
#define LOGIN_VERSION "0.8.0"
|
|
||||||
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
||||||
|
|
||||||
#define CURRENT_VERSION "2.0"
|
// Build variables
|
||||||
|
// these get injected during the build pipeline
|
||||||
|
#define CURRENT_VERSION "22.3.0-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__
|
||||||
|
#ifndef WIN32
|
||||||
|
#define LAST_MODIFIED __TIME__
|
||||||
|
#else
|
||||||
|
#define LAST_MODIFIED __TIMESTAMP__
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every time a Database SQL is added to Github increment CURRENT_BINARY_DATABASE_VERSION
|
* Every time a Database SQL is added to Github increment CURRENT_BINARY_DATABASE_VERSION
|
||||||
@@ -34,16 +42,8 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9217
|
#define CURRENT_BINARY_DATABASE_VERSION 9219
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9036
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9037
|
||||||
|
|
||||||
#define COMPILE_DATE __DATE__
|
|
||||||
#define COMPILE_TIME __TIME__
|
|
||||||
#ifndef WIN32
|
|
||||||
#define LAST_MODIFIED __TIME__
|
|
||||||
#else
|
|
||||||
#define LAST_MODIFIED __TIMESTAMP__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "eqemu-server",
|
||||||
|
"version": "22.3.0",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -78,7 +78,7 @@ ChatChannel *ChatChannelList::CreateChannel(
|
|||||||
{
|
{
|
||||||
uint8 max_perm_player_channels = RuleI(Chat, MaxPermanentPlayerChannels);
|
uint8 max_perm_player_channels = RuleI(Chat, MaxPermanentPlayerChannels);
|
||||||
|
|
||||||
if (!database.CheckChannelNameFilter(name)) {
|
if (!RuleB(Chat, ChannelsIgnoreNameFilter) && !database.CheckChannelNameFilter(name)) {
|
||||||
if (!(owner == SYSTEM_OWNER)) {
|
if (!(owner == SYSTEM_OWNER)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,9 @@ bool UCSDatabase::GetVariable(const char *varname, char *varvalue, uint16 varval
|
|||||||
|
|
||||||
bool UCSDatabase::LoadChatChannels()
|
bool UCSDatabase::LoadChatChannels()
|
||||||
{
|
{
|
||||||
|
if (!RuleB(Chat, ChannelsIgnoreNameFilter)) {
|
||||||
LoadFilteredNamesFromDB();
|
LoadFilteredNamesFromDB();
|
||||||
|
}
|
||||||
LoadReservedNamesFromDB();
|
LoadReservedNamesFromDB();
|
||||||
LogInfo("Loading chat channels from the database");
|
LogInfo("Loading chat channels from the database");
|
||||||
|
|
||||||
|
|||||||
Executable
+31
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
sudo chown eqemu:eqemu /drone/src/ * -R
|
||||||
|
sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
|
||||||
|
|
||||||
|
git submodule init && git submodule update
|
||||||
|
|
||||||
|
perl utils/scripts/build/tag-version.pl
|
||||||
|
|
||||||
|
mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-Os" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
|
||||||
|
|
||||||
|
curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
|
||||||
|
./bin/tests
|
||||||
|
|
||||||
|
# shellcheck disable=SC2164
|
||||||
|
cd /drone/src/
|
||||||
|
|
||||||
|
chmod +x ./utils/scripts/build/should-release/should-release
|
||||||
|
./utils/scripts/build/should-release/should-release || exit
|
||||||
|
|
||||||
|
rm ./build/bin/*.a
|
||||||
|
zip -j eqemu-server-linux-x64.zip ./build/bin/*
|
||||||
|
|
||||||
|
# shellcheck disable=SC2010
|
||||||
|
ls -lsh | grep zip
|
||||||
|
sudo apt-get update && sudo apt-get install -y rclone
|
||||||
|
rclone config create remote ftp env_auth true > /dev/null
|
||||||
|
rclone copy eqemu-server-linux-x64.zip remote: 2>&1
|
||||||
|
rclone ls remote: 2>&1
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#############################################
|
||||||
|
# debian
|
||||||
|
#############################################
|
||||||
|
FROM debian:11-slim
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# basics
|
||||||
|
#############################################
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
rclone \
|
||||||
|
git \
|
||||||
|
make \
|
||||||
|
jq \
|
||||||
|
wget \
|
||||||
|
curl
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# node
|
||||||
|
#############################################
|
||||||
|
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash && \
|
||||||
|
apt-get update && apt-get install -y nodejs && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN npm install -g gh-release
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
module should-release
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/google/go-github/v41 v41.0.0
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/golang/protobuf v1.3.2 // indirect
|
||||||
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
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-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 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
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/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=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
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=
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/go-github/v41/github"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PackageJson struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Repository struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
} `json:"repository"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// get latest release from github
|
||||||
|
client := github.NewClient(nil)
|
||||||
|
if len(os.Getenv("GITHUB_TOKEN")) > 0 {
|
||||||
|
ts := oauth2.StaticTokenSource(
|
||||||
|
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
|
||||||
|
)
|
||||||
|
tc := &http.Client{
|
||||||
|
Transport: &oauth2.Transport{
|
||||||
|
Source: ts,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
client = github.NewClient(tc)
|
||||||
|
}
|
||||||
|
|
||||||
|
release, _, err := client.Repositories.GetLatestRelease(context.Background(), "EQEmu", "Server")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
version := strings.ReplaceAll(*release.TagName, "v", "")
|
||||||
|
|
||||||
|
// get current version from package.json
|
||||||
|
currentLevel := filepath.Join("./package.json")
|
||||||
|
packageJsonFile := currentLevel
|
||||||
|
if _, err := os.Stat(currentLevel); errors.Is(err, os.ErrNotExist) {
|
||||||
|
packageJsonFile = ""
|
||||||
|
// this is only really needed when developing this binary
|
||||||
|
walkUpToRoot := filepath.Join("../../../../package.json")
|
||||||
|
if _, err := os.Stat(walkUpToRoot); err == nil {
|
||||||
|
// path/to/whatever exists
|
||||||
|
packageJsonFile = walkUpToRoot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD").Output()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
currentBranch := strings.TrimSpace(string(out))
|
||||||
|
if currentBranch != "master" {
|
||||||
|
fmt.Printf("Not on master, no need to release\n")
|
||||||
|
fmt.Printf("Exiting code 78 to halt pipeline steps gracefully\n")
|
||||||
|
os.Exit(78)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Getenv("RCLONE_FTP_PASS")) == 0 {
|
||||||
|
fmt.Printf("Missing RCLONE_FTP_PASS no need to deploy\n")
|
||||||
|
fmt.Printf("Exiting code 78 to halt pipeline steps gracefully\n")
|
||||||
|
os.Exit(78)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Getenv("GH_RELEASE_GITHUB_API_TOKEN")) == 0 {
|
||||||
|
fmt.Printf("Missing GH_RELEASE_GITHUB_API_TOKEN no need to deploy\n")
|
||||||
|
fmt.Printf("Exiting code 78 to halt pipeline steps gracefully\n")
|
||||||
|
os.Exit(78)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(packageJsonFile) == 0 {
|
||||||
|
fmt.Printf("Could not find package.json\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
packageJson, err := os.ReadFile(packageJsonFile)
|
||||||
|
var p PackageJson
|
||||||
|
_ = json.Unmarshal(packageJson, &p)
|
||||||
|
|
||||||
|
// version compare
|
||||||
|
if p.Version == version {
|
||||||
|
fmt.Printf("Version [%v] already exists. No need to release\n", version)
|
||||||
|
fmt.Printf("Exiting code 78 to halt pipeline steps gracefully\n")
|
||||||
|
os.Exit(78)
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
use warnings FATAL => 'all';
|
||||||
|
|
||||||
|
open my $fh, '<', './package.json' or die "Can't open file $!";
|
||||||
|
my $package_json = do {
|
||||||
|
local $/;
|
||||||
|
<$fh>
|
||||||
|
};
|
||||||
|
|
||||||
|
my $version = "";
|
||||||
|
sub trim($)
|
||||||
|
{
|
||||||
|
my $string = shift;
|
||||||
|
$string =~ s/^\s+//;
|
||||||
|
$string =~ s/\s+$//;
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
# manually parse because we can't guarantee json module is available
|
||||||
|
# it's jank but it's quick and dirty
|
||||||
|
# this is only used in the build pipeline
|
||||||
|
foreach my $line (split("\n", $package_json)) {
|
||||||
|
if ($line =~ /version/i) {
|
||||||
|
$version = $line;
|
||||||
|
$version =~ s/version//g;
|
||||||
|
$version =~ s/://g;
|
||||||
|
$version =~ s/"//g;
|
||||||
|
$version =~ s/,//g;
|
||||||
|
$version = trim($version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Version is [" . $version . "]\n";
|
||||||
|
|
||||||
|
# server version file
|
||||||
|
my $version_file_name = "./common/version.h";
|
||||||
|
open my $vfh, '<', $version_file_name or die "Can't open file $!";
|
||||||
|
my $version_file = do {
|
||||||
|
local $/;
|
||||||
|
<$vfh>
|
||||||
|
};
|
||||||
|
|
||||||
|
# write new version
|
||||||
|
my $new_version_file = "";
|
||||||
|
foreach my $line (split("\n", $version_file)) {
|
||||||
|
if ($line =~ /CURRENT_VERSION/i) {
|
||||||
|
my @s = split("\"", $line);
|
||||||
|
if ($#s == 2) {
|
||||||
|
$line =~ s/$s[1]/$version/g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_version_file .= $line . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
open(my $wfh, '>', $version_file_name) or die "Could not open file '$version_file_name' $!";
|
||||||
|
print $wfh $new_version_file;
|
||||||
|
close $wfh;
|
||||||
|
|
||||||
|
print $new_version_file;
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
try
|
||||||
|
{
|
||||||
|
$cwd = Get-Location
|
||||||
|
|
||||||
|
Set-Location -Path "$cwd"
|
||||||
|
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
|
||||||
|
if (![System.IO.Directory]::Exists("$cwd\win-build-x64"))
|
||||||
|
{
|
||||||
|
Write-Information -MessageData "Creating build x64 folder" -InformationAction Continue
|
||||||
|
New-Item -Path "$cwd\win-build-x64" -ItemType Directory
|
||||||
|
}
|
||||||
|
|
||||||
|
perl .\utils\scripts\build\tag-version.pl
|
||||||
|
|
||||||
|
Write-Information -MessageData "Creating build x64" -InformationAction Continue
|
||||||
|
Set-Location -Path "$cwd\win-build-x64"
|
||||||
|
cmake -Wno-dev -G "Visual Studio 17 2022" -A x64 -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON "$cwd"
|
||||||
|
cmake --build . --config RelWithDebInfo --clean-first
|
||||||
|
Set-Location -Path "$cwd"
|
||||||
|
|
||||||
|
.\utils\scripts\build\should-release\should-release.exe; if ($LASTEXITCODE -ne 0) { exit }
|
||||||
|
|
||||||
|
# trim some fat
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\export_client_files.pdb
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\import_client_files.pdb
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\shared_memory.pdb
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\queryserv.pdb
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\eqlaunch.pdb
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\cppunit.pdb
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\tests.pdb
|
||||||
|
del $cwd\win-build-x64\bin\RelWithDebInfo\tests.exe
|
||||||
|
|
||||||
|
7z a eqemu-server-windows-x64.zip $cwd\win-build-x64\bin\RelWithDebInfo\*.exe $cwd\win-build-x64\bin\RelWithDebInfo\*.dll $cwd\win-build-x64\bin\RelWithDebInfo\*.pdb $cwd\win-build-x64\libs\zlibng\RelWithDebInfo\*.dll $cwd\win-build-x64\libs\zlibng\RelWithDebInfo\*.pdb
|
||||||
|
|
||||||
|
dir *.zip
|
||||||
|
rclone config create remote ftp env_auth true
|
||||||
|
rclone copy eqemu-server-windows-x64.zip remote: 2>&1
|
||||||
|
rclone ls remote: 2>&1
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-Host ("Caught signal to end")
|
||||||
|
Write-Host $_
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -963,9 +963,6 @@ sub fetch_utility_scripts
|
|||||||
|
|
||||||
sub setup_bots
|
sub setup_bots
|
||||||
{
|
{
|
||||||
if ($OS eq "Windows") {
|
|
||||||
fetch_latest_windows_appveyor_bots();
|
|
||||||
}
|
|
||||||
if ($OS eq "Linux") {
|
if ($OS eq "Linux") {
|
||||||
build_linux_source("bots");
|
build_linux_source("bots");
|
||||||
}
|
}
|
||||||
@@ -1202,6 +1199,25 @@ sub get_mysql_path
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($path eq "") {
|
||||||
|
my @files;
|
||||||
|
my $start_dir = trim(`echo %programfiles%`);
|
||||||
|
find(
|
||||||
|
sub {
|
||||||
|
if ($#files > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
push @files, $File::Find::name unless $File::Find::name!~/mysql.exe/i;
|
||||||
|
},
|
||||||
|
$start_dir
|
||||||
|
);
|
||||||
|
for my $file (@files) {
|
||||||
|
if ($file=~/mysql.exe/i) {
|
||||||
|
$path = $file;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($OS eq "Linux") {
|
if ($OS eq "Linux") {
|
||||||
$path = `which mysql`;
|
$path = `which mysql`;
|
||||||
|
|||||||
@@ -471,6 +471,8 @@
|
|||||||
9215|2023_01_08_zone_max_level.sql|SHOW COLUMNS FROM `zone` LIKE 'max_level'|empty|
|
9215|2023_01_08_zone_max_level.sql|SHOW COLUMNS FROM `zone` LIKE 'max_level'|empty|
|
||||||
9216|2023_01_15_merc_data.sql|SHOW TABLES LIKE 'mercs'|empty|
|
9216|2023_01_15_merc_data.sql|SHOW TABLES LIKE 'mercs'|empty|
|
||||||
9217|2023_01_15_chatchannel_reserved_names.sql|SHOW TABLES LIKE 'chatchannel_reserved_names'|empty|
|
9217|2023_01_15_chatchannel_reserved_names.sql|SHOW TABLES LIKE 'chatchannel_reserved_names'|empty|
|
||||||
|
9218|2023_01_24_item_recast.sql|show columns from character_item_recast like '%recast_type%'|contains|smallint
|
||||||
|
9219|2023_01_29_merchant_status_requirements.sql|SHOW COLUMNS FROM merchantlist LIKE 'min_status'|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
9034|2022_12_02_bot_spell_settings.sql|SHOW COLUMNS FROM `bot_data` LIKE 'enforce_spell_settings'|empty|
|
9034|2022_12_02_bot_spell_settings.sql|SHOW COLUMNS FROM `bot_data` LIKE 'enforce_spell_settings'|empty|
|
||||||
9035|2022_12_04_bot_archery.sql|SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'|empty|
|
9035|2022_12_04_bot_archery.sql|SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'|empty|
|
||||||
9036|2023_01_19_drop_bot_views.sql|SHOW TABLES LIKE 'vw_groups'|not_empty|
|
9036|2023_01_19_drop_bot_views.sql|SHOW TABLES LIKE 'vw_groups'|not_empty|
|
||||||
|
9037|2023_01_22_add_name_index.sql||show index from bot_data WHERE key_name = 'name`|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
create index `name` on bot_data(`name`);
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `character_item_recast`
|
||||||
|
CHANGE COLUMN `recast_type` `recast_type` INT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `id`;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
ALTER TABLE `merchantlist`
|
||||||
|
ADD COLUMN `min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `level_required`,
|
||||||
|
ADD COLUMN `max_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 255 AFTER `min_status`;
|
||||||
+124
-20630
File diff suppressed because one or more lines are too long
@@ -1,5 +1,6 @@
|
|||||||
#include "../../common/version.h"
|
#include "../../common/version.h"
|
||||||
#include "../../common/json/json.h"
|
#include "../../common/json/json.h"
|
||||||
|
#include "../../common/rulesys.h"
|
||||||
|
|
||||||
void WorldserverCLI::DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description)
|
void WorldserverCLI::DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||||
{
|
{
|
||||||
@@ -9,13 +10,13 @@ void WorldserverCLI::DatabaseVersion(int argc, char **argv, argh::parser &cmd, s
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value database_version;
|
Json::Value v;
|
||||||
|
|
||||||
database_version["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
v["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
||||||
database_version["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION;
|
v["bots_database_version"] = RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0;
|
||||||
|
|
||||||
std::stringstream payload;
|
std::stringstream payload;
|
||||||
payload << database_version;
|
payload << v;
|
||||||
|
|
||||||
std::cout << payload.str() << std::endl;
|
std::cout << payload.str() << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-6
@@ -1778,12 +1778,39 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
|||||||
pp.binds[0].heading = pp.heading;
|
pp.binds[0].heading = pp.heading;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Current location [{}] [{}] [{}] [{}] [{}] [{}]",
|
if (GetZone(pp.zone_id)) {
|
||||||
ZoneName(pp.zone_id), pp.zone_id, pp.x, pp.y, pp.z, pp.heading);
|
LogInfo(
|
||||||
LogInfo("Bind location [{}] [{}] [{}] [{}] [{}]",
|
"Current location [{}] [{}] [{:.2f}] [{:.2f}] [{:.2f}] [{:.2f}]",
|
||||||
ZoneName(pp.binds[0].zone_id), pp.binds[0].zone_id, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z);
|
ZoneName(pp.zone_id),
|
||||||
LogInfo("Home location [{}] [{}] [{}] [{}] [{}]",
|
pp.zone_id,
|
||||||
ZoneName(pp.binds[4].zone_id), pp.binds[4].zone_id, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z);
|
pp.x,
|
||||||
|
pp.y,
|
||||||
|
pp.z,
|
||||||
|
pp.heading
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetZone(pp.binds[0].zone_id)) {
|
||||||
|
LogInfo(
|
||||||
|
"Bind location [{}] [{}] [{:.2f}] [{:.2f}] [{:.2f}]",
|
||||||
|
ZoneName(pp.binds[0].zone_id),
|
||||||
|
pp.binds[0].zone_id,
|
||||||
|
pp.binds[0].x,
|
||||||
|
pp.binds[0].y,
|
||||||
|
pp.binds[0].z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetZone(pp.binds[4].zone_id)) {
|
||||||
|
LogInfo(
|
||||||
|
"Home location [{}] [{}] [{:.2f}] [{:.2f}] [{:.2f}]",
|
||||||
|
ZoneName(pp.binds[4].zone_id),
|
||||||
|
pp.binds[4].zone_id,
|
||||||
|
pp.binds[4].x,
|
||||||
|
pp.binds[4].y,
|
||||||
|
pp.binds[4].z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* Starting Items inventory */
|
/* Starting Items inventory */
|
||||||
content_db.SetStartingItems(&pp, &inv, pp.race, pp.class_, pp.deity, pp.zone_id, pp.name, GetAdmin());
|
content_db.SetStartingItems(&pp, &inv, pp.race, pp.class_, pp.deity, pp.zone_id, pp.name, GetAdmin());
|
||||||
|
|||||||
@@ -290,16 +290,16 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ignore_db) {
|
|
||||||
LogInfo("Checking Database Conversions");
|
|
||||||
database.CheckDatabaseConversions();
|
|
||||||
}
|
|
||||||
|
|
||||||
// logging system init
|
// logging system init
|
||||||
auto logging = LogSys.SetDatabase(&database)
|
auto logging = LogSys.SetDatabase(&database)
|
||||||
->SetLogPath(path.GetLogPath())
|
->SetLogPath(path.GetLogPath())
|
||||||
->LoadLogDatabaseSettings();
|
->LoadLogDatabaseSettings();
|
||||||
|
|
||||||
|
if (!ignore_db) {
|
||||||
|
LogInfo("Checking Database Conversions");
|
||||||
|
database.CheckDatabaseConversions();
|
||||||
|
}
|
||||||
|
|
||||||
if (RuleB(Logging, WorldGMSayLogging)) {
|
if (RuleB(Logging, WorldGMSayLogging)) {
|
||||||
logging->SetGMSayHandler(&WorldBoot::GMSayHookCallBackProcessWorld);
|
logging->SetGMSayHandler(&WorldBoot::GMSayHookCallBackProcessWorld);
|
||||||
}
|
}
|
||||||
|
|||||||
+151
-47
@@ -871,16 +871,16 @@ int Mob::ACSum(bool skip_caps)
|
|||||||
int ac = 0; // this should be base AC whenever shrouds come around
|
int ac = 0; // this should be base AC whenever shrouds come around
|
||||||
ac += itembonuses.AC; // items + food + tribute
|
ac += itembonuses.AC; // items + food + tribute
|
||||||
int shield_ac = 0;
|
int shield_ac = 0;
|
||||||
if (HasShieldEquiped() && IsClient()) {
|
if (HasShieldEquiped() && (IsClient() || IsBot())) {
|
||||||
auto client = CastToClient();
|
auto inst = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotSecondary);
|
||||||
auto inst = client->GetInv().GetItem(EQ::invslot::slotSecondary);
|
|
||||||
if (inst) {
|
if (inst) {
|
||||||
if (inst->GetItemRecommendedLevel(true) <= GetLevel())
|
if (inst->GetItemRecommendedLevel(true) <= GetLevel()) {
|
||||||
shield_ac = inst->GetItemArmorClass(true);
|
shield_ac = inst->GetItemArmorClass(true);
|
||||||
else
|
} else {
|
||||||
shield_ac = client->CalcRecommendedLevelBonus(GetLevel(), inst->GetItemRecommendedLevel(true), inst->GetItemArmorClass(true));
|
shield_ac = CalcRecommendedLevelBonus(GetLevel(), inst->GetItemRecommendedLevel(true), inst->GetItemArmorClass(true));
|
||||||
}
|
}
|
||||||
shield_ac += client->GetHeroicSTR() / 10;
|
}
|
||||||
|
shield_ac += GetHeroicSTR() / 10;
|
||||||
}
|
}
|
||||||
// EQ math
|
// EQ math
|
||||||
ac = (ac * 4) / 3;
|
ac = (ac * 4) / 3;
|
||||||
@@ -1275,7 +1275,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
|
|||||||
return std::max((int64)0, dmg);
|
return std::max((int64)0, dmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 Client::DoDamageCaps(int64 base_damage)
|
int64 Mob::DoDamageCaps(int64 base_damage)
|
||||||
{
|
{
|
||||||
// this is based on a client function that caps melee base_damage
|
// this is based on a client function that caps melee base_damage
|
||||||
auto level = GetLevel();
|
auto level = GetLevel();
|
||||||
@@ -1404,8 +1404,8 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
|
|||||||
|
|
||||||
// check to see if we hit..
|
// check to see if we hit..
|
||||||
if (!FromRiposte && other->AvoidDamage(this, hit)) {
|
if (!FromRiposte && other->AvoidDamage(this, hit)) {
|
||||||
int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
if (int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
|
||||||
if (strike_through && zone->random.Roll(strike_through)) {
|
strike_through && zone->random.Roll(strike_through)) {
|
||||||
MessageString(Chat::StrikeThrough,
|
MessageString(Chat::StrikeThrough,
|
||||||
STRIKETHROUGH_STRING); // You strike through your opponents defenses!
|
STRIKETHROUGH_STRING); // You strike through your opponents defenses!
|
||||||
hit.damage_done = 1; // set to one, we will check this to continue
|
hit.damage_done = 1; // set to one, we will check this to continue
|
||||||
@@ -1460,71 +1460,77 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
|
|||||||
//stop the attack calculations
|
//stop the attack calculations
|
||||||
// IsFromSpell added to allow spell effects to use Attack. (Mainly for the Rampage AA right now.)
|
// IsFromSpell added to allow spell effects to use Attack. (Mainly for the Rampage AA right now.)
|
||||||
//SYNC WITH: tune.cpp, mob.h TuneClientAttack
|
//SYNC WITH: tune.cpp, mob.h TuneClientAttack
|
||||||
bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
|
bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts)
|
||||||
{
|
{
|
||||||
if (!other) {
|
if (!other) {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
LogError("A null Mob object was passed to Client::Attack() for evaluation!");
|
LogError("A null Mob object was passed for evaluation!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetTarget())
|
if (!GetTarget()) {
|
||||||
SetTarget(other);
|
SetTarget(other);
|
||||||
|
}
|
||||||
|
|
||||||
LogCombat("Attacking [{}] with hand [{}] [{}]", other ? other->GetName() : "(nullptr)", Hand, bRiposte ? "(this is a riposte)" : "");
|
LogCombatDetail("Attacking [{}] with hand [{}] [{}]", other ? other->GetName() : "nullptr", Hand, bRiposte ? "this is a riposte" : "");
|
||||||
|
|
||||||
//SetAttackTimer();
|
|
||||||
if (
|
if (
|
||||||
(IsCasting() && GetClass() != BARD && !IsFromSpell)
|
(IsCasting() && GetClass() != BARD && !IsFromSpell)
|
||||||
|| other == nullptr
|
|| other == nullptr
|
||||||
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
||||||
|| (GetHP() < 0)
|
|| (GetHP() < 0)
|
||||||
|| (!IsAttackAllowed(other))
|
|| (!IsAttackAllowed(other))
|
||||||
|
|| (IsBot() && GetAppearance() == eaDead)
|
||||||
) {
|
) {
|
||||||
LogCombat("Attack cancelled, invalid circumstances");
|
LogCombat("Attack cancelled, invalid circumstances");
|
||||||
return false; // Only bards can attack while casting
|
return false; // Only bards can attack while casting
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DivineAura() && !GetGM()) {//cant attack while invulnerable unless your a gm
|
if (DivineAura() && !CastToClient()->GetGM()) { //cant attack while invulnerable unless your a gm
|
||||||
LogCombat("Attack cancelled, Divine Aura is in effect");
|
LogCombat("Attack cancelled, Divine Aura is in effect");
|
||||||
MessageString(Chat::DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable
|
MessageString(Chat::DefaultText, DIVINE_AURA_NO_ATK);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetFeigned())
|
if (GetFeigned()) {
|
||||||
return false; // Rogean: How can you attack while feigned? Moved up from Aggro Code.
|
return false; // Rogean: How can you attack while feigned? Moved up from Aggro Code.
|
||||||
|
}
|
||||||
|
|
||||||
EQ::ItemInstance* weapon = nullptr;
|
const EQ::ItemInstance* weapon = nullptr;
|
||||||
if (Hand == EQ::invslot::slotSecondary) { // Kaiyodo - Pick weapon from the attacking hand
|
|
||||||
weapon = GetInv().GetItem(EQ::invslot::slotSecondary);
|
|
||||||
|
if (IsBot()) {
|
||||||
|
FaceTarget(GetTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Hand == EQ::invslot::slotSecondary) {
|
||||||
|
weapon = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotSecondary) : CastToBot()->GetBotItem(EQ::invslot::slotPrimary);
|
||||||
OffHandAtk(true);
|
OffHandAtk(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
weapon = GetInv().GetItem(EQ::invslot::slotPrimary);
|
weapon = (IsClient()) ? GetInv().GetItem(EQ::invslot::slotPrimary) : CastToBot()->GetBotItem(EQ::invslot::slotPrimary);
|
||||||
OffHandAtk(false);
|
OffHandAtk(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weapon != nullptr) {
|
if (weapon != nullptr) {
|
||||||
if (!weapon->IsWeapon()) {
|
if (!weapon->IsWeapon()) {
|
||||||
LogCombat("Attack cancelled, Item [{}] ([{}]) is not a weapon", weapon->GetItem()->Name, weapon->GetID());
|
LogCombat("Attack cancelled, Item [{}] ([{}]) is not a weapon", weapon->GetItem()->Name, weapon->GetID());
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
LogCombat("Attacking with weapon: [{}] ([{}])", weapon->GetItem()->Name, weapon->GetID());
|
LogCombatDetail("Attacking with weapon: [{}] ([{}])", weapon->GetItem()->Name, weapon->GetID());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogCombat("Attacking without a weapon");
|
LogCombatDetail("Attacking without a weapon");
|
||||||
}
|
}
|
||||||
|
|
||||||
DamageHitInfo my_hit;
|
DamageHitInfo my_hit;
|
||||||
// calculate attack_skill and skillinuse depending on hand and weapon
|
// calculate attack_skill and skillinuse depending on hand and weapon
|
||||||
// also send Packet to near clients
|
// also send Packet to near clients
|
||||||
my_hit.skill = AttackAnimation(Hand, weapon);
|
my_hit.skill = AttackAnimation(Hand, weapon);
|
||||||
LogCombat("Attacking with [{}] in slot [{}] using skill [{}]", weapon ? weapon->GetItem()->Name : "Fist", Hand, my_hit.skill);
|
LogCombatDetail("Attacking with [{}] in slot [{}] using skill [{}]", weapon ? weapon->GetItem()->Name : "Fist", Hand, my_hit.skill);
|
||||||
|
|
||||||
// Now figure out damage
|
// Now figure out damage
|
||||||
my_hit.damage_done = 1;
|
my_hit.damage_done = 1;
|
||||||
my_hit.min_damage = 0;
|
my_hit.min_damage = 0;
|
||||||
uint8 mylevel = GetLevel() ? GetLevel() : 1;
|
|
||||||
int64 hate = 0;
|
int64 hate = 0;
|
||||||
if (weapon)
|
if (weapon)
|
||||||
hate = (weapon->GetItem()->Damage + weapon->GetItem()->ElemDmgAmt);
|
hate = (weapon->GetItem()->Damage + weapon->GetItem()->ElemDmgAmt);
|
||||||
@@ -1546,8 +1552,10 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
hate = hate * (100 + shield_inc) / 100;
|
hate = hate * (100 + shield_inc) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckIncreaseSkill(my_hit.skill, other, -15);
|
if (IsClient()) {
|
||||||
CheckIncreaseSkill(EQ::skills::SkillOffense, other, -15);
|
CastToClient()->CheckIncreaseSkill(my_hit.skill, other, -15);
|
||||||
|
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillOffense, other, -15);
|
||||||
|
}
|
||||||
|
|
||||||
// ***************************************************************
|
// ***************************************************************
|
||||||
// *** Calculate the damage bonus, if applicable, for this hit ***
|
// *** Calculate the damage bonus, if applicable, for this hit ***
|
||||||
@@ -1575,19 +1583,20 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
|
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
|
||||||
if (Hand == EQ::invslot::slotSecondary) {
|
if (Hand == EQ::invslot::slotSecondary &&
|
||||||
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc) {
|
(
|
||||||
|
aabonuses.SecondaryDmgInc ||
|
||||||
|
itembonuses.SecondaryDmgInc ||
|
||||||
|
spellbonuses.SecondaryDmgInc
|
||||||
|
)
|
||||||
|
) {
|
||||||
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQ::ItemData*) nullptr, true);
|
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQ::ItemData*) nullptr, true);
|
||||||
|
|
||||||
my_hit.min_damage = ucDamageBonus;
|
my_hit.min_damage = ucDamageBonus;
|
||||||
hate += ucDamageBonus;
|
hate += ucDamageBonus;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// damage = mod_client_damage(damage, skillinuse, Hand, weapon, other);
|
LogCombatDetail("Damage calculated base [{}] min damage [{}] skill [{}]", my_hit.base_damage, my_hit.min_damage, my_hit.skill);
|
||||||
|
|
||||||
LogCombat("Damage calculated: base [{}] min damage [{}] skill [{}]", my_hit.base_damage, my_hit.min_damage, my_hit.skill);
|
|
||||||
|
|
||||||
int hit_chance_bonus = 0;
|
int hit_chance_bonus = 0;
|
||||||
my_hit.offense = offense(my_hit.skill); // we need this a few times
|
my_hit.offense = offense(my_hit.skill); // we need this a few times
|
||||||
@@ -1604,6 +1613,8 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
||||||
|
|
||||||
DoAttack(other, my_hit, opts, bRiposte);
|
DoAttack(other, my_hit, opts, bRiposte);
|
||||||
|
|
||||||
|
LogCombatDetail("Final damage after all reductions [{}]", my_hit.damage_done);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my_hit.damage_done = DMG_INVULNERABLE;
|
my_hit.damage_done = DMG_INVULNERABLE;
|
||||||
@@ -1615,11 +1626,13 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
other->AddToHateList(this, hate);
|
other->AddToHateList(this, hate);
|
||||||
|
|
||||||
//Guard Assist Code
|
//Guard Assist Code
|
||||||
if (RuleB(Character, PVPEnableGuardFactionAssist)) {
|
if (RuleB(Character, PVPEnableGuardFactionAssist) &&
|
||||||
if (IsClient() && other->IsClient() || (HasOwner() && GetOwner()->IsClient() && other->IsClient() )) {
|
(
|
||||||
auto& mob_list = entity_list.GetCloseMobList(other);
|
(IsClient() && other->IsClient()) ||
|
||||||
for (auto& e : mob_list) {
|
(HasOwner() && GetOwner()->IsClient() && other->IsClient())
|
||||||
auto mob = e.second;
|
)
|
||||||
|
) {
|
||||||
|
for (auto const& [id, mob] : entity_list.GetCloseMobList(other)) {
|
||||||
if (!mob) {
|
if (!mob) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1635,14 +1648,13 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
////// Send Attack Damage
|
////// Send Attack Damage
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill, true, -1, false, m_specialattacks);
|
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill, true, -1, false, m_specialattacks);
|
||||||
|
|
||||||
if (IsDead()) {
|
if (CastToClient()->IsDead() || (IsBot() && GetAppearance() == eaDead)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2758,7 +2770,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killer_mob->IsBot()) {
|
if (killer_mob && killer_mob->IsBot()) {
|
||||||
parse->EventBot(EVENT_NPC_SLAY, killer_mob->CastToBot(), this, "", 0);
|
parse->EventBot(EVENT_NPC_SLAY, killer_mob->CastToBot(), this, "", 0);
|
||||||
killer_mob->TrySpellOnKill(killed_level, spell);
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
}
|
}
|
||||||
@@ -3808,6 +3820,98 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
|||||||
//final damage has been determined.
|
//final damage has been determined.
|
||||||
SetHP(int64(GetHP() - damage));
|
SetHP(int64(GetHP() - damage));
|
||||||
|
|
||||||
|
const auto has_bot_given_event = parse->BotHasQuestSub(EVENT_DAMAGE_GIVEN);
|
||||||
|
|
||||||
|
const auto has_bot_taken_event = parse->BotHasQuestSub(EVENT_DAMAGE_TAKEN);
|
||||||
|
|
||||||
|
const auto has_npc_given_event = (
|
||||||
|
(
|
||||||
|
IsNPC() &&
|
||||||
|
parse->HasQuestSub(CastToNPC()->GetNPCTypeID(), EVENT_DAMAGE_GIVEN)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
attacker->IsNPC() &&
|
||||||
|
parse->HasQuestSub(attacker->CastToNPC()->GetNPCTypeID(), EVENT_DAMAGE_GIVEN)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto has_npc_taken_event = (
|
||||||
|
(
|
||||||
|
IsNPC() &&
|
||||||
|
parse->HasQuestSub(CastToNPC()->GetNPCTypeID(), EVENT_DAMAGE_TAKEN)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
attacker->IsNPC() &&
|
||||||
|
parse->HasQuestSub(attacker->CastToNPC()->GetNPCTypeID(), EVENT_DAMAGE_TAKEN)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto has_player_given_event = parse->PlayerHasQuestSub(EVENT_DAMAGE_GIVEN);
|
||||||
|
|
||||||
|
const auto has_player_taken_event = parse->PlayerHasQuestSub(EVENT_DAMAGE_TAKEN);
|
||||||
|
|
||||||
|
const auto has_given_event = (
|
||||||
|
has_bot_given_event ||
|
||||||
|
has_npc_given_event ||
|
||||||
|
has_player_given_event
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto has_taken_event = (
|
||||||
|
has_bot_taken_event ||
|
||||||
|
has_npc_taken_event ||
|
||||||
|
has_player_taken_event
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<std::any> args;
|
||||||
|
|
||||||
|
if (has_taken_event) {
|
||||||
|
const auto export_string = fmt::format(
|
||||||
|
"{} {} {} {} {} {} {} {} {}",
|
||||||
|
attacker ? attacker->GetID() : 0,
|
||||||
|
damage,
|
||||||
|
spell_id,
|
||||||
|
static_cast<int>(skill_used),
|
||||||
|
FromDamageShield ? 1 : 0,
|
||||||
|
avoidable ? 1 : 0,
|
||||||
|
buffslot,
|
||||||
|
iBuffTic ? 1 : 0,
|
||||||
|
static_cast<int>(special)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (IsBot() && has_bot_taken_event) {
|
||||||
|
parse->EventBot(EVENT_DAMAGE_TAKEN, CastToBot(), attacker ? attacker : nullptr, export_string, 0);
|
||||||
|
} else if (IsClient() && has_player_taken_event) {
|
||||||
|
args.push_back(attacker ? attacker : nullptr);
|
||||||
|
parse->EventPlayer(EVENT_DAMAGE_TAKEN, CastToClient(), export_string, 0, &args);
|
||||||
|
} else if (IsNPC() && has_npc_taken_event) {
|
||||||
|
parse->EventNPC(EVENT_DAMAGE_TAKEN, CastToNPC(), attacker ? attacker : nullptr, export_string, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_given_event && attacker) {
|
||||||
|
const auto export_string = fmt::format(
|
||||||
|
"{} {} {} {} {} {} {} {} {}",
|
||||||
|
GetID(),
|
||||||
|
damage,
|
||||||
|
spell_id,
|
||||||
|
static_cast<int>(skill_used),
|
||||||
|
FromDamageShield ? 1 : 0,
|
||||||
|
avoidable ? 1 : 0,
|
||||||
|
buffslot,
|
||||||
|
iBuffTic ? 1 : 0,
|
||||||
|
static_cast<int>(special)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (attacker->IsBot() && has_bot_given_event) {
|
||||||
|
parse->EventBot(EVENT_DAMAGE_GIVEN, attacker->CastToBot(), this, export_string, 0);
|
||||||
|
} else if (attacker->IsClient() && has_player_given_event) {
|
||||||
|
args.push_back(this);
|
||||||
|
parse->EventPlayer(EVENT_DAMAGE_GIVEN, attacker->CastToClient(), export_string, 0, &args);
|
||||||
|
} else if (attacker->IsNPC() && has_npc_given_event) {
|
||||||
|
parse->EventNPC(EVENT_DAMAGE_GIVEN, attacker->CastToNPC(), this, export_string, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (HasDied()) {
|
if (HasDied()) {
|
||||||
bool IsSaved = false;
|
bool IsSaved = false;
|
||||||
|
|
||||||
@@ -5689,15 +5793,15 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
|||||||
TryCriticalHit(defender, hit, opts);
|
TryCriticalHit(defender, hit, opts);
|
||||||
|
|
||||||
hit.damage_done += hit.min_damage;
|
hit.damage_done += hit.min_damage;
|
||||||
if (IsClient()) {
|
if (IsClient() || IsBot()) {
|
||||||
int extra = 0;
|
int extra = 0;
|
||||||
switch (hit.skill) {
|
switch (hit.skill) {
|
||||||
case EQ::skills::SkillThrowing:
|
case EQ::skills::SkillThrowing:
|
||||||
case EQ::skills::SkillArchery:
|
case EQ::skills::SkillArchery:
|
||||||
extra = CastToClient()->GetHeroicDEX() / 10;
|
extra = GetHeroicDEX() / 10;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
extra = CastToClient()->GetHeroicSTR() / 10;
|
extra = GetHeroicSTR() / 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hit.damage_done += extra;
|
hit.damage_done += extra;
|
||||||
|
|||||||
+2
-2
@@ -36,12 +36,12 @@ public:
|
|||||||
//abstract virtual function implementations requird by base abstract class
|
//abstract virtual function implementations requird by base abstract class
|
||||||
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) { return true; }
|
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) { return true; }
|
||||||
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
||||||
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
|
||||||
ExtraAttackOptions *opts = nullptr) { return false; }
|
|
||||||
virtual bool HasRaid() { return false; }
|
virtual bool HasRaid() { return false; }
|
||||||
virtual bool HasGroup() { return false; }
|
virtual bool HasGroup() { return false; }
|
||||||
virtual Raid* GetRaid() { return 0; }
|
virtual Raid* GetRaid() { return 0; }
|
||||||
virtual Group* GetGroup() { return 0; }
|
virtual Group* GetGroup() { return 0; }
|
||||||
|
bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||||
|
ExtraAttackOptions *opts = nullptr) override { return false; }
|
||||||
|
|
||||||
bool IsBeacon() const { return true; }
|
bool IsBeacon() const { return true; }
|
||||||
bool Process();
|
bool Process();
|
||||||
|
|||||||
+1
-1
@@ -128,7 +128,7 @@ void Client::CalcBonuses()
|
|||||||
consume_food_timer.SetTimer(timer);
|
consume_food_timer.SetTimer(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat)
|
int Mob::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat)
|
||||||
{
|
{
|
||||||
if( (reclevel > 0) && (level < reclevel) )
|
if( (reclevel > 0) && (level < reclevel) )
|
||||||
{
|
{
|
||||||
|
|||||||
+20
-165
@@ -4859,6 +4859,10 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trade_instance->GetItem()->ItemType == EQ::item::ItemTypeAugmentation) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//if (stage_loop == stageStackable) {
|
//if (stage_loop == stageStackable) {
|
||||||
// // TODO: implement
|
// // TODO: implement
|
||||||
// continue;
|
// continue;
|
||||||
@@ -5070,6 +5074,13 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
|||||||
|
|
||||||
BotRemoveEquipItem(return_iterator.from_bot_slot);
|
BotRemoveEquipItem(return_iterator.from_bot_slot);
|
||||||
|
|
||||||
|
const auto export_string = fmt::format(
|
||||||
|
"{} {}",
|
||||||
|
return_iterator.return_item_instance->IsStackable() ? return_iterator.return_item_instance->GetCharges() : 1,
|
||||||
|
return_iterator.from_bot_slot
|
||||||
|
);
|
||||||
|
|
||||||
|
parse->EventBot(EVENT_UNEQUIP_ITEM_BOT, this, nullptr, export_string , return_iterator.return_item_instance->GetID());
|
||||||
if (return_instance) {
|
if (return_instance) {
|
||||||
EQ::SayLinkEngine linker;
|
EQ::SayLinkEngine linker;
|
||||||
linker.SetLinkType(EQ::saylink::SayLinkItemInst);
|
linker.SetLinkType(EQ::saylink::SayLinkItemInst);
|
||||||
@@ -5118,6 +5129,15 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
|||||||
|
|
||||||
m_inv.PutItem(trade_iterator.to_bot_slot, *trade_iterator.trade_item_instance);
|
m_inv.PutItem(trade_iterator.to_bot_slot, *trade_iterator.trade_item_instance);
|
||||||
BotAddEquipItem(trade_iterator.to_bot_slot, (trade_iterator.trade_item_instance ? trade_iterator.trade_item_instance->GetID() : 0));
|
BotAddEquipItem(trade_iterator.to_bot_slot, (trade_iterator.trade_item_instance ? trade_iterator.trade_item_instance->GetID() : 0));
|
||||||
|
|
||||||
|
const auto export_string = fmt::format(
|
||||||
|
"{} {}",
|
||||||
|
trade_iterator.trade_item_instance->IsStackable() ? trade_iterator.trade_item_instance->GetCharges() : 1,
|
||||||
|
trade_iterator.to_bot_slot
|
||||||
|
);
|
||||||
|
|
||||||
|
parse->EventBot(EVENT_EQUIP_ITEM_BOT, this, nullptr, export_string , trade_iterator.trade_item_instance->GetID());
|
||||||
|
|
||||||
trade_iterator.trade_item_instance = nullptr; // actual deletion occurs in client delete below
|
trade_iterator.trade_item_instance = nullptr; // actual deletion occurs in client delete below
|
||||||
|
|
||||||
client->DeleteItemInInventory(trade_iterator.from_client_slot, 0, (trade_iterator.from_client_slot == EQ::invslot::slotCursor));
|
client->DeleteItemInInventory(trade_iterator.from_client_slot, 0, (trade_iterator.from_client_slot == EQ::invslot::slotCursor));
|
||||||
@@ -5316,171 +5336,6 @@ void Bot::Damage(Mob *from, int64 damage, uint16 spell_id, EQ::skills::SkillType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts) {
|
|
||||||
if (!other) {
|
|
||||||
SetTarget(nullptr);
|
|
||||||
LogErrorDetail("A null Mob object was passed to Bot::Attack for evaluation!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((GetHP() <= 0) || (GetAppearance() == eaDead)) {
|
|
||||||
SetTarget(nullptr);
|
|
||||||
LogCombatDetail("Attempted to attack [{}] while unconscious or, otherwise, appearing dead", other->GetCleanName());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(!GetTarget() || GetTarget() != other) // NPC::Attack() doesn't do this
|
|
||||||
// SetTarget(other);
|
|
||||||
|
|
||||||
// apparently, we always want our target to be 'other'..why not just set it?
|
|
||||||
SetTarget(other);
|
|
||||||
// takes more to compare a call result, load for a call, load a compare to address and compare, and finally
|
|
||||||
// push a value to an address than to just load for a call and push a value to an address.
|
|
||||||
|
|
||||||
LogCombat("Attacking [{}] with hand [{}] [{}]", other->GetCleanName(), Hand, (FromRiposte ? "(this is a riposte)" : ""));
|
|
||||||
if ((IsCasting() && (GetClass() != BARD) && !IsFromSpell) || (!IsAttackAllowed(other))) {
|
|
||||||
if(GetOwnerID())
|
|
||||||
entity_list.MessageClose(this, 1, 200, 10, "%s says, '%s is not a legal target master.'", GetCleanName(), GetTarget()->GetCleanName());
|
|
||||||
|
|
||||||
if(other) {
|
|
||||||
RemoveFromHateList(other);
|
|
||||||
LogCombat("I am not allowed to attack [{}]", other->GetCleanName());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DivineAura()) {//cant attack while invulnerable
|
|
||||||
LogCombat("Attack canceled, Divine Aura is in effect");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FaceTarget(GetTarget());
|
|
||||||
EQ::ItemInstance* weapon = nullptr;
|
|
||||||
if (Hand == EQ::invslot::slotPrimary) {
|
|
||||||
weapon = GetBotItem(EQ::invslot::slotPrimary);
|
|
||||||
OffHandAtk(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Hand == EQ::invslot::slotSecondary) {
|
|
||||||
weapon = GetBotItem(EQ::invslot::slotSecondary);
|
|
||||||
OffHandAtk(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(weapon != nullptr) {
|
|
||||||
if (!weapon->IsWeapon()) {
|
|
||||||
LogCombat("Attack canceled, Item [{}] ([{}]) is not a weapon", weapon->GetItem()->Name, weapon->GetID());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LogCombat("Attacking with weapon: [{}] ([{}])", weapon->GetItem()->Name, weapon->GetID());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogCombat("Attacking without a weapon");
|
|
||||||
|
|
||||||
// calculate attack_skill and skillinuse depending on hand and weapon
|
|
||||||
// also send Packet to near clients
|
|
||||||
DamageHitInfo my_hit;
|
|
||||||
my_hit.skill = AttackAnimation(Hand, weapon);
|
|
||||||
LogCombat("Attacking with [{}] in slot [{}] using skill [{}]", weapon?weapon->GetItem()->Name:"Fist", Hand, my_hit.skill);
|
|
||||||
|
|
||||||
// Now figure out damage
|
|
||||||
my_hit.damage_done = 1;
|
|
||||||
my_hit.min_damage = 0;
|
|
||||||
uint8 mylevel = GetLevel() ? GetLevel() : 1;
|
|
||||||
int64 hate = 0;
|
|
||||||
if (weapon)
|
|
||||||
hate = (weapon->GetItem()->Damage + weapon->GetItem()->ElemDmgAmt);
|
|
||||||
|
|
||||||
my_hit.base_damage = GetWeaponDamage(other, weapon, &hate);
|
|
||||||
if (hate == 0 && my_hit.base_damage > 1)
|
|
||||||
hate = my_hit.base_damage;
|
|
||||||
|
|
||||||
//if weapon damage > 0 then we know we can hit the target with this weapon
|
|
||||||
//otherwise we cannot and we set the damage to -5 later on
|
|
||||||
if (my_hit.base_damage > 0) {
|
|
||||||
my_hit.min_damage = 0;
|
|
||||||
|
|
||||||
// ***************************************************************
|
|
||||||
// *** Calculate the damage bonus, if applicable, for this hit ***
|
|
||||||
// ***************************************************************
|
|
||||||
|
|
||||||
#ifndef EQEMU_NO_WEAPON_DAMAGE_BONUS
|
|
||||||
|
|
||||||
// If you include the preprocessor directive "#define EQEMU_NO_WEAPON_DAMAGE_BONUS", that indicates that you do not
|
|
||||||
// want damage bonuses added to weapon damage at all. This feature was requested by ChaosSlayer on the EQEmu Forums.
|
|
||||||
//
|
|
||||||
// This is not recommended for normal usage, as the damage bonus represents a non-trivial component of the DPS output
|
|
||||||
// of weapons wielded by higher-level melee characters (especially for two-handed weapons).
|
|
||||||
int ucDamageBonus = 0;
|
|
||||||
if (Hand == EQ::invslot::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) {
|
|
||||||
// Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above
|
|
||||||
// who belong to a melee class. If we're here, then all of these conditions apply.
|
|
||||||
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQ::ItemData*) nullptr);
|
|
||||||
my_hit.min_damage = ucDamageBonus;
|
|
||||||
hate += ucDamageBonus;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
|
|
||||||
if (Hand == EQ::invslot::slotSecondary) {
|
|
||||||
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc) {
|
|
||||||
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQ::ItemData*) nullptr);
|
|
||||||
my_hit.min_damage = ucDamageBonus;
|
|
||||||
hate += ucDamageBonus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogCombat("Damage calculated: base [{}] min damage [{}] skill [{}]", my_hit.base_damage, my_hit.min_damage, my_hit.skill);
|
|
||||||
|
|
||||||
int hit_chance_bonus = 0;
|
|
||||||
my_hit.offense = offense(my_hit.skill);
|
|
||||||
my_hit.hand = Hand;
|
|
||||||
|
|
||||||
if (opts) {
|
|
||||||
my_hit.base_damage *= opts->damage_percent;
|
|
||||||
my_hit.base_damage += opts->damage_flat;
|
|
||||||
hate *= opts->hate_percent;
|
|
||||||
hate += opts->hate_flat;
|
|
||||||
hit_chance_bonus += opts->hit_chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
my_hit.tohit = GetTotalToHit(my_hit.skill, hit_chance_bonus);
|
|
||||||
|
|
||||||
DoAttack(other, my_hit, opts, FromRiposte);
|
|
||||||
|
|
||||||
LogCombat("Final damage after all reductions: [{}]", my_hit.damage_done);
|
|
||||||
} else {
|
|
||||||
my_hit.damage_done = DMG_INVULNERABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hate Generation is on a per swing basis, regardless of a hit, miss, or block, its always the same.
|
|
||||||
// If we are this far, this means we are atleast making a swing.
|
|
||||||
other->AddToHateList(this, hate);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
////// Send Attack Damage
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill);
|
|
||||||
|
|
||||||
if (GetHP() < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
MeleeLifeTap(my_hit.damage_done);
|
|
||||||
|
|
||||||
if (my_hit.damage_done > 0)
|
|
||||||
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
|
|
||||||
|
|
||||||
CommonBreakInvisibleFromCombat();
|
|
||||||
if (spellbonuses.NegateIfCombat)
|
|
||||||
BuffFadeByEffect(SE_NegateIfCombat);
|
|
||||||
|
|
||||||
if(GetTarget())
|
|
||||||
TriggerDefensiveProcs(other, Hand, true, my_hit.damage_done);
|
|
||||||
|
|
||||||
if (my_hit.damage_done > 0)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//proc chance includes proc bonus
|
//proc chance includes proc bonus
|
||||||
float Bot::GetProcChances(float ProcBonus, uint16 hand) {
|
float Bot::GetProcChances(float ProcBonus, uint16 hand) {
|
||||||
int mydex = GetDEX();
|
int mydex = GetDEX();
|
||||||
|
|||||||
+9
-2
@@ -147,8 +147,6 @@ public:
|
|||||||
void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1,
|
void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1,
|
||||||
bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) override;
|
bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) override;
|
||||||
|
|
||||||
bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
|
||||||
ExtraAttackOptions *opts = nullptr) override;
|
|
||||||
bool HasRaid() override { return (GetRaid() ? true : false); }
|
bool HasRaid() override { return (GetRaid() ? true : false); }
|
||||||
bool HasGroup() override { return (GetGroup() ? true : false); }
|
bool HasGroup() override { return (GetGroup() ? true : false); }
|
||||||
Raid* GetRaid() override { return entity_list.GetRaidByMob(this); }
|
Raid* GetRaid() override { return entity_list.GetRaidByMob(this); }
|
||||||
@@ -374,6 +372,14 @@ public:
|
|||||||
uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0);
|
uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0);
|
||||||
inline int64 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr, bool from_buff_tic = false) override
|
inline int64 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr, bool from_buff_tic = false) override
|
||||||
{ return Mob::GetFocusEffect(type, spell_id, caster, from_buff_tic); }
|
{ return Mob::GetFocusEffect(type, spell_id, caster, from_buff_tic); }
|
||||||
|
inline bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||||
|
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) override
|
||||||
|
{ return Mob::Attack(other, Hand, FromRiposte, IsStrikethrough, IsFromSpell, opts); }
|
||||||
|
|
||||||
|
[[nodiscard]] int GetMaxBuffSlots() const override { return EQ::spells::LONG_BUFFS; }
|
||||||
|
[[nodiscard]] int GetMaxSongSlots() const override { return EQ::spells::SHORT_BUFFS; }
|
||||||
|
[[nodiscard]] int GetMaxDiscSlots() const override { return EQ::spells::DISC_BUFFS; }
|
||||||
|
[[nodiscard]] int GetMaxTotalSlots() const override { return EQ::spells::TOTAL_BUFFS; }
|
||||||
|
|
||||||
bool GetBotOwnerDataBuckets();
|
bool GetBotOwnerDataBuckets();
|
||||||
bool GetBotDataBuckets();
|
bool GetBotDataBuckets();
|
||||||
@@ -466,6 +472,7 @@ public:
|
|||||||
bool IsBotArcher() { return m_bot_archery_setting; }
|
bool IsBotArcher() { return m_bot_archery_setting; }
|
||||||
bool IsBotCharmer() { return _botCharmer; }
|
bool IsBotCharmer() { return _botCharmer; }
|
||||||
bool IsBot() const override { return true; }
|
bool IsBot() const override { return true; }
|
||||||
|
bool IsOfClientBotMerc() const override { return true; }
|
||||||
bool GetRangerAutoWeaponSelect() { return _rangerAutoWeaponSelect; }
|
bool GetRangerAutoWeaponSelect() { return _rangerAutoWeaponSelect; }
|
||||||
BotRoleType GetBotRole() { return _botRole; }
|
BotRoleType GetBotRole() { return _botRole; }
|
||||||
EQ::constants::StanceType GetBotStance() { return _botStance; }
|
EQ::constants::StanceType GetBotStance() { return _botStance; }
|
||||||
|
|||||||
+168
-74
@@ -122,10 +122,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int spell_id = 2; spell_id < SPDAT_RECORDS; ++spell_id) {
|
for (int spell_id = 2; spell_id < SPDAT_RECORDS; ++spell_id) {
|
||||||
if (spells[spell_id].player_1[0] == '\0')
|
if (!IsValidSpell(spell_id)) {
|
||||||
continue;
|
continue;
|
||||||
if (spells[spell_id].target_type != ST_Target && spells[spell_id].cast_restriction != 0) // watch
|
}
|
||||||
|
|
||||||
|
if (spells[spell_id].player_1[0] == '\0') {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
spells[spell_id].target_type != ST_Target &&
|
||||||
|
spells[spell_id].cast_restriction != 0
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto target_type = BCEnum::TT_None;
|
auto target_type = BCEnum::TT_None;
|
||||||
switch (spells[spell_id].target_type) {
|
switch (spells[spell_id].target_type) {
|
||||||
@@ -5364,40 +5374,54 @@ void bot_subcommand_bot_clone(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
void bot_command_view_combos(Client *c, const Seperator *sep)
|
void bot_command_view_combos(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
const std::string class_substrs[17] = { "",
|
const std::string class_substrs[17] = {
|
||||||
"%u (WAR)", "%u (CLR)", "%u (PAL)", "%u (RNG)",
|
"",
|
||||||
"%u (SHD)", "%u (DRU)", "%u (MNK)", "%u (BRD)",
|
"WAR", "CLR", "PAL", "RNG",
|
||||||
"%u (ROG)", "%u (SHM)", "%u (NEC)", "%u (WIZ)",
|
"SHD", "DRU", "MNK", "BRD",
|
||||||
"%u (MAG)", "%u (ENC)", "%u (BST)", "%u (BER)"
|
"ROG", "SHM", "NEC", "WIZ",
|
||||||
|
"MAG", "ENC", "BST", "BER"
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string race_substrs[17] = { "",
|
const std::string race_substrs[17] = {
|
||||||
"%u (HUM)", "%u (BAR)", "%u (ERU)", "%u (ELF)",
|
"",
|
||||||
"%u (HIE)", "%u (DEF)", "%u (HEF)", "%u (DWF)",
|
"HUM", "BAR", "ERU", "ELF",
|
||||||
"%u (TRL)", "%u (OGR)", "%u (HFL)", "%u (GNM)",
|
"HIE", "DEF", "HEF", "DWF",
|
||||||
"%u (IKS)", "%u (VAH)", "%u (FRG)", "%u (DRK)"
|
"TRL", "OGR", "HFL", "GNM",
|
||||||
|
"IKS", "VAH", "FRG", "DRK"
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint16 race_values[17] = { 0,
|
const uint16 race_values[17] = {
|
||||||
HUMAN, BARBARIAN, ERUDITE, WOOD_ELF,
|
RACE_DOUG_0,
|
||||||
HIGH_ELF, DARK_ELF, HALF_ELF, DWARF,
|
RACE_HUMAN_1, RACE_BARBARIAN_2, RACE_ERUDITE_3, RACE_WOOD_ELF_4,
|
||||||
TROLL, OGRE, HALFLING, GNOME,
|
RACE_HIGH_ELF_5, RACE_DARK_ELF_6, RACE_HALF_ELF_7, RACE_DWARF_8,
|
||||||
IKSAR, VAHSHIR, FROGLOK, DRAKKIN
|
RACE_TROLL_9, RACE_OGRE_10, RACE_HALFLING_11, RACE_GNOME_12,
|
||||||
|
RACE_IKSAR_128, RACE_VAH_SHIR_130, RACE_FROGLOK_330, RACE_DRAKKIN_522
|
||||||
};
|
};
|
||||||
if (helper_command_alias_fail(c, "bot_command_view_combos", sep->arg[0], "viewcombos"))
|
|
||||||
|
if (helper_command_alias_fail(c, "bot_command_view_combos", sep->arg[0], "viewcombos")) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||||
std::string window_title = "Bot Races";
|
|
||||||
std::string window_text;
|
std::string window_text;
|
||||||
std::string message_separator = " ";
|
std::string message_separator = " ";
|
||||||
c->Message(Chat::White, "Usage: %s [bot_race]", sep->arg[0]);
|
c->Message(Chat::White, fmt::format("Usage: {} [Race]", sep->arg[0]).c_str());
|
||||||
window_text.append("<c \"#FFFFFF\">Races:<c \"#FFFF\">");
|
|
||||||
|
window_text.append("<c \"#FFFF\">");
|
||||||
|
|
||||||
for (int race_id = 0; race_id <= 15; ++race_id) {
|
for (int race_id = 0; race_id <= 15; ++race_id) {
|
||||||
window_text.append(message_separator);
|
window_text.append(message_separator);
|
||||||
window_text.append(StringFormat(race_substrs[race_id + 1].c_str(), race_values[race_id + 1]));
|
window_text.append(
|
||||||
|
fmt::format(
|
||||||
|
"{} ({})",
|
||||||
|
race_substrs[race_id + 1],
|
||||||
|
race_values[race_id + 1]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
message_separator = ", ";
|
message_separator = ", ";
|
||||||
}
|
}
|
||||||
c->SendPopupToClient(window_title.c_str(), window_text.c_str());
|
c->SendPopupToClient("Bot Races", window_text.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5405,53 +5429,92 @@ void bot_command_view_combos(Client *c, const Seperator *sep)
|
|||||||
c->Message(Chat::White, "Invalid Race!");
|
c->Message(Chat::White, "Invalid Race!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16 bot_race = atoi(sep->arg[1]);
|
|
||||||
auto classes_bitmask = database.botdb.GetRaceClassBitmask(bot_race);
|
const uint16 bot_race = static_cast<uint16>(std::stoul(sep->arg[1]));
|
||||||
auto race_name = GetRaceIDName(bot_race);
|
const std::string race_name = GetRaceIDName(bot_race);
|
||||||
std::string window_title = "Bot Classes";
|
|
||||||
|
if (!Mob::IsPlayerRace(bot_race)) {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} ({}) is not a race bots can use.",
|
||||||
|
race_name,
|
||||||
|
bot_race
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto classes_bitmask = database.botdb.GetRaceClassBitmask(bot_race);
|
||||||
|
|
||||||
std::string window_text;
|
std::string window_text;
|
||||||
std::string message_separator = " ";
|
std::string message_separator = " ";
|
||||||
c->Message(Chat::White, "%s can be these classes.", race_name);
|
|
||||||
window_text.append("<c \"#FFFFFF\">Classes:<c \"#FFFF\">");
|
window_text.append("<c \"#FFFF\">");
|
||||||
|
|
||||||
|
const int object_max = 4;
|
||||||
|
auto object_count = 0;
|
||||||
|
|
||||||
for (int class_id = 0; class_id <= 15; ++class_id) {
|
for (int class_id = 0; class_id <= 15; ++class_id) {
|
||||||
if (classes_bitmask & GetPlayerClassBit(class_id)) {
|
if (classes_bitmask & GetPlayerClassBit(class_id)) {
|
||||||
window_text.append(message_separator);
|
window_text.append(message_separator);
|
||||||
window_text.append(StringFormat(class_substrs[class_id].c_str(), class_id));
|
|
||||||
|
if (object_count >= object_max) {
|
||||||
|
window_text.append(DialogueWindow::Break());
|
||||||
|
object_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
window_text.append(
|
||||||
|
fmt::format(
|
||||||
|
"{} ({})",
|
||||||
|
class_substrs[class_id],
|
||||||
|
class_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
++object_count;
|
||||||
message_separator = ", ";
|
message_separator = ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->SendPopupToClient(window_title.c_str(), window_text.c_str());
|
|
||||||
return;
|
c->SendPopupToClient(
|
||||||
|
fmt::format(
|
||||||
|
"Bot Classes for {} ({})",
|
||||||
|
race_name,
|
||||||
|
bot_race
|
||||||
|
).c_str(),
|
||||||
|
window_text.c_str()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
const std::string class_substrs[17] = {
|
const std::string class_substrs[17] = {
|
||||||
"",
|
"",
|
||||||
"{} (WAR)", "{} (CLR)", "{} (PAL)", "{} (RNG)",
|
"WAR", "CLR", "PAL", "RNG",
|
||||||
"{} (SHD)", "{} (DRU)", "{} (MNK)", "{} (BRD)",
|
"SHD", "DRU", "MNK", "BRD",
|
||||||
"{} (ROG)", "{} (SHM)", "{} (NEC)", "{} (WIZ)",
|
"ROG", "SHM", "NEC", "WIZ",
|
||||||
"{} (MAG)", "{} (ENC)", "{} (BST)", "{} (BER)"
|
"MAG", "ENC", "BST", "BER"
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string race_substrs[17] = {
|
const std::string race_substrs[17] = {
|
||||||
"",
|
"",
|
||||||
"{} (HUM)", "{} (BAR)", "{} (ERU)", "{} (ELF)",
|
"HUM", "BAR", "ERU", "ELF",
|
||||||
"{} (HIE)", "{} (DEF)", "{} (HEF)", "{} (DWF)",
|
"HIE", "DEF", "HEF", "DWF",
|
||||||
"{} (TRL)", "{} (OGR)", "{} (HFL)", "{} (GNM)",
|
"TRL", "OGR", "HFL", "GNM",
|
||||||
"{} (IKS)", "{} (VAH)", "{} (FRG)", "{} (DRK)"
|
"IKS", "VAH", "FRG", "DRK"
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint16 race_values[17] = {
|
const uint16 race_values[17] = {
|
||||||
0,
|
RACE_DOUG_0,
|
||||||
HUMAN, BARBARIAN, ERUDITE, WOOD_ELF,
|
RACE_HUMAN_1, RACE_BARBARIAN_2, RACE_ERUDITE_3, RACE_WOOD_ELF_4,
|
||||||
HIGH_ELF, DARK_ELF, HALF_ELF, DWARF,
|
RACE_HIGH_ELF_5, RACE_DARK_ELF_6, RACE_HALF_ELF_7, RACE_DWARF_8,
|
||||||
TROLL, OGRE, HALFLING, GNOME,
|
RACE_TROLL_9, RACE_OGRE_10, RACE_HALFLING_11, RACE_GNOME_12,
|
||||||
IKSAR, VAHSHIR, FROGLOK, DRAKKIN
|
RACE_IKSAR_128, RACE_VAH_SHIR_130, RACE_FROGLOK_330, RACE_DRAKKIN_522
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string gender_substrs[2] = {
|
const std::string gender_substrs[2] = {
|
||||||
"{} (M)", "{} (F)",
|
"Male", "Female",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_create", sep->arg[0], "botcreate")) {
|
if (helper_command_alias_fail(c, "bot_subcommand_bot_create", sep->arg[0], "botcreate")) {
|
||||||
@@ -5462,7 +5525,7 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
|||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Usage: {} [bot_name] [bot_class] [bot_race] [bot_gender]",
|
"Usage: {} [Name] [Class] [Race] [Gender]",
|
||||||
sep->arg[0]
|
sep->arg[0]
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
@@ -5470,22 +5533,27 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
|||||||
std::string window_text;
|
std::string window_text;
|
||||||
std::string message_separator;
|
std::string message_separator;
|
||||||
int object_count = 0;
|
int object_count = 0;
|
||||||
const int object_max = 5;
|
const int object_max = 4;
|
||||||
|
|
||||||
window_text.append("<c \"#FFFFFF\">Classes:<c \"#FFFF\">");
|
window_text.append(
|
||||||
|
fmt::format(
|
||||||
|
"Classes{}<c \"#FFFF\">",
|
||||||
|
DialogueWindow::Break()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
message_separator = " ";
|
message_separator = " ";
|
||||||
object_count = 1;
|
object_count = 0;
|
||||||
for (int i = 0; i <= 15; ++i) {
|
for (int i = 0; i <= 15; ++i) {
|
||||||
window_text.append(message_separator);
|
window_text.append(message_separator);
|
||||||
|
|
||||||
if (object_count >= object_max) {
|
if (object_count >= object_max) {
|
||||||
window_text.append("<br>");
|
window_text.append(DialogueWindow::Break());
|
||||||
object_count = 0;
|
object_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
window_text.append(
|
window_text.append(
|
||||||
fmt::format("{} {}",
|
fmt::format("{} ({})",
|
||||||
class_substrs[i + 1],
|
class_substrs[i + 1],
|
||||||
(i + 1)
|
(i + 1)
|
||||||
)
|
)
|
||||||
@@ -5495,22 +5563,27 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
|||||||
message_separator = ", ";
|
message_separator = ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
window_text.append("<br><br>");
|
window_text.append(DialogueWindow::Break(2));
|
||||||
|
|
||||||
window_text.append("<c \"#FFFFFF\">Races:<c \"#FFFF\">");
|
window_text.append(
|
||||||
|
fmt::format(
|
||||||
|
"<c \"#FFFFFF\">Races{}<c \"#FFFF\">",
|
||||||
|
DialogueWindow::Break()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
message_separator = " ";
|
message_separator = " ";
|
||||||
object_count = 1;
|
object_count = 0;
|
||||||
for (int i = 0; i <= 15; ++i) {
|
for (int i = 0; i <= 15; ++i) {
|
||||||
window_text.append(message_separator);
|
window_text.append(message_separator);
|
||||||
|
|
||||||
if (object_count >= object_max) {
|
if (object_count >= object_max) {
|
||||||
window_text.append("<br>");
|
window_text.append(DialogueWindow::Break());
|
||||||
object_count = 0;
|
object_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
window_text.append(
|
window_text.append(
|
||||||
fmt::format("{}, {}",
|
fmt::format("{} ({})",
|
||||||
race_substrs[i + 1],
|
race_substrs[i + 1],
|
||||||
race_values[i + 1]
|
race_values[i + 1]
|
||||||
)
|
)
|
||||||
@@ -5520,16 +5593,21 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
|||||||
message_separator = ", ";
|
message_separator = ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
window_text.append("<br><br>");
|
window_text.append(DialogueWindow::Break(2));
|
||||||
|
|
||||||
window_text.append("<c \"#FFFFFF\">Genders:<c \"#FFFF\">");
|
window_text.append(
|
||||||
|
fmt::format(
|
||||||
|
"<c \"#FFFFFF\">Genders{}<c \"#FFFF\">",
|
||||||
|
DialogueWindow::Break()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
message_separator = " ";
|
message_separator = " ";
|
||||||
for (int i = 0; i <= 1; ++i) {
|
for (int i = 0; i <= 1; ++i) {
|
||||||
window_text.append(message_separator);
|
window_text.append(message_separator);
|
||||||
|
|
||||||
window_text.append(
|
window_text.append(
|
||||||
fmt::format("{}, {}",
|
fmt::format("{} ({})",
|
||||||
gender_substrs[i],
|
gender_substrs[i],
|
||||||
i
|
i
|
||||||
)
|
)
|
||||||
@@ -5538,13 +5616,12 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
|||||||
message_separator = ", ";
|
message_separator = ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
c->SendPopupToClient("Bot Create Options", window_text.c_str());
|
c->SendPopupToClient("Bot Creation Options", window_text.c_str());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto arguments = sep->argnum;
|
const auto arguments = sep->argnum;
|
||||||
|
|
||||||
if (!arguments || sep->IsNumber(1)) {
|
if (!arguments || sep->IsNumber(1)) {
|
||||||
c->Message(Chat::White, "You must name your bot!");
|
c->Message(Chat::White, "You must name your bot!");
|
||||||
return;
|
return;
|
||||||
@@ -5571,15 +5648,18 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bot_gender = 0;
|
auto bot_gender = MALE;
|
||||||
|
|
||||||
if (sep->IsNumber(4)) {
|
if (sep->IsNumber(4)) {
|
||||||
bot_gender = static_cast<uint8>(std::stoul(sep->arg[4]));
|
bot_gender = static_cast<uint8>(std::stoul(sep->arg[4]));
|
||||||
|
if (bot_gender == NEUTER) {
|
||||||
|
bot_gender = MALE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!strcasecmp(sep->arg[4], "m") || !strcasecmp(sep->arg[4], "male")) {
|
if (!strcasecmp(sep->arg[4], "m") || !strcasecmp(sep->arg[4], "male")) {
|
||||||
bot_gender = 0;
|
bot_gender = MALE;
|
||||||
} else if (!strcasecmp(sep->arg[4], "f") || !strcasecmp(sep->arg[4], "female")) {
|
} else if (!strcasecmp(sep->arg[4], "f") || !strcasecmp(sep->arg[4], "female")) {
|
||||||
bot_gender = 1;
|
bot_gender = FEMALE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5674,7 +5754,7 @@ void bot_subcommand_bot_dye_armor(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
if (helper_is_help_or_usage(sep->arg[1]) || !sep->arg[1] || (sep->arg[1] && !Strings::IsNumber(sep->arg[1]))) {
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -7192,7 +7272,13 @@ void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep)
|
|||||||
std::list<Bot*> sbl;
|
std::list<Bot*> sbl;
|
||||||
MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[1]);
|
MyBots::PopulateSBL_ByNamedBot(c, sbl, sep->arg[1]);
|
||||||
if (sbl.empty()) {
|
if (sbl.empty()) {
|
||||||
c->Message(Chat::White, "You must name a new member as a bot that you own to use this command.");
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Usage: (<target_leader>) {} [member_name]",
|
||||||
|
sep->arg[0]
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7720,7 +7806,7 @@ void bot_subcommand_botgroup_list(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<std::pair<std::string, std::string>> botgroups_list;
|
std::list<std::pair<std::string, uint32>> botgroups_list;
|
||||||
if (!database.botdb.LoadBotGroupsListByOwnerID(c->CharacterID(), botgroups_list)) {
|
if (!database.botdb.LoadBotGroupsListByOwnerID(c->CharacterID(), botgroups_list)) {
|
||||||
c->Message(Chat::White, "Failed to load bot-group.");
|
c->Message(Chat::White, "Failed to load bot-group.");
|
||||||
return;
|
return;
|
||||||
@@ -7733,17 +7819,17 @@ void bot_subcommand_botgroup_list(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint32 botgroup_count = 0;
|
uint32 botgroup_count = 0;
|
||||||
|
|
||||||
for (auto botgroups_iter : botgroups_list) {
|
for (const auto& [group_name, group_leader_id] : botgroups_list) {
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Bot-group {} | Name: {} | Leader: {}{} | {}",
|
"Bot-group {} | Name: {} | Leader: {}{} | {}",
|
||||||
(botgroup_count + 1),
|
(botgroup_count + 1),
|
||||||
botgroups_iter.first,
|
group_name,
|
||||||
botgroups_iter.second,
|
database.botdb.GetBotNameByID(group_leader_id),
|
||||||
database.botdb.IsBotGroupAutoSpawn(botgroups_iter.first) ? " (Auto Spawn)" : "",
|
database.botdb.IsBotGroupAutoSpawn(group_name) ? " (Auto Spawn)" : "",
|
||||||
Saylink::Silent(
|
Saylink::Silent(
|
||||||
fmt::format("^botgroupload {}", botgroups_iter.first),
|
fmt::format("^botgroupload {}", group_name),
|
||||||
"Load"
|
"Load"
|
||||||
)
|
)
|
||||||
).c_str()
|
).c_str()
|
||||||
@@ -9391,6 +9477,14 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
|||||||
slot_id
|
slot_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const auto export_string = fmt::format(
|
||||||
|
"{} {}",
|
||||||
|
inst->IsStackable() ? inst->GetCharges() : 1,
|
||||||
|
slot_id
|
||||||
|
);
|
||||||
|
|
||||||
|
parse->EventBot(EVENT_UNEQUIP_ITEM_BOT, my_bot, nullptr, export_string, inst->GetID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+45
-10
@@ -173,13 +173,23 @@ bool BotDatabase::QueryNameAvailablity(const std::string& bot_name, bool& availa
|
|||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"SELECT b.bot_id FROM bot_data b "
|
"SELECT b.bot_id FROM bot_data b "
|
||||||
"INNER JOIN character_data c ON b.`name` = c.`name` "
|
"WHERE b.`name` LIKE '{}' "
|
||||||
"WHERE b.`name` LIKE '{0}' OR c.`name` LIKE '{0}' "
|
|
||||||
"LIMIT 1",
|
"LIMIT 1",
|
||||||
bot_name
|
bot_name
|
||||||
);
|
);
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.RowCount()) {
|
||||||
|
query = fmt::format(
|
||||||
|
"SELECT c.id FROM character_data c "
|
||||||
|
"WHERE c.`name` LIKE '{}' "
|
||||||
|
"LIMIT 1",
|
||||||
|
bot_name
|
||||||
|
);
|
||||||
|
results = database.QueryDatabase(query);
|
||||||
|
}
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2348,7 +2358,7 @@ bool BotDatabase::LoadLeaderIDByBotGroupID(const uint32 group_id, uint32& leader
|
|||||||
bool BotDatabase::LoadBotGroupNameByBotGroupID(const uint32 group_id, std::string& botgroup_name)
|
bool BotDatabase::LoadBotGroupNameByBotGroupID(const uint32 group_id, std::string& botgroup_name)
|
||||||
{
|
{
|
||||||
if (!group_id) {
|
if (!group_id) {
|
||||||
false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
@@ -2536,18 +2546,18 @@ bool BotDatabase::RemoveMemberFromBotGroup(const uint32 member_id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, const std::string& group_name, uint32& botgroup_id)
|
bool BotDatabase::LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, std::string_view group_name, uint32& botgroup_id)
|
||||||
{
|
{
|
||||||
if (!owner_id || group_name.empty()) {
|
if (!owner_id || group_name.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"SELECT groups_index, group_name FROM "
|
"SELECT bg.groups_index, group_name FROM "
|
||||||
"bot_groups bg INNER JOIN bot_group_members bgm "
|
"bot_groups bg INNER JOIN bot_group_members bgm "
|
||||||
"ON bg.groups_index = bgm.groups_index "
|
"ON bg.groups_index = bgm.groups_index "
|
||||||
"WHERE bgm.bot_id IN "
|
"WHERE bgm.bot_id IN "
|
||||||
"(SELECT bot_id FROM bot_data WHERE WHERE owner_id = {})",
|
"(SELECT bot_id FROM bot_data WHERE owner_id = {})",
|
||||||
owner_id
|
owner_id
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2606,7 +2616,7 @@ bool BotDatabase::LoadBotGroup(const std::string& group_name, std::map<uint32, s
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<std::pair<std::string, std::string>>& botgroups_list)
|
bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<std::pair<std::string, uint32>>& botgroups_list)
|
||||||
{
|
{
|
||||||
if (!owner_id) {
|
if (!owner_id) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2614,11 +2624,11 @@ bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<st
|
|||||||
|
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"SELECT group_name, group_leader_name FROM "
|
"SELECT DISTINCT(group_name), group_leader_id FROM "
|
||||||
"bot_groups bg INNER JOIN bot_group_members bgm "
|
"bot_groups bg INNER JOIN bot_group_members bgm "
|
||||||
"ON bg.groups_index = bgm.groups_index "
|
"ON bg.groups_index = bgm.groups_index "
|
||||||
"WHERE bgm.bot_id IN "
|
"WHERE bgm.bot_id IN "
|
||||||
"(SELECT bot_id FROM bot_data WHERE WHERE owner_id = {})",
|
"(SELECT bot_id FROM bot_data WHERE owner_id = {})",
|
||||||
owner_id
|
owner_id
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2632,7 +2642,7 @@ bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<st
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row : results) {
|
for (auto row : results) {
|
||||||
botgroups_list.push_back(std::pair<std::string, std::string>(row[0], row[1]));
|
botgroups_list.push_back(std::pair<std::string, uint32>(row[0], atoul(row[1])));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -3113,6 +3123,30 @@ bool BotDatabase::SaveBotArcherSetting(const uint32 bot_id, const bool bot_arche
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string BotDatabase::GetBotNameByID(const uint32 bot_id)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!bot_id) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
query = fmt::format(
|
||||||
|
"SELECT `name` FROM `bot_data` WHERE `bot_id` = {}",
|
||||||
|
bot_id
|
||||||
|
);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
auto row = results.begin();
|
||||||
|
return row[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* fail::Bot functions */
|
/* fail::Bot functions */
|
||||||
const char* BotDatabase::fail::LoadBotsList() { return "Failed to bots list"; }
|
const char* BotDatabase::fail::LoadBotsList() { return "Failed to bots list"; }
|
||||||
const char* BotDatabase::fail::LoadOwnerID() { return "Failed to load owner ID"; }
|
const char* BotDatabase::fail::LoadOwnerID() { return "Failed to load owner ID"; }
|
||||||
@@ -3178,3 +3212,4 @@ const char* BotDatabase::fail::DeleteHealRotation() { return "Failed to delete h
|
|||||||
const char* BotDatabase::fail::DeleteAllHealRotations() { return "Failed to delete all heal rotations"; }
|
const char* BotDatabase::fail::DeleteAllHealRotations() { return "Failed to delete all heal rotations"; }
|
||||||
|
|
||||||
/* fail::Bot miscellaneous functions */
|
/* fail::Bot miscellaneous functions */
|
||||||
|
const char* BotDatabase::fail::GetBotNameByID() { return "Failed to get bot name by bot ID"; }
|
||||||
|
|||||||
+4
-2
@@ -164,10 +164,10 @@ public:
|
|||||||
bool AddMemberToBotGroup(const uint32 leader_id, const uint32 member_id);
|
bool AddMemberToBotGroup(const uint32 leader_id, const uint32 member_id);
|
||||||
bool RemoveMemberFromBotGroup(const uint32 member_id);
|
bool RemoveMemberFromBotGroup(const uint32 member_id);
|
||||||
|
|
||||||
bool LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, const std::string& botgroup_name, uint32& botgroup_id);
|
bool LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, std::string_view botgroup_name, uint32& botgroup_id);
|
||||||
bool LoadBotGroup(const std::string& botgroup_name, std::map<uint32, std::list<uint32>>& member_list);
|
bool LoadBotGroup(const std::string& botgroup_name, std::map<uint32, std::list<uint32>>& member_list);
|
||||||
|
|
||||||
bool LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<std::pair<std::string, std::string>>& botgroups_list);
|
bool LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<std::pair<std::string, uint32>>& botgroups_list);
|
||||||
|
|
||||||
|
|
||||||
/* Bot group functions */
|
/* Bot group functions */
|
||||||
@@ -190,6 +190,7 @@ public:
|
|||||||
|
|
||||||
/* Bot miscellaneous functions */
|
/* Bot miscellaneous functions */
|
||||||
uint8 GetSpellCastingChance(uint8 spell_type_index, uint8 class_index, uint8 stance_index, uint8 conditional_index);
|
uint8 GetSpellCastingChance(uint8 spell_type_index, uint8 class_index, uint8 stance_index, uint8 conditional_index);
|
||||||
|
std::string GetBotNameByID(const uint32 bot_id);
|
||||||
|
|
||||||
uint16 GetRaceClassBitmask(uint16 bot_race);
|
uint16 GetRaceClassBitmask(uint16 bot_race);
|
||||||
|
|
||||||
@@ -280,6 +281,7 @@ public:
|
|||||||
static const char* DeleteAllHealRotations();
|
static const char* DeleteAllHealRotations();
|
||||||
|
|
||||||
/* fail::Bot miscellaneous functions */
|
/* fail::Bot miscellaneous functions */
|
||||||
|
static const char* GetBotNameByID();
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
+139
-4
@@ -10446,8 +10446,8 @@ int Client::CountItem(uint32 item_id)
|
|||||||
{ EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END },
|
{ EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END },
|
||||||
{ EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END },
|
{ EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END },
|
||||||
};
|
};
|
||||||
const size_t size = sizeof(slots) / sizeof(slots[0]);
|
const size_t slot_index_count = sizeof(slots) / sizeof(slots[0]);
|
||||||
for (int slot_index = 0; slot_index < size; ++slot_index) {
|
for (int slot_index = 0; slot_index < slot_index_count; ++slot_index) {
|
||||||
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
||||||
item = GetInv().GetItem(slot_id);
|
item = GetInv().GetItem(slot_id);
|
||||||
if (item && item->GetID() == item_id) {
|
if (item && item->GetID() == item_id) {
|
||||||
@@ -10459,6 +10459,133 @@ int Client::CountItem(uint32 item_id)
|
|||||||
return quantity;
|
return quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::ResetItemCooldown(uint32 item_id)
|
||||||
|
{
|
||||||
|
EQ::ItemInstance *item = nullptr;
|
||||||
|
const EQ::ItemData* item_d = database.GetItem(item_id);
|
||||||
|
if (!item_d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int recast_type = item_d->RecastType;
|
||||||
|
bool found_item = false;
|
||||||
|
|
||||||
|
static const int16 slots[][2] = {
|
||||||
|
{ EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END },
|
||||||
|
{ EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END },
|
||||||
|
{ EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END},
|
||||||
|
{ EQ::invslot::BANK_BEGIN, EQ::invslot::BANK_END },
|
||||||
|
{ EQ::invbag::BANK_BAGS_BEGIN, EQ::invbag::BANK_BAGS_END },
|
||||||
|
{ EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END },
|
||||||
|
{ EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END },
|
||||||
|
};
|
||||||
|
const size_t slot_index_count = sizeof(slots) / sizeof(slots[0]);
|
||||||
|
for (int slot_index = 0; slot_index < slot_index_count; ++slot_index) {
|
||||||
|
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
||||||
|
item = GetInv().GetItem(slot_id);
|
||||||
|
if (item) {
|
||||||
|
item_d = item->GetItem();
|
||||||
|
if (item_d && item->GetID() == item_id || (item_d->RecastType != RECAST_TYPE_UNLINKED_ITEM && item_d->RecastType == recast_type)) {
|
||||||
|
item->SetRecastTimestamp(0);
|
||||||
|
DeleteItemRecastTimer(item_d->ID);
|
||||||
|
SendItemPacket(slot_id, item, ItemPacketCharmUpdate);
|
||||||
|
found_item = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found_item) {
|
||||||
|
DeleteItemRecastTimer(item_id); //We didn't find the item but we still want to remove the timer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::SetItemCooldown(uint32 item_id, bool use_saved_timer, uint32 in_seconds)
|
||||||
|
{
|
||||||
|
EQ::ItemInstance *item = nullptr;
|
||||||
|
const EQ::ItemData* item_d = database.GetItem(item_id);
|
||||||
|
if (!item_d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int recast_type = item_d->RecastType;
|
||||||
|
auto timestamps = database.GetItemRecastTimestamps(CharacterID());
|
||||||
|
uint32 total_time = 0;
|
||||||
|
uint32 current_time = static_cast<uint32>(std::time(nullptr));
|
||||||
|
uint32 final_time = 0;
|
||||||
|
const auto timer_type = item_d->RecastType != RECAST_TYPE_UNLINKED_ITEM ? item_d->RecastType : item_id;
|
||||||
|
const int timer_id = recast_type != RECAST_TYPE_UNLINKED_ITEM ? (pTimerItemStart + recast_type) : (pTimerNegativeItemReuse * item_id);
|
||||||
|
|
||||||
|
if (use_saved_timer) {
|
||||||
|
if (item_d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
|
||||||
|
total_time = timestamps.count(item_d->RecastType) ? timestamps.at(item_d->RecastType) : 0;
|
||||||
|
} else {
|
||||||
|
total_time = timestamps.count(item_id) ? timestamps.at(item_id) : 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
total_time = current_time + in_seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_time > current_time) {
|
||||||
|
final_time = total_time - current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int16 slots[][2] = {
|
||||||
|
{ EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END },
|
||||||
|
{ EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END },
|
||||||
|
{ EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END},
|
||||||
|
{ EQ::invslot::BANK_BEGIN, EQ::invslot::BANK_END },
|
||||||
|
{ EQ::invbag::BANK_BAGS_BEGIN, EQ::invbag::BANK_BAGS_END },
|
||||||
|
{ EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END },
|
||||||
|
{ EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END },
|
||||||
|
};
|
||||||
|
const size_t slot_index_count = sizeof(slots) / sizeof(slots[0]);
|
||||||
|
for (int slot_index = 0; slot_index < slot_index_count; ++slot_index) {
|
||||||
|
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
||||||
|
item = GetInv().GetItem(slot_id);
|
||||||
|
if (item) {
|
||||||
|
item_d = item->GetItem();
|
||||||
|
if (item_d && item->GetID() == item_id || (item_d->RecastType != RECAST_TYPE_UNLINKED_ITEM && item_d->RecastType == recast_type)) {
|
||||||
|
item->SetRecastTimestamp(total_time);
|
||||||
|
SendItemPacket(slot_id, item, ItemPacketCharmUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start timers and update in database only when timer is changed
|
||||||
|
if (!use_saved_timer) {
|
||||||
|
GetPTimers().Clear(&database, timer_id);
|
||||||
|
GetPTimers().Start((timer_id), in_seconds);
|
||||||
|
database.UpdateItemRecast(
|
||||||
|
CharacterID(),
|
||||||
|
timer_type,
|
||||||
|
GetPTimers().Get(timer_id)->GetReadyTimestamp()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
SendItemRecastTimer(recast_type, final_time, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Client::GetItemCooldown(uint32 item_id)
|
||||||
|
{
|
||||||
|
const EQ::ItemData* item_d = database.GetItem(item_id);
|
||||||
|
if (!item_d) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int recast_type = item_d->RecastType;
|
||||||
|
auto timestamps = database.GetItemRecastTimestamps(CharacterID());
|
||||||
|
const auto timer_type = recast_type != RECAST_TYPE_UNLINKED_ITEM ? recast_type : item_id;
|
||||||
|
uint32 total_time = 0;
|
||||||
|
uint32 current_time = static_cast<uint32>(std::time(nullptr));
|
||||||
|
uint32 final_time = 0;
|
||||||
|
|
||||||
|
total_time = timestamps.count(timer_type) ? timestamps.at(timer_type) : 0;
|
||||||
|
|
||||||
|
if (total_time > current_time) {
|
||||||
|
final_time = total_time - current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_time;
|
||||||
|
}
|
||||||
|
|
||||||
void Client::RemoveItem(uint32 item_id, uint32 quantity)
|
void Client::RemoveItem(uint32 item_id, uint32 quantity)
|
||||||
{
|
{
|
||||||
EQ::ItemInstance *item = nullptr;
|
EQ::ItemInstance *item = nullptr;
|
||||||
@@ -10472,8 +10599,8 @@ void Client::RemoveItem(uint32 item_id, uint32 quantity)
|
|||||||
{ EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END },
|
{ EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END },
|
||||||
};
|
};
|
||||||
int16 removed_count = 0;
|
int16 removed_count = 0;
|
||||||
const size_t size = sizeof(slots) / sizeof(slots[0]);
|
const size_t slot_index_count = sizeof(slots) / sizeof(slots[0]);
|
||||||
for (int slot_index = 0; slot_index < size; ++slot_index) {
|
for (int slot_index = 0; slot_index < slot_index_count; ++slot_index) {
|
||||||
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
|
||||||
if (removed_count == quantity) {
|
if (removed_count == quantity) {
|
||||||
break;
|
break;
|
||||||
@@ -11833,3 +11960,11 @@ void Client::SendPath(Mob* target)
|
|||||||
|
|
||||||
SendPathPacket(points);
|
SendPathPacket(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::UseAugmentContainer(int container_slot) {
|
||||||
|
auto in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)];
|
||||||
|
in_augment->container_slot = container_slot;
|
||||||
|
in_augment->augment_slot = -1;
|
||||||
|
Object::HandleAugmentation(this, in_augment, nullptr);
|
||||||
|
safe_delete_array(in_augment);
|
||||||
|
}
|
||||||
|
|||||||
+8
-5
@@ -254,8 +254,6 @@ public:
|
|||||||
//abstract virtual function implementations required by base abstract class
|
//abstract virtual function implementations required by base abstract class
|
||||||
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill);
|
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill);
|
||||||
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None);
|
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None);
|
||||||
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
|
||||||
ExtraAttackOptions *opts = nullptr);
|
|
||||||
virtual bool HasRaid() { return (GetRaid() ? true : false); }
|
virtual bool HasRaid() { return (GetRaid() ? true : false); }
|
||||||
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
||||||
virtual Raid* GetRaid() { return entity_list.GetRaidByClient(this); }
|
virtual Raid* GetRaid() { return entity_list.GetRaidByClient(this); }
|
||||||
@@ -264,7 +262,6 @@ public:
|
|||||||
virtual void SetAttackTimer();
|
virtual void SetAttackTimer();
|
||||||
int GetQuiverHaste(int delay);
|
int GetQuiverHaste(int delay);
|
||||||
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||||
int64 DoDamageCaps(int64 base_damage);
|
|
||||||
|
|
||||||
void AI_Init();
|
void AI_Init();
|
||||||
void AI_Start(uint32 iMoveDelay = 0);
|
void AI_Start(uint32 iMoveDelay = 0);
|
||||||
@@ -281,6 +278,7 @@ public:
|
|||||||
bool KeyRingCheck(uint32 item_id);
|
bool KeyRingCheck(uint32 item_id);
|
||||||
void KeyRingList();
|
void KeyRingList();
|
||||||
virtual bool IsClient() const { return true; }
|
virtual bool IsClient() const { return true; }
|
||||||
|
bool IsOfClientBotMerc() const override { return true; }
|
||||||
void CompleteConnect();
|
void CompleteConnect();
|
||||||
bool TryStacking(EQ::ItemInstance* item, uint8 type = ItemPacketTrade, bool try_worn = true, bool try_cursor = true);
|
bool TryStacking(EQ::ItemInstance* item, uint8 type = ItemPacketTrade, bool try_worn = true, bool try_cursor = true);
|
||||||
void SendTraderPacket(Client* trader, uint32 Unknown72 = 51);
|
void SendTraderPacket(Client* trader, uint32 Unknown72 = 51);
|
||||||
@@ -955,6 +953,7 @@ public:
|
|||||||
void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing, uint32 reduction = 0);
|
void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing, uint32 reduction = 0);
|
||||||
|
|
||||||
// Item methods
|
// Item methods
|
||||||
|
void UseAugmentContainer(int container_slot);
|
||||||
void EVENT_ITEM_ScriptStopReturn();
|
void EVENT_ITEM_ScriptStopReturn();
|
||||||
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
|
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
|
||||||
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
|
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
|
||||||
@@ -969,6 +968,9 @@ public:
|
|||||||
void SendCursorBuffer();
|
void SendCursorBuffer();
|
||||||
void DeleteItemInInventory(int16 slot_id, int16 quantity = 0, bool client_update = false, bool update_db = true);
|
void DeleteItemInInventory(int16 slot_id, int16 quantity = 0, bool client_update = false, bool update_db = true);
|
||||||
int CountItem(uint32 item_id);
|
int CountItem(uint32 item_id);
|
||||||
|
void ResetItemCooldown(uint32 item_id);
|
||||||
|
void SetItemCooldown(uint32 item_id, bool use_saved_timer = false, uint32 in_seconds = 1);
|
||||||
|
uint32 GetItemCooldown(uint32 item_id);
|
||||||
void RemoveItem(uint32 item_id, uint32 quantity = 1);
|
void RemoveItem(uint32 item_id, uint32 quantity = 1);
|
||||||
bool SwapItem(MoveItem_Struct* move_in);
|
bool SwapItem(MoveItem_Struct* move_in);
|
||||||
void SwapItemResync(MoveItem_Struct* move_slots);
|
void SwapItemResync(MoveItem_Struct* move_slots);
|
||||||
@@ -1519,8 +1521,9 @@ public:
|
|||||||
|
|
||||||
void SendReloadCommandMessages();
|
void SendReloadCommandMessages();
|
||||||
|
|
||||||
void SendItemRecastTimer(int32 recast_type, uint32 recast_delay = 0);
|
void SendItemRecastTimer(int32 recast_type, uint32 recast_delay = 0, bool in_ignore_casting_requirement = false);
|
||||||
void SetItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
void SetItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
||||||
|
void DeleteItemRecastTimer(uint32 item_id);
|
||||||
bool HasItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
bool HasItemRecastTimer(int32 spell_id, uint32 inventory_slot);
|
||||||
|
|
||||||
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQ::versions::maskRoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
|
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQ::versions::maskRoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
|
||||||
@@ -1680,7 +1683,6 @@ protected:
|
|||||||
void CalcItemBonuses(StatBonuses* newbon);
|
void CalcItemBonuses(StatBonuses* newbon);
|
||||||
void AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false);
|
void AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false);
|
||||||
void AdditiveWornBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false);
|
void AdditiveWornBonuses(const EQ::ItemInstance *inst, StatBonuses* newbon, bool isAug = false);
|
||||||
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
|
||||||
void CalcEdibleBonuses(StatBonuses* newbon);
|
void CalcEdibleBonuses(StatBonuses* newbon);
|
||||||
void ProcessItemCaps();
|
void ProcessItemCaps();
|
||||||
void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true);
|
void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true);
|
||||||
@@ -2082,6 +2084,7 @@ private:
|
|||||||
bool m_bot_precombat;
|
bool m_bot_precombat;
|
||||||
|
|
||||||
bool CanTradeFVNoDropItem();
|
bool CanTradeFVNoDropItem();
|
||||||
|
void SendMobPositions();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1031,14 +1031,14 @@ int Client::CalcHaste()
|
|||||||
h += spellbonuses.hastetype2 > 10 ? 10 : spellbonuses.hastetype2;
|
h += spellbonuses.hastetype2 > 10 ? 10 : spellbonuses.hastetype2;
|
||||||
}
|
}
|
||||||
// 26+ no cap, 1-25 10
|
// 26+ no cap, 1-25 10
|
||||||
if (level > 25) { // 26+
|
if (level > 25 || RuleB(Character, IgnoreLevelBasedHasteCaps)) { // 26+
|
||||||
h += itembonuses.haste;
|
h += itembonuses.haste;
|
||||||
}
|
}
|
||||||
else { // 1-25
|
else { // 1-25
|
||||||
h += itembonuses.haste > 10 ? 10 : itembonuses.haste;
|
h += itembonuses.haste > 10 ? 10 : itembonuses.haste;
|
||||||
}
|
}
|
||||||
// 60+ 100, 51-59 85, 1-50 level+25
|
// 60+ 100, 51-59 85, 1-50 level+25
|
||||||
if (level > 59) { // 60+
|
if (level > 59 || RuleB(Character, IgnoreLevelBasedHasteCaps)) { // 60+
|
||||||
cap = RuleI(Character, HasteCap);
|
cap = RuleI(Character, HasteCap);
|
||||||
}
|
}
|
||||||
else if (level > 50) { // 51-59
|
else if (level > 50) { // 51-59
|
||||||
@@ -1052,7 +1052,7 @@ int Client::CalcHaste()
|
|||||||
h = cap;
|
h = cap;
|
||||||
}
|
}
|
||||||
// 51+ 25 (despite there being higher spells...), 1-50 10
|
// 51+ 25 (despite there being higher spells...), 1-50 10
|
||||||
if (level > 50) { // 51+
|
if (level > 50 || RuleB(Character, IgnoreLevelBasedHasteCaps)) { // 51+
|
||||||
cap = RuleI(Character, Hastev3Cap);
|
cap = RuleI(Character, Hastev3Cap);
|
||||||
if (spellbonuses.hastetype3 > cap) {
|
if (spellbonuses.hastetype3 > cap) {
|
||||||
h += cap;
|
h += cap;
|
||||||
|
|||||||
+142
-16
@@ -778,6 +778,12 @@ void Client::CompleteConnect()
|
|||||||
|
|
||||||
parse->EventPlayer(EVENT_ENTER_ZONE, this, "", 0);
|
parse->EventPlayer(EVENT_ENTER_ZONE, this, "", 0);
|
||||||
|
|
||||||
|
// the way that the client deals with positions during the initial spawn struct
|
||||||
|
// is subtly different from how it deals with getting a position update
|
||||||
|
// if a mob is slightly in the wall or slightly clipping a floor they will be
|
||||||
|
// sent to a succor point
|
||||||
|
SendMobPositions();
|
||||||
|
|
||||||
SetLastPositionBeforeBulkUpdate(GetPosition());
|
SetLastPositionBeforeBulkUpdate(GetPosition());
|
||||||
|
|
||||||
/* This sub event is for if a player logs in for the first time since entering world. */
|
/* This sub event is for if a player logs in for the first time since entering world. */
|
||||||
@@ -4168,8 +4174,26 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
if (GetLevel() >= item->Click.Level2)
|
if (GetLevel() >= item->Click.Level2)
|
||||||
{
|
{
|
||||||
EQ::ItemInstance* p_inst = (EQ::ItemInstance*)inst;
|
auto* p_inst = (EQ::ItemInstance*) inst;
|
||||||
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot);
|
int i = 0;
|
||||||
|
|
||||||
|
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
|
||||||
|
i = parse->EventItem(
|
||||||
|
EVENT_ITEM_CLICK_CAST,
|
||||||
|
this,
|
||||||
|
p_inst,
|
||||||
|
nullptr,
|
||||||
|
"",
|
||||||
|
castspell->inventoryslot
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
|
||||||
|
std::vector<std::any> args;
|
||||||
|
args.emplace_back(p_inst);
|
||||||
|
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(castspell->inventoryslot), 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot);
|
CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot);
|
||||||
}
|
}
|
||||||
@@ -4187,8 +4211,26 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EQ::ItemInstance* p_inst = (EQ::ItemInstance*)inst;
|
auto* p_inst = (EQ::ItemInstance*) inst;
|
||||||
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot);
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
|
||||||
|
i = parse->EventItem(
|
||||||
|
EVENT_ITEM_CLICK_CAST,
|
||||||
|
this,
|
||||||
|
p_inst,
|
||||||
|
nullptr,
|
||||||
|
"",
|
||||||
|
castspell->inventoryslot
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
|
||||||
|
std::vector<std::any> args;
|
||||||
|
args.emplace_back(p_inst);
|
||||||
|
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(castspell->inventoryslot), 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot);
|
CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot);
|
||||||
@@ -4343,27 +4385,46 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set door selected
|
float distance = DistanceNoZ(GetPosition(), currentdoor->GetPosition());
|
||||||
if (IsDevToolsEnabled()) {
|
|
||||||
|
LogDoors(
|
||||||
|
"Door [{}] client handle, client distance from door [{:.2f}]",
|
||||||
|
currentdoor->GetDoorID(),
|
||||||
|
distance
|
||||||
|
);
|
||||||
|
|
||||||
|
bool within_distance = distance < RuleI(Range, MaxDistanceToClickDoors);
|
||||||
|
|
||||||
|
// distance gate this because some doors are client controlled and the client
|
||||||
|
// will spam door click even across the zone to force a door back into desired state
|
||||||
|
if (IsDevToolsEnabled() && within_distance) {
|
||||||
SetDoorToolEntityId(currentdoor->GetEntityID());
|
SetDoorToolEntityId(currentdoor->GetEntityID());
|
||||||
DoorManipulation::CommandHeader(this);
|
DoorManipulation::CommandHeader(this);
|
||||||
Message(
|
Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Door ({}) [{}]",
|
"Door ({}) [{}]",
|
||||||
currentdoor->GetEntityID(),
|
currentdoor->GetDoorID(),
|
||||||
Saylink::Silent("#door edit")
|
Saylink::Silent("#door edit")
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't spam scripts with client controlled doors if not within distance
|
||||||
|
if (within_distance) {
|
||||||
std::string export_string = fmt::format("{}", cd->doorid);
|
std::string export_string = fmt::format("{}", cd->doorid);
|
||||||
std::vector<std::any> args;
|
std::vector<std::any> args;
|
||||||
args.push_back(currentdoor);
|
args.push_back(currentdoor);
|
||||||
if (parse->EventPlayer(EVENT_CLICK_DOOR, this, export_string, 0, &args) == 0)
|
if (parse->EventPlayer(EVENT_CLICK_DOOR, this, export_string, 0, &args) == 0) {
|
||||||
{
|
|
||||||
currentdoor->HandleClick(this, 0);
|
currentdoor->HandleClick(this, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we let this pass because client controlled doors require this to force the linked doors
|
||||||
|
// back into state
|
||||||
|
currentdoor->HandleClick(this, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_ClickObject(const EQApplicationPacket *app)
|
void Client::Handle_OP_ClickObject(const EQApplicationPacket *app)
|
||||||
@@ -8836,9 +8897,18 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == EQ::item::ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check
|
if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == EQ::item::ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check
|
||||||
{
|
{
|
||||||
EQ::ItemInstance* p_inst = (EQ::ItemInstance*)inst;
|
auto* p_inst = (EQ::ItemInstance*) inst;
|
||||||
|
|
||||||
|
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK)) {
|
||||||
parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id);
|
parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CLIENT)) {
|
||||||
|
std::vector<std::any> args;
|
||||||
|
args.emplace_back(p_inst);
|
||||||
|
parse->EventPlayer(EVENT_ITEM_CLICK_CLIENT, this, std::to_string(slot_id), 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
inst = m_inv[slot_id];
|
inst = m_inv[slot_id];
|
||||||
if (!inst)
|
if (!inst)
|
||||||
{
|
{
|
||||||
@@ -8927,16 +8997,38 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
if (item->RecastDelay > 0)
|
if (item->RecastDelay > 0)
|
||||||
{
|
{
|
||||||
if (!GetPTimers().Expired(&database, (pTimerItemStart + item->RecastType), false)) {
|
if (item->RecastType != RECAST_TYPE_UNLINKED_ITEM && !GetPTimers().Expired(&database, (pTimerItemStart + item->RecastType), false)) {
|
||||||
SendItemRecastTimer(item->RecastType); //Problem: When you loot corpse, recast display is not present. This causes it to display again. Could not get to display when sending from looting.
|
SetItemCooldown(item->ID, true);
|
||||||
MessageString(Chat::Red, SPELL_RECAST);
|
SendSpellBarEnable(item->Click.Effect);
|
||||||
|
LogSpells("Casting of [{}] canceled: item spell reuse timer not expired", spell_id);
|
||||||
|
return;
|
||||||
|
} else if (item->RecastType == RECAST_TYPE_UNLINKED_ITEM && !GetPTimers().Expired(&database, (pTimerNegativeItemReuse * item->ID), false)) {
|
||||||
|
SetItemCooldown(item->ID, true);
|
||||||
SendSpellBarEnable(item->Click.Effect);
|
SendSpellBarEnable(item->Click.Effect);
|
||||||
LogSpells("Casting of [{}] canceled: item spell reuse timer not expired", spell_id);
|
LogSpells("Casting of [{}] canceled: item spell reuse timer not expired", spell_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", slot_id);
|
int i = 0;
|
||||||
|
|
||||||
|
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
|
||||||
|
i = parse->EventItem(
|
||||||
|
EVENT_ITEM_CLICK_CAST,
|
||||||
|
this,
|
||||||
|
p_inst,
|
||||||
|
nullptr,
|
||||||
|
"",
|
||||||
|
slot_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
|
||||||
|
std::vector<std::any> args;
|
||||||
|
args.emplace_back(p_inst);
|
||||||
|
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(slot_id), 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
inst = m_inv[slot_id];
|
inst = m_inv[slot_id];
|
||||||
if (!inst)
|
if (!inst)
|
||||||
{
|
{
|
||||||
@@ -8972,15 +9064,38 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
if (augitem->RecastDelay > 0)
|
if (augitem->RecastDelay > 0)
|
||||||
{
|
{
|
||||||
if (!GetPTimers().Expired(&database, (pTimerItemStart + augitem->RecastType), false)) {
|
if (augitem->RecastType != RECAST_TYPE_UNLINKED_ITEM && !GetPTimers().Expired(&database, (pTimerItemStart + augitem->RecastType), false)) {
|
||||||
LogSpells("Casting of [{}] canceled: item spell reuse timer from augment not expired", spell_id);
|
LogSpells("Casting of [{}] canceled: item spell reuse timer from augment not expired", spell_id);
|
||||||
MessageString(Chat::Red, SPELL_RECAST);
|
MessageString(Chat::Red, SPELL_RECAST);
|
||||||
SendSpellBarEnable(augitem->Click.Effect);
|
SendSpellBarEnable(augitem->Click.Effect);
|
||||||
return;
|
return;
|
||||||
|
} else if (augitem->RecastType == RECAST_TYPE_UNLINKED_ITEM && !GetPTimers().Expired(&database, (pTimerNegativeItemReuse * augitem->ID), false)) {
|
||||||
|
MessageString(Chat::Red, SPELL_RECAST);
|
||||||
|
SendSpellBarEnable(augitem->Click.Effect);
|
||||||
|
LogSpells("Casting of [{}] canceled: item spell reuse timer not expired", spell_id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, clickaug, nullptr, "", slot_id);
|
int i = 0;
|
||||||
|
|
||||||
|
if (parse->ItemHasQuestSub(p_inst, EVENT_ITEM_CLICK_CAST)) {
|
||||||
|
i = parse->EventItem(
|
||||||
|
EVENT_ITEM_CLICK_CAST,
|
||||||
|
this,
|
||||||
|
clickaug,
|
||||||
|
nullptr,
|
||||||
|
"",
|
||||||
|
slot_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_ITEM_CLICK_CAST_CLIENT)) {
|
||||||
|
std::vector<std::any> args;
|
||||||
|
args.emplace_back(clickaug);
|
||||||
|
i = parse->EventPlayer(EVENT_ITEM_CLICK_CAST_CLIENT, this, std::to_string(slot_id), 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
inst = m_inv[slot_id];
|
inst = m_inv[slot_id];
|
||||||
if (!inst)
|
if (!inst)
|
||||||
{
|
{
|
||||||
@@ -15640,3 +15755,14 @@ bool Client::CanTradeFVNoDropItem()
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::SendMobPositions()
|
||||||
|
{
|
||||||
|
auto p = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||||
|
auto *s = (PlayerPositionUpdateServer_Struct *) p->pBuffer;
|
||||||
|
for (auto &m: entity_list.GetMobList()) {
|
||||||
|
m.second->MakeSpawnUpdate(s);
|
||||||
|
QueuePacket(p, false);
|
||||||
|
}
|
||||||
|
safe_delete(p);
|
||||||
|
}
|
||||||
|
|||||||
@@ -872,6 +872,9 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!EQ::ValueWithin(Admin(), static_cast<int16>(ml.min_status), static_cast<int16>(ml.max_status))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int32 faction_id = npc ? npc->GetPrimaryFaction() : 0;
|
int32 faction_id = npc ? npc->GetPrimaryFaction() : 0;
|
||||||
int32 faction_level = (
|
int32 faction_level = (
|
||||||
|
|||||||
+1
-9
@@ -94,7 +94,7 @@ int command_init(void)
|
|||||||
command_add("aggrozone", "[aggro] - Aggro every mob in the zone with X aggro. Default is 0. Not recommend if you're not invulnerable.", AccountStatus::GMAdmin, command_aggrozone) ||
|
command_add("aggrozone", "[aggro] - Aggro every mob in the zone with X aggro. Default is 0. Not recommend if you're not invulnerable.", AccountStatus::GMAdmin, command_aggrozone) ||
|
||||||
command_add("ai", "[factionid/spellslist/con/guard/roambox/stop/start] - Modify AI on NPC target", AccountStatus::GMAdmin, command_ai) ||
|
command_add("ai", "[factionid/spellslist/con/guard/roambox/stop/start] - Modify AI on NPC target", AccountStatus::GMAdmin, command_ai) ||
|
||||||
command_add("appearance", "[type] [value] - Send an appearance packet for you or your target", AccountStatus::GMLeadAdmin, command_appearance) ||
|
command_add("appearance", "[type] [value] - Send an appearance packet for you or your target", AccountStatus::GMLeadAdmin, command_appearance) ||
|
||||||
command_add("appearanceeffects", "[view] [set] [remove] appearance effects.", AccountStatus::GMAdmin, command_appearanceeffects) ||
|
command_add("appearanceeffects", "[Help|Remove|Set|View] - Modify appearance effects on yourself or your target.", AccountStatus::GMAdmin, command_appearanceeffects) ||
|
||||||
command_add("apply_shared_memory", "[shared_memory_name] - Tells every zone and world to apply a specific shared memory segment by name.", AccountStatus::GMImpossible, command_apply_shared_memory) ||
|
command_add("apply_shared_memory", "[shared_memory_name] - Tells every zone and world to apply a specific shared memory segment by name.", AccountStatus::GMImpossible, command_apply_shared_memory) ||
|
||||||
command_add("attack", "[Entity Name] - Make your NPC target attack an entity by name", AccountStatus::GMLeadAdmin, command_attack) ||
|
command_add("attack", "[Entity Name] - Make your NPC target attack an entity by name", AccountStatus::GMLeadAdmin, command_attack) ||
|
||||||
command_add("augmentitem", "Force augments an item. Must have the augment item window open.", AccountStatus::GMImpossible, command_augmentitem) ||
|
command_add("augmentitem", "Force augments an item. Must have the augment item window open.", AccountStatus::GMImpossible, command_augmentitem) ||
|
||||||
@@ -176,9 +176,6 @@ int command_init(void)
|
|||||||
command_add("goto", "[playername] or [x y z] [h] - Teleport to the provided coordinates or to your target", AccountStatus::Steward, command_goto) ||
|
command_add("goto", "[playername] or [x y z] [h] - Teleport to the provided coordinates or to your target", AccountStatus::Steward, command_goto) ||
|
||||||
command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", AccountStatus::GMAreas, command_grid) ||
|
command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", AccountStatus::GMAreas, command_grid) ||
|
||||||
command_add("guild", "Guild manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_guild) ||
|
command_add("guild", "Guild manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_guild) ||
|
||||||
command_add("guildapprove", "[guildapproveid] - Approve a guild with specified ID (guild creator receives the id)", AccountStatus::Player, command_guildapprove) ||
|
|
||||||
command_add("guildcreate", "[guildname] - Creates an approval setup for guild name specified", AccountStatus::Player, command_guildcreate) ||
|
|
||||||
command_add("guildlist", "[guildapproveid] - Lists character names who have approved the guild specified by the approve id", AccountStatus::Player, command_guildlist) ||
|
|
||||||
command_add("haste", "[percentage] - Set your haste percentage", AccountStatus::GMAdmin, command_haste) ||
|
command_add("haste", "[percentage] - Set your haste percentage", AccountStatus::GMAdmin, command_haste) ||
|
||||||
command_add("hatelist", "Display hate list for NPC.", AccountStatus::QuestTroupe, command_hatelist) ||
|
command_add("hatelist", "Display hate list for NPC.", AccountStatus::QuestTroupe, command_hatelist) ||
|
||||||
command_add("heal", "Completely heal your target", AccountStatus::Steward, command_heal) ||
|
command_add("heal", "Completely heal your target", AccountStatus::Steward, command_heal) ||
|
||||||
@@ -333,7 +330,6 @@ int command_init(void)
|
|||||||
command_add("trapinfo", "Gets infomation about the traps currently spawned in the zone.", AccountStatus::QuestTroupe, command_trapinfo) ||
|
command_add("trapinfo", "Gets infomation about the traps currently spawned in the zone.", AccountStatus::QuestTroupe, command_trapinfo) ||
|
||||||
command_add("tune", "Calculate statistical values related to combat.", AccountStatus::GMAdmin, command_tune) ||
|
command_add("tune", "Calculate statistical values related to combat.", AccountStatus::GMAdmin, command_tune) ||
|
||||||
command_add("undye", "Remove dye from all of your or your target's armor slots", AccountStatus::GMAdmin, command_undye) ||
|
command_add("undye", "Remove dye from all of your or your target's armor slots", AccountStatus::GMAdmin, command_undye) ||
|
||||||
command_add("undyeme", "Remove dye from all of your armor slots", AccountStatus::Player, command_undyeme) ||
|
|
||||||
command_add("unfreeze", "Unfreeze your target", AccountStatus::QuestTroupe, command_unfreeze) ||
|
command_add("unfreeze", "Unfreeze your target", AccountStatus::QuestTroupe, command_unfreeze) ||
|
||||||
command_add("unmemspell", "[Spell ID] - Unmemorize a Spell by ID for you or your target", AccountStatus::Guide, command_unmemspell) ||
|
command_add("unmemspell", "[Spell ID] - Unmemorize a Spell by ID for you or your target", AccountStatus::Guide, command_unmemspell) ||
|
||||||
command_add("unmemspells", " Unmemorize all spells for you or your target", AccountStatus::Guide, command_unmemspells) ||
|
command_add("unmemspells", " Unmemorize all spells for you or your target", AccountStatus::Guide, command_unmemspells) ||
|
||||||
@@ -1015,9 +1011,6 @@ void command_bot(Client *c, const Seperator *sep)
|
|||||||
#include "gm_commands/goto.cpp"
|
#include "gm_commands/goto.cpp"
|
||||||
#include "gm_commands/grid.cpp"
|
#include "gm_commands/grid.cpp"
|
||||||
#include "gm_commands/guild.cpp"
|
#include "gm_commands/guild.cpp"
|
||||||
#include "gm_commands/guildapprove.cpp"
|
|
||||||
#include "gm_commands/guildcreate.cpp"
|
|
||||||
#include "gm_commands/guildlist.cpp"
|
|
||||||
#include "gm_commands/haste.cpp"
|
#include "gm_commands/haste.cpp"
|
||||||
#include "gm_commands/hatelist.cpp"
|
#include "gm_commands/hatelist.cpp"
|
||||||
#include "gm_commands/heal.cpp"
|
#include "gm_commands/heal.cpp"
|
||||||
@@ -1169,7 +1162,6 @@ void command_bot(Client *c, const Seperator *sep)
|
|||||||
#include "gm_commands/trapinfo.cpp"
|
#include "gm_commands/trapinfo.cpp"
|
||||||
#include "gm_commands/tune.cpp"
|
#include "gm_commands/tune.cpp"
|
||||||
#include "gm_commands/undye.cpp"
|
#include "gm_commands/undye.cpp"
|
||||||
#include "gm_commands/undyeme.cpp"
|
|
||||||
#include "gm_commands/unfreeze.cpp"
|
#include "gm_commands/unfreeze.cpp"
|
||||||
#include "gm_commands/unmemspell.cpp"
|
#include "gm_commands/unmemspell.cpp"
|
||||||
#include "gm_commands/unmemspells.cpp"
|
#include "gm_commands/unmemspells.cpp"
|
||||||
|
|||||||
@@ -122,9 +122,6 @@ void command_godmode(Client* c, const Seperator *sep);
|
|||||||
void command_goto(Client *c, const Seperator *sep);
|
void command_goto(Client *c, const Seperator *sep);
|
||||||
void command_grid(Client *c, const Seperator *sep);
|
void command_grid(Client *c, const Seperator *sep);
|
||||||
void command_guild(Client *c, const Seperator *sep);
|
void command_guild(Client *c, const Seperator *sep);
|
||||||
void command_guildapprove(Client *c, const Seperator *sep);
|
|
||||||
void command_guildcreate(Client *c, const Seperator *sep);
|
|
||||||
void command_guildlist(Client *c, const Seperator *sep);
|
|
||||||
void command_haste(Client *c, const Seperator *sep);
|
void command_haste(Client *c, const Seperator *sep);
|
||||||
void command_hatelist(Client *c, const Seperator *sep);
|
void command_hatelist(Client *c, const Seperator *sep);
|
||||||
void command_heal(Client *c, const Seperator *sep);
|
void command_heal(Client *c, const Seperator *sep);
|
||||||
@@ -284,7 +281,6 @@ void command_traindisc(Client *c, const Seperator *sep);
|
|||||||
void command_trapinfo(Client *c, const Seperator *sep);
|
void command_trapinfo(Client *c, const Seperator *sep);
|
||||||
void command_tune(Client *c, const Seperator *sep);
|
void command_tune(Client *c, const Seperator *sep);
|
||||||
void command_undye(Client *c, const Seperator *sep);
|
void command_undye(Client *c, const Seperator *sep);
|
||||||
void command_undyeme(Client *c, const Seperator *sep);
|
|
||||||
void command_unfreeze(Client *c, const Seperator *sep);
|
void command_unfreeze(Client *c, const Seperator *sep);
|
||||||
void command_unlock(Client *c, const Seperator *sep);
|
void command_unlock(Client *c, const Seperator *sep);
|
||||||
void command_unmemspell(Client *c, const Seperator *sep);
|
void command_unmemspell(Client *c, const Seperator *sep);
|
||||||
|
|||||||
+22
-2
@@ -1209,8 +1209,13 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
auto pkinst = database.CreateItem(pkitem, pkitem->MaxCharges);
|
auto pkinst = database.CreateItem(pkitem, pkitem->MaxCharges);
|
||||||
|
|
||||||
if (pkinst) {
|
if (pkinst) {
|
||||||
if (pkitem->RecastDelay)
|
if (pkitem->RecastDelay) {
|
||||||
|
if (pkitem->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
|
||||||
pkinst->SetRecastTimestamp(timestamps.count(pkitem->RecastType) ? timestamps.at(pkitem->RecastType) : 0);
|
pkinst->SetRecastTimestamp(timestamps.count(pkitem->RecastType) ? timestamps.at(pkitem->RecastType) : 0);
|
||||||
|
} else {
|
||||||
|
pkinst->SetRecastTimestamp(timestamps.count(pkitem->ID) ? timestamps.at(pkitem->ID) : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LogInventory("MakeLootRequestPackets() Slot [{}], Item [{}]", EQ::invslot::CORPSE_BEGIN, pkitem->Name);
|
LogInventory("MakeLootRequestPackets() Slot [{}], Item [{}]", EQ::invslot::CORPSE_BEGIN, pkitem->Name);
|
||||||
|
|
||||||
@@ -1264,8 +1269,13 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
|||||||
if (!inst)
|
if (!inst)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (item->RecastDelay)
|
if (item->RecastDelay) {
|
||||||
|
if (item->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
|
||||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||||
|
} else {
|
||||||
|
inst->SetRecastTimestamp(timestamps.count(item->ID) ? timestamps.at(item->ID) : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LogInventory("MakeLootRequestPackets() Slot [{}], Item [{}]", loot_slot, item->Name);
|
LogInventory("MakeLootRequestPackets() Slot [{}], Item [{}]", loot_slot, item->Name);
|
||||||
|
|
||||||
@@ -1477,6 +1487,16 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
|||||||
|
|
||||||
// get count for task update before it's mutated by AutoPutLootInInventory
|
// get count for task update before it's mutated by AutoPutLootInInventory
|
||||||
int count = inst->IsStackable() ? inst->GetCharges() : 1;
|
int count = inst->IsStackable() ? inst->GetCharges() : 1;
|
||||||
|
//Set recast on item when looting it!
|
||||||
|
auto timestamps = database.GetItemRecastTimestamps(client->CharacterID());
|
||||||
|
const auto* d = inst->GetItem();
|
||||||
|
if (d->RecastDelay) {
|
||||||
|
if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
|
||||||
|
inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0);
|
||||||
|
} else {
|
||||||
|
inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* First add it to the looter - this will do the bag contents too */
|
/* First add it to the looter - this will do the bag contents too */
|
||||||
if (lootitem->auto_loot > 0) {
|
if (lootitem->auto_loot > 0) {
|
||||||
|
|||||||
+4
-1
@@ -53,7 +53,10 @@ class Corpse : public Mob {
|
|||||||
/* Corpse: General */
|
/* Corpse: General */
|
||||||
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) { return true; }
|
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) { return true; }
|
||||||
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
||||||
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; }
|
bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = true,
|
||||||
|
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
virtual bool HasRaid() { return false; }
|
virtual bool HasRaid() { return false; }
|
||||||
virtual bool HasGroup() { return false; }
|
virtual bool HasGroup() { return false; }
|
||||||
virtual Raid* GetRaid() { return 0; }
|
virtual Raid* GetRaid() { return 0; }
|
||||||
|
|||||||
+77
-13
@@ -121,6 +121,7 @@ Doors::~Doors()
|
|||||||
bool Doors::Process()
|
bool Doors::Process()
|
||||||
{
|
{
|
||||||
if (m_close_timer.Enabled() && m_close_timer.Check() && IsDoorOpen()) {
|
if (m_close_timer.Enabled() && m_close_timer.Check() && IsDoorOpen()) {
|
||||||
|
LogDoorsDetail("door open and timer triggered door_id [{}] open_type [{}]", GetDoorID(), m_open_type);
|
||||||
if (m_open_type == 40 || GetTriggerType() == 1) {
|
if (m_open_type == 40 || GetTriggerType() == 1) {
|
||||||
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
auto outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
|
||||||
MoveDoor_Struct *md = (MoveDoor_Struct *) outapp->pBuffer;
|
MoveDoor_Struct *md = (MoveDoor_Struct *) outapp->pBuffer;
|
||||||
@@ -627,11 +628,13 @@ void Doors::ForceOpen(Mob *sender, bool alt_mode)
|
|||||||
if (!alt_mode) { // original function
|
if (!alt_mode) { // original function
|
||||||
if (!m_is_open) {
|
if (!m_is_open) {
|
||||||
if (!m_disable_timer) {
|
if (!m_disable_timer) {
|
||||||
|
LogDoorsDetail("door_id [{}] starting timer", md->doorid);
|
||||||
m_close_timer.Start();
|
m_close_timer.Start();
|
||||||
}
|
}
|
||||||
m_is_open = true;
|
m_is_open = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
LogDoorsDetail("door_id [{}] disable timer", md->doorid);
|
||||||
m_close_timer.Disable();
|
m_close_timer.Disable();
|
||||||
if (!m_disable_timer) {
|
if (!m_disable_timer) {
|
||||||
m_is_open = false;
|
m_is_open = false;
|
||||||
@@ -640,6 +643,7 @@ void Doors::ForceOpen(Mob *sender, bool alt_mode)
|
|||||||
}
|
}
|
||||||
else { // alternative function
|
else { // alternative function
|
||||||
if (!m_disable_timer) {
|
if (!m_disable_timer) {
|
||||||
|
LogDoorsDetail("door_id [{}] alt starting timer", md->doorid);
|
||||||
m_close_timer.Start();
|
m_close_timer.Start();
|
||||||
}
|
}
|
||||||
m_is_open = true;
|
m_is_open = true;
|
||||||
@@ -802,20 +806,75 @@ void Doors::CreateDatabaseEntry()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
content_db.InsertDoor(
|
const auto& l = DoorsRepository::GetWhere(
|
||||||
GetDoorDBID(),
|
content_db,
|
||||||
GetDoorID(),
|
fmt::format(
|
||||||
GetDoorName(),
|
"zone = '{}' AND doorid = {}",
|
||||||
m_position,
|
zone->GetShortName(),
|
||||||
GetOpenType(),
|
GetDoorID()
|
||||||
static_cast<uint16>(GetGuildID()),
|
)
|
||||||
GetLockpick(),
|
|
||||||
GetKeyItem(),
|
|
||||||
static_cast<uint8>(GetDoorParam()),
|
|
||||||
static_cast<uint8>(GetInvertState()),
|
|
||||||
GetIncline(),
|
|
||||||
GetSize()
|
|
||||||
);
|
);
|
||||||
|
if (!l.empty()) {
|
||||||
|
auto e = l[0];
|
||||||
|
|
||||||
|
e.name = GetDoorName();
|
||||||
|
e.pos_x = GetX();
|
||||||
|
e.pos_y = GetY();
|
||||||
|
e.pos_z = GetZ();
|
||||||
|
e.heading = GetHeading();
|
||||||
|
e.opentype = GetOpenType();
|
||||||
|
e.guild = static_cast<uint16>(GetGuildID());
|
||||||
|
e.lockpick = GetLockpick();
|
||||||
|
e.keyitem = GetKeyItem();
|
||||||
|
e.door_param = static_cast<uint8>(GetDoorParam());
|
||||||
|
e.invert_state = static_cast<uint8>(GetInvertState());
|
||||||
|
e.incline = GetIncline();
|
||||||
|
e.size = GetSize();
|
||||||
|
|
||||||
|
auto updated = DoorsRepository::UpdateOne(content_db, e);
|
||||||
|
if (!updated) {
|
||||||
|
LogError(
|
||||||
|
"Failed to update door in Zone [{}] Version [{}] Database ID [{}] ID [{}]",
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion(),
|
||||||
|
GetDoorDBID(),
|
||||||
|
GetDoorID()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto e = DoorsRepository::NewEntity();
|
||||||
|
|
||||||
|
e.id = GetDoorDBID();
|
||||||
|
e.doorid = GetDoorID();
|
||||||
|
e.zone = zone->GetShortName();
|
||||||
|
e.version = zone->GetInstanceVersion();
|
||||||
|
e.name = GetDoorName();
|
||||||
|
e.pos_x = GetX();
|
||||||
|
e.pos_y = GetY();
|
||||||
|
e.pos_z = GetZ();
|
||||||
|
e.heading = GetHeading();
|
||||||
|
e.opentype = GetOpenType();
|
||||||
|
e.guild = static_cast<uint16>(GetGuildID());
|
||||||
|
e.lockpick = GetLockpick();
|
||||||
|
e.keyitem = GetKeyItem();
|
||||||
|
e.door_param = static_cast<uint8>(GetDoorParam());
|
||||||
|
e.invert_state = static_cast<uint8>(GetInvertState());
|
||||||
|
e.incline = GetIncline();
|
||||||
|
e.size = GetSize();
|
||||||
|
|
||||||
|
const auto& n = DoorsRepository::InsertOne(content_db, e);
|
||||||
|
if (!n.id) {
|
||||||
|
LogError(
|
||||||
|
"Failed to create door in Zone [{}] Version [{}] Database ID [{}] ID [{}]",
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion(),
|
||||||
|
GetDoorDBID(),
|
||||||
|
GetDoorID()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Doors::GetX()
|
float Doors::GetX()
|
||||||
@@ -832,3 +891,8 @@ float Doors::GetZ()
|
|||||||
{
|
{
|
||||||
return m_position.z;
|
return m_position.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Doors::GetHeading()
|
||||||
|
{
|
||||||
|
return m_position.w;
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ public:
|
|||||||
float GetX();
|
float GetX();
|
||||||
float GetY();
|
float GetY();
|
||||||
float GetZ();
|
float GetZ();
|
||||||
|
float GetHeading();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -437,7 +437,6 @@ int64 Mob::GetActSpellHealing(uint16 spell_id, int64 value, Mob* target, bool fr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (critical_chance && zone->random.Roll(critical_chance))
|
|
||||||
value *= critical_modifier;
|
value *= critical_modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,12 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
|||||||
"EVENT_BOT_CREATE",
|
"EVENT_BOT_CREATE",
|
||||||
"EVENT_AUGMENT_INSERT_CLIENT",
|
"EVENT_AUGMENT_INSERT_CLIENT",
|
||||||
"EVENT_AUGMENT_REMOVE_CLIENT",
|
"EVENT_AUGMENT_REMOVE_CLIENT",
|
||||||
|
"EVENT_EQUIP_ITEM_BOT",
|
||||||
|
"EVENT_UNEQUIP_ITEM_BOT",
|
||||||
|
"EVENT_DAMAGE_GIVEN",
|
||||||
|
"EVENT_DAMAGE_TAKEN",
|
||||||
|
"EVENT_ITEM_CLICK_CLIENT",
|
||||||
|
"EVENT_ITEM_CLICK_CAST_CLIENT",
|
||||||
// Add new events before these or Lua crashes
|
// Add new events before these or Lua crashes
|
||||||
"EVENT_SPELL_EFFECT_BOT",
|
"EVENT_SPELL_EFFECT_BOT",
|
||||||
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
|
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
|
||||||
@@ -1709,6 +1715,20 @@ void PerlembParser::ExportEventVariables(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EVENT_ITEM_CLICK_CAST_CLIENT:
|
||||||
|
case EVENT_ITEM_CLICK_CLIENT: {
|
||||||
|
ExportVar(package_name.c_str(), "slot_id", data);
|
||||||
|
if (extra_pointers && extra_pointers->size() == 1) {
|
||||||
|
auto* item = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0));
|
||||||
|
if (item) {
|
||||||
|
ExportVar(package_name.c_str(), "item_id", item->GetID());
|
||||||
|
ExportVar(package_name.c_str(), "item_name", item->GetItem()->Name);
|
||||||
|
ExportVar(package_name.c_str(), "spell_id", item->GetItem()->Click.Effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EVENT_GROUP_CHANGE: {
|
case EVENT_GROUP_CHANGE: {
|
||||||
if (mob && mob->IsClient()) {
|
if (mob && mob->IsClient()) {
|
||||||
ExportVar(package_name.c_str(), "grouped", mob->IsGrouped());
|
ExportVar(package_name.c_str(), "grouped", mob->IsGrouped());
|
||||||
@@ -1901,6 +1921,15 @@ void PerlembParser::ExportEventVariables(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EVENT_EQUIP_ITEM_BOT:
|
||||||
|
case EVENT_UNEQUIP_ITEM_BOT: {
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "item_id", extradata);
|
||||||
|
ExportVar(package_name.c_str(), "item_quantity", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "slot_id", sep.arg[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EVENT_AUGMENT_INSERT_CLIENT:
|
case EVENT_AUGMENT_INSERT_CLIENT:
|
||||||
case EVENT_AUGMENT_REMOVE_CLIENT: {
|
case EVENT_AUGMENT_REMOVE_CLIENT: {
|
||||||
Seperator sep(data);
|
Seperator sep(data);
|
||||||
@@ -2020,6 +2049,21 @@ void PerlembParser::ExportEventVariables(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EVENT_DAMAGE_GIVEN:
|
||||||
|
case EVENT_DAMAGE_TAKEN:{
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "entity_id", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "damage", sep.arg[1]);
|
||||||
|
ExportVar(package_name.c_str(), "spell_id", sep.arg[2]);
|
||||||
|
ExportVar(package_name.c_str(), "skill_id", sep.arg[3]);
|
||||||
|
ExportVar(package_name.c_str(), "is_damage_shield", sep.arg[4]);
|
||||||
|
ExportVar(package_name.c_str(), "is_avoidable", sep.arg[5]);
|
||||||
|
ExportVar(package_name.c_str(), "buff_slot", sep.arg[6]);
|
||||||
|
ExportVar(package_name.c_str(), "is_buff_tic", sep.arg[7]);
|
||||||
|
ExportVar(package_name.c_str(), "special_attack", sep.arg[8]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3981,6 +3981,11 @@ int8 Perl__does_augment_fit(EQ::ItemInstance* inst, uint32 augment_id)
|
|||||||
return quest_manager.DoesAugmentFit(inst, augment_id);
|
return quest_manager.DoesAugmentFit(inst, augment_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8 Perl__does_augment_fit_slot(EQ::ItemInstance* inst, uint32 augment_id, uint8 augment_slot)
|
||||||
|
{
|
||||||
|
return quest_manager.DoesAugmentFit(inst, augment_id, augment_slot);
|
||||||
|
}
|
||||||
|
|
||||||
void perl_register_quest()
|
void perl_register_quest()
|
||||||
{
|
{
|
||||||
perl::interpreter perl(PERL_GET_THX);
|
perl::interpreter perl(PERL_GET_THX);
|
||||||
@@ -4326,7 +4331,8 @@ void perl_register_quest()
|
|||||||
package.add("doanim", (void(*)(int, int, bool))&Perl__doanim);
|
package.add("doanim", (void(*)(int, int, bool))&Perl__doanim);
|
||||||
package.add("doanim", (void(*)(int, int, bool, int))&Perl__doanim);
|
package.add("doanim", (void(*)(int, int, bool, int))&Perl__doanim);
|
||||||
package.add("do_augment_slots_match", &Perl__do_augment_slots_match);
|
package.add("do_augment_slots_match", &Perl__do_augment_slots_match);
|
||||||
package.add("does_augment_fit", &Perl__does_augment_fit);
|
package.add("does_augment_fit", (int8(*)(EQ::ItemInstance*, uint32))&Perl__does_augment_fit);
|
||||||
|
package.add("does_augment_fit_slot", (int8(*)(EQ::ItemInstance*, uint32, uint8))&Perl__does_augment_fit_slot);
|
||||||
package.add("echo", &Perl__echo);
|
package.add("echo", &Perl__echo);
|
||||||
package.add("emote", &Perl__emote);
|
package.add("emote", &Perl__emote);
|
||||||
package.add("enable_proximity_say", &Perl__enable_proximity_say);
|
package.add("enable_proximity_say", &Perl__enable_proximity_say);
|
||||||
|
|||||||
+2
-2
@@ -36,8 +36,8 @@ public:
|
|||||||
//abstract virtual function implementations required by base abstract class
|
//abstract virtual function implementations required by base abstract class
|
||||||
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) { return true; }
|
virtual bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) { return true; }
|
||||||
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
virtual void Damage(Mob* from, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
||||||
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||||
ExtraAttackOptions *opts = nullptr) {
|
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual bool HasRaid() { return false; }
|
virtual bool HasRaid() { return false; }
|
||||||
|
|||||||
+5
-1
@@ -718,6 +718,8 @@ void EntityList::AddNPC(NPC *npc, bool send_spawn_packet, bool dont_queue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
npc->SendPositionToClients();
|
||||||
|
|
||||||
entity_list.ScanCloseMobs(npc->close_mobs, npc, true);
|
entity_list.ScanCloseMobs(npc->close_mobs, npc, true);
|
||||||
|
|
||||||
npc->DispatchZoneControllerEvent(EVENT_SPAWN_ZONE, npc, "", 0, nullptr);
|
npc->DispatchZoneControllerEvent(EVENT_SPAWN_ZONE, npc, "", 0, nullptr);
|
||||||
@@ -844,9 +846,11 @@ void EntityList::CheckSpawnQueue()
|
|||||||
NPC *pnpc = it->second;
|
NPC *pnpc = it->second;
|
||||||
pnpc->SendArmorAppearance();
|
pnpc->SendArmorAppearance();
|
||||||
pnpc->SetAppearance(pnpc->GetGuardPointAnim(), false);
|
pnpc->SetAppearance(pnpc->GetGuardPointAnim(), false);
|
||||||
if (!pnpc->IsTargetable())
|
if (!pnpc->IsTargetable()) {
|
||||||
pnpc->SendTargetable(false);
|
pnpc->SendTargetable(false);
|
||||||
}
|
}
|
||||||
|
pnpc->SendPositionToClients();
|
||||||
|
}
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public:
|
|||||||
virtual bool IsEncounter() const { return false; }
|
virtual bool IsEncounter() const { return false; }
|
||||||
virtual bool IsBot() const { return false; }
|
virtual bool IsBot() const { return false; }
|
||||||
virtual bool IsAura() const { return false; }
|
virtual bool IsAura() const { return false; }
|
||||||
|
virtual bool IsOfClientBotMerc() const { return false; }
|
||||||
|
|
||||||
virtual bool Process() { return false; }
|
virtual bool Process() { return false; }
|
||||||
virtual bool Save() { return true; }
|
virtual bool Save() { return true; }
|
||||||
|
|||||||
@@ -114,6 +114,12 @@ typedef enum {
|
|||||||
EVENT_BOT_CREATE,
|
EVENT_BOT_CREATE,
|
||||||
EVENT_AUGMENT_INSERT_CLIENT,
|
EVENT_AUGMENT_INSERT_CLIENT,
|
||||||
EVENT_AUGMENT_REMOVE_CLIENT,
|
EVENT_AUGMENT_REMOVE_CLIENT,
|
||||||
|
EVENT_EQUIP_ITEM_BOT,
|
||||||
|
EVENT_UNEQUIP_ITEM_BOT,
|
||||||
|
EVENT_DAMAGE_GIVEN,
|
||||||
|
EVENT_DAMAGE_TAKEN,
|
||||||
|
EVENT_ITEM_CLICK_CLIENT,
|
||||||
|
EVENT_ITEM_CLICK_CAST_CLIENT,
|
||||||
// Add new events before these or Lua crashes
|
// Add new events before these or Lua crashes
|
||||||
EVENT_SPELL_EFFECT_BOT,
|
EVENT_SPELL_EFFECT_BOT,
|
||||||
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
||||||
|
|||||||
@@ -2,43 +2,98 @@
|
|||||||
|
|
||||||
void command_appearanceeffects(Client *c, const Seperator *sep)
|
void command_appearanceeffects(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
if (sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) {
|
const auto arguments = sep->argnum;
|
||||||
c->Message(Chat::White, "Syntax: #appearanceeffects [subcommand].");
|
if (!arguments) {
|
||||||
c->Message(Chat::White, "[view] Display all appearance effects saved to your target. #appearanceffects view");
|
c->Message(Chat::White, "Usage: #appearanceeffects help - Display appearance effects help menu");
|
||||||
c->Message(Chat::White, "[set] Set an appearance effects saved to your target. #appearanceffects set [app_effectid] [slotid]");
|
c->Message(Chat::White, "Usage: #appearanceeffects remove - Remove all appearance effects saved to your target");
|
||||||
c->Message(Chat::White, "[remove] Remove all appearance effects saved to your target. #appearanceffects remove");
|
c->Message(Chat::White, "Usage: #appearanceeffects set [Effect ID] [Slot ID] - Set an appearance effect saved to your target");
|
||||||
}
|
c->Message(Chat::White, "Usage: #appearanceeffects view - Display all appearance effects saved to your target");
|
||||||
|
|
||||||
if (!strcasecmp(sep->arg[1], "view")) {
|
|
||||||
Mob* m_target = c->GetTarget();
|
|
||||||
if (m_target) {
|
|
||||||
m_target->GetAppearenceEffects();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool is_help = !strcasecmp(sep->arg[1], "help");
|
||||||
|
const bool is_remove = !strcasecmp(sep->arg[1], "remove");
|
||||||
|
const bool is_set = !strcasecmp(sep->arg[1], "set");
|
||||||
|
const bool is_view = !strcasecmp(sep->arg[1], "view");
|
||||||
|
|
||||||
if (!strcasecmp(sep->arg[1], "set")) {
|
if (is_help) {
|
||||||
int32 app_effectid = atof(sep->arg[2]);
|
c->Message(Chat::White, "Usage: #appearanceeffects help - Display appearance effects help menu");
|
||||||
int32 slot = atoi(sep->arg[3]);
|
c->Message(Chat::White, "Usage: #appearanceeffects remove - Remove all appearance effects saved to your target");
|
||||||
|
c->Message(Chat::White, "Usage: #appearanceeffects set [Effect ID] [Slot ID] - Set an appearance effect saved to your target");
|
||||||
Mob* m_target = c->GetTarget();
|
c->Message(Chat::White, "Usage: #appearanceeffects view - Display all appearance effects saved to your target");
|
||||||
if (m_target) {
|
|
||||||
m_target->SendAppearanceEffect(app_effectid, 0, 0, 0, 0, nullptr, slot, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
||||||
c->Message(Chat::White, "Appearance Effect ID %i for slot %i has been set.", app_effectid, slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcasecmp(sep->arg[1], "remove")) {
|
|
||||||
Mob* m_target = c->GetTarget();
|
|
||||||
if (m_target) {
|
|
||||||
m_target->SendIllusionPacket(m_target->GetRace(), m_target->GetGender(), m_target->GetTexture(), m_target->GetHelmTexture(),
|
|
||||||
m_target->GetHairColor(), m_target->GetBeardColor(), m_target->GetEyeColor1(), m_target->GetEyeColor2(),
|
|
||||||
m_target->GetHairStyle(), m_target->GetLuclinFace(), m_target->GetBeard(), 0xFF,
|
|
||||||
m_target->GetDrakkinHeritage(), m_target->GetDrakkinTattoo(), m_target->GetDrakkinDetails(), m_target->GetSize(), false);
|
|
||||||
m_target->ClearAppearenceEffects();
|
|
||||||
c->Message(Chat::White, "All Appearance Effects have been removed.");
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mob* t = c;
|
||||||
|
if (c->GetTarget()) {
|
||||||
|
t = c->GetTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_set) {
|
||||||
|
if (arguments != 3 || !sep->IsNumber(2) || !sep->IsNumber(3)) {
|
||||||
|
c->Message(Chat::White, "Usage: #appearanceeffects set [Effect ID] [Slot ID] - Set an appearance effect saved to your target");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto effect_id = std::stoul(sep->arg[2]);
|
||||||
|
const auto slot_id = std::stoul(sep->arg[3]);
|
||||||
|
|
||||||
|
t->SendAppearanceEffect(
|
||||||
|
effect_id,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
nullptr,
|
||||||
|
slot_id,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Appearance Effect ID {} in slot ID {} has been set for {}.",
|
||||||
|
effect_id,
|
||||||
|
slot_id,
|
||||||
|
c->GetTargetDescription(t, TargetDescriptionType::LCSelf)
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else if (is_remove) {
|
||||||
|
t->SendIllusionPacket(
|
||||||
|
t->GetRace(),
|
||||||
|
t->GetGender(),
|
||||||
|
t->GetTexture(),
|
||||||
|
t->GetHelmTexture(),
|
||||||
|
t->GetHairColor(),
|
||||||
|
t->GetBeardColor(),
|
||||||
|
t->GetEyeColor1(),
|
||||||
|
t->GetEyeColor2(),
|
||||||
|
t->GetHairStyle(),
|
||||||
|
t->GetLuclinFace(),
|
||||||
|
t->GetBeard(),
|
||||||
|
0xFF,
|
||||||
|
t->GetDrakkinHeritage(),
|
||||||
|
t->GetDrakkinTattoo(),
|
||||||
|
t->GetDrakkinDetails(),
|
||||||
|
t->GetSize(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
t->ClearAppearenceEffects();
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Appearance Effects have been removed for {}.",
|
||||||
|
c->GetTargetDescription(t, TargetDescriptionType::LCSelf)
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else if (is_view) {
|
||||||
|
t->ListAppearanceEffects(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|||||||
std::vector<std::string> set_size_options_negative;
|
std::vector<std::string> set_size_options_negative;
|
||||||
|
|
||||||
std::vector<std::string> xyz_values = {
|
std::vector<std::string> xyz_values = {
|
||||||
".1", "1", "5", "10", "25", "50", "100"
|
"0.1", "1", "5", "10", "25", "50", "100"
|
||||||
};
|
};
|
||||||
|
|
||||||
// build positive options x/y/z
|
// build positive options x/y/z
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void command_findaa(Client *c, const Seperator *sep)
|
|||||||
std::map<int, std::string> ordered_aas;
|
std::map<int, std::string> ordered_aas;
|
||||||
|
|
||||||
for (const auto& a : zone->aa_abilities) {
|
for (const auto& a : zone->aa_abilities) {
|
||||||
ordered_aas[a.second.get()->id] = a.second.get()->name;
|
ordered_aas[a.second.get()->first->id] = a.second.get()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
int found_count = 0;
|
int found_count = 0;
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#include "../client.h"
|
|
||||||
#include "../guild_mgr.h"
|
|
||||||
|
|
||||||
void command_guildapprove(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
guild_mgr.AddMemberApproval(atoi(sep->arg[1]), c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#include "../client.h"
|
|
||||||
#include "../guild_mgr.h"
|
|
||||||
|
|
||||||
void command_guildcreate(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
if (strlen(sep->argplus[1]) > 4 && strlen(sep->argplus[1]) < 16) {
|
|
||||||
guild_mgr.AddGuildApproval(sep->argplus[1], c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c->Message(Chat::White, "Guild name must be more than 4 characters and less than 16.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#include "../client.h"
|
|
||||||
#include "../guild_mgr.h"
|
|
||||||
|
|
||||||
void command_guildlist(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
GuildApproval *tmp = guild_mgr.FindGuildByIDApproval(atoi(sep->arg[1]));
|
|
||||||
if (tmp) {
|
|
||||||
tmp->ApprovedMembers(c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c->Message(Chat::White, "Could not find reference id.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+11
-37
@@ -34,12 +34,10 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
std::string search_string;
|
std::string search_string;
|
||||||
|
|
||||||
if (sep->arg[2]) {
|
if (sep->arg[2]) {
|
||||||
search_string = sep->arg[2];
|
search_string = Strings::ToLower(sep->arg[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// NPC
|
||||||
* NPC
|
|
||||||
*/
|
|
||||||
if (search_type.find("npcs") != std::string::npos) {
|
if (search_type.find("npcs") != std::string::npos) {
|
||||||
auto &entity_list_search = entity_list.GetMobList();
|
auto &entity_list_search = entity_list.GetMobList();
|
||||||
|
|
||||||
@@ -51,11 +49,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
entity_count++;
|
entity_count++;
|
||||||
|
|
||||||
std::string entity_name = entity->GetName();
|
std::string entity_name = Strings::ToLower(entity->GetName());
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter by name
|
|
||||||
*/
|
|
||||||
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -81,9 +75,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Client
|
||||||
* Client
|
|
||||||
*/
|
|
||||||
if (search_type.find("players") != std::string::npos) {
|
if (search_type.find("players") != std::string::npos) {
|
||||||
auto &entity_list_search = entity_list.GetClientList();
|
auto &entity_list_search = entity_list.GetClientList();
|
||||||
|
|
||||||
@@ -92,7 +84,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
entity_count++;
|
entity_count++;
|
||||||
|
|
||||||
std::string entity_name = entity->GetName();
|
std::string entity_name = Strings::ToLower(entity->GetName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter by name
|
* Filter by name
|
||||||
@@ -122,9 +114,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Corpse
|
||||||
* Corpse
|
|
||||||
*/
|
|
||||||
if (search_type.find("corpses") != std::string::npos) {
|
if (search_type.find("corpses") != std::string::npos) {
|
||||||
auto &entity_list_search = entity_list.GetCorpseList();
|
auto &entity_list_search = entity_list.GetCorpseList();
|
||||||
|
|
||||||
@@ -133,11 +123,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
entity_count++;
|
entity_count++;
|
||||||
|
|
||||||
std::string entity_name = entity->GetName();
|
std::string entity_name = Strings::ToLower(entity->GetName());
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter by name
|
|
||||||
*/
|
|
||||||
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -163,9 +149,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Doors
|
||||||
* Doors
|
|
||||||
*/
|
|
||||||
if (search_type.find("doors") != std::string::npos) {
|
if (search_type.find("doors") != std::string::npos) {
|
||||||
auto &entity_list_search = entity_list.GetDoorsList();
|
auto &entity_list_search = entity_list.GetDoorsList();
|
||||||
|
|
||||||
@@ -174,11 +158,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
entity_count++;
|
entity_count++;
|
||||||
|
|
||||||
std::string entity_name = entity->GetDoorName();
|
std::string entity_name = Strings::ToLower(entity->GetDoorName());
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter by name
|
|
||||||
*/
|
|
||||||
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -205,9 +185,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Objects
|
||||||
* Objects
|
|
||||||
*/
|
|
||||||
if (search_type.find("objects") != std::string::npos) {
|
if (search_type.find("objects") != std::string::npos) {
|
||||||
auto &entity_list_search = entity_list.GetObjectList();
|
auto &entity_list_search = entity_list.GetObjectList();
|
||||||
|
|
||||||
@@ -216,11 +194,7 @@ void command_list(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
entity_count++;
|
entity_count++;
|
||||||
|
|
||||||
std::string entity_name = entity->GetModelName();
|
std::string entity_name = Strings::ToLower(entity->GetModelName());
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter by name
|
|
||||||
*/
|
|
||||||
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ void command_loc(Client *c, const Seperator *sep)
|
|||||||
glm::vec3 hit;
|
glm::vec3 hit;
|
||||||
|
|
||||||
auto best_z = zone->zonemap->FindBestZ(tarloc, &hit);
|
auto best_z = zone->zonemap->FindBestZ(tarloc, &hit);
|
||||||
|
auto fixed_z = c->GetFixedZ(c->GetPosition());
|
||||||
|
|
||||||
if (best_z != BEST_Z_INVALID) {
|
if (best_z != BEST_Z_INVALID) {
|
||||||
c->Message(
|
c->Message(
|
||||||
@@ -39,6 +40,14 @@ void command_loc(Client *c, const Seperator *sep)
|
|||||||
best_z
|
best_z
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Fixed Z for {} | {:.2f}",
|
||||||
|
c->GetTargetDescription(target, TargetDescriptionType::UCSelf),
|
||||||
|
fixed_z
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
c->Message(Chat::White, "Could not find Best Z.");
|
c->Message(Chat::White, "Could not find Best Z.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -536,14 +536,14 @@ void command_npcedit(Client *c, const Seperator *sep)
|
|||||||
} else if (!strcasecmp(sep->arg[1], "weapon")) {
|
} else if (!strcasecmp(sep->arg[1], "weapon")) {
|
||||||
if (sep->IsNumber(2)) {
|
if (sep->IsNumber(2)) {
|
||||||
auto primary_model = std::stoul(sep->arg[2]);
|
auto primary_model = std::stoul(sep->arg[2]);
|
||||||
uint32_t secondary_model = sep->IsNumber(3) ? std::stoul(sep->arg[3]) : 0;
|
uint32_t secondary_model = sep->arg[3] && sep->IsNumber(3) ? std::stoul(sep->arg[3]) : 0;
|
||||||
n.d_melee_texture1 = primary_model;
|
n.d_melee_texture1 = primary_model;
|
||||||
n.d_melee_texture2 = secondary_model;
|
n.d_melee_texture2 = secondary_model;
|
||||||
d = fmt::format(
|
d = fmt::format(
|
||||||
"{} will have Model {} set to their Primary and Model {} set to their Secondary on repop.",
|
"{} will have Model {} set to their Primary and Model {} set to their Secondary on repop.",
|
||||||
npc_id_string,
|
npc_id_string,
|
||||||
Strings::Commify(sep->arg[2]),
|
Strings::Commify(sep->arg[2]),
|
||||||
sep->IsNumber(3) ? Strings::Commify(sep->arg[3]) : 0
|
sep->arg[3] && sep->IsNumber(3) ? Strings::Commify(sep->arg[3]) : 0
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
c->Message(
|
c->Message(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
void command_undye(Client *c, const Seperator *sep)
|
void command_undye(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
auto target = c;
|
auto target = c;
|
||||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) {
|
||||||
target = c->GetTarget()->CastToClient();
|
target = c->GetTarget()->CastToClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
#include "../client.h"
|
|
||||||
|
|
||||||
void command_undyeme(Client *c, const Seperator *sep)
|
|
||||||
{
|
|
||||||
c->Undye();
|
|
||||||
c->Message(Chat::White, "Undyed armor for yourself.");
|
|
||||||
}
|
|
||||||
@@ -22,10 +22,6 @@ void command_weather(Client *c, const Seperator *sep)
|
|||||||
weather_message = "Raindrops begin to fall from the sky.";
|
weather_message = "Raindrops begin to fall from the sky.";
|
||||||
new_weather = EQ::constants::WeatherTypes::Raining;
|
new_weather = EQ::constants::WeatherTypes::Raining;
|
||||||
new_intensity = 0x01; // This is how it's done in Fear, and you can see a decent distance with it at this value
|
new_intensity = 0x01; // This is how it's done in Fear, and you can see a decent distance with it at this value
|
||||||
} else {
|
|
||||||
c->Message(Chat::White, "Usage: #weather [0|1|2] - [Off|Rain|Snow]");
|
|
||||||
c->Message(Chat::White, "Usage: #weather 3 [Type] [Intensity] - Manually set weather type and intensity");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zone->zone_weather = new_weather;
|
zone->zone_weather = new_weather;
|
||||||
|
|||||||
@@ -652,79 +652,11 @@ void ZoneGuildManager::RequestOnlineGuildMembers(uint32 FromID, uint32 GuildID)
|
|||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneGuildManager::ProcessApproval()
|
|
||||||
{
|
|
||||||
LinkedListIterator<GuildApproval*> iterator(list);
|
|
||||||
|
|
||||||
iterator.Reset();
|
|
||||||
while(iterator.MoreElements())
|
|
||||||
{
|
|
||||||
if(!iterator.GetData()->ProcessApproval())
|
|
||||||
iterator.RemoveCurrent();
|
|
||||||
iterator.Advance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZoneGuildManager::AddGuildApproval(const char* guildname,Client* owner)
|
|
||||||
{
|
|
||||||
auto tmp = new GuildApproval(guildname, owner, GetFreeID());
|
|
||||||
list.Insert(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZoneGuildManager::AddMemberApproval(uint32 refid,Client* name)
|
|
||||||
{
|
|
||||||
GuildApproval* tmp = FindGuildByIDApproval(refid);
|
|
||||||
if(tmp != 0)
|
|
||||||
{
|
|
||||||
if(!tmp->AddMemberApproval(name))
|
|
||||||
name->Message(Chat::White,"Unable to add to list.");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name->Message(Chat::White,"Added to list.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
name->Message(Chat::White,"Unable to find guild reference id.");
|
|
||||||
}
|
|
||||||
|
|
||||||
ZoneGuildManager::~ZoneGuildManager()
|
ZoneGuildManager::~ZoneGuildManager()
|
||||||
{
|
{
|
||||||
ClearGuilds();
|
ClearGuilds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneGuildManager::ClearGuildsApproval()
|
|
||||||
{
|
|
||||||
list.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
GuildApproval* ZoneGuildManager::FindGuildByIDApproval(uint32 refid)
|
|
||||||
{
|
|
||||||
LinkedListIterator<GuildApproval*> iterator(list);
|
|
||||||
|
|
||||||
iterator.Reset();
|
|
||||||
while(iterator.MoreElements())
|
|
||||||
{
|
|
||||||
if(iterator.GetData()->GetID() == refid)
|
|
||||||
return iterator.GetData();
|
|
||||||
iterator.Advance();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GuildApproval* ZoneGuildManager::FindGuildByOwnerApproval(Client* owner)
|
|
||||||
{
|
|
||||||
LinkedListIterator<GuildApproval*> iterator(list);
|
|
||||||
|
|
||||||
iterator.Reset();
|
|
||||||
while(iterator.MoreElements())
|
|
||||||
{
|
|
||||||
if(iterator.GetData()->GetOwner() == owner)
|
|
||||||
return iterator.GetData();
|
|
||||||
iterator.Advance();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GuildBankManager::~GuildBankManager()
|
GuildBankManager::~GuildBankManager()
|
||||||
{
|
{
|
||||||
auto Iterator = Banks.begin();
|
auto Iterator = Banks.begin();
|
||||||
@@ -1524,154 +1456,3 @@ bool GuildBankManager::AllowedToWithdraw(uint32 GuildID, uint16 Area, uint16 Slo
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*================== GUILD APPROVAL ========================*/
|
|
||||||
|
|
||||||
bool GuildApproval::ProcessApproval()
|
|
||||||
{
|
|
||||||
if(owner && owner->GuildID() != 0)
|
|
||||||
{
|
|
||||||
owner->Message(Chat::NPCQuestSay,"You are already in a guild! Guild request deleted.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(deletion_timer->Check() || !owner)
|
|
||||||
{
|
|
||||||
if(owner)
|
|
||||||
owner->Message(Chat::White,"You took too long! Your guild request has been deleted.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
GuildApproval::GuildApproval(const char* guildname, Client* owner,uint32 id)
|
|
||||||
{
|
|
||||||
std::string founders;
|
|
||||||
database.GetVariable("GuildCreation", founders);
|
|
||||||
uint8 tmp = atoi(founders.c_str());
|
|
||||||
deletion_timer = new Timer(1800000);
|
|
||||||
strcpy(guild,guildname);
|
|
||||||
owner = owner;
|
|
||||||
refid = id;
|
|
||||||
if(owner)
|
|
||||||
owner->Message(Chat::White,"You can now start getting your guild approved, tell your %i members to #guildapprove %i, you have 30 minutes to create your guild.",tmp,GetID());
|
|
||||||
for(int i=0;i<tmp;i++)
|
|
||||||
members[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GuildApproval::~GuildApproval()
|
|
||||||
{
|
|
||||||
safe_delete(deletion_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GuildApproval::AddMemberApproval(Client* addition)
|
|
||||||
{
|
|
||||||
std::string founders;
|
|
||||||
database.GetVariable("GuildCreation", founders);
|
|
||||||
uint8 tmp = atoi(founders.c_str());
|
|
||||||
for(int i=0;i<tmp;i++)
|
|
||||||
{
|
|
||||||
if(members[i] && members[i] == addition)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0;i<tmp;i++)
|
|
||||||
{
|
|
||||||
if(!members[i])
|
|
||||||
{
|
|
||||||
members[i] = addition;
|
|
||||||
int z=0;
|
|
||||||
for(int i=0;i<tmp;i++)
|
|
||||||
{
|
|
||||||
if(members[i])
|
|
||||||
z++;
|
|
||||||
}
|
|
||||||
if(z==tmp)
|
|
||||||
GuildApproved();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GuildApproval::ApprovedMembers(Client* requestee)
|
|
||||||
{
|
|
||||||
std::string founders;
|
|
||||||
database.GetVariable("GuildCreation", founders);
|
|
||||||
uint8 tmp = atoi(founders.c_str());
|
|
||||||
for(int i=0;i<tmp;i++)
|
|
||||||
{
|
|
||||||
if(members[i])
|
|
||||||
requestee->Message(Chat::White,"%i: %s",i,members[i]->GetName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GuildApproval::GuildApproved()
|
|
||||||
{
|
|
||||||
char petitext[PBUFFER] = "A new guild was founded! Guildname: ";
|
|
||||||
char gmembers[MBUFFER] = " ";
|
|
||||||
|
|
||||||
if(!owner)
|
|
||||||
return;
|
|
||||||
std::string founders;
|
|
||||||
database.GetVariable("GuildCreation", founders);
|
|
||||||
uint8 tmp = atoi(founders.c_str());
|
|
||||||
uint32 tmpeq = guild_mgr.CreateGuild(guild, owner->CharacterID());
|
|
||||||
guild_mgr.SetGuild(owner->CharacterID(),tmpeq,2);
|
|
||||||
owner->SendAppearancePacket(AT_GuildID,true,false);
|
|
||||||
for(int i=0;i<tmp;i++)
|
|
||||||
{
|
|
||||||
if(members[i])
|
|
||||||
{
|
|
||||||
owner->Message(Chat::White, "%s",members[i]->GetName());
|
|
||||||
owner->Message(Chat::White, "%i",members[i]->CharacterID());
|
|
||||||
guild_mgr.SetGuild(members[i]->CharacterID(),tmpeq,0);
|
|
||||||
size_t len = MBUFFER - strlen(gmembers)+1;
|
|
||||||
strncat(gmembers," ",len);
|
|
||||||
strncat(gmembers,members[i]->GetName(),len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
size_t len = PBUFFER - strlen(petitext)+1;
|
|
||||||
strncat(petitext,guild,len);
|
|
||||||
strncat(petitext," Leader: ",len);
|
|
||||||
strncat(petitext,owner->CastToClient()->GetName(),len);
|
|
||||||
strncat(petitext," Members:",len);
|
|
||||||
strncat(petitext,gmembers,len);
|
|
||||||
auto pet = new Petition(owner->CastToClient()->CharacterID());
|
|
||||||
pet->SetAName(owner->CastToClient()->AccountName());
|
|
||||||
pet->SetClass(owner->CastToClient()->GetClass());
|
|
||||||
pet->SetLevel(owner->CastToClient()->GetLevel());
|
|
||||||
pet->SetCName(owner->CastToClient()->GetName());
|
|
||||||
pet->SetRace(owner->CastToClient()->GetRace());
|
|
||||||
pet->SetLastGM("");
|
|
||||||
pet->SetCName(owner->CastToClient()->GetName()); //aza77 is this really 2 times needed ??
|
|
||||||
pet->SetPetitionText(petitext);
|
|
||||||
pet->SetZone(zone->GetZoneID());
|
|
||||||
pet->SetUrgency(0);
|
|
||||||
petition_list.AddPetition(pet);
|
|
||||||
database.InsertPetitionToDB(pet);
|
|
||||||
petition_list.UpdateGMQueue();
|
|
||||||
petition_list.UpdateZoneListQueue();
|
|
||||||
worldserver.SendEmoteMessage(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
AccountStatus::QuestTroupe,
|
|
||||||
Chat::Yellow,
|
|
||||||
fmt::format(
|
|
||||||
"{} has made a petition. ID: {}",
|
|
||||||
owner->CastToClient()->GetName(),
|
|
||||||
pet->GetID()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
auto pack = new ServerPacket;
|
|
||||||
pack->opcode = ServerOP_RefreshGuild;
|
|
||||||
pack->size = tmp;
|
|
||||||
pack->pBuffer = new uchar[pack->size];
|
|
||||||
memcpy(pack->pBuffer, &tmpeq, 4);
|
|
||||||
worldserver.SendPacket(pack);
|
|
||||||
safe_delete(pack);
|
|
||||||
owner->Message(Chat::White, "Your guild was created.");
|
|
||||||
owner = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,36 +47,10 @@ enum { GuildBankDepositArea = 0, GuildBankMainArea = 1 };
|
|||||||
|
|
||||||
enum { GuildBankBankerOnly = 0, GuildBankSingleMember = 1, GuildBankPublicIfUsable = 2, GuildBankPublic = 3 };
|
enum { GuildBankBankerOnly = 0, GuildBankSingleMember = 1, GuildBankPublicIfUsable = 2, GuildBankPublic = 3 };
|
||||||
|
|
||||||
class GuildApproval
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GuildApproval(const char* guildname,Client* owner,uint32 id);
|
|
||||||
~GuildApproval();
|
|
||||||
bool ProcessApproval();
|
|
||||||
bool AddMemberApproval(Client* addition);
|
|
||||||
uint32 GetID() { return refid; }
|
|
||||||
Client* GetOwner() { return owner; }
|
|
||||||
void GuildApproved();
|
|
||||||
void ApprovedMembers(Client* requestee);
|
|
||||||
private:
|
|
||||||
Timer* deletion_timer;
|
|
||||||
char guild[16];
|
|
||||||
Client* owner;
|
|
||||||
Client* members[6];
|
|
||||||
uint32 refid;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ZoneGuildManager : public BaseGuildManager {
|
class ZoneGuildManager : public BaseGuildManager {
|
||||||
public:
|
public:
|
||||||
~ZoneGuildManager(void);
|
~ZoneGuildManager(void);
|
||||||
|
|
||||||
void AddGuildApproval(const char* guildname, Client* owner);
|
|
||||||
void AddMemberApproval(uint32 refid,Client* name);
|
|
||||||
void ClearGuildsApproval();
|
|
||||||
GuildApproval* FindGuildByIDApproval(uint32 refid);
|
|
||||||
GuildApproval* FindGuildByOwnerApproval(Client* owner);
|
|
||||||
void ProcessApproval();
|
|
||||||
uint32 GetFreeID() { return id+1; }
|
|
||||||
//called by worldserver when it receives a message from world.
|
//called by worldserver when it receives a message from world.
|
||||||
void ProcessWorldPacket(ServerPacket *pack);
|
void ProcessWorldPacket(ServerPacket *pack);
|
||||||
|
|
||||||
@@ -103,9 +77,7 @@ protected:
|
|||||||
std::map<uint32, std::pair<uint32, uint8> > m_inviteQueue; //map from char ID to guild,rank
|
std::map<uint32, std::pair<uint32, uint8> > m_inviteQueue; //map from char ID to guild,rank
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LinkedList<GuildApproval*> list;
|
|
||||||
uint32 id;
|
uint32 id;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -714,6 +714,15 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
|
|||||||
// in any other situation just use charges as passed
|
// in any other situation just use charges as passed
|
||||||
|
|
||||||
EQ::ItemInstance* inst = database.CreateItem(item, charges);
|
EQ::ItemInstance* inst = database.CreateItem(item, charges);
|
||||||
|
auto timestamps = database.GetItemRecastTimestamps(CharacterID());
|
||||||
|
const auto* d = inst->GetItem();
|
||||||
|
if (d->RecastDelay) {
|
||||||
|
if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
|
||||||
|
inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0);
|
||||||
|
} else {
|
||||||
|
inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(inst == nullptr) {
|
if(inst == nullptr) {
|
||||||
Message(Chat::Red, "An unknown server error has occurred and your item was not created.");
|
Message(Chat::Red, "An unknown server error has occurred and your item was not created.");
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "lua_iteminst.h"
|
#include "lua_iteminst.h"
|
||||||
#include "lua_mob.h"
|
#include "lua_mob.h"
|
||||||
#include "lua_group.h"
|
#include "lua_group.h"
|
||||||
|
#include "lua_item.h"
|
||||||
|
|
||||||
void Lua_Bot::AddBotItem(uint16 slot_id, uint32 item_id) {
|
void Lua_Bot::AddBotItem(uint16 slot_id, uint32 item_id) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
@@ -393,6 +394,66 @@ void Lua_Bot::SendSpellAnim(uint16 target_id, uint16 spell_id)
|
|||||||
self->SendSpellAnim(target_id, spell_id);
|
self->SendSpellAnim(target_id, spell_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
luabind::object Lua_Bot::GetAugmentIDsBySlotID(lua_State* L, int16 slot_id) const {
|
||||||
|
auto lua_table = luabind::newtable(L);
|
||||||
|
if (d_) {
|
||||||
|
auto self = reinterpret_cast<NativeType*>(d_);
|
||||||
|
auto augments = self->GetInv().GetAugmentIDsBySlotID(slot_id);
|
||||||
|
int index = 1;
|
||||||
|
for (auto item_id : augments) {
|
||||||
|
lua_table[index] = item_id;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lua_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Bot::AddItem(const luabind::object& item_table) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
if (luabind::type(item_table) != LUA_TTABLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto item_id = luabind::object_cast<uint32>(item_table["item_id"]);
|
||||||
|
int16 charges = luabind::object_cast<uint32>(item_table["charges"]);
|
||||||
|
uint32 augment_one = luabind::type(item_table["augment_one"]) != LUA_TNIL ? luabind::object_cast<uint32>(item_table["augment_one"]) : 0;
|
||||||
|
uint32 augment_two = luabind::type(item_table["augment_two"]) != LUA_TNIL ? luabind::object_cast<uint32>(item_table["augment_two"]) : 0;
|
||||||
|
uint32 augment_three = luabind::type(item_table["augment_three"]) != LUA_TNIL ? luabind::object_cast<uint32>(item_table["augment_three"]) : 0;
|
||||||
|
uint32 augment_four = luabind::type(item_table["augment_four"]) != LUA_TNIL ? luabind::object_cast<uint32>(item_table["augment_four"]) : 0;
|
||||||
|
uint32 augment_five = luabind::type(item_table["augment_five"]) != LUA_TNIL ? luabind::object_cast<uint32>(item_table["augment_five"]) : 0;
|
||||||
|
uint32 augment_six = luabind::type(item_table["augment_six"]) != LUA_TNIL ? luabind::object_cast<uint32>(item_table["augment_six"]) : 0;
|
||||||
|
bool attuned = luabind::type(item_table["attuned"]) != LUA_TNIL ? luabind::object_cast<bool>(item_table["attuned"]) : false;
|
||||||
|
uint16 slot_id = luabind::type(item_table["slot_id"]) != LUA_TNIL ? luabind::object_cast<uint16>(item_table["slot_id"]) : EQ::invslot::slotCursor;
|
||||||
|
|
||||||
|
if (slot_id <= EQ::invslot::slotAmmo) {
|
||||||
|
self->AddBotItem(
|
||||||
|
slot_id,
|
||||||
|
item_id,
|
||||||
|
charges,
|
||||||
|
attuned,
|
||||||
|
augment_one,
|
||||||
|
augment_two,
|
||||||
|
augment_three,
|
||||||
|
augment_four,
|
||||||
|
augment_five,
|
||||||
|
augment_six
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self->GetOwner()->CastToClient()->SummonItem(
|
||||||
|
item_id,
|
||||||
|
charges,
|
||||||
|
augment_one,
|
||||||
|
augment_two,
|
||||||
|
augment_three,
|
||||||
|
augment_four,
|
||||||
|
augment_five,
|
||||||
|
augment_six,
|
||||||
|
attuned,
|
||||||
|
slot_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_bot() {
|
luabind::scope lua_register_bot() {
|
||||||
return luabind::class_<Lua_Bot, Lua_Mob>("Bot")
|
return luabind::class_<Lua_Bot, Lua_Mob>("Bot")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@@ -405,6 +466,7 @@ luabind::scope lua_register_bot() {
|
|||||||
.def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem)
|
.def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem)
|
||||||
.def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem)
|
.def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem)
|
||||||
.def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem)
|
.def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem)
|
||||||
|
.def("AddItem", (void(Lua_Bot::*)(luabind::adl::object))&Lua_Bot::AddItem)
|
||||||
.def("ApplySpell", (void(Lua_Bot::*)(int))&Lua_Bot::ApplySpell)
|
.def("ApplySpell", (void(Lua_Bot::*)(int))&Lua_Bot::ApplySpell)
|
||||||
.def("ApplySpell", (void(Lua_Bot::*)(int,int))&Lua_Bot::ApplySpell)
|
.def("ApplySpell", (void(Lua_Bot::*)(int,int))&Lua_Bot::ApplySpell)
|
||||||
.def("ApplySpell", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::ApplySpell)
|
.def("ApplySpell", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::ApplySpell)
|
||||||
@@ -424,6 +486,7 @@ luabind::scope lua_register_bot() {
|
|||||||
.def("Fling", (void(Lua_Bot::*)(float,float,float,float,bool,bool))&Lua_Bot::Fling)
|
.def("Fling", (void(Lua_Bot::*)(float,float,float,float,bool,bool))&Lua_Bot::Fling)
|
||||||
.def("GetAugmentAt", (Lua_ItemInst(Lua_Bot::*)(int16,uint8))&Lua_Bot::GetAugmentAt)
|
.def("GetAugmentAt", (Lua_ItemInst(Lua_Bot::*)(int16,uint8))&Lua_Bot::GetAugmentAt)
|
||||||
.def("GetAugmentIDAt", (int(Lua_Bot::*)(int16,uint8))&Lua_Bot::GetAugmentIDAt)
|
.def("GetAugmentIDAt", (int(Lua_Bot::*)(int16,uint8))&Lua_Bot::GetAugmentIDAt)
|
||||||
|
.def("GetAugmentIDsBySlotID", (luabind::object(Lua_Bot::*)(lua_State* L,int16))&Lua_Bot::GetAugmentIDsBySlotID)
|
||||||
.def("GetBaseAGI", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseAGI)
|
.def("GetBaseAGI", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseAGI)
|
||||||
.def("GetBaseCHA", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseCHA)
|
.def("GetBaseCHA", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseCHA)
|
||||||
.def("GetBaseDEX", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseDEX)
|
.def("GetBaseDEX", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseDEX)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class Bot;
|
|||||||
class Lua_Bot;
|
class Lua_Bot;
|
||||||
class Lua_Mob;
|
class Lua_Mob;
|
||||||
class Lua_Group;
|
class Lua_Group;
|
||||||
|
class Lua_Inventory;
|
||||||
|
|
||||||
namespace luabind {
|
namespace luabind {
|
||||||
struct scope;
|
struct scope;
|
||||||
@@ -36,6 +37,7 @@ public:
|
|||||||
void AddBotItem(uint16 slot_id, uint32 item_id, int16 charges, bool attuned, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four);
|
void AddBotItem(uint16 slot_id, uint32 item_id, int16 charges, bool attuned, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four);
|
||||||
void AddBotItem(uint16 slot_id, uint32 item_id, int16 charges, bool attuned, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four, uint32 augment_five);
|
void AddBotItem(uint16 slot_id, uint32 item_id, int16 charges, bool attuned, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four, uint32 augment_five);
|
||||||
void AddBotItem(uint16 slot_id, uint32 item_id, int16 charges, bool attuned, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four, uint32 augment_five, uint32 augment_six);
|
void AddBotItem(uint16 slot_id, uint32 item_id, int16 charges, bool attuned, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four, uint32 augment_five, uint32 augment_six);
|
||||||
|
void AddItem(const luabind::object& item_table);
|
||||||
uint32 CountBotItem(uint32 item_id);
|
uint32 CountBotItem(uint32 item_id);
|
||||||
Lua_ItemInst GetBotItem(uint16 slot_id);
|
Lua_ItemInst GetBotItem(uint16 slot_id);
|
||||||
uint32 GetBotItemIDBySlot(uint16 slot_id);
|
uint32 GetBotItemIDBySlot(uint16 slot_id);
|
||||||
@@ -59,6 +61,7 @@ public:
|
|||||||
void Camp(bool save_to_database);
|
void Camp(bool save_to_database);
|
||||||
Lua_ItemInst GetAugmentAt(int16 slot_id, uint8 augment_index);
|
Lua_ItemInst GetAugmentAt(int16 slot_id, uint8 augment_index);
|
||||||
int GetAugmentIDAt(int16 slot_id, uint8 augment_index);
|
int GetAugmentIDAt(int16 slot_id, uint8 augment_index);
|
||||||
|
luabind::object GetAugmentIDsBySlotID(lua_State* L, int16 slot_id) const;
|
||||||
Lua_ItemInst GetItemAt(int16 slot_id);
|
Lua_ItemInst GetItemAt(int16 slot_id);
|
||||||
int GetItemIDAt(int16 slot_id);
|
int GetItemIDAt(int16 slot_id);
|
||||||
void SendSpellAnim(uint16 target_id, uint16 spell_id);
|
void SendSpellAnim(uint16 target_id, uint16 spell_id);
|
||||||
|
|||||||
@@ -3014,6 +3014,30 @@ void Lua_Client::CampAllBots(uint8 class_id)
|
|||||||
self->CampAllBots(class_id);
|
self->CampAllBots(class_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_Client::ResetItemCooldown(uint32 item_id)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->ResetItemCooldown(item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::SetItemCooldown(uint32 item_id, uint32 in_time)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetItemCooldown(item_id, false, in_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Lua_Client::GetItemCooldown(uint32 item_id)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetItemCooldown(item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Client::UseAugmentContainer(int container_slot)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->UseAugmentContainer(container_slot);
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_client() {
|
luabind::scope lua_register_client() {
|
||||||
return luabind::class_<Lua_Client, Lua_Mob>("Client")
|
return luabind::class_<Lua_Client, Lua_Mob>("Client")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@@ -3204,6 +3228,7 @@ luabind::scope lua_register_client() {
|
|||||||
.def("GetInventory", (Lua_Inventory(Lua_Client::*)(void))&Lua_Client::GetInventory)
|
.def("GetInventory", (Lua_Inventory(Lua_Client::*)(void))&Lua_Client::GetInventory)
|
||||||
.def("GetInvulnerableEnvironmentDamage", (bool(Lua_Client::*)(void))&Lua_Client::GetInvulnerableEnvironmentDamage)
|
.def("GetInvulnerableEnvironmentDamage", (bool(Lua_Client::*)(void))&Lua_Client::GetInvulnerableEnvironmentDamage)
|
||||||
.def("GetItemIDAt", (int(Lua_Client::*)(int))&Lua_Client::GetItemIDAt)
|
.def("GetItemIDAt", (int(Lua_Client::*)(int))&Lua_Client::GetItemIDAt)
|
||||||
|
.def("GetItemCooldown", (uint32(Lua_Client::*)(uint32))&Lua_Client::GetItemCooldown)
|
||||||
.def("GetLDoNLosses", (int(Lua_Client::*)(void))&Lua_Client::GetLDoNLosses)
|
.def("GetLDoNLosses", (int(Lua_Client::*)(void))&Lua_Client::GetLDoNLosses)
|
||||||
.def("GetLDoNLossesTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNLossesTheme)
|
.def("GetLDoNLossesTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNLossesTheme)
|
||||||
.def("GetLDoNPointsTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNPointsTheme)
|
.def("GetLDoNPointsTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNPointsTheme)
|
||||||
@@ -3373,6 +3398,7 @@ luabind::scope lua_register_client() {
|
|||||||
.def("ResetCastbarCooldownBySlot", (void(Lua_Client::*)(int))&Lua_Client::ResetCastbarCooldownBySlot)
|
.def("ResetCastbarCooldownBySlot", (void(Lua_Client::*)(int))&Lua_Client::ResetCastbarCooldownBySlot)
|
||||||
.def("ResetCastbarCooldownBySpellID", (void(Lua_Client::*)(uint32))&Lua_Client::ResetCastbarCooldownBySpellID)
|
.def("ResetCastbarCooldownBySpellID", (void(Lua_Client::*)(uint32))&Lua_Client::ResetCastbarCooldownBySpellID)
|
||||||
.def("ResetDisciplineTimer", (void(Lua_Client::*)(uint32))&Lua_Client::ResetDisciplineTimer)
|
.def("ResetDisciplineTimer", (void(Lua_Client::*)(uint32))&Lua_Client::ResetDisciplineTimer)
|
||||||
|
.def("ResetItemCooldown", (void(Lua_Client::*)(uint32))&Lua_Client::ResetItemCooldown)
|
||||||
.def("ResetTrade", (void(Lua_Client::*)(void))&Lua_Client::ResetTrade)
|
.def("ResetTrade", (void(Lua_Client::*)(void))&Lua_Client::ResetTrade)
|
||||||
.def("RewardFaction", (void(Lua_Client::*)(int,int))&Lua_Client::RewardFaction)
|
.def("RewardFaction", (void(Lua_Client::*)(int,int))&Lua_Client::RewardFaction)
|
||||||
.def("Save", (void(Lua_Client::*)(int))&Lua_Client::Save)
|
.def("Save", (void(Lua_Client::*)(int))&Lua_Client::Save)
|
||||||
@@ -3447,6 +3473,7 @@ luabind::scope lua_register_client() {
|
|||||||
.def("SetHunger", (void(Lua_Client::*)(int))&Lua_Client::SetHunger)
|
.def("SetHunger", (void(Lua_Client::*)(int))&Lua_Client::SetHunger)
|
||||||
.def("SetInvulnerableEnvironmentDamage", (void(Lua_Client::*)(int))&Lua_Client::SetInvulnerableEnvironmentDamage)
|
.def("SetInvulnerableEnvironmentDamage", (void(Lua_Client::*)(int))&Lua_Client::SetInvulnerableEnvironmentDamage)
|
||||||
.def("SetIPExemption", (void(Lua_Client::*)(int))&Lua_Client::SetIPExemption)
|
.def("SetIPExemption", (void(Lua_Client::*)(int))&Lua_Client::SetIPExemption)
|
||||||
|
.def("SetItemCooldown", (void(Lua_Client::*)(uint32,uint32))&Lua_Client::SetItemCooldown)
|
||||||
.def("SetLanguageSkill", (void(Lua_Client::*)(int,int))&Lua_Client::SetLanguageSkill)
|
.def("SetLanguageSkill", (void(Lua_Client::*)(int,int))&Lua_Client::SetLanguageSkill)
|
||||||
.def("SetMaterial", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetMaterial)
|
.def("SetMaterial", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetMaterial)
|
||||||
.def("SetPEQZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetPEQZoneFlag)
|
.def("SetPEQZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetPEQZoneFlag)
|
||||||
@@ -3532,6 +3559,7 @@ luabind::scope lua_register_client() {
|
|||||||
.def("UpdateLDoNPoints", (void(Lua_Client::*)(uint32,int))&Lua_Client::UpdateLDoNPoints)
|
.def("UpdateLDoNPoints", (void(Lua_Client::*)(uint32,int))&Lua_Client::UpdateLDoNPoints)
|
||||||
.def("UpdateTaskActivity", (void(Lua_Client::*)(int,int,int))&Lua_Client::UpdateTaskActivity)
|
.def("UpdateTaskActivity", (void(Lua_Client::*)(int,int,int))&Lua_Client::UpdateTaskActivity)
|
||||||
.def("UseDiscipline", (bool(Lua_Client::*)(int,int))&Lua_Client::UseDiscipline)
|
.def("UseDiscipline", (bool(Lua_Client::*)(int,int))&Lua_Client::UseDiscipline)
|
||||||
|
.def("UseAugmentContainer", (void(Lua_Client::*)(int))&Lua_Client::UseAugmentContainer)
|
||||||
.def("WorldKick", (void(Lua_Client::*)(void))&Lua_Client::WorldKick);
|
.def("WorldKick", (void(Lua_Client::*)(void))&Lua_Client::WorldKick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -462,6 +462,10 @@ public:
|
|||||||
bool CanEnterZone(std::string zone_short_name);
|
bool CanEnterZone(std::string zone_short_name);
|
||||||
bool CanEnterZone(std::string zone_short_name, int16 instance_version);
|
bool CanEnterZone(std::string zone_short_name, int16 instance_version);
|
||||||
void SendPath(Lua_Mob target);
|
void SendPath(Lua_Mob target);
|
||||||
|
void ResetItemCooldown(uint32 item_id);
|
||||||
|
void SetItemCooldown(uint32 item_id, uint32 in_time);
|
||||||
|
uint32 GetItemCooldown(uint32 item_id);
|
||||||
|
void UseAugmentContainer(int container_slot);
|
||||||
|
|
||||||
void ApplySpell(int spell_id);
|
void ApplySpell(int spell_id);
|
||||||
void ApplySpell(int spell_id, int duration);
|
void ApplySpell(int spell_id, int duration);
|
||||||
|
|||||||
+14
-2
@@ -3700,6 +3700,11 @@ int8 lua_does_augment_fit(Lua_ItemInst inst, uint32 augment_id)
|
|||||||
return quest_manager.DoesAugmentFit(inst, augment_id);
|
return quest_manager.DoesAugmentFit(inst, augment_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8 lua_does_augment_fit_slot(Lua_ItemInst inst, uint32 augment_id, uint8 augment_slot)
|
||||||
|
{
|
||||||
|
return quest_manager.DoesAugmentFit(inst, augment_id, augment_slot);
|
||||||
|
}
|
||||||
|
|
||||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||||
cur = table[#name]; \
|
cur = table[#name]; \
|
||||||
if(luabind::type(cur) != LUA_TNIL) { \
|
if(luabind::type(cur) != LUA_TNIL) { \
|
||||||
@@ -4217,7 +4222,8 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("do_anim", (void(*)(int,int,bool))&lua_do_anim),
|
luabind::def("do_anim", (void(*)(int,int,bool))&lua_do_anim),
|
||||||
luabind::def("do_anim", (void(*)(int,int,bool,int))&lua_do_anim),
|
luabind::def("do_anim", (void(*)(int,int,bool,int))&lua_do_anim),
|
||||||
luabind::def("do_augment_slots_match", &lua_do_augment_slots_match),
|
luabind::def("do_augment_slots_match", &lua_do_augment_slots_match),
|
||||||
luabind::def("does_augment_fit", &lua_does_augment_fit),
|
luabind::def("does_augment_fit", (int8(*)(Lua_ItemInst, uint32))&lua_does_augment_fit),
|
||||||
|
luabind::def("does_augment_fit_slot", (int8(*)(Lua_ItemInst, uint32, uint8))&lua_does_augment_fit_slot),
|
||||||
/*
|
/*
|
||||||
Cross Zone
|
Cross Zone
|
||||||
*/
|
*/
|
||||||
@@ -4625,7 +4631,13 @@ luabind::scope lua_register_events() {
|
|||||||
luabind::value("despawn_zone", static_cast<int>(EVENT_DESPAWN_ZONE)),
|
luabind::value("despawn_zone", static_cast<int>(EVENT_DESPAWN_ZONE)),
|
||||||
luabind::value("bot_create", static_cast<int>(EVENT_BOT_CREATE)),
|
luabind::value("bot_create", static_cast<int>(EVENT_BOT_CREATE)),
|
||||||
luabind::value("augment_insert_client", static_cast<int>(EVENT_AUGMENT_INSERT_CLIENT)),
|
luabind::value("augment_insert_client", static_cast<int>(EVENT_AUGMENT_INSERT_CLIENT)),
|
||||||
luabind::value("augment_remove_client", static_cast<int>(EVENT_AUGMENT_REMOVE_CLIENT))
|
luabind::value("augment_remove_client", static_cast<int>(EVENT_AUGMENT_REMOVE_CLIENT)),
|
||||||
|
luabind::value("equip_item_bot", static_cast<int>(EVENT_EQUIP_ITEM_BOT)),
|
||||||
|
luabind::value("unequip_item_bot", static_cast<int>(EVENT_UNEQUIP_ITEM_BOT)),
|
||||||
|
luabind::value("damage_given", static_cast<int>(EVENT_DAMAGE_GIVEN)),
|
||||||
|
luabind::value("damage_taken", static_cast<int>(EVENT_DAMAGE_TAKEN)),
|
||||||
|
luabind::value("item_click_client", static_cast<int>(EVENT_ITEM_CLICK_CLIENT)),
|
||||||
|
luabind::value("item_click_cast_client", static_cast<int>(EVENT_ITEM_CLICK_CAST_CLIENT))
|
||||||
)];
|
)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+85
-6
@@ -573,12 +573,6 @@ void Lua_NPC::RecalculateSkills()
|
|||||||
self->RecalculateSkills();
|
self->RecalculateSkills();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_NPC::ScaleNPC(uint8 npc_level)
|
|
||||||
{
|
|
||||||
Lua_Safe_Call_Void();
|
|
||||||
self->ScaleNPC(npc_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Lua_NPC::IsRaidTarget()
|
bool Lua_NPC::IsRaidTarget()
|
||||||
{
|
{
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
@@ -701,6 +695,78 @@ void Lua_NPC::SetKeepsSoldItems(bool keeps_sold_items) {
|
|||||||
self->SetKeepsSoldItems(keeps_sold_items);
|
self->SetKeepsSoldItems(keeps_sold_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lua_NPC::IsLDoNTrapped() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsLDoNTrapped();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetLDoNTrapped(bool is_trapped) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetLDoNTrapped(is_trapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 Lua_NPC::GetLDoNTrapType() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetLDoNTrapType();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetLDoNTrapType(uint8 trap_type) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetLDoNTrapType(trap_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Lua_NPC::GetLDoNTrapSpellID() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetLDoNTrapSpellID();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetLDoNTrapSpellID(uint16 spell_id) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetLDoNTrapSpellID(spell_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_NPC::IsLDoNLocked() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsLDoNLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetLDoNLocked(bool is_locked) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetLDoNLocked(is_locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Lua_NPC::GetLDoNLockedSkill() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetLDoNLockedSkill();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetLDoNLockedSkill(uint16 skill_value) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetLDoNLockedSkill(skill_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_NPC::IsLDoNTrapDetected() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->IsLDoNTrapDetected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetLDoNTrapDetected(bool is_detected) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetLDoNTrapDetected(is_detected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::ScaleNPC(uint8 npc_level)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->ScaleNPC(npc_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::ScaleNPC(uint8 npc_level, bool override_special_abilities)
|
||||||
|
{
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->ScaleNPC(npc_level, true, override_special_abilities);
|
||||||
|
}
|
||||||
|
|
||||||
luabind::scope lua_register_npc() {
|
luabind::scope lua_register_npc() {
|
||||||
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
@@ -753,6 +819,9 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("GetMaxDamage", (uint32(Lua_NPC::*)(int))&Lua_NPC::GetMaxDamage)
|
.def("GetMaxDamage", (uint32(Lua_NPC::*)(int))&Lua_NPC::GetMaxDamage)
|
||||||
.def("GetMaxWp", (int(Lua_NPC::*)(void))&Lua_NPC::GetMaxWp)
|
.def("GetMaxWp", (int(Lua_NPC::*)(void))&Lua_NPC::GetMaxWp)
|
||||||
.def("GetMinDMG", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetMinDMG)
|
.def("GetMinDMG", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetMinDMG)
|
||||||
|
.def("GetLDoNLockedSkill", (uint16(Lua_NPC::*)(void))&Lua_NPC::GetLDoNLockedSkill)
|
||||||
|
.def("GetLDoNTrapType", (uint8(Lua_NPC::*)(void))&Lua_NPC::GetLDoNTrapType)
|
||||||
|
.def("GetLDoNTrapSpellID", (uint16(Lua_NPC::*)(void))&Lua_NPC::GetLDoNTrapSpellID)
|
||||||
.def("GetNPCFactionID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCFactionID)
|
.def("GetNPCFactionID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCFactionID)
|
||||||
.def("GetNPCHate", (int64(Lua_NPC::*)(Lua_Mob))&Lua_NPC::GetNPCHate)
|
.def("GetNPCHate", (int64(Lua_NPC::*)(Lua_Mob))&Lua_NPC::GetNPCHate)
|
||||||
.def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
.def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
||||||
@@ -784,6 +853,9 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("HasItem", (bool(Lua_NPC::*)(uint32))&Lua_NPC::HasItem)
|
.def("HasItem", (bool(Lua_NPC::*)(uint32))&Lua_NPC::HasItem)
|
||||||
.def("IsAnimal", (bool(Lua_NPC::*)(void))&Lua_NPC::IsAnimal)
|
.def("IsAnimal", (bool(Lua_NPC::*)(void))&Lua_NPC::IsAnimal)
|
||||||
.def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding)
|
.def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding)
|
||||||
|
.def("IsLDoNLocked", (bool(Lua_NPC::*)(void))&Lua_NPC::IsLDoNLocked)
|
||||||
|
.def("IsLDoNTrapped", (bool(Lua_NPC::*)(void))&Lua_NPC::IsLDoNTrapped)
|
||||||
|
.def("IsLDoNTrapDetected", (bool(Lua_NPC::*)(void))&Lua_NPC::IsLDoNTrapDetected)
|
||||||
.def("IsOnHatelist", (bool(Lua_NPC::*)(Lua_Mob))&Lua_NPC::IsOnHatelist)
|
.def("IsOnHatelist", (bool(Lua_NPC::*)(Lua_Mob))&Lua_NPC::IsOnHatelist)
|
||||||
.def("IsRaidTarget", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRaidTarget)
|
.def("IsRaidTarget", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRaidTarget)
|
||||||
.def("IsRareSpawn", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRareSpawn)
|
.def("IsRareSpawn", (bool(Lua_NPC::*)(void))&Lua_NPC::IsRareSpawn)
|
||||||
@@ -808,6 +880,7 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("SaveGuardSpot", (void(Lua_NPC::*)(bool))&Lua_NPC::SaveGuardSpot)
|
.def("SaveGuardSpot", (void(Lua_NPC::*)(bool))&Lua_NPC::SaveGuardSpot)
|
||||||
.def("SaveGuardSpot", (void(Lua_NPC::*)(float,float,float,float))&Lua_NPC::SaveGuardSpot)
|
.def("SaveGuardSpot", (void(Lua_NPC::*)(float,float,float,float))&Lua_NPC::SaveGuardSpot)
|
||||||
.def("ScaleNPC", (void(Lua_NPC::*)(uint8))&Lua_NPC::ScaleNPC)
|
.def("ScaleNPC", (void(Lua_NPC::*)(uint8))&Lua_NPC::ScaleNPC)
|
||||||
|
.def("ScaleNPC", (void(Lua_NPC::*)(uint8,bool))&Lua_NPC::ScaleNPC)
|
||||||
.def("SendPayload", (void(Lua_NPC::*)(int))&Lua_NPC::SendPayload)
|
.def("SendPayload", (void(Lua_NPC::*)(int))&Lua_NPC::SendPayload)
|
||||||
.def("SendPayload", (void(Lua_NPC::*)(int,std::string))&Lua_NPC::SendPayload)
|
.def("SendPayload", (void(Lua_NPC::*)(int,std::string))&Lua_NPC::SendPayload)
|
||||||
.def("SetCopper", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetCopper)
|
.def("SetCopper", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetCopper)
|
||||||
@@ -817,6 +890,12 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("SetGold", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetGold)
|
.def("SetGold", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetGold)
|
||||||
.def("SetGrid", (void(Lua_NPC::*)(int))&Lua_NPC::SetGrid)
|
.def("SetGrid", (void(Lua_NPC::*)(int))&Lua_NPC::SetGrid)
|
||||||
.def("SetKeepsSoldItems", (void(Lua_NPC::*)(bool))&Lua_NPC::SetKeepsSoldItems)
|
.def("SetKeepsSoldItems", (void(Lua_NPC::*)(bool))&Lua_NPC::SetKeepsSoldItems)
|
||||||
|
.def("SetLDoNLocked", (void(Lua_NPC::*)(bool))&Lua_NPC::SetLDoNLocked)
|
||||||
|
.def("SetLDoNLockedSkill", (void(Lua_NPC::*)(uint16))&Lua_NPC::SetLDoNLockedSkill)
|
||||||
|
.def("SetLDoNTrapped", (void(Lua_NPC::*)(bool))&Lua_NPC::SetLDoNTrapped)
|
||||||
|
.def("SetLDoNTrapDetected", (void(Lua_NPC::*)(bool))&Lua_NPC::SetLDoNTrapDetected)
|
||||||
|
.def("SetLDoNTrapSpellID", (void(Lua_NPC::*)(uint16))&Lua_NPC::SetLDoNTrapSpellID)
|
||||||
|
.def("SetLDoNTrapType", (void(Lua_NPC::*)(uint8))&Lua_NPC::SetLDoNTrapType)
|
||||||
.def("SetNPCFactionID", (void(Lua_NPC::*)(int))&Lua_NPC::SetNPCFactionID)
|
.def("SetNPCFactionID", (void(Lua_NPC::*)(int))&Lua_NPC::SetNPCFactionID)
|
||||||
.def("SetPetSpellID", (void(Lua_NPC::*)(int))&Lua_NPC::SetPetSpellID)
|
.def("SetPetSpellID", (void(Lua_NPC::*)(int))&Lua_NPC::SetPetSpellID)
|
||||||
.def("SetPlatinum", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetPlatinum)
|
.def("SetPlatinum", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetPlatinum)
|
||||||
|
|||||||
+14
-1
@@ -141,7 +141,6 @@ public:
|
|||||||
void SetSimpleRoamBox(float box_size, float move_distance, int move_delay);
|
void SetSimpleRoamBox(float box_size, float move_distance, int move_delay);
|
||||||
void RecalculateSkills();
|
void RecalculateSkills();
|
||||||
void ReloadSpells();
|
void ReloadSpells();
|
||||||
void ScaleNPC(uint8 npc_level);
|
|
||||||
bool IsRaidTarget();
|
bool IsRaidTarget();
|
||||||
bool IsRareSpawn();
|
bool IsRareSpawn();
|
||||||
void ChangeLastName(std::string last_name);
|
void ChangeLastName(std::string last_name);
|
||||||
@@ -161,6 +160,20 @@ public:
|
|||||||
void SendPayload(int payload_id, std::string payload_value);
|
void SendPayload(int payload_id, std::string payload_value);
|
||||||
bool GetKeepsSoldItems();
|
bool GetKeepsSoldItems();
|
||||||
void SetKeepsSoldItems(bool keeps_sold_items);
|
void SetKeepsSoldItems(bool keeps_sold_items);
|
||||||
|
bool IsLDoNTrapped();
|
||||||
|
void SetLDoNTrapped(bool is_trapped);
|
||||||
|
uint8 GetLDoNTrapType();
|
||||||
|
void SetLDoNTrapType(uint8 trap_type);
|
||||||
|
uint16 GetLDoNTrapSpellID();
|
||||||
|
void SetLDoNTrapSpellID(uint16 spell_id);
|
||||||
|
bool IsLDoNLocked();
|
||||||
|
void SetLDoNLocked(bool is_locked);
|
||||||
|
uint16 GetLDoNLockedSkill();
|
||||||
|
void SetLDoNLockedSkill(uint16 skill_value);
|
||||||
|
bool IsLDoNTrapDetected();
|
||||||
|
void SetLDoNTrapDetected(bool is_detected);
|
||||||
|
void ScaleNPC(uint8 npc_level);
|
||||||
|
void ScaleNPC(uint8 npc_level, bool override_special_abilities);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+18
-1
@@ -156,6 +156,12 @@ const char *LuaEvents[_LargestEventID] = {
|
|||||||
"event_bot_create",
|
"event_bot_create",
|
||||||
"event_augment_insert_client",
|
"event_augment_insert_client",
|
||||||
"event_augment_remove_client",
|
"event_augment_remove_client",
|
||||||
|
"event_equip_item_bot",
|
||||||
|
"event_unequip_item_bot",
|
||||||
|
"event_damage_given",
|
||||||
|
"event_damage_taken",
|
||||||
|
"event_item_click_client",
|
||||||
|
"event_item_click_cast_client"
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Zone *zone;
|
extern Zone *zone;
|
||||||
@@ -171,7 +177,7 @@ std::map<std::string, bool> lua_encounters_loaded;
|
|||||||
std::map<std::string, Encounter *> lua_encounters;
|
std::map<std::string, Encounter *> lua_encounters;
|
||||||
|
|
||||||
LuaParser::LuaParser() {
|
LuaParser::LuaParser() {
|
||||||
for(int i = 0; i < _LargestEventID; ++i) {
|
for (int i = 0; i < _LargestEventID; ++i) {
|
||||||
NPCArgumentDispatch[i] = handle_npc_null;
|
NPCArgumentDispatch[i] = handle_npc_null;
|
||||||
PlayerArgumentDispatch[i] = handle_player_null;
|
PlayerArgumentDispatch[i] = handle_player_null;
|
||||||
ItemArgumentDispatch[i] = handle_item_null;
|
ItemArgumentDispatch[i] = handle_item_null;
|
||||||
@@ -211,6 +217,8 @@ LuaParser::LuaParser() {
|
|||||||
NPCArgumentDispatch[EVENT_SPAWN_ZONE] = handle_npc_spawn_zone;
|
NPCArgumentDispatch[EVENT_SPAWN_ZONE] = handle_npc_spawn_zone;
|
||||||
NPCArgumentDispatch[EVENT_PAYLOAD] = handle_npc_payload;
|
NPCArgumentDispatch[EVENT_PAYLOAD] = handle_npc_payload;
|
||||||
NPCArgumentDispatch[EVENT_DESPAWN_ZONE] = handle_npc_despawn_zone;
|
NPCArgumentDispatch[EVENT_DESPAWN_ZONE] = handle_npc_despawn_zone;
|
||||||
|
NPCArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_npc_damage;
|
||||||
|
NPCArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_npc_damage;
|
||||||
|
|
||||||
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
|
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
|
||||||
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
|
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
|
||||||
@@ -234,6 +242,7 @@ LuaParser::LuaParser() {
|
|||||||
PlayerArgumentDispatch[EVENT_DUEL_LOSE] = handle_player_duel_loss;
|
PlayerArgumentDispatch[EVENT_DUEL_LOSE] = handle_player_duel_loss;
|
||||||
PlayerArgumentDispatch[EVENT_LOOT] = handle_player_loot;
|
PlayerArgumentDispatch[EVENT_LOOT] = handle_player_loot;
|
||||||
PlayerArgumentDispatch[EVENT_TASK_STAGE_COMPLETE] = handle_player_task_stage_complete;
|
PlayerArgumentDispatch[EVENT_TASK_STAGE_COMPLETE] = handle_player_task_stage_complete;
|
||||||
|
PlayerArgumentDispatch[EVENT_TASK_ACCEPTED] = handle_player_task_accepted;
|
||||||
PlayerArgumentDispatch[EVENT_TASK_COMPLETE] = handle_player_task_update;
|
PlayerArgumentDispatch[EVENT_TASK_COMPLETE] = handle_player_task_update;
|
||||||
PlayerArgumentDispatch[EVENT_TASK_UPDATE] = handle_player_task_update;
|
PlayerArgumentDispatch[EVENT_TASK_UPDATE] = handle_player_task_update;
|
||||||
PlayerArgumentDispatch[EVENT_TASK_BEFORE_UPDATE] = handle_player_task_update;
|
PlayerArgumentDispatch[EVENT_TASK_BEFORE_UPDATE] = handle_player_task_update;
|
||||||
@@ -271,6 +280,10 @@ LuaParser::LuaParser() {
|
|||||||
PlayerArgumentDispatch[EVENT_BOT_CREATE] = handle_player_bot_create;
|
PlayerArgumentDispatch[EVENT_BOT_CREATE] = handle_player_bot_create;
|
||||||
PlayerArgumentDispatch[EVENT_AUGMENT_INSERT_CLIENT] = handle_player_augment_insert;
|
PlayerArgumentDispatch[EVENT_AUGMENT_INSERT_CLIENT] = handle_player_augment_insert;
|
||||||
PlayerArgumentDispatch[EVENT_AUGMENT_REMOVE_CLIENT] = handle_player_augment_remove;
|
PlayerArgumentDispatch[EVENT_AUGMENT_REMOVE_CLIENT] = handle_player_augment_remove;
|
||||||
|
PlayerArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_player_damage;
|
||||||
|
PlayerArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_player_damage;
|
||||||
|
PlayerArgumentDispatch[EVENT_ITEM_CLICK_CAST_CLIENT] = handle_player_item_click;
|
||||||
|
PlayerArgumentDispatch[EVENT_ITEM_CLICK_CLIENT] = handle_player_item_click;
|
||||||
|
|
||||||
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
|
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
|
||||||
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
|
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
|
||||||
@@ -308,6 +321,10 @@ LuaParser::LuaParser() {
|
|||||||
BotArgumentDispatch[EVENT_TRADE] = handle_bot_trade;
|
BotArgumentDispatch[EVENT_TRADE] = handle_bot_trade;
|
||||||
BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill;
|
BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill;
|
||||||
BotArgumentDispatch[EVENT_PAYLOAD] = handle_bot_payload;
|
BotArgumentDispatch[EVENT_PAYLOAD] = handle_bot_payload;
|
||||||
|
BotArgumentDispatch[EVENT_EQUIP_ITEM_BOT] = handle_bot_equip_item;
|
||||||
|
BotArgumentDispatch[EVENT_UNEQUIP_ITEM_BOT] = handle_bot_equip_item;
|
||||||
|
BotArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_bot_damage;
|
||||||
|
BotArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_bot_damage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
L = nullptr;
|
L = nullptr;
|
||||||
|
|||||||
+293
-94
@@ -120,12 +120,12 @@ void handle_npc_event_hp(
|
|||||||
if(extra_data == 1) {
|
if(extra_data == 1) {
|
||||||
lua_pushinteger(L, -1);
|
lua_pushinteger(L, -1);
|
||||||
lua_setfield(L, -2, "hp_event");
|
lua_setfield(L, -2, "hp_event");
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "inc_hp_event");
|
lua_setfield(L, -2, "inc_hp_event");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "hp_event");
|
lua_setfield(L, -2, "hp_event");
|
||||||
lua_pushinteger(L, -1);
|
lua_pushinteger(L, -1);
|
||||||
lua_setfield(L, -2, "inc_hp_event");
|
lua_setfield(L, -2, "inc_hp_event");
|
||||||
@@ -191,7 +191,7 @@ void handle_npc_task_accepted(
|
|||||||
l_client_o.push(L);
|
l_client_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "task_id");
|
lua_setfield(L, -2, "task_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ void handle_npc_popup(
|
|||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "popup_id");
|
lua_setfield(L, -2, "popup_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ void handle_npc_waypoint(
|
|||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data, -1));
|
||||||
lua_setfield(L, -2, "wp");
|
lua_setfield(L, -2, "wp");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ void handle_npc_hate(
|
|||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushboolean(L, std::stoi(data) == 0 ? false : true);
|
lua_pushboolean(L, Strings::ToInt(data) == 0 ? false : true);
|
||||||
lua_setfield(L, -2, "joined");
|
lua_setfield(L, -2, "joined");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ void handle_npc_signal(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "signal");
|
lua_setfield(L, -2, "signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ void handle_npc_payload(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "payload_id");
|
lua_setfield(L, -2, "payload_id");
|
||||||
|
|
||||||
lua_pushstring(L, sep.argplus[1]);
|
lua_pushstring(L, sep.argplus[1]);
|
||||||
@@ -309,13 +309,13 @@ void handle_npc_death(
|
|||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "killer_id");
|
lua_setfield(L, -2, "killer_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "damage");
|
lua_setfield(L, -2, "damage");
|
||||||
|
|
||||||
int spell_id = std::stoi(sep.arg[2]);
|
int spell_id = Strings::ToInt(sep.arg[2]);
|
||||||
if(IsValidSpell(spell_id)) {
|
if(IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
@@ -328,7 +328,7 @@ void handle_npc_death(
|
|||||||
lua_setfield(L, -2, "spell");
|
lua_setfield(L, -2, "spell");
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "skill_id");
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
if (extra_pointers && extra_pointers->size() >= 1)
|
if (extra_pointers && extra_pointers->size() >= 1)
|
||||||
@@ -357,7 +357,7 @@ void handle_npc_cast(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
int spell_id = std::stoi(data);
|
int spell_id = Strings::ToInt(data);
|
||||||
if(IsValidSpell(spell_id)) {
|
if(IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
@@ -453,6 +453,50 @@ void handle_npc_despawn_zone(
|
|||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_npc_damage(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
NPC* npc,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoul(sep.arg[0]));
|
||||||
|
lua_setfield(L, -2, "entity_id");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoll(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "damage");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[2]));
|
||||||
|
lua_setfield(L, -2, "spell_id");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[3]));
|
||||||
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[4]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_damage_shield");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[5]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_avoidable");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[6]));
|
||||||
|
lua_setfield(L, -2, "buff_slot");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[7]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_buff_tic");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[8]));
|
||||||
|
lua_setfield(L, -2, "special_attack");
|
||||||
|
|
||||||
|
Lua_Mob l_mob(init);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
}
|
||||||
|
|
||||||
// Player
|
// Player
|
||||||
void handle_player_say(
|
void handle_player_say(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
@@ -478,13 +522,13 @@ void handle_player_environmental_damage(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "env_damage");
|
lua_setfield(L, -2, "env_damage");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "env_damage_type");
|
lua_setfield(L, -2, "env_damage_type");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "env_final_damage");
|
lua_setfield(L, -2, "env_final_damage");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,19 +542,19 @@ void handle_player_death(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0]));
|
Mob *o = entity_list.GetMobID(Strings::ToInt(sep.arg[0]));
|
||||||
Lua_Mob l_mob(o);
|
Lua_Mob l_mob(o);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "killer_id");
|
lua_setfield(L, -2, "killer_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "damage");
|
lua_setfield(L, -2, "damage");
|
||||||
|
|
||||||
int spell_id = std::stoi(sep.arg[3]);
|
int spell_id = Strings::ToInt(sep.arg[3]);
|
||||||
if(IsValidSpell(spell_id)) {
|
if(IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
@@ -523,7 +567,7 @@ void handle_player_death(
|
|||||||
lua_setfield(L, -2, "spell");
|
lua_setfield(L, -2, "spell");
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[4]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[4]));
|
||||||
lua_setfield(L, -2, "skill");
|
lua_setfield(L, -2, "skill");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,7 +655,7 @@ void handle_player_signal(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "signal");
|
lua_setfield(L, -2, "signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,7 +669,7 @@ void handle_player_payload(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "payload_id");
|
lua_setfield(L, -2, "payload_id");
|
||||||
|
|
||||||
lua_pushstring(L, sep.argplus[1]);
|
lua_pushstring(L, sep.argplus[1]);
|
||||||
@@ -640,7 +684,7 @@ void handle_player_popup_response(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "popup_id");
|
lua_setfield(L, -2, "popup_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,7 +712,7 @@ void handle_player_cast(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
int spell_id = std::stoi(sep.arg[0]);
|
int spell_id = Strings::ToInt(sep.arg[0]);
|
||||||
if(IsValidSpell(spell_id)) {
|
if(IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
@@ -681,10 +725,10 @@ void handle_player_cast(
|
|||||||
|
|
||||||
lua_setfield(L, -2, "spell");
|
lua_setfield(L, -2, "spell");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "caster_id");
|
lua_setfield(L, -2, "caster_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "caster_level");
|
lua_setfield(L, -2, "caster_level");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,7 +740,7 @@ void handle_player_task_fail(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "task_id");
|
lua_setfield(L, -2, "task_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,22 +754,22 @@ void handle_player_zone(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "from_zone_id");
|
lua_setfield(L, -2, "from_zone_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "from_instance_id");
|
lua_setfield(L, -2, "from_instance_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "from_instance_version");
|
lua_setfield(L, -2, "from_instance_version");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "zone_id");
|
lua_setfield(L, -2, "zone_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[4]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[4]));
|
||||||
lua_setfield(L, -2, "instance_id");
|
lua_setfield(L, -2, "instance_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[5]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[5]));
|
||||||
lua_setfield(L, -2, "instance_version");
|
lua_setfield(L, -2, "instance_version");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,13 +829,25 @@ void handle_player_task_stage_complete(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "task_id");
|
lua_setfield(L, -2, "task_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "activity_id");
|
lua_setfield(L, -2, "activity_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_player_task_accepted(
|
||||||
|
QuestInterface* parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any>* extra_pointers
|
||||||
|
) {
|
||||||
|
lua_pushinteger(L, std::stoi(data));
|
||||||
|
lua_setfield(L, -2, "task_id");
|
||||||
|
}
|
||||||
|
|
||||||
void handle_player_task_update(
|
void handle_player_task_update(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
lua_State* L,
|
lua_State* L,
|
||||||
@@ -801,13 +857,13 @@ void handle_player_task_update(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "count");
|
lua_setfield(L, -2, "count");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "activity_id");
|
lua_setfield(L, -2, "activity_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "task_id");
|
lua_setfield(L, -2, "task_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -888,7 +944,7 @@ void handle_player_respawn(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "option");
|
lua_setfield(L, -2, "option");
|
||||||
|
|
||||||
lua_pushboolean(L, extra_data == 1 ? true : false);
|
lua_pushboolean(L, extra_data == 1 ? true : false);
|
||||||
@@ -931,10 +987,10 @@ void handle_player_use_skill(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "skill_id");
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "skill_level");
|
lua_setfield(L, -2, "skill_level");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -966,10 +1022,10 @@ void handle_player_combine_validate(
|
|||||||
int zone_id = -1;
|
int zone_id = -1;
|
||||||
int tradeskill_id = -1;
|
int tradeskill_id = -1;
|
||||||
if (strcmp(sep.arg[0], "check_zone") == 0) {
|
if (strcmp(sep.arg[0], "check_zone") == 0) {
|
||||||
zone_id = std::stoi(sep.arg[1]);
|
zone_id = Strings::ToInt(sep.arg[1]);
|
||||||
}
|
}
|
||||||
else if (strcmp(sep.arg[0], "check_tradeskill") == 0) {
|
else if (strcmp(sep.arg[0], "check_tradeskill") == 0) {
|
||||||
tradeskill_id = std::stoi(sep.arg[1]);
|
tradeskill_id = Strings::ToInt(sep.arg[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushinteger(L, zone_id);
|
lua_pushinteger(L, zone_id);
|
||||||
@@ -1031,7 +1087,7 @@ void handle_player_quest_combine(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "container_slot");
|
lua_setfield(L, -2, "container_slot");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1043,7 +1099,7 @@ void handle_player_consider(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "entity_id");
|
lua_setfield(L, -2, "entity_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1055,7 +1111,7 @@ void handle_player_consider_corpse(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "corpse_entity_id");
|
lua_setfield(L, -2, "corpse_entity_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1082,16 +1138,16 @@ void handle_player_aa_buy(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "aa_cost");
|
lua_setfield(L, -2, "aa_cost");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "aa_id");
|
lua_setfield(L, -2, "aa_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "aa_previous_id");
|
lua_setfield(L, -2, "aa_previous_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "aa_next_id");
|
lua_setfield(L, -2, "aa_next_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1103,7 +1159,7 @@ void handle_player_aa_gain(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "aa_gained");
|
lua_setfield(L, -2, "aa_gained");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1155,19 +1211,92 @@ void handle_player_bot_create(
|
|||||||
lua_pushstring(L, sep.arg[0]);
|
lua_pushstring(L, sep.arg[0]);
|
||||||
lua_setfield(L, -2, "bot_name");
|
lua_setfield(L, -2, "bot_name");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "bot_id");
|
lua_setfield(L, -2, "bot_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "bot_race");
|
lua_setfield(L, -2, "bot_race");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "bot_class");
|
lua_setfield(L, -2, "bot_class");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[4]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[4]));
|
||||||
lua_setfield(L, -2, "bot_gender");
|
lua_setfield(L, -2, "bot_gender");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_player_damage(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoul(sep.arg[0]));
|
||||||
|
lua_setfield(L, -2, "entity_id");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoll(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "damage");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[2]));
|
||||||
|
lua_setfield(L, -2, "spell_id");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[3]));
|
||||||
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[4]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_damage_shield");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[5]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_avoidable");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[6]));
|
||||||
|
lua_setfield(L, -2, "buff_slot");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[7]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_buff_tic");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[8]));
|
||||||
|
lua_setfield(L, -2, "special_attack");
|
||||||
|
|
||||||
|
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||||
|
Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(0)));
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_player_item_click(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
lua_pushnumber(L, std::stoi(data));
|
||||||
|
lua_setfield(L, -2, "slot_id");
|
||||||
|
|
||||||
|
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||||
|
lua_pushnumber(L, std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0))->GetID());
|
||||||
|
lua_setfield(L, -2, "item_id");
|
||||||
|
|
||||||
|
lua_pushstring(L, std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0))->GetItem()->Name);
|
||||||
|
lua_setfield(L, -2, "item_name");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0))->GetItem()->Click.Effect);
|
||||||
|
lua_setfield(L, -2, "spell_id");
|
||||||
|
|
||||||
|
Lua_ItemInst l_item(std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
|
||||||
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
|
l_item_o.push(L);
|
||||||
|
lua_setfield(L, -2, "item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Item
|
// Item
|
||||||
void handle_item_click(
|
void handle_item_click(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
@@ -1366,16 +1495,16 @@ void handle_spell_event(
|
|||||||
|
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "caster_id");
|
lua_setfield(L, -2, "caster_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "tics_remaining");
|
lua_setfield(L, -2, "tics_remaining");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "caster_level");
|
lua_setfield(L, -2, "caster_level");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "buff_slot");
|
lua_setfield(L, -2, "buff_slot");
|
||||||
|
|
||||||
Lua_Spell l_spell(spell_id);
|
Lua_Spell l_spell(spell_id);
|
||||||
@@ -1424,10 +1553,10 @@ void handle_player_equip_item(
|
|||||||
|
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
lua_pushnumber(L, std::stoi(sep.arg[0]));
|
lua_pushnumber(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "item_quantity");
|
lua_setfield(L, -2, "item_quantity");
|
||||||
|
|
||||||
lua_pushnumber(L, std::stoi(sep.arg[1]));
|
lua_pushnumber(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "slot_id");
|
lua_setfield(L, -2, "slot_id");
|
||||||
|
|
||||||
Lua_ItemInst l_item(extra_data);
|
Lua_ItemInst l_item(extra_data);
|
||||||
@@ -1515,16 +1644,16 @@ void handle_player_skill_up(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "skill_id");
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "skill_value");
|
lua_setfield(L, -2, "skill_value");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "skill_max");
|
lua_setfield(L, -2, "skill_max");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "is_tradeskill");
|
lua_setfield(L, -2, "is_tradeskill");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1537,13 +1666,13 @@ void handle_player_language_skill_up(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "skill_id");
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "skill_value");
|
lua_setfield(L, -2, "skill_value");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "skill_max");
|
lua_setfield(L, -2, "skill_max");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1556,19 +1685,19 @@ void handle_player_alt_currency_merchant(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "currency_id");
|
lua_setfield(L, -2, "currency_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "npc_id");
|
lua_setfield(L, -2, "npc_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "merchant_id");
|
lua_setfield(L, -2, "merchant_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "item_id");
|
lua_setfield(L, -2, "item_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[4]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[4]));
|
||||||
lua_setfield(L, -2, "item_cost");
|
lua_setfield(L, -2, "item_cost");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1581,19 +1710,19 @@ void handle_player_merchant(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "npc_id");
|
lua_setfield(L, -2, "npc_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "merchant_id");
|
lua_setfield(L, -2, "merchant_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "item_id");
|
lua_setfield(L, -2, "item_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "item_quantity");
|
lua_setfield(L, -2, "item_quantity");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[4]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[4]));
|
||||||
lua_setfield(L, -2, "item_cost");
|
lua_setfield(L, -2, "item_cost");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1619,7 +1748,7 @@ void handle_player_augment_insert(
|
|||||||
lua_pushinteger(L, std::stoul(sep.arg[0]));
|
lua_pushinteger(L, std::stoul(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "item_id");
|
lua_setfield(L, -2, "item_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "item_slot");
|
lua_setfield(L, -2, "item_slot");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoul(sep.arg[2]));
|
lua_pushinteger(L, std::stoul(sep.arg[2]));
|
||||||
@@ -1651,7 +1780,7 @@ void handle_player_augment_remove(
|
|||||||
lua_pushinteger(L, std::stoul(sep.arg[0]));
|
lua_pushinteger(L, std::stoul(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "item_id");
|
lua_setfield(L, -2, "item_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "item_slot");
|
lua_setfield(L, -2, "item_slot");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoul(sep.arg[2]));
|
lua_pushinteger(L, std::stoul(sep.arg[2]));
|
||||||
@@ -1688,7 +1817,7 @@ void handle_bot_cast(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
int spell_id = std::stoi(sep.arg[0]);
|
int spell_id = Strings::ToInt(sep.arg[0]);
|
||||||
if (IsValidSpell(spell_id)) {
|
if (IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
@@ -1701,10 +1830,10 @@ void handle_bot_cast(
|
|||||||
|
|
||||||
lua_setfield(L, -2, "spell");
|
lua_setfield(L, -2, "spell");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "caster_id");
|
lua_setfield(L, -2, "caster_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||||
lua_setfield(L, -2, "caster_level");
|
lua_setfield(L, -2, "caster_level");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1722,7 +1851,7 @@ void handle_bot_combat(
|
|||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushboolean(L, std::stoi(data) == 0 ? false : true);
|
lua_pushboolean(L, Strings::ToInt(data) == 0 ? false : true);
|
||||||
lua_setfield(L, -2, "joined");
|
lua_setfield(L, -2, "joined");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1737,16 +1866,16 @@ void handle_bot_death(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0]));
|
Mob *o = entity_list.GetMobID(Strings::ToInt(sep.arg[0]));
|
||||||
Lua_Mob l_mob(o);
|
Lua_Mob l_mob(o);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "damage");
|
lua_setfield(L, -2, "damage");
|
||||||
|
|
||||||
int spell_id = std::stoi(sep.arg[2]);
|
int spell_id = Strings::ToInt(sep.arg[2]);
|
||||||
if (IsValidSpell(spell_id)) {
|
if (IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
@@ -1759,7 +1888,7 @@ void handle_bot_death(
|
|||||||
lua_setfield(L, -2, "spell");
|
lua_setfield(L, -2, "spell");
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||||
lua_setfield(L, -2, "skill");
|
lua_setfield(L, -2, "skill");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1777,7 +1906,7 @@ void handle_bot_popup_response(
|
|||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "popup_id");
|
lua_setfield(L, -2, "popup_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1811,7 +1940,7 @@ void handle_bot_signal(
|
|||||||
uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, Strings::ToInt(data));
|
||||||
lua_setfield(L, -2, "signal");
|
lua_setfield(L, -2, "signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1826,7 +1955,7 @@ void handle_bot_payload(
|
|||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "payload_id");
|
lua_setfield(L, -2, "payload_id");
|
||||||
|
|
||||||
lua_pushstring(L, sep.argplus[1]);
|
lua_pushstring(L, sep.argplus[1]);
|
||||||
@@ -1944,11 +2073,81 @@ void handle_bot_use_skill(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
) {
|
) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "skill_id");
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||||
lua_setfield(L, -2, "skill_level");
|
lua_setfield(L, -2, "skill_level");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_bot_equip_item(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
lua_pushnumber(L, extra_data);
|
||||||
|
lua_setfield(L, -2, "item_id");
|
||||||
|
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[0]));
|
||||||
|
lua_setfield(L, -2, "item_quantity");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "slot_id");
|
||||||
|
|
||||||
|
Lua_ItemInst l_item(extra_data);
|
||||||
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
|
l_item_o.push(L);
|
||||||
|
lua_setfield(L, -2, "item");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_damage(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoul(sep.arg[0]));
|
||||||
|
lua_setfield(L, -2, "entity_id");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoll(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "damage");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[2]));
|
||||||
|
lua_setfield(L, -2, "spell_id");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[3]));
|
||||||
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[4]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_damage_shield");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[5]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_avoidable");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[6]));
|
||||||
|
lua_setfield(L, -2, "buff_slot");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(sep.arg[7]) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "is_buff_tic");
|
||||||
|
|
||||||
|
lua_pushnumber(L, std::stoi(sep.arg[8]));
|
||||||
|
lua_setfield(L, -2, "special_attack");
|
||||||
|
|
||||||
|
Lua_Mob l_mob(init);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -210,6 +210,16 @@ void handle_npc_despawn_zone(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void handle_npc_damage(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
NPC* npc,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
// Player
|
// Player
|
||||||
void handle_player_say(
|
void handle_player_say(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
@@ -373,6 +383,15 @@ void handle_player_task_stage_complete(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void handle_player_task_accepted(
|
||||||
|
QuestInterface* parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any>* extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
void handle_player_task_update(
|
void handle_player_task_update(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
lua_State* L,
|
lua_State* L,
|
||||||
@@ -652,6 +671,23 @@ void handle_player_augment_remove(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void handle_player_damage(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_player_item_click(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
// Item
|
// Item
|
||||||
void handle_item_click(
|
void handle_item_click(
|
||||||
@@ -955,5 +991,25 @@ void handle_bot_payload(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void handle_bot_equip_item(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_damage(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ public:
|
|||||||
bool UseDiscipline(int32 spell_id, int32 target);
|
bool UseDiscipline(int32 spell_id, int32 target);
|
||||||
|
|
||||||
virtual bool IsMerc() const { return true; }
|
virtual bool IsMerc() const { return true; }
|
||||||
|
bool IsOfClientBotMerc() const override { return true; }
|
||||||
|
|
||||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||||
static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false);
|
static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false);
|
||||||
|
|||||||
+18
-4
@@ -3063,16 +3063,30 @@ void Mob::SetAppearenceEffects(int32 slot, int32 value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::GetAppearenceEffects()
|
void Mob::ListAppearanceEffects(Client* c)
|
||||||
{
|
{
|
||||||
//used with GM command
|
|
||||||
if (!appearance_effects_id[0]) {
|
if (!appearance_effects_id[0]) {
|
||||||
Message(Chat::Red, "No Appearance Effects exist on this mob");
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} {} no appearance effects.",
|
||||||
|
c->GetTargetDescription(this, TargetDescriptionType::UCYou),
|
||||||
|
c == this ? "have" : "has"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAX_APPEARANCE_EFFECTS; i++) {
|
for (int i = 0; i < MAX_APPEARANCE_EFFECTS; i++) {
|
||||||
Message(Chat::Red, "ID: %i :: App Effect ID %i :: Slot %i", i, appearance_effects_id[i], appearance_effects_slot[i]);
|
c->Message(
|
||||||
|
Chat::Red,
|
||||||
|
fmt::format(
|
||||||
|
"Effect {} | ID: {} Slot: {}",
|
||||||
|
i,
|
||||||
|
appearance_effects_id[i],
|
||||||
|
appearance_effects_slot[i]
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -199,7 +199,7 @@ public:
|
|||||||
virtual void ThrowingAttack(Mob* other) { }
|
virtual void ThrowingAttack(Mob* other) { }
|
||||||
// 13 = Primary (default), 14 = secondary
|
// 13 = Primary (default), 14 = secondary
|
||||||
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
virtual bool Attack(Mob* other, int Hand = EQ::invslot::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
|
||||||
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0;
|
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr);
|
||||||
void DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr, bool FromRiposte = false);
|
void DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr, bool FromRiposte = false);
|
||||||
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
int MonkSpecialAttack(Mob* other, uint8 skill_used);
|
||||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||||
@@ -472,7 +472,7 @@ public:
|
|||||||
inline void SetEndurUpkeep(bool val) { endur_upkeep = val; }
|
inline void SetEndurUpkeep(bool val) { endur_upkeep = val; }
|
||||||
bool HasBuffWithSpellGroup(int spell_group);
|
bool HasBuffWithSpellGroup(int spell_group);
|
||||||
void SetAppearenceEffects(int32 slot, int32 value);
|
void SetAppearenceEffects(int32 slot, int32 value);
|
||||||
void GetAppearenceEffects();
|
void ListAppearanceEffects(Client* c);
|
||||||
void ClearAppearenceEffects();
|
void ClearAppearenceEffects();
|
||||||
void SendSavedAppearenceEffects(Client *receiver);
|
void SendSavedAppearenceEffects(Client *receiver);
|
||||||
void SetBuffDuration(int spell_id, int duration = 0);
|
void SetBuffDuration(int spell_id, int duration = 0);
|
||||||
@@ -657,7 +657,7 @@ public:
|
|||||||
inline int32 GetHeroicStrikethrough() const { return heroic_strikethrough; }
|
inline int32 GetHeroicStrikethrough() const { return heroic_strikethrough; }
|
||||||
inline const bool GetKeepsSoldItems() const { return keeps_sold_items; }
|
inline const bool GetKeepsSoldItems() const { return keeps_sold_items; }
|
||||||
inline void SetKeepsSoldItems(bool in_keeps_sold_items) { keeps_sold_items = in_keeps_sold_items; }
|
inline void SetKeepsSoldItems(bool in_keeps_sold_items) { keeps_sold_items = in_keeps_sold_items; }
|
||||||
|
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
|
||||||
void CopyHateList(Mob* to);
|
void CopyHateList(Mob* to);
|
||||||
|
|
||||||
//Group
|
//Group
|
||||||
@@ -1413,6 +1413,7 @@ public:
|
|||||||
void ResetAssistCap() { npc_assist_cap = 0; }
|
void ResetAssistCap() { npc_assist_cap = 0; }
|
||||||
int64 GetWeaponDamage(Mob *against, const EQ::ItemData *weapon_item);
|
int64 GetWeaponDamage(Mob *against, const EQ::ItemData *weapon_item);
|
||||||
int64 GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, int64 *hate = nullptr);
|
int64 GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, int64 *hate = nullptr);
|
||||||
|
int64 DoDamageCaps(int64 base_damage);
|
||||||
|
|
||||||
int64 GetHPRegen() const;
|
int64 GetHPRegen() const;
|
||||||
int64 GetManaRegen() const;
|
int64 GetManaRegen() const;
|
||||||
@@ -1450,6 +1451,8 @@ public:
|
|||||||
void SetManualFollow(bool flag) { m_manual_follow = flag; }
|
void SetManualFollow(bool flag) { m_manual_follow = flag; }
|
||||||
bool GetManualFollow() const { return m_manual_follow; }
|
bool GetManualFollow() const { return m_manual_follow; }
|
||||||
|
|
||||||
|
void DrawDebugCoordinateNode(std::string node_name, const glm::vec4 vec);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CommonDamage(Mob* other, int64 &damage, const uint16 spell_id, const EQ::skills::SkillType attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks specal = eSpecialAttacks::None);
|
void CommonDamage(Mob* other, int64 &damage, const uint16 spell_id, const EQ::skills::SkillType attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks specal = eSpecialAttacks::None);
|
||||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||||
|
|||||||
@@ -999,8 +999,14 @@ void Mob::AI_Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (door->GetTriggerDoorID() > 0) {
|
if (door->GetTriggerDoorID() > 0) {
|
||||||
|
auto trigger_door = entity_list.GetDoorsByDoorID(door->GetTriggerDoorID());
|
||||||
|
if (trigger_door) {
|
||||||
|
if (Strings::RemoveNumbers(door->GetDoorName()) !=
|
||||||
|
Strings::RemoveNumbers(trigger_door->GetDoorName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (door->GetDoorParam() > 0) {
|
if (door->GetDoorParam() > 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1053,6 +1053,13 @@ void MobMovementManager::FillCommandStruct(
|
|||||||
position_update->delta_z = FloatToEQ13(delta_z);
|
position_update->delta_z = FloatToEQ13(delta_z);
|
||||||
position_update->delta_heading = FloatToEQ10(delta_heading);
|
position_update->delta_heading = FloatToEQ10(delta_heading);
|
||||||
position_update->animation = (mob->IsBot() ? (int) ((float) anim / 1.785714f) : anim);
|
position_update->animation = (mob->IsBot() ? (int) ((float) anim / 1.785714f) : anim);
|
||||||
|
|
||||||
|
if (RuleB(Map, MobPathingVisualDebug)) {
|
||||||
|
mob->DrawDebugCoordinateNode(
|
||||||
|
fmt::format("{} position update", mob->GetCleanName()),
|
||||||
|
mob->GetPosition()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+34
-23
@@ -196,6 +196,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
WIS = npc_type_data->WIS;
|
WIS = npc_type_data->WIS;
|
||||||
CHA = npc_type_data->CHA;
|
CHA = npc_type_data->CHA;
|
||||||
npc_mana = npc_type_data->Mana;
|
npc_mana = npc_type_data->Mana;
|
||||||
|
m_is_underwater_only = npc_type_data->underwater;
|
||||||
|
|
||||||
//quick fix of ordering if they screwed it up in the DB
|
//quick fix of ordering if they screwed it up in the DB
|
||||||
if (max_dmg < min_dmg) {
|
if (max_dmg < min_dmg) {
|
||||||
@@ -371,12 +372,12 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ldon_trapped = false;
|
SetLDoNTrapped(false);
|
||||||
ldon_trap_type = 0;
|
SetLDoNTrapType(0);
|
||||||
ldon_spell_id = 0;
|
SetLDoNTrapSpellID(0);
|
||||||
ldon_locked = false;
|
SetLDoNLocked(false);
|
||||||
ldon_locked_skill = 0;
|
SetLDoNLockedSkill(0);
|
||||||
ldon_trap_detected = false;
|
SetLDoNTrapDetected(false);
|
||||||
|
|
||||||
if (npc_type_data->trap_template > 0) {
|
if (npc_type_data->trap_template > 0) {
|
||||||
std::map<uint32, std::list<LDoNTrapTemplate *> >::iterator trap_ent_iter;
|
std::map<uint32, std::list<LDoNTrapTemplate *> >::iterator trap_ent_iter;
|
||||||
@@ -390,26 +391,25 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
|||||||
std::advance(trap_list_iter, zone->random.Int(0, trap_list.size() - 1));
|
std::advance(trap_list_iter, zone->random.Int(0, trap_list.size() - 1));
|
||||||
LDoNTrapTemplate *trap_template = (*trap_list_iter);
|
LDoNTrapTemplate *trap_template = (*trap_list_iter);
|
||||||
if (trap_template) {
|
if (trap_template) {
|
||||||
if ((uint8) trap_template->spell_id > 0) {
|
if (trap_template->spell_id > 0) {
|
||||||
ldon_trapped = true;
|
SetLDoNTrapped(true);
|
||||||
ldon_spell_id = trap_template->spell_id;
|
SetLDoNTrapSpellID(trap_template->spell_id);
|
||||||
}
|
} else {
|
||||||
else {
|
SetLDoNTrapped(false);
|
||||||
ldon_trapped = false;
|
SetLDoNTrapSpellID(0);
|
||||||
ldon_spell_id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ldon_trap_type = (uint8) trap_template->type;
|
SetLDoNTrapType(static_cast<uint8>(trap_template->type));
|
||||||
|
|
||||||
if (trap_template->locked > 0) {
|
if (trap_template->locked > 0) {
|
||||||
ldon_locked = true;
|
SetLDoNLocked(true);
|
||||||
ldon_locked_skill = trap_template->skill;
|
SetLDoNLockedSkill(trap_template->skill);
|
||||||
}
|
} else {
|
||||||
else {
|
SetLDoNLocked(false);
|
||||||
ldon_locked = false;
|
SetLDoNLockedSkill(0);
|
||||||
ldon_locked_skill = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ldon_trap_detected = 0;
|
SetLDoNTrapDetected(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3692,7 +3692,7 @@ void NPC::ReloadSpells() {
|
|||||||
AI_AddNPCSpellsEffects(GetNPCSpellsEffectsID());
|
AI_AddNPCSpellsEffects(GetNPCSpellsEffectsID());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::ScaleNPC(uint8 npc_level) {
|
void NPC::ScaleNPC(uint8 npc_level, bool always_scale, bool override_special_abilities) {
|
||||||
if (GetLevel() != npc_level) {
|
if (GetLevel() != npc_level) {
|
||||||
SetLevel(npc_level);
|
SetLevel(npc_level);
|
||||||
RecalculateSkills();
|
RecalculateSkills();
|
||||||
@@ -3700,7 +3700,7 @@ void NPC::ScaleNPC(uint8 npc_level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
npc_scale_manager->ResetNPCScaling(this);
|
npc_scale_manager->ResetNPCScaling(this);
|
||||||
npc_scale_manager->ScaleNPC(this);
|
npc_scale_manager->ScaleNPC(this, always_scale, override_special_abilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPC::IsGuard()
|
bool NPC::IsGuard()
|
||||||
@@ -3784,3 +3784,14 @@ int NPC::GetRolledItemCount(uint32 item_id)
|
|||||||
|
|
||||||
return rolled_count;
|
return rolled_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NPC::SendPositionToClients()
|
||||||
|
{
|
||||||
|
auto p = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||||
|
auto *s = (PlayerPositionUpdateServer_Struct *) p->pBuffer;
|
||||||
|
for (auto &c: entity_list.GetClientList()) {
|
||||||
|
MakeSpawnUpdate(s);
|
||||||
|
c.second->QueuePacket(p, false);
|
||||||
|
}
|
||||||
|
safe_delete(p);
|
||||||
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user