mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 13:16:39 +00:00
Compare commits
178 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 703862d977 | |||
| 6e325c1ee3 | |||
| 933b83add6 | |||
| b3cd4e63f1 | |||
| 3c894cb533 | |||
| b19ad64800 | |||
| 2cd3d27c67 | |||
| d3b46becd0 | |||
| 286479198f | |||
| 21ec832ca6 | |||
| bdf5f8b4a3 | |||
| 4ca6485398 | |||
| 0c9c2e25c1 | |||
| 7e651877c7 | |||
| 9739c1c8ef | |||
| 8aae59eebe | |||
| c1b07afae9 | |||
| 9c238cd08d | |||
| 33adb9bcc1 | |||
| 2e8bf82861 | |||
| 4d118ab978 | |||
| fcb40daaf1 | |||
| 553bafdbe1 | |||
| d0443db199 | |||
| 9206163190 | |||
| e504482b94 | |||
| 77b88e3dec | |||
| aeeb350068 | |||
| df83113cea | |||
| 940abfaf7a | |||
| a46443b95e | |||
| 871f320311 | |||
| a222128599 | |||
| 45b249e33d | |||
| c24834de5d | |||
| 841d7f2700 | |||
| 56c29154f0 | |||
| 6466c2ff21 | |||
| 16dc210cd8 | |||
| 77045f558e | |||
| e1fa2d5bc5 | |||
| b03f52de18 | |||
| 226cc3d6cb | |||
| 7f54e26dec | |||
| 11a81d8e8a | |||
| e719aa43cf | |||
| 22994e3264 | |||
| cfbdecad19 | |||
| 2427f7e034 | |||
| 9a6403b196 | |||
| d8953c5156 | |||
| 33b40e83b7 | |||
| e75c31d524 | |||
| cf1f8d5460 | |||
| 690cacdaab | |||
| f9f45eedcd | |||
| 93ddffa57f | |||
| c9993fb698 | |||
| aa0fbb8b45 | |||
| 62532c6bdd | |||
| f8c3c03185 | |||
| 692a90f3f0 | |||
| 3a49d851ca | |||
| fdc5c27061 | |||
| 56be69ddb1 | |||
| 9477ff72ac | |||
| 6d8e80b1e5 | |||
| ebeaef598b | |||
| 60b65da7f2 | |||
| 100e6698ea | |||
| 2bd94ab7a2 | |||
| 4c8d68c24b | |||
| 1755678b1f | |||
| 39e2763968 | |||
| f7780b0247 | |||
| c0fe0f11f7 | |||
| a1f1f11940 | |||
| 4c5013e09e | |||
| 838ffbd8c7 | |||
| 42b41d973c | |||
| e7761133a9 | |||
| 93f2bea96e | |||
| ded82ac6d6 | |||
| 6ef182edfd | |||
| e466ca1c6d | |||
| fa5a3155fe | |||
| a20d333f9d | |||
| 853739b538 | |||
| 6094ec9c7b | |||
| 9da1d6b397 | |||
| 8ea7299a57 | |||
| 0811a899d1 | |||
| fad9599642 | |||
| 62711b13d8 | |||
| 2702485206 | |||
| 0aadb891a1 | |||
| d812310c5b | |||
| 1420983700 | |||
| d25cc35f1b | |||
| ed7f395612 | |||
| 8dceb20dd8 | |||
| 6929d180ca | |||
| 011a66a75e | |||
| 07120563a2 | |||
| cc985cbcd5 | |||
| 97caa79472 | |||
| cfa575c756 | |||
| 85063249b4 | |||
| 04d6f8feea | |||
| dfc1bf0381 | |||
| 2237c3a056 | |||
| 4af191c593 | |||
| 0a3972deb9 | |||
| 9d2f258390 | |||
| 0b452f4ec1 | |||
| fef629e1df | |||
| a5a51fbe44 | |||
| 47db92cdb6 | |||
| 690301e80d | |||
| 1887e48b76 | |||
| af2691eb12 | |||
| 2df4289588 | |||
| 49d4d0acc3 | |||
| 5a663910a5 | |||
| b027edd21e | |||
| 0bbfcf7adc | |||
| 7962a0bd38 | |||
| 4d9b51df0a | |||
| 508ecec6ea | |||
| f0c6fa2a26 | |||
| ad6dbb7beb | |||
| 6ddbb41617 | |||
| 8a558f6a29 | |||
| 0585be0360 | |||
| 6927baef7f | |||
| 52d64781b5 | |||
| 0667fe435f | |||
| 9959070f24 | |||
| 2a91f08845 | |||
| adc64005f1 | |||
| 605480f1c4 | |||
| 3b95601c62 | |||
| a4f2ed28f1 | |||
| e19b969541 | |||
| 4241556f75 | |||
| 961332b40c | |||
| a1a861e0c4 | |||
| 4bbb1aa92f | |||
| 1212ccefef | |||
| c203fec9b4 | |||
| 16ab1839e8 | |||
| f5e4c6a127 | |||
| 166c87c931 | |||
| 345dd442dd | |||
| 565baec675 | |||
| 9884c442e9 | |||
| ad0b5d6a1c | |||
| b82b32e1d2 | |||
| 2fb72e5729 | |||
| 3791bc788f | |||
| 833fa55fdf | |||
| 4fc3c27715 | |||
| cea3ad6a42 | |||
| d8926cd5f3 | |||
| efb03164c7 | |||
| 455eb2e6d9 | |||
| b5b0e53da2 | |||
| 68cb94b39c | |||
| 3d95b6c184 | |||
| 7db7631308 | |||
| f053cd3b56 | |||
| cf27f2bc88 | |||
| 79918ebaba | |||
| 2a648507f2 | |||
| f395ee0508 | |||
| 7166fcc650 | |||
| ae8e58ddc5 | |||
| 26e72c6857 |
+1
-1
@@ -15,7 +15,7 @@ volumes:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Build Linux X64
|
- name: Build Linux X64
|
||||||
image: akkadius/eqemu-server:v11
|
image: akkadius/eqemu-server:v14
|
||||||
environment:
|
environment:
|
||||||
GITHUB_TOKEN:
|
GITHUB_TOKEN:
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||||
|
|||||||
+451
@@ -1,3 +1,454 @@
|
|||||||
|
## [22.37.0] - 12/18/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add ScanCloseMobs support to fix AEs ([#3786](https://github.com/EQEmu/Server/pull/3786)) @nytmyr 2023-12-18
|
||||||
|
* Expand ^itemuse options ([#3756](https://github.com/EQEmu/Server/pull/3756)) @nytmyr 2023-12-17
|
||||||
|
* Fix ^defensive from checking aggressive disciplines. ([#3787](https://github.com/EQEmu/Server/pull/3787)) @nytmyr 2023-12-18
|
||||||
|
* Fix ^oo autodefend from sending bots/pets to invalid haters ([#3772](https://github.com/EQEmu/Server/pull/3772)) @nytmyr 2023-12-16
|
||||||
|
* Fix unnecessary failed to save timer error ([#3788](https://github.com/EQEmu/Server/pull/3788)) @nytmyr 2023-12-18
|
||||||
|
* [Quest API] Add ^clickitem, ^timer, fix GetBestBotSpellForCure ([#3755](https://github.com/EQEmu/Server/pull/3755)) @nytmyr 2023-12-17
|
||||||
|
|
||||||
|
### CI
|
||||||
|
|
||||||
|
* Switch to use clang for Linux builds (speed) ([#3777](https://github.com/EQEmu/Server/pull/3777)) @Akkadius 2023-12-17
|
||||||
|
|
||||||
|
### Compilation
|
||||||
|
|
||||||
|
* Use pre-compiled headers for Windows (speed) ([#3778](https://github.com/EQEmu/Server/pull/3778)) @Akkadius 2023-12-18
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Drop Invisibility when hit by traps ([#3785](https://github.com/EQEmu/Server/pull/3785)) @Kinglykrab 2023-12-18
|
||||||
|
* Fix NPCs routing to 0.0, 0.0 on #summon ([#3780](https://github.com/EQEmu/Server/pull/3780)) @Kinglykrab 2023-12-18
|
||||||
|
* Fix bad merge @Akkadius 2023-12-17
|
||||||
|
* Fix issue with HOTBonusHealingSplitOverDuration Rule ([#3776](https://github.com/EQEmu/Server/pull/3776)) @Kinglykrab 2023-12-17
|
||||||
|
* Fixed the discrepacy with time using command #time and in quests. ([#3767](https://github.com/EQEmu/Server/pull/3767)) @regneq 2023-12-17
|
||||||
|
* Send Entity ID in Death Events to resolve #3721 ([#3779](https://github.com/EQEmu/Server/pull/3779)) @Kinglykrab 2023-12-18
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add EVENT_ALT_CURRENCY_GAIN and EVENT_ALT_CURRENCY_LOSS to Perl/Lua ([#3734](https://github.com/EQEmu/Server/pull/3734)) @Kinglykrab 2023-12-17
|
||||||
|
* Add EVENT_CRYSTAL_GAIN and EVENT_CRYSTAL_LOSS to Perl/Lua ([#3735](https://github.com/EQEmu/Server/pull/3735)) @Kinglykrab 2023-12-17
|
||||||
|
* Add EVENT_LDON_POINTS_GAIN and EVENT_LDON_POINTS_LOSS to Perl/Lua ([#3742](https://github.com/EQEmu/Server/pull/3742)) @Kinglykrab 2023-12-17
|
||||||
|
* Add EVENT_LEVEL_UP and EVENT_LEVEL_DOWN to Bots ([#3750](https://github.com/EQEmu/Server/pull/3750)) @Kinglykrab 2023-12-17
|
||||||
|
* Add EVENT_LOOT_ADDED to Perl/Lua ([#3739](https://github.com/EQEmu/Server/pull/3739)) @Kinglykrab 2023-12-17
|
||||||
|
* Add GetNPCAggro() and SetNPCAggro() to Perl/Lua ([#3781](https://github.com/EQEmu/Server/pull/3781)) @Kinglykrab 2023-12-18
|
||||||
|
|
||||||
|
## [22.36.0] - 12/16/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add rule to toggle DT hitting owner ([#3757](https://github.com/EQEmu/Server/pull/3757)) @nytmyr 2023-12-11
|
||||||
|
* Enable auto-saving of bots. ([#3758](https://github.com/EQEmu/Server/pull/3758)) @nytmyr 2023-12-13
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Cleanup classes.cpp/classes.h ([#3752](https://github.com/EQEmu/Server/pull/3752)) @Kinglykrab 2023-12-13
|
||||||
|
|
||||||
|
### Corpse
|
||||||
|
|
||||||
|
* Fix /corpse command regression from #3727 ([#3770](https://github.com/EQEmu/Server/pull/3770)) @Akkadius 2023-12-16
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Make it clearer to users that a database backup is occurring ([#3769](https://github.com/EQEmu/Server/pull/3769)) @Akkadius 2023-12-16
|
||||||
|
* When database version is greater than binary, we are up to date ([#3771](https://github.com/EQEmu/Server/pull/3771)) @Akkadius 2023-12-16
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix Starting Items SQL ([#3766](https://github.com/EQEmu/Server/pull/3766)) @Kinglykrab 2023-12-16
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
* Change empty object loading to warning ([#3759](https://github.com/EQEmu/Server/pull/3759)) @nytmyr 2023-12-11
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add DOT and HOT Rules ([#3760](https://github.com/EQEmu/Server/pull/3760)) @Kinglykrab 2023-12-16
|
||||||
|
|
||||||
|
## [22.35.0] - 12/10/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add BotHealOnLevel to fully heal/mana on level. ([#3745](https://github.com/EQEmu/Server/pull/3745)) @nytmyr 2023-12-08
|
||||||
|
* Fix bots learning spells on level ([#3744](https://github.com/EQEmu/Server/pull/3744)) @nytmyr 2023-12-08
|
||||||
|
|
||||||
|
### Bug
|
||||||
|
|
||||||
|
* Fix blocked spells regression from #3638 ([#3753](https://github.com/EQEmu/Server/pull/3753)) @joligario 2023-12-11
|
||||||
|
* PR 3638 Missed the blocked spells repository updates ([#3748](https://github.com/EQEmu/Server/pull/3748)) @fryguy503 2023-12-08
|
||||||
|
|
||||||
|
### CMake
|
||||||
|
|
||||||
|
* Update minimum version of CMake ([#3743](https://github.com/EQEmu/Server/pull/3743)) @joligario 2023-12-08
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Remove hard-coded Status Checks ([#3727](https://github.com/EQEmu/Server/pull/3727)) @Kinglykrab 2023-12-03
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* #guild set CharName 0 did not remove char from guild. ([#3717](https://github.com/EQEmu/Server/pull/3717)) @noudess 2023-11-25
|
||||||
|
* #petname changes PC to Nobody if selected. ([#3720](https://github.com/EQEmu/Server/pull/3720)) @noudess 2023-11-26
|
||||||
|
* Add #show aas Command ([#3710](https://github.com/EQEmu/Server/pull/3710)) @Kinglykrab 2023-11-26
|
||||||
|
* Add #task complete Command ([#3711](https://github.com/EQEmu/Server/pull/3711)) @Kinglykrab 2023-11-26
|
||||||
|
* Cleanup #acceptrules Command ([#3716](https://github.com/EQEmu/Server/pull/3716)) @Kinglykrab 2023-11-26
|
||||||
|
* Cleanup #disarmtrap Command ([#3713](https://github.com/EQEmu/Server/pull/3713)) @Kinglykrab 2023-11-26
|
||||||
|
* Cleanup #list Command ([#3714](https://github.com/EQEmu/Server/pull/3714)) @Kinglykrab 2023-11-26
|
||||||
|
* Cleanup #movement Command ([#3715](https://github.com/EQEmu/Server/pull/3715)) @Kinglykrab 2023-11-26
|
||||||
|
* Cleanup #object Command ([#3722](https://github.com/EQEmu/Server/pull/3722)) @Kinglykrab 2023-12-03
|
||||||
|
* Cleanup #zonebootup and #zoneshutdown Commands ([#3729](https://github.com/EQEmu/Server/pull/3729)) @Kinglykrab 2023-12-03
|
||||||
|
* Fix formatting of #wpinfo output. ([#3728](https://github.com/EQEmu/Server/pull/3728)) @noudess 2023-12-01
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Add primary key to keyring table ([#3746](https://github.com/EQEmu/Server/pull/3746)) @Kinglykrab 2023-12-08
|
||||||
|
* Consolidate Starting Items Table ([#3723](https://github.com/EQEmu/Server/pull/3723)) @Kinglykrab 2023-11-30
|
||||||
|
* Extra whitespace in #3723 ([#3730](https://github.com/EQEmu/Server/pull/3730)) @joligario 2023-12-02
|
||||||
|
* Minor adjustment to #3726 ([#3732](https://github.com/EQEmu/Server/pull/3732)) @joligario 2023-12-03
|
||||||
|
* Modify `updated` column in `items` table with proper default. ([#3726](https://github.com/EQEmu/Server/pull/3726)) @joligario 2023-12-02
|
||||||
|
* Pull Spell Group Cache from Content DB ([#3749](https://github.com/EQEmu/Server/pull/3749)) @fryguy503 2023-12-08
|
||||||
|
|
||||||
|
### Faction
|
||||||
|
|
||||||
|
* Alliance line is only allowed 1 faction change at a time. ([#3718](https://github.com/EQEmu/Server/pull/3718)) @noudess 2023-11-26
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Changing Group Leader Invalidated GetLeaderName() ([#3712](https://github.com/EQEmu/Server/pull/3712)) @Kinglykrab 2023-11-26
|
||||||
|
* Fix 9245 SQL ([#3740](https://github.com/EQEmu/Server/pull/3740)) @Kinglykrab 2023-12-05
|
||||||
|
* Fix Swarm Pets Requiring NPC Aggros Flag ([#3738](https://github.com/EQEmu/Server/pull/3738)) @Kinglykrab 2023-12-05
|
||||||
|
* Guild Message Limits ([#3724](https://github.com/EQEmu/Server/pull/3724)) @neckkola 2023-11-29
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add EVENT_AA_GAIN to AddAAPoints() ([#3733](https://github.com/EQEmu/Server/pull/3733)) @Kinglykrab 2023-12-03
|
||||||
|
* Add GMMove Overloads to Perl/Lua ([#3719](https://github.com/EQEmu/Server/pull/3719)) @Kinglykrab 2023-11-25
|
||||||
|
|
||||||
|
### Scripts
|
||||||
|
|
||||||
|
* Import items into `items_new` table instead of writing directly to the existing `items` table. ([#3725](https://github.com/EQEmu/Server/pull/3725)) @joligario 2023-11-30
|
||||||
|
* Revert database engine change from #3702. ([#3736](https://github.com/EQEmu/Server/pull/3736)) @joligario 2023-12-03
|
||||||
|
* Update 13th Floor Import Tool ([#3702](https://github.com/EQEmu/Server/pull/3702)) @joligario 2023-11-26
|
||||||
|
|
||||||
|
## [22.34.2] - 11/23/2023
|
||||||
|
|
||||||
|
### Admin
|
||||||
|
|
||||||
|
* Update date in changelog ([#3698](https://github.com/EQEmu/Server/pull/3698)) @joligario 2023-11-19
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Fix typo in #giveitem ([#3704](https://github.com/EQEmu/Server/pull/3704)) @Kinglykrab 2023-11-22
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add "IgnoreLevelBasedHasteCaps" rule to GetHaste() ([#3705](https://github.com/EQEmu/Server/pull/3705)) @jcr4990 2023-11-23
|
||||||
|
* Fix bots/Mercenaries being removed from hatelist ([#3708](https://github.com/EQEmu/Server/pull/3708)) @Kinglykrab 2023-11-23
|
||||||
|
* Fix some spell types failing IsValidSpellRange check ([#3707](https://github.com/EQEmu/Server/pull/3707)) @nytmyr 2023-11-23
|
||||||
|
|
||||||
|
### Loginserver
|
||||||
|
|
||||||
|
* Update ticket login table structure ([#3703](https://github.com/EQEmu/Server/pull/3703)) @KimLS 2023-11-22
|
||||||
|
|
||||||
|
## [22.34.1] - 11/20/2023
|
||||||
|
|
||||||
|
### EQTime
|
||||||
|
|
||||||
|
Hotfix for world not spamming save messages by setting to detail level logging @Akkadius 2023-11-20
|
||||||
|
|
||||||
|
## [22.34.0] - 11/19/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Add ownerraid, byclass and byrace actionables and fix group-based arguments for raids. ([#3680](https://github.com/EQEmu/Server/pull/3680)) @nytmyr 2023-11-19
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Cleanup #giveitem and #summonitem ([#3692](https://github.com/EQEmu/Server/pull/3692)) @Kinglykrab 2023-11-19
|
||||||
|
* Cleanup #show currencies Command ([#3693](https://github.com/EQEmu/Server/pull/3693)) @Kinglykrab 2023-11-19
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add #show aa_points Command ([#3695](https://github.com/EQEmu/Server/pull/3695)) @Kinglykrab 2023-11-19
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Pull pet power from content database ([#3689](https://github.com/EQEmu/Server/pull/3689)) @joligario 2023-11-18
|
||||||
|
|
||||||
|
### GM Commands
|
||||||
|
|
||||||
|
* Add `#takeplatinum` ([#3690](https://github.com/EQEmu/Server/pull/3690)) @joligario 2023-11-19
|
||||||
|
* Remove duplicate comment ([#3691](https://github.com/EQEmu/Server/pull/3691)) @joligario 2023-11-19
|
||||||
|
|
||||||
|
### Illusions
|
||||||
|
|
||||||
|
* RandomizeFeastures erased texture. ([#3686](https://github.com/EQEmu/Server/pull/3686)) @noudess 2023-11-12
|
||||||
|
|
||||||
|
### Spawn
|
||||||
|
|
||||||
|
* (imported from takp) Added min_time and max_time to spawnentry. This will prevent a NPC from… ([#3685](https://github.com/EQEmu/Server/pull/3685)) @regneq 2023-11-18
|
||||||
|
|
||||||
|
## [22.33.0] - 11/11/2023
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Comment to Item Data/Quest API ([#3669](https://github.com/EQEmu/Server/pull/3669)) @Kinglykrab 2023-11-07
|
||||||
|
|
||||||
|
### Spawn2
|
||||||
|
|
||||||
|
* Fix edge case with instances not copying disabled spawn state ([#3688](https://github.com/EQEmu/Server/pull/3688)) @Akkadius 2023-11-12
|
||||||
|
|
||||||
|
## [22.32.1] - 11/6/2023
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Adjust spawn2_disabled migration to copy data over
|
||||||
|
|
||||||
|
## [22.32.0] - 11/6/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Fix invalid races from being created ([#3681](https://github.com/EQEmu/Server/pull/3681)) @nytmyr 2023-11-06
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash on CentOS when forming a raid with PCs or BOTs ([#3676](https://github.com/EQEmu/Server/pull/3676)) @neckkola 2023-11-06
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add IsTGBCompatibleSpell() to package.add ([#3675](https://github.com/EQEmu/Server/pull/3675)) @Kinglykrab 2023-11-04
|
||||||
|
* Fix Perl__worldwideremovetask package ([#3670](https://github.com/EQEmu/Server/pull/3670)) @Kinglykrab 2023-11-04
|
||||||
|
* Revert " Fix Killed XYZH support in EVENT_DEATH in Perl. " (#3682) ([#3591](https://github.com/EQEmu/Server/pull/3591)) @fryguy503 2023-11-06
|
||||||
|
CRASH
|
||||||
|
|
||||||
|
### GCC
|
||||||
|
|
||||||
|
* Compatibility fix for GCC 13 ([#3677](https://github.com/EQEmu/Server/pull/3677)) @joligario 2023-11-05
|
||||||
|
|
||||||
|
### Parser
|
||||||
|
|
||||||
|
* Cleanup Spire Parsing for crosszonemoveplayerbycharid ([#3674](https://github.com/EQEmu/Server/pull/3674)) @Kinglykrab 2023-11-04
|
||||||
|
* Cleanup Spire Parsing for crosszonemoveplayerbyexpeditionid ([#3671](https://github.com/EQEmu/Server/pull/3671)) @Kinglykrab 2023-11-04
|
||||||
|
* Cleanup Spire Parsing for crosszonemoveplayerbygroupid ([#3673](https://github.com/EQEmu/Server/pull/3673)) @Kinglykrab 2023-11-04
|
||||||
|
* Cleanup Spire Parsing for crosszonemoveplayerbyguildid ([#3672](https://github.com/EQEmu/Server/pull/3672)) @Kinglykrab 2023-11-04
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add GetBaseRaceName() to Perl and Lua ([#3668](https://github.com/EQEmu/Server/pull/3668)) @joligario 2023-11-01
|
||||||
|
* Add details to Lua event dispatch errors ([#3679](https://github.com/EQEmu/Server/pull/3679)) @hgtw 2023-11-06
|
||||||
|
|
||||||
|
### Spawn
|
||||||
|
|
||||||
|
* Split spawn2 enabled into its own state table ([#3664](https://github.com/EQEmu/Server/pull/3664)) @Akkadius 2023-11-06
|
||||||
|
|
||||||
|
### Spells
|
||||||
|
|
||||||
|
* Added IsNightTime() for Dance of the Fireflies ([#3667](https://github.com/EQEmu/Server/pull/3667)) @regneq 2023-11-04
|
||||||
|
|
||||||
|
## [22.31.3] - 10/31/2023
|
||||||
|
|
||||||
|
### Bug
|
||||||
|
|
||||||
|
* Force raids off content database ([#3665](https://github.com/EQEmu/Server/pull/3665)) @joligario 2023-10-31
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Revert " Fix spell in AESpell related to beacons " ([#3659](https://github.com/EQEmu/Server/pull/3659)) @Akkadius 2023-10-31
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix issue with blocked spells not loading properly @Akkadius 2023-10-31
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
* Convert Loot Messages to Error Logs ([#3663](https://github.com/EQEmu/Server/pull/3663)) @Kinglykrab 2023-10-31
|
||||||
|
|
||||||
|
## [22.31.2] - 10/31/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Hotfix issue with beacon spells crashing @Akkadius 2023-10-31
|
||||||
|
|
||||||
|
## [22.31.1] - 10/31/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Hotfix issue with blocked spells not loading properly @Akkadius 2023-10-31
|
||||||
|
|
||||||
|
## [22.31.0] - 10/29/2023
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash when client pointer does not exist during #hotfix ([#3661](https://github.com/EQEmu/Server/pull/3661)) @Akkadius 2023-10-29
|
||||||
|
* Fix spell in AESpell related to beacons ([#3659](https://github.com/EQEmu/Server/pull/3659)) @Akkadius 2023-10-29
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Add id to variables table ([#3658](https://github.com/EQEmu/Server/pull/3658)) @Akkadius 2023-10-29
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
* Add symbols to release builds ([#3660](https://github.com/EQEmu/Server/pull/3660)) @Akkadius 2023-10-29
|
||||||
|
|
||||||
|
### Perl
|
||||||
|
|
||||||
|
* Revert " Reload perl quests on zone bootup " ([#3648](https://github.com/EQEmu/Server/pull/3648)) @Akkadius 2023-10-26
|
||||||
|
|
||||||
|
### Trading
|
||||||
|
|
||||||
|
* Fix part 3 of Issue 932. ([#3654](https://github.com/EQEmu/Server/pull/3654)) @noudess 2023-10-29
|
||||||
|
|
||||||
|
## [22.30.2] - 10/26/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Revert Perl regression in #3648 causing scripts to not reliably initialize on zone bootup. @Akkadius 2023-10-26
|
||||||
|
|
||||||
|
## [22.30.1] - 10/24/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix empty InsertMany in bot starting items. ([#3653](https://github.com/EQEmu/Server/pull/3653)) @Kinglykrab 2023-10-24
|
||||||
|
|
||||||
|
## [22.30.0] - 10/23/2023
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
* Implement Zone Sidecar ([#3635](https://github.com/EQEmu/Server/pull/3635)) @Akkadius 2023-10-24
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Move #suspend from content database ([#3651](https://github.com/EQEmu/Server/pull/3651)) @joligario 2023-10-24
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix Bot Starting Items SQL ([#3649](https://github.com/EQEmu/Server/pull/3649)) @Kinglykrab 2023-10-23
|
||||||
|
|
||||||
|
### Perl
|
||||||
|
|
||||||
|
* Implement eqemu-perl for Linux ([#3652](https://github.com/EQEmu/Server/pull/3652)) @Akkadius 2023-10-24
|
||||||
|
* Reload perl quests on zone bootup ([#3648](https://github.com/EQEmu/Server/pull/3648)) @hgtw 2023-10-24
|
||||||
|
|
||||||
|
### Pets
|
||||||
|
|
||||||
|
* Disallow effect of alliance line when cast on pets. ([#3650](https://github.com/EQEmu/Server/pull/3650)) @noudess 2023-10-24
|
||||||
|
|
||||||
|
## [22.29.1] - 10/21/2023
|
||||||
|
|
||||||
|
### DB
|
||||||
|
|
||||||
|
* Fix manifest for blocked spells ([#3646](https://github.com/EQEmu/Server/pull/3646)) @joligario 2023-10-21
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix issue with subcommand settings not working ([#3643](https://github.com/EQEmu/Server/pull/3643)) @Kinglykrab 2023-10-21
|
||||||
|
* Hotfix command without hotfix name ([#3644](https://github.com/EQEmu/Server/pull/3644)) @joligario 2023-10-21
|
||||||
|
* Verifying mail keys when none exist ([#3645](https://github.com/EQEmu/Server/pull/3645)) @joligario 2023-10-21
|
||||||
|
|
||||||
|
## [22.29.0] - 10/20/2023
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Expansion and Content Flag support to Blocked Spells ([#3638](https://github.com/EQEmu/Server/pull/3638)) @Kinglykrab 2023-10-20
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix crash when checking Bot Group/Raid membership ([#3641](https://github.com/EQEmu/Server/pull/3641)) @Aeadoin 2023-10-20
|
||||||
|
|
||||||
|
### Perl
|
||||||
|
|
||||||
|
* Static linker fix on Linux ([#3642](https://github.com/EQEmu/Server/pull/3642)) @Akkadius 2023-10-20
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Add rule to configure max number of procs per round Combat:MaxProcs ([#3640](https://github.com/EQEmu/Server/pull/3640)) @Akkadius 2023-10-20
|
||||||
|
|
||||||
|
## [22.28.1] - 10/20/2023
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
* Perl Linux build fix
|
||||||
|
|
||||||
|
## [22.28.0] - 10/15/2023
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Adjust Bot Movement Speed ([#3615](https://github.com/EQEmu/Server/pull/3615)) @Kinglykrab 2023-10-14
|
||||||
|
* Fix bot removal on zone, regression from #3611 ([#3631](https://github.com/EQEmu/Server/pull/3631)) @Akkadius 2023-10-16
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix Crash with #summon ([#3618](https://github.com/EQEmu/Server/pull/3618)) @Kinglykrab 2023-10-14
|
||||||
|
* Fix crash in Mob::ShowBuffs ([#3632](https://github.com/EQEmu/Server/pull/3632)) @Akkadius 2023-10-16
|
||||||
|
* Resolve crash when assigning empty raid note. ([#3628](https://github.com/EQEmu/Server/pull/3628)) @Aeadoin 2023-10-15
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Add Extra Kick Classes ([#3613](https://github.com/EQEmu/Server/pull/3613)) @Kinglykrab 2023-10-11
|
||||||
|
* Add Immune to Assassinate Special Ability ([#3622](https://github.com/EQEmu/Server/pull/3622)) @Kinglykrab 2023-10-14
|
||||||
|
* Add Immune to Headshot Special Ability ([#3624](https://github.com/EQEmu/Server/pull/3624)) @Kinglykrab 2023-10-14
|
||||||
|
* Update Raid Functions for Titanium and Underfoot ([#3524](https://github.com/EQEmu/Server/pull/3524)) @neckkola 2023-10-14
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix #cast defaulting to cast time ([#3617](https://github.com/EQEmu/Server/pull/3617)) @Kinglykrab 2023-10-14
|
||||||
|
|
||||||
|
### Parser Fix
|
||||||
|
|
||||||
|
* Fix SendIllusion Spire parsing ([#3623](https://github.com/EQEmu/Server/pull/3623)) @Kinglykrab 2023-10-14
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add GrantAllAAPoints() to Perl/Lua and Modify #grantaa ([#3616](https://github.com/EQEmu/Server/pull/3616)) @Kinglykrab 2023-10-14
|
||||||
|
* Add target ID and spell exports to events ([#3620](https://github.com/EQEmu/Server/pull/3620)) @Kinglykrab 2023-10-15
|
||||||
|
|
||||||
|
### Scripts
|
||||||
|
|
||||||
|
* Update 13th Floor importer ([#3630](https://github.com/EQEmu/Server/pull/3630)) @joligario 2023-10-16
|
||||||
|
* Update 13th Floor script for legacy research tome bagtypes ([#3621](https://github.com/EQEmu/Server/pull/3621)) @joligario 2023-10-14
|
||||||
|
|
||||||
|
## [22.27.0] - 10/07/2023
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Bot member zoned crash fix ([#3607](https://github.com/EQEmu/Server/pull/3607)) @Akkadius 2023-10-07
|
||||||
|
* Fix #summon crash ([#3608](https://github.com/EQEmu/Server/pull/3608)) @Akkadius 2023-10-07
|
||||||
|
* Fix CanUseAlternateAdvancementRank crash ([#3609](https://github.com/EQEmu/Server/pull/3609)) @Akkadius 2023-10-07
|
||||||
|
* Fix crash in #movechar ([#3612](https://github.com/EQEmu/Server/pull/3612)) @Akkadius 2023-10-07
|
||||||
|
* Fix crash in CastSpell Quest API input cast ([#3610](https://github.com/EQEmu/Server/pull/3610)) @Akkadius 2023-10-07
|
||||||
|
* Fix dangling pointer crash observed in SendHPPacketsFrom ([#3611](https://github.com/EQEmu/Server/pull/3611)) @Akkadius 2023-10-07
|
||||||
|
* Fix rarer crash with File::Makedir ([#3606](https://github.com/EQEmu/Server/pull/3606)) @Akkadius 2023-10-07
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add Validation to #find, #set, and #show args ([#3598](https://github.com/EQEmu/Server/pull/3598)) @Kinglykrab 2023-09-18
|
||||||
|
* Ensure Linux builds report failures @Akkadius 2023-10-03
|
||||||
|
* Fix #show group_info Popup ([#3605](https://github.com/EQEmu/Server/pull/3605)) @Kinglykrab 2023-10-04
|
||||||
|
* Fix swarm pet names to use '_' instead of ' ' ([#3601](https://github.com/EQEmu/Server/pull/3601)) @noudess 2023-09-19
|
||||||
|
* Invis vs. Undead/Animal Breaks Charm for Pets ([#3587](https://github.com/EQEmu/Server/pull/3587)) @crdunwel 2023-09-19
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
* Change pathing log messages from Error to Pathing. ([#3604](https://github.com/EQEmu/Server/pull/3604)) @joligario 2023-09-29
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add Caster ID Parameter to FindBuff in Perl/Lua ([#3590](https://github.com/EQEmu/Server/pull/3590)) @Kinglykrab 2023-09-29
|
||||||
|
|
||||||
|
## [22.26.2] - 09/18/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix an issue with schema versioning for the AA update
|
||||||
|
|
||||||
|
## [22.26.1] - 09/17/2023
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add Validation to #find, #set, and #show args ([#3598](https://github.com/EQEmu/Server/pull/3598)) @Kinglykrab 2023-09-17
|
||||||
|
|
||||||
## [22.26.0] - 09/17/2023
|
## [22.26.0] - 09/17/2023
|
||||||
|
|
||||||
### Bug
|
### Bug
|
||||||
|
|||||||
@@ -17,12 +17,18 @@ SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
||||||
|
OPTION(EQEMU_BUILD_PCH "Build with precompiled headers (Windows)" ON)
|
||||||
|
|
||||||
IF (EQEMU_BUILD_STATIC)
|
IF (EQEMU_BUILD_STATIC)
|
||||||
SET(BUILD_SHARED_LIBS OFF)
|
SET(BUILD_SHARED_LIBS OFF)
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
|
||||||
MESSAGE(STATUS "Building with static linking")
|
MESSAGE(STATUS "Building with static linking")
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
||||||
|
IF (UNIX)
|
||||||
|
SET(PERL_LIBRARY "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/libperl.so")
|
||||||
|
SET(PERL_INCLUDE_PATH "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/")
|
||||||
|
SET(PERL_EXECUTABLE "/opt/eqemu-perl/bin/perl")
|
||||||
|
ENDIF ()
|
||||||
ENDIF (EQEMU_BUILD_STATIC)
|
ENDIF (EQEMU_BUILD_STATIC)
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
@@ -133,6 +139,13 @@ ELSE()
|
|||||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
MESSAGE(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
|
||||||
|
MESSAGE(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
|
||||||
|
MESSAGE(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
|
||||||
|
MESSAGE(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
|
||||||
|
MESSAGE(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
|
||||||
|
MESSAGE(STATUS "PERL_VERSION: ${PERL_VERSION}")
|
||||||
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
MESSAGE(STATUS "**************************************************")
|
||||||
|
|
||||||
#options
|
#options
|
||||||
@@ -389,6 +402,9 @@ IF(PERL_LIBRARY_ENABLED)
|
|||||||
ADD_DEFINITIONS(-DEMBPERL)
|
ADD_DEFINITIONS(-DEMBPERL)
|
||||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||||
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
|
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
|
||||||
|
IF (UNIX AND EQEMU_BUILD_STATIC)
|
||||||
|
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
|
||||||
|
ENDIF ()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||||
|
|
||||||
add_subdirectory(import)
|
add_subdirectory(import)
|
||||||
add_subdirectory(export)
|
add_subdirectory(export)
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ SET(common_sources
|
|||||||
perl_eqdb.cpp
|
perl_eqdb.cpp
|
||||||
perl_eqdb_res.cpp
|
perl_eqdb_res.cpp
|
||||||
process/process.cpp
|
process/process.cpp
|
||||||
|
process.cpp
|
||||||
proc_launcher.cpp
|
proc_launcher.cpp
|
||||||
profanity_manager.cpp
|
profanity_manager.cpp
|
||||||
ptimer.cpp
|
ptimer.cpp
|
||||||
@@ -90,6 +91,7 @@ SET(common_sources
|
|||||||
timer.cpp
|
timer.cpp
|
||||||
unix.cpp
|
unix.cpp
|
||||||
platform.cpp
|
platform.cpp
|
||||||
|
json/json.hpp
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
zone_store.cpp
|
zone_store.cpp
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
@@ -583,12 +585,14 @@ SET(common_headers
|
|||||||
path_manager.cpp
|
path_manager.cpp
|
||||||
platform.h
|
platform.h
|
||||||
process/process.h
|
process/process.h
|
||||||
|
process.h
|
||||||
proc_launcher.h
|
proc_launcher.h
|
||||||
profanity_manager.h
|
profanity_manager.h
|
||||||
profiler.h
|
profiler.h
|
||||||
ptimer.h
|
ptimer.h
|
||||||
queue.h
|
queue.h
|
||||||
races.h
|
races.h
|
||||||
|
raid.h
|
||||||
random.h
|
random.h
|
||||||
rdtsc.h
|
rdtsc.h
|
||||||
rulesys.h
|
rulesys.h
|
||||||
@@ -788,5 +792,8 @@ IF (UNIX)
|
|||||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
||||||
ENDIF (UNIX)
|
ENDIF (UNIX)
|
||||||
|
|
||||||
|
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||||
|
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||||
|
|||||||
+288
-465
File diff suppressed because it is too large
Load Diff
+96
-93
@@ -19,99 +19,106 @@
|
|||||||
#define CLASSES_CH
|
#define CLASSES_CH
|
||||||
|
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
|
#include "../common/rulesys.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#define NO_CLASS 0
|
namespace Class {
|
||||||
#define WARRIOR 1
|
constexpr uint8 None = 0;
|
||||||
#define CLERIC 2
|
constexpr uint8 Warrior = 1;
|
||||||
#define PALADIN 3
|
constexpr uint8 Cleric = 2;
|
||||||
#define RANGER 4
|
constexpr uint8 Paladin = 3;
|
||||||
#define SHADOWKNIGHT 5
|
constexpr uint8 Ranger = 4;
|
||||||
#define DRUID 6
|
constexpr uint8 ShadowKnight = 5;
|
||||||
#define MONK 7
|
constexpr uint8 Druid = 6;
|
||||||
#define BARD 8
|
constexpr uint8 Monk = 7;
|
||||||
#define ROGUE 9
|
constexpr uint8 Bard = 8;
|
||||||
#define SHAMAN 10
|
constexpr uint8 Rogue = 9;
|
||||||
#define NECROMANCER 11
|
constexpr uint8 Shaman = 10;
|
||||||
#define WIZARD 12
|
constexpr uint8 Necromancer = 11;
|
||||||
#define MAGICIAN 13
|
constexpr uint8 Wizard = 12;
|
||||||
#define ENCHANTER 14
|
constexpr uint8 Magician = 13;
|
||||||
#define BEASTLORD 15
|
constexpr uint8 Enchanter = 14;
|
||||||
#define BERSERKER 16
|
constexpr uint8 Beastlord = 15;
|
||||||
#define WARRIORGM 20
|
constexpr uint8 Berserker = 16;
|
||||||
#define CLERICGM 21
|
constexpr uint8 WarriorGM = 20;
|
||||||
#define PALADINGM 22
|
constexpr uint8 ClericGM = 21;
|
||||||
#define RANGERGM 23
|
constexpr uint8 PaladinGM = 22;
|
||||||
#define SHADOWKNIGHTGM 24
|
constexpr uint8 RangerGM = 23;
|
||||||
#define DRUIDGM 25
|
constexpr uint8 ShadowKnightGM = 24;
|
||||||
#define MONKGM 26
|
constexpr uint8 DruidGM = 25;
|
||||||
#define BARDGM 27
|
constexpr uint8 MonkGM = 26;
|
||||||
#define ROGUEGM 28
|
constexpr uint8 BardGM = 27;
|
||||||
#define SHAMANGM 29
|
constexpr uint8 RogueGM = 28;
|
||||||
#define NECROMANCERGM 30
|
constexpr uint8 ShamanGM = 29;
|
||||||
#define WIZARDGM 31
|
constexpr uint8 NecromancerGM = 30;
|
||||||
#define MAGICIANGM 32
|
constexpr uint8 WizardGM = 31;
|
||||||
#define ENCHANTERGM 33
|
constexpr uint8 MagicianGM = 32;
|
||||||
#define BEASTLORDGM 34
|
constexpr uint8 EnchanterGM = 33;
|
||||||
#define BERSERKERGM 35
|
constexpr uint8 BeastlordGM = 34;
|
||||||
#define BANKER 40
|
constexpr uint8 BerserkerGM = 35;
|
||||||
#define MERCHANT 41
|
constexpr uint8 Banker = 40;
|
||||||
#define DISCORD_MERCHANT 59
|
constexpr uint8 Merchant = 41;
|
||||||
#define ADVENTURE_RECRUITER 60
|
constexpr uint8 DiscordMerchant = 59;
|
||||||
#define ADVENTURE_MERCHANT 61
|
constexpr uint8 AdventureRecruiter = 60;
|
||||||
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
|
constexpr uint8 AdventureMerchant = 61;
|
||||||
#define TRIBUTE_MASTER 63
|
constexpr uint8 LDoNTreasure = 62;
|
||||||
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
constexpr uint8 TributeMaster = 63;
|
||||||
#define GUILD_BANKER 66
|
constexpr uint8 GuildTributeMaster = 64;
|
||||||
#define NORRATHS_KEEPERS_MERCHANT 67
|
constexpr uint8 GuildBanker = 66;
|
||||||
#define DARK_REIGN_MERCHANT 68
|
constexpr uint8 NorrathsKeepersMerchant = 67;
|
||||||
#define FELLOWSHIP_MASTER 69
|
constexpr uint8 DarkReignMerchant = 68;
|
||||||
#define ALT_CURRENCY_MERCHANT 70
|
constexpr uint8 FellowshipMaster = 69;
|
||||||
#define MERCENARY_MASTER 71
|
constexpr uint8 AlternateCurrencyMerchant = 70;
|
||||||
|
constexpr uint8 MercenaryLiaison = 71;
|
||||||
|
|
||||||
|
constexpr uint8 PLAYER_CLASS_COUNT = 16;
|
||||||
|
constexpr uint16 ALL_CLASSES_BITMASK = 65535;
|
||||||
|
};
|
||||||
|
|
||||||
// player class values
|
static std::map<uint8, uint16> player_class_bitmasks = {
|
||||||
#define PLAYER_CLASS_UNKNOWN 0
|
{Class::Warrior, 1},
|
||||||
#define PLAYER_CLASS_WARRIOR 1
|
{Class::Cleric, 2},
|
||||||
#define PLAYER_CLASS_CLERIC 2
|
{Class::Paladin, 4},
|
||||||
#define PLAYER_CLASS_PALADIN 3
|
{Class::Ranger, 8},
|
||||||
#define PLAYER_CLASS_RANGER 4
|
{Class::ShadowKnight, 16},
|
||||||
#define PLAYER_CLASS_SHADOWKNIGHT 5
|
{Class::Druid, 32},
|
||||||
#define PLAYER_CLASS_DRUID 6
|
{Class::Monk, 64},
|
||||||
#define PLAYER_CLASS_MONK 7
|
{Class::Bard, 128},
|
||||||
#define PLAYER_CLASS_BARD 8
|
{Class::Rogue, 256},
|
||||||
#define PLAYER_CLASS_ROGUE 9
|
{Class::Shaman, 512},
|
||||||
#define PLAYER_CLASS_SHAMAN 10
|
{Class::Necromancer, 1024},
|
||||||
#define PLAYER_CLASS_NECROMANCER 11
|
{Class::Wizard, 2048},
|
||||||
#define PLAYER_CLASS_WIZARD 12
|
{Class::Magician, 4096},
|
||||||
#define PLAYER_CLASS_MAGICIAN 13
|
{Class::Enchanter, 8192},
|
||||||
#define PLAYER_CLASS_ENCHANTER 14
|
{Class::Beastlord, 16384},
|
||||||
#define PLAYER_CLASS_BEASTLORD 15
|
{Class::Berserker, 32768},
|
||||||
#define PLAYER_CLASS_BERSERKER 16
|
};
|
||||||
|
|
||||||
#define PLAYER_CLASS_COUNT 16
|
static std::string shadow_knight_class_name = (
|
||||||
|
RuleB(World, UseOldShadowKnightClassExport) ?
|
||||||
|
"Shadowknight" :
|
||||||
|
"Shadow Knight"
|
||||||
|
);
|
||||||
|
|
||||||
|
static std::map<uint8, std::string> class_names = {
|
||||||
// player class bits
|
{Class::Warrior, "Warrior"},
|
||||||
#define PLAYER_CLASS_UNKNOWN_BIT 0
|
{Class::Cleric, "Cleric"},
|
||||||
#define PLAYER_CLASS_WARRIOR_BIT 1
|
{Class::Paladin, "Paladin"},
|
||||||
#define PLAYER_CLASS_CLERIC_BIT 2
|
{Class::Ranger, "Ranger"},
|
||||||
#define PLAYER_CLASS_PALADIN_BIT 4
|
{Class::ShadowKnight, shadow_knight_class_name},
|
||||||
#define PLAYER_CLASS_RANGER_BIT 8
|
{Class::Druid, "Druid"},
|
||||||
#define PLAYER_CLASS_SHADOWKNIGHT_BIT 16
|
{Class::Monk, "Monk"},
|
||||||
#define PLAYER_CLASS_DRUID_BIT 32
|
{Class::Bard, "Bard"},
|
||||||
#define PLAYER_CLASS_MONK_BIT 64
|
{Class::Rogue, "Rogue"},
|
||||||
#define PLAYER_CLASS_BARD_BIT 128
|
{Class::Shaman, "Shaman"},
|
||||||
#define PLAYER_CLASS_ROGUE_BIT 256
|
{Class::Necromancer, "Necromancer"},
|
||||||
#define PLAYER_CLASS_SHAMAN_BIT 512
|
{Class::Wizard, "Wizard"},
|
||||||
#define PLAYER_CLASS_NECROMANCER_BIT 1024
|
{Class::Magician, "Magician"},
|
||||||
#define PLAYER_CLASS_WIZARD_BIT 2048
|
{Class::Enchanter, "Enchanter"},
|
||||||
#define PLAYER_CLASS_MAGICIAN_BIT 4096
|
{Class::Beastlord, "Beastlord"},
|
||||||
#define PLAYER_CLASS_ENCHANTER_BIT 8192
|
{Class::Berserker, "Berserker"},
|
||||||
#define PLAYER_CLASS_BEASTLORD_BIT 16384
|
};
|
||||||
#define PLAYER_CLASS_BERSERKER_BIT 32768
|
|
||||||
|
|
||||||
#define PLAYER_CLASS_ALL_MASK 65535 // was 65536
|
|
||||||
|
|
||||||
|
|
||||||
#define ARMOR_TYPE_UNKNOWN 0
|
#define ARMOR_TYPE_UNKNOWN 0
|
||||||
@@ -126,16 +133,12 @@
|
|||||||
|
|
||||||
|
|
||||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||||
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
|
||||||
|
|
||||||
bool IsPlayerClass(uint8 class_id);
|
bool IsPlayerClass(uint8 class_id);
|
||||||
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
||||||
|
|
||||||
uint32 GetPlayerClassValue(uint8 class_id);
|
uint8 GetPlayerClassValue(uint8 class_id);
|
||||||
uint32 GetPlayerClassBit(uint8 class_id);
|
uint16 GetPlayerClassBit(uint8 class_id);
|
||||||
|
|
||||||
uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value);
|
|
||||||
uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
|
|
||||||
|
|
||||||
bool IsFighterClass(uint8 class_id);
|
bool IsFighterClass(uint8 class_id);
|
||||||
bool IsSpellFighterClass(uint8 class_id);
|
bool IsSpellFighterClass(uint8 class_id);
|
||||||
|
|||||||
@@ -124,14 +124,6 @@ namespace EQEmuCommand {
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::string description;
|
std::string description;
|
||||||
bool ran_command = false;
|
|
||||||
for (auto &it: in_function_map) {
|
|
||||||
if (it.first == argv[1]) {
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
|
||||||
ran_command = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd[{"-h", "--help"}]) {
|
if (cmd[{"-h", "--help"}]) {
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout <<
|
std::cout <<
|
||||||
@@ -142,9 +134,7 @@ namespace EQEmuCommand {
|
|||||||
<< std::endl
|
<< std::endl
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
/**
|
// Get max command length for padding length
|
||||||
* Get max command length for padding length
|
|
||||||
*/
|
|
||||||
int max_command_length = 0;
|
int max_command_length = 0;
|
||||||
|
|
||||||
for (auto &it: in_function_map) {
|
for (auto &it: in_function_map) {
|
||||||
@@ -155,18 +145,14 @@ namespace EQEmuCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Display command menu
|
||||||
* Display command menu
|
|
||||||
*/
|
|
||||||
std::string command_section;
|
std::string command_section;
|
||||||
for (auto &it: in_function_map) {
|
for (auto &it: in_function_map) {
|
||||||
description.clear();
|
description.clear();
|
||||||
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
(it.second)(argc, argv, cmd, description);
|
||||||
|
|
||||||
/**
|
// Print section header
|
||||||
* Print section header
|
|
||||||
*/
|
|
||||||
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
||||||
|
|
||||||
if (command_prefix.find("test") != std::string::npos) {
|
if (command_prefix.find("test") != std::string::npos) {
|
||||||
@@ -178,9 +164,7 @@ namespace EQEmuCommand {
|
|||||||
std::cout << termcolor::reset << command_prefix << std::endl;
|
std::cout << termcolor::reset << command_prefix << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Print commands
|
||||||
* Print commands
|
|
||||||
*/
|
|
||||||
std::stringstream command;
|
std::stringstream command;
|
||||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||||
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
||||||
@@ -191,6 +175,15 @@ namespace EQEmuCommand {
|
|||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ran_command = false;
|
||||||
|
|
||||||
|
for (auto &it: in_function_map) {
|
||||||
|
if (it.first == argv[1]) {
|
||||||
|
(it.second)(argc, argv, cmd, description);
|
||||||
|
ran_command = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ran_command) {
|
if (ran_command) {
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-32
@@ -29,6 +29,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../common/repositories/account_repository.h"
|
||||||
|
|
||||||
// Disgrace: for windows compile
|
// Disgrace: for windows compile
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -1643,25 +1645,20 @@ void Database::ClearGroupLeader(uint32 gid) {
|
|||||||
std::cout << "Unable to clear group leader: " << results.ErrorMessage() << std::endl;
|
std::cout << "Unable to clear group leader: " << results.ErrorMessage() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Database::GetAgreementFlag(uint32 acctid) {
|
uint8 Database::GetAgreementFlag(uint32 account_id)
|
||||||
|
{
|
||||||
std::string query = StringFormat("SELECT rulesflag FROM account WHERE id=%i",acctid);
|
const auto& e = AccountRepository::FindOne(*this, account_id);
|
||||||
auto results = QueryDatabase(query);
|
if (!e.id) {
|
||||||
|
|
||||||
if (!results.Success())
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (results.RowCount() != 1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
|
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetAgreementFlag(uint32 acctid) {
|
return e.rulesflag;
|
||||||
std::string query = StringFormat("UPDATE account SET rulesflag=1 where id=%i", acctid);
|
}
|
||||||
QueryDatabase(query);
|
|
||||||
|
void Database::SetAgreementFlag(uint32 account_id) {
|
||||||
|
auto e = AccountRepository::FindOne(*this, account_id);
|
||||||
|
e.rulesflag = 1;
|
||||||
|
AccountRepository::UpdateOne(*this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::ClearRaid(uint32 rid) {
|
void Database::ClearRaid(uint32 rid) {
|
||||||
@@ -2097,37 +2094,45 @@ void Database::ClearInvSnapshots(bool from_now) {
|
|||||||
|
|
||||||
struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
||||||
{
|
{
|
||||||
|
TimeOfDay_Struct t{};
|
||||||
TimeOfDay_Struct eqTime;
|
|
||||||
std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1");
|
std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1");
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success() || results.RowCount() == 0) {
|
if (!results.Success() || results.RowCount() == 0) {
|
||||||
LogInfo("Loading EQ time of day failed. Using defaults");
|
LogInfo("Loading EQ time of day failed. Using defaults");
|
||||||
eqTime.minute = 0;
|
t.minute = 0;
|
||||||
eqTime.hour = 9;
|
t.hour = 9;
|
||||||
eqTime.day = 1;
|
t.day = 1;
|
||||||
eqTime.month = 1;
|
t.month = 1;
|
||||||
eqTime.year = 3100;
|
t.year = 3100;
|
||||||
realtime = time(nullptr);
|
realtime = time(nullptr);
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
eqTime.minute = Strings::ToUnsignedInt(row[0]);
|
uint8 hour = Strings::ToUnsignedInt(row[1]);
|
||||||
eqTime.hour = Strings::ToUnsignedInt(row[1]);
|
time_t realtime_ = Strings::ToBigInt(row[5]);
|
||||||
eqTime.day = Strings::ToUnsignedInt(row[2]);
|
if (RuleI(World, BootHour) > 0 && RuleI(World, BootHour) <= 24) {
|
||||||
eqTime.month = Strings::ToUnsignedInt(row[3]);
|
hour = RuleI(World, BootHour);
|
||||||
eqTime.year = Strings::ToUnsignedInt(row[4]);
|
realtime_ = time(nullptr);
|
||||||
realtime = Strings::ToBigInt(row[5]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return eqTime;
|
t.minute = Strings::ToUnsignedInt(row[0]);
|
||||||
|
t.hour = hour;
|
||||||
|
t.day = Strings::ToUnsignedInt(row[2]);
|
||||||
|
t.month = Strings::ToUnsignedInt(row[3]);
|
||||||
|
t.year = Strings::ToUnsignedInt(row[4]);
|
||||||
|
realtime = realtime_;
|
||||||
|
|
||||||
|
LogEqTime("Setting hour to [{}]", hour);
|
||||||
|
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year)
|
bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year)
|
||||||
{
|
{
|
||||||
std::string query = StringFormat("UPDATE eqtime set minute = %d, hour = %d, day = %d, month = %d, year = %d, realtime = %d limit 1", minute, hour, day, month, year, time(0));
|
std::string query = StringFormat("UPDATE eqtime set minute = %d, hour = %d, day = %d, month = %d, year = %d, realtime = %d limit 1", minute, hour, day, month, year, time(nullptr));
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
return results.Success();
|
return results.Success();
|
||||||
|
|||||||
+2
-2
@@ -188,10 +188,10 @@ public:
|
|||||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
||||||
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
||||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||||
uint8 GetAgreementFlag(uint32 acctid);
|
uint8 GetAgreementFlag(uint32 account_id);
|
||||||
|
|
||||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||||
void SetAgreementFlag(uint32 acctid);
|
void SetAgreementFlag(uint32 account_id);
|
||||||
|
|
||||||
int GetIPExemption(std::string account_ip);
|
int GetIPExemption(std::string account_ip);
|
||||||
void SetIPExemption(std::string account_ip, int exemption_amount);
|
void SetIPExemption(std::string account_ip, int exemption_amount);
|
||||||
|
|||||||
@@ -322,6 +322,10 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
pipe_file
|
pipe_file
|
||||||
);
|
);
|
||||||
|
|
||||||
|
LogInfo("Backing up database [{}]", execute_command);
|
||||||
|
LogInfo("This can take a few minutes depending on the size of your database");
|
||||||
|
LogInfo("LOADING... PLEASE WAIT...");
|
||||||
|
|
||||||
BuildCredentialsFile();
|
BuildCredentialsFile();
|
||||||
std::string execution_result = Process::execute(execute_command);
|
std::string execution_result = Process::execute(execute_command);
|
||||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
||||||
|
|||||||
@@ -274,9 +274,9 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
|||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
// server database version is required
|
// server database version is required
|
||||||
bool server_up_to_date = v.server_database_version == b.server_database_version;
|
bool server_up_to_date = v.server_database_version >= b.server_database_version;
|
||||||
// bots database version is optional, if not enabled then it is always up-to-date
|
// bots database version is optional, if not enabled then it is always up-to-date
|
||||||
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version == b.bots_database_version : true;
|
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version >= b.bots_database_version : true;
|
||||||
|
|
||||||
return server_up_to_date && bots_up_to_date;
|
return server_up_to_date && bots_up_to_date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4943,6 +4943,198 @@ ALTER TABLE `aa_ability` ADD COLUMN `auto_grant_enabled` TINYINT(4) NOT NULL DEF
|
|||||||
UPDATE `aa_ability` SET `auto_grant_enabled` = 1 WHERE `grant_only` = 0 AND `charges` = 0 AND `category` = -1;
|
UPDATE `aa_ability` SET `auto_grant_enabled` = 1 WHERE `grant_only` = 0 AND `charges` = 0 AND `category` = -1;
|
||||||
)"
|
)"
|
||||||
},
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9237,
|
||||||
|
.description = "2023_10_15_import_13th_floor.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `items` LIKE 'bardeffect';",
|
||||||
|
.condition = "contains",
|
||||||
|
.match = "mediumint",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `items`
|
||||||
|
MODIFY COLUMN `scriptfileid` MEDIUMINT(6) NOT NULL DEFAULT 0,
|
||||||
|
MODIFY COLUMN `powersourcecapacity` MEDIUMINT(7) NOT NULL DEFAULT 0,
|
||||||
|
MODIFY COLUMN `augdistiller` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
MODIFY COLUMN `scrollunk1` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
MODIFY COLUMN `bardeffect` MEDIUMINT(6) NOT NULL DEFAULT 0;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9238,
|
||||||
|
.description = "2023_10_18_tradeskill_add_learned_by_item_id.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `tradeskill_recipe` LIKE 'learned_by_item_id'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `tradeskill_recipe`
|
||||||
|
ADD COLUMN `learned_by_item_id` int(11) NOT NULL DEFAULT 0 AFTER `must_learn`;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9239,
|
||||||
|
.description = "2023_10_18_blocked_spells_expansions_content_flags.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `blocked_spells` LIKE 'min_expansion'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `blocked_spells`
|
||||||
|
ADD COLUMN `min_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `description`,
|
||||||
|
ADD COLUMN `max_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `min_expansion`,
|
||||||
|
ADD COLUMN `content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `max_expansion`,
|
||||||
|
ADD COLUMN `content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `content_flags`;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9240,
|
||||||
|
.description = "2023_10_29_variables_id.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `variables` LIKE 'id'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `variables`
|
||||||
|
ADD COLUMN `id` int(11) NOT NULL AUTO_INCREMENT FIRST,
|
||||||
|
DROP PRIMARY KEY,
|
||||||
|
ADD PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
ADD UNIQUE INDEX(`varname`);
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9241,
|
||||||
|
.description = "2023_10_29_split_spawn2_enabled.sql",
|
||||||
|
.check = "SHOW TABLES LIKE 'spawn2_disabled'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
CREATE TABLE `spawn2_backup_2023_10_29` LIKE `spawn2`;
|
||||||
|
INSERT INTO `spawn2_backup_2023_10_29` SELECT * FROM `spawn2`;
|
||||||
|
CREATE TABLE `spawn2_disabled` (
|
||||||
|
`id` bigint(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`spawn2_id` int(11) DEFAULT NULL,
|
||||||
|
`instance_id` int(11) DEFAULT 0,
|
||||||
|
`disabled` smallint(11) DEFAULT 0,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `spawn2_id` (`spawn2_id`,`instance_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||||
|
INSERT INTO spawn2_disabled (spawn2_id, disabled) SELECT id, 1 FROM spawn2 WHERE enabled = 0;
|
||||||
|
ALTER TABLE `spawn2` DROP COLUMN `enabled`;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9242,
|
||||||
|
.description = "2023_11_7_mintime_maxtime_spawnentry.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `spawnentry` LIKE 'min_time'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `spawnentry`
|
||||||
|
ADD COLUMN `min_time` smallint(4) NOT NULL DEFAULT 0 AFTER `condition_value_filter`,
|
||||||
|
ADD COLUMN `max_time` smallint(4) NOT NULL DEFAULT 0 AFTER `min_time`;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9243,
|
||||||
|
.description = "2023_11_27_starting_items_revamp.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `starting_items` LIKE 'race_list'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
CREATE TABLE `starting_items_backup_9243` LIKE `starting_items`;
|
||||||
|
INSERT INTO `starting_items_backup_9243` SELECT * FROM `starting_items`;
|
||||||
|
|
||||||
|
CREATE TABLE `starting_items_new` (
|
||||||
|
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`race_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
`class_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
`deity_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
`zone_id_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
|
||||||
|
`gm` mediumint(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`slot` mediumint(9) NOT NULL DEFAULT -1,
|
||||||
|
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||||
|
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||||
|
`content_flags` varchar(100) NULL,
|
||||||
|
`content_flags_disabled` varchar(100) NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO
|
||||||
|
`starting_items_new`
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
0 AS `id`,
|
||||||
|
GROUP_CONCAT(DISTINCT `class` ORDER BY class ASC SEPARATOR '|') AS `class_list`,
|
||||||
|
GROUP_CONCAT(DISTINCT `race` ORDER BY race ASC SEPARATOR '|') AS `race_list`,
|
||||||
|
GROUP_CONCAT(DISTINCT `deityid` ORDER BY deityid ASC SEPARATOR '|') AS `deity_list`,
|
||||||
|
GROUP_CONCAT(DISTINCT `zoneid` ORDER BY zoneid ASC SEPARATOR '|') AS `zone_list`,
|
||||||
|
`itemid`,
|
||||||
|
`item_charges`,
|
||||||
|
`gm`,
|
||||||
|
`slot`,
|
||||||
|
`min_expansion`,
|
||||||
|
`max_expansion`,
|
||||||
|
`content_flags`,
|
||||||
|
`content_flags_disabled`
|
||||||
|
FROM
|
||||||
|
`starting_items`
|
||||||
|
GROUP BY
|
||||||
|
`itemid`
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TABLE `starting_items`;
|
||||||
|
RENAME TABLE `starting_items_new` TO `starting_items`;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9244,
|
||||||
|
.description = "2023_11_30_items_table_schema.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `items` LIKE 'updated'",
|
||||||
|
.condition = "contains",
|
||||||
|
.match = "0000-00-00 00:00:00",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `items` MODIFY COLUMN `updated` datetime NULL DEFAULT NULL;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9245,
|
||||||
|
.description = "2023_12_03_object_incline.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `object` LIKE 'incline'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `object` CHANGE COLUMN `unknown08` `size_percentage` float NOT NULL DEFAULT 0 AFTER `icon`;
|
||||||
|
ALTER TABLE `object` CHANGE COLUMN `unknown10` `solid_type` mediumint(5) NOT NULL DEFAULT 0 AFTER `size`;
|
||||||
|
ALTER TABLE `object` CHANGE COLUMN `unknown20` `incline` int(11) NOT NULL DEFAULT 0 AFTER `solid_type`;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9246,
|
||||||
|
.description = "2023_12_07_keyring_id.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `keyring` LIKE 'id'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `keyring`
|
||||||
|
ADD COLUMN `id` int UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||||
|
ADD PRIMARY KEY (`id`);
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9247,
|
||||||
|
.description = "2023_12_14_starting_items_fix.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `starting_items` LIKE 'inventory_slot'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `starting_items`
|
||||||
|
CHANGE COLUMN `race_list` `temporary` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `id`,
|
||||||
|
CHANGE COLUMN `class_list` `race_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `temporary`,
|
||||||
|
CHANGE COLUMN `gm` `status` mediumint(3) NOT NULL DEFAULT 0 AFTER `item_charges`,
|
||||||
|
CHANGE COLUMN `slot` `inventory_slot` mediumint(9) NOT NULL DEFAULT -1 AFTER `status`;
|
||||||
|
|
||||||
|
ALTER TABLE `starting_items`
|
||||||
|
CHANGE COLUMN `temporary` `class_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `id`;
|
||||||
|
)"
|
||||||
|
}
|
||||||
|
|
||||||
// -- template; copy/paste this when you need to create a new entry
|
// -- template; copy/paste this when you need to create a new entry
|
||||||
// ManifestEntry{
|
// ManifestEntry{
|
||||||
|
|||||||
@@ -61,6 +61,51 @@ DROP TABLE IF EXISTS `bot_group_members`;
|
|||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
)",
|
)",
|
||||||
},
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9040,
|
||||||
|
.description = "2023_11_16_bot_starting_items.sql",
|
||||||
|
.check = "SHOW TABLES LIKE 'bot_starting_items'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
CREATE TABLE `bot_starting_items` (
|
||||||
|
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`races` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`classes` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
|
||||||
|
`min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
`slot_id` mediumint(9) NOT NULL DEFAULT -1,
|
||||||
|
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||||
|
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||||
|
`content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
`content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
|
||||||
|
)",
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9041,
|
||||||
|
.description = "2023_12_04_bot_timers.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `bot_timers` LIKE 'recast_time'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `bot_timers`
|
||||||
|
ADD COLUMN `recast_time` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `timer_value`,
|
||||||
|
ADD COLUMN `is_spell` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `recast_time`,
|
||||||
|
ADD COLUMN `is_disc` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `is_spell`,
|
||||||
|
ADD COLUMN `spell_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `is_disc`,
|
||||||
|
ADD COLUMN `is_item` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `spell_id`,
|
||||||
|
ADD COLUMN `item_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `is_item`;
|
||||||
|
ALTER TABLE `bot_timers`
|
||||||
|
DROP FOREIGN KEY `FK_bot_timers_1`;
|
||||||
|
ALTER TABLE `bot_timers`
|
||||||
|
DROP PRIMARY KEY;
|
||||||
|
ALTER TABLE `bot_timers`
|
||||||
|
ADD PRIMARY KEY (`bot_id`, `timer_id`, `spell_id`, `item_id`);
|
||||||
|
)"
|
||||||
|
}
|
||||||
// -- template; copy/paste this when you need to create a new entry
|
// -- template; copy/paste this when you need to create a new entry
|
||||||
// ManifestEntry{
|
// ManifestEntry{
|
||||||
// .version = 9228,
|
// .version = 9228,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../common/repositories/raid_members_repository.h"
|
#include "../common/repositories/raid_members_repository.h"
|
||||||
#include "../common/repositories/respawn_times_repository.h"
|
#include "../common/repositories/respawn_times_repository.h"
|
||||||
#include "../common/repositories/spawn_condition_values_repository.h"
|
#include "../common/repositories/spawn_condition_values_repository.h"
|
||||||
|
#include "repositories/spawn2_disabled_repository.h"
|
||||||
|
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
@@ -49,6 +50,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
||||||
{
|
{
|
||||||
auto e = InstanceListPlayerRepository::NewEntity();
|
auto e = InstanceListPlayerRepository::NewEntity();
|
||||||
@@ -553,6 +555,7 @@ void Database::PurgeExpiredInstances()
|
|||||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
||||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||||
|
Spawn2DisabledRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||||
|
|||||||
@@ -345,6 +345,7 @@ namespace DatabaseSchema {
|
|||||||
"respawn_times",
|
"respawn_times",
|
||||||
"saylink",
|
"saylink",
|
||||||
"server_scheduled_events",
|
"server_scheduled_events",
|
||||||
|
"spawn2_disabled",
|
||||||
"player_event_log_settings",
|
"player_event_log_settings",
|
||||||
"player_event_logs",
|
"player_event_logs",
|
||||||
"shared_task_activity_state",
|
"shared_task_activity_state",
|
||||||
|
|||||||
@@ -1052,4 +1052,27 @@ enum ScribeSpellActions
|
|||||||
Unmemorize
|
Unmemorize
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SpellTimeRestrictions
|
||||||
|
{
|
||||||
|
NoRestriction,
|
||||||
|
Day,
|
||||||
|
Night
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MoneyTypes
|
||||||
|
{
|
||||||
|
Copper,
|
||||||
|
Silver,
|
||||||
|
Gold,
|
||||||
|
Platinum
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MoneySubtypes
|
||||||
|
{
|
||||||
|
Personal,
|
||||||
|
Bank,
|
||||||
|
Cursor,
|
||||||
|
SharedBank // Platinum Only
|
||||||
|
};
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
@@ -124,6 +124,12 @@ struct LDoNTrapTemplate
|
|||||||
uint8 locked;
|
uint8 locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CrystalReclaimTypes
|
||||||
|
{
|
||||||
|
Ebon = 5,
|
||||||
|
Radiant = 4,
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
@@ -2594,11 +2600,11 @@ struct BookButton_Struct
|
|||||||
struct Object_Struct {
|
struct Object_Struct {
|
||||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||||
/*08*/ float size; //
|
/*08*/ float size; //
|
||||||
/*10*/ uint16 solidtype; //
|
/*10*/ uint16 solid_type; //
|
||||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||||
/*18*/ uint16 zone_instance; //
|
/*18*/ uint16 zone_instance; //
|
||||||
/*20*/ uint32 unknown020; //
|
/*20*/ uint32 incline; //
|
||||||
/*24*/ uint32 unknown024; //
|
/*24*/ uint32 unknown024; //
|
||||||
/*28*/ float tilt_x;
|
/*28*/ float tilt_x;
|
||||||
/*32*/ float tilt_y;
|
/*32*/ float tilt_y;
|
||||||
@@ -4164,7 +4170,6 @@ struct RaidGeneral_Struct {
|
|||||||
/*68*/ uint32 unknown1;
|
/*68*/ uint32 unknown1;
|
||||||
/*72*/ char leader_name[64];
|
/*72*/ char leader_name[64];
|
||||||
/*136*/ uint32 parameter;
|
/*136*/ uint32 parameter;
|
||||||
/*200*/ char note[64];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidAddMember_Struct {
|
struct RaidAddMember_Struct {
|
||||||
@@ -4175,9 +4180,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general;
|
||||||
/*136*/ char motd[0]; // max size is 1024, but reply is variable
|
/*140*/ char motd[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::QuestErrors].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::QuestErrors].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::EqTime].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RFC 5424
|
* RFC 5424
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ namespace Logs {
|
|||||||
PlayerEvents,
|
PlayerEvents,
|
||||||
DataBuckets,
|
DataBuckets,
|
||||||
Zoning,
|
Zoning,
|
||||||
|
EqTime,
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -237,6 +238,7 @@ namespace Logs {
|
|||||||
"PlayerEvents",
|
"PlayerEvents",
|
||||||
"DataBuckets",
|
"DataBuckets",
|
||||||
"Zoning",
|
"Zoning",
|
||||||
|
"EqTime",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -814,6 +814,16 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LogEqTime(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::General, Logs::EqTime))\
|
||||||
|
OutF(LogSys, Logs::General, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogEqTimeDetail(message, ...) do {\
|
||||||
|
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EqTime))\
|
||||||
|
OutF(LogSys, Logs::Detail, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
|||||||
+51
-7
@@ -46,16 +46,16 @@ EQTime::EQTime()
|
|||||||
timezone = 0;
|
timezone = 0;
|
||||||
memset(&eqTime, 0, sizeof(eqTime));
|
memset(&eqTime, 0, sizeof(eqTime));
|
||||||
//Defaults for time
|
//Defaults for time
|
||||||
TimeOfDay_Struct start;
|
TimeOfDay_Struct t{};
|
||||||
start.day = 1;
|
t.day = 1;
|
||||||
start.hour = 9;
|
t.hour = 9;
|
||||||
start.minute = 0;
|
t.minute = 0;
|
||||||
start.month = 1;
|
t.month = 1;
|
||||||
start.year = 3100;
|
t.year = 3100;
|
||||||
//Set default time zone
|
//Set default time zone
|
||||||
timezone = 0;
|
timezone = 0;
|
||||||
//Start EQTimer
|
//Start EQTimer
|
||||||
SetCurrentEQTimeOfDay(start, time(0));
|
SetCurrentEQTimeOfDay(t, time(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
||||||
@@ -200,3 +200,47 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
|||||||
buf[127] = '\0';
|
buf[127] = '\0';
|
||||||
str = buf;
|
str = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQTime::IsDayTime() {
|
||||||
|
TimeOfDay_Struct tod{}; //Day time is 5am to 6:59pm (14 hours in-game)
|
||||||
|
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||||
|
|
||||||
|
if (tod.hour >= 5 || tod.hour < 19) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQTime::IsNightTime() {
|
||||||
|
TimeOfDay_Struct tod{}; //Night time is 7pm to 4:59am (10 hours in-game)
|
||||||
|
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||||
|
|
||||||
|
if (tod.hour >= 19 || tod.hour < 5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQTime::IsInbetweenTime(uint8 min_time, uint8 max_time) {
|
||||||
|
TimeOfDay_Struct tod{};
|
||||||
|
GetCurrentEQTimeOfDay(&tod);
|
||||||
|
|
||||||
|
if (min_time == 0 || max_time == 0 || min_time > 24 || max_time > 24) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_time < min_time) {
|
||||||
|
if ((tod.hour >= min_time && tod.hour > max_time) || (tod.hour < min_time && tod.hour <= max_time)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (tod.hour >= min_time && tod.hour <= max_time) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ public:
|
|||||||
uint32 getEQTimeZone() { return timezone; }
|
uint32 getEQTimeZone() { return timezone; }
|
||||||
uint32 getEQTimeZoneHr() { return timezone/60; }
|
uint32 getEQTimeZoneHr() { return timezone/60; }
|
||||||
uint32 getEQTimeZoneMin() { return timezone%60; }
|
uint32 getEQTimeZoneMin() { return timezone%60; }
|
||||||
|
bool IsDayTime();
|
||||||
|
bool IsNightTime();
|
||||||
|
bool IsInbetweenTime(uint8 min_time, uint8 max_time);
|
||||||
|
|
||||||
//Set functions
|
//Set functions
|
||||||
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
||||||
|
|||||||
@@ -238,27 +238,6 @@ enum { //some random constants
|
|||||||
// Timer to update aggrometer
|
// Timer to update aggrometer
|
||||||
#define AGGRO_METER_UPDATE_MS 1000
|
#define AGGRO_METER_UPDATE_MS 1000
|
||||||
|
|
||||||
//Some hard coded statuses from commands and other places:
|
|
||||||
enum {
|
|
||||||
minStatusToBeGM = 40,
|
|
||||||
minStatusToUseGMCommands = 80,
|
|
||||||
minStatusToKick = 150,
|
|
||||||
minStatusToAvoidFalling = 100,
|
|
||||||
minStatusToIgnoreZoneFlags = 80,
|
|
||||||
minStatusToSeeOthersZoneFlags = 80,
|
|
||||||
minStatusToEditOtherGuilds = 80,
|
|
||||||
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
|
||||||
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
|
||||||
commandCastSpecials = 100, //can cast special spells
|
|
||||||
commandInstacast = 100, //insta-cast all #casted spells
|
|
||||||
commandDoAnimOthers = 100, //can #doanim on others
|
|
||||||
commandLockZones = 101, //can lock or unlock zones
|
|
||||||
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
|
||||||
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
|
||||||
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
|
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
|
||||||
#define SAYLINK_ITEM_ID 0xFFFFF
|
#define SAYLINK_ITEM_ID 0xFFFFF
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,15 @@ bool File::Exists(const std::string &name)
|
|||||||
*/
|
*/
|
||||||
void File::Makedir(const std::string &directory_name)
|
void File::Makedir(const std::string &directory_name)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
fs::create_directory(directory_name);
|
fs::create_directory(directory_name);
|
||||||
fs::permissions(directory_name, fs::perms::owner_all);
|
fs::permissions(directory_name, fs::perms::owner_all);
|
||||||
}
|
}
|
||||||
|
catch (const fs::filesystem_error &ex) {
|
||||||
|
std::cout << "Failed to create directory: " << directory_name << std::endl;
|
||||||
|
std::cout << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string File::FindEqemuConfigPath()
|
std::string File::FindEqemuConfigPath()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ namespace EQ
|
|||||||
|
|
||||||
// Swap items in inventory
|
// Swap items in inventory
|
||||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
||||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = RACE_DOUG_0, uint8 class_id = NO_CLASS, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = RACE_DOUG_0, uint8 class_id = Class::None, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
||||||
|
|
||||||
// Remove item from inventory
|
// Remove item from inventory
|
||||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
||||||
|
|||||||
@@ -356,6 +356,7 @@ namespace EQ
|
|||||||
struct ItemData {
|
struct ItemData {
|
||||||
// Non packet based fields
|
// Non packet based fields
|
||||||
uint8 MinStatus {};
|
uint8 MinStatus {};
|
||||||
|
char Comment[255] {};
|
||||||
|
|
||||||
// Packet based fields
|
// Packet based fields
|
||||||
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
||||||
|
|||||||
+24640
File diff suppressed because it is too large
Load Diff
+118
-71
@@ -34,6 +34,7 @@
|
|||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -2609,19 +2610,22 @@ namespace RoF
|
|||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket* inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
|
*p = nullptr;
|
||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
@@ -2631,65 +2635,98 @@ namespace RoF
|
|||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4861,34 +4898,44 @@ namespace RoF
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
|
||||||
IN(general.action);
|
IN(general.action);
|
||||||
IN(general.parameter);
|
IN(general.parameter);
|
||||||
FINISH_DIRECT_DECODE();
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(motd);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 36: { // raidPlayerNote unhandled
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
{
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
|
||||||
IN(action);
|
IN(action);
|
||||||
IN(parameter);
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+119
-85
@@ -35,7 +35,7 @@
|
|||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../classes.h"
|
#include "../classes.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
#include "../../zone/raids.h"
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -2679,19 +2679,22 @@ namespace RoF2
|
|||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket* inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
|
*p = nullptr;
|
||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
@@ -2701,77 +2704,98 @@ namespace RoF2
|
|||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == raidSetNote)
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
auto in_note = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
|
|
||||||
auto note = (RaidGeneral_Struct*)outapp->pBuffer;
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
note->action = raidSetNote;
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(note->leader_name, in_note->leader_name, sizeof(note->leader_name));
|
|
||||||
strn0cpy(note->player_name, in_note->player_name, sizeof(note->leader_name));
|
OUT(action);
|
||||||
strn0cpy(note->note, in_note->note, sizeof(note->note));
|
OUT_str(player_name);
|
||||||
dest->QueuePacket(outapp);
|
OUT_str(leader_name);
|
||||||
safe_delete(outapp);
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetNote:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3962,7 +3986,7 @@ namespace RoF2
|
|||||||
if (strlen(emu->suffix))
|
if (strlen(emu->suffix))
|
||||||
PacketSize += strlen(emu->suffix) + 1;
|
PacketSize += strlen(emu->suffix) + 1;
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
if (emu->DestructibleObject)
|
if (emu->DestructibleObject)
|
||||||
PacketSize = PacketSize - 4; // No bodytype
|
PacketSize = PacketSize - 4; // No bodytype
|
||||||
@@ -4052,7 +4076,7 @@ namespace RoF2
|
|||||||
// actually part of bitfields
|
// actually part of bitfields
|
||||||
uint8 OtherData = 0;
|
uint8 OtherData = 0;
|
||||||
|
|
||||||
if (emu->class_ == LDON_TREASURE) //LDoN Chest
|
if (emu->class_ == Class::LDoNTreasure) //LDoN Chest
|
||||||
{
|
{
|
||||||
OtherData = OtherData | 0x04;
|
OtherData = OtherData | 0x04;
|
||||||
}
|
}
|
||||||
@@ -4080,7 +4104,7 @@ namespace RoF2
|
|||||||
// int DefaultEmitterID
|
// int DefaultEmitterID
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
||||||
@@ -5091,34 +5115,44 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
|
||||||
IN(general.action);
|
IN(general.action);
|
||||||
IN(general.parameter);
|
IN(general.parameter);
|
||||||
FINISH_DIRECT_DECODE();
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(motd);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 36: { // raidPlayerNote unhandled
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
{
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
|
||||||
IN(action);
|
IN(action);
|
||||||
IN(parameter);
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4198,9 +4198,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general;
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
@@ -4136,9 +4136,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
+118
-71
@@ -34,6 +34,7 @@
|
|||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -1687,19 +1688,22 @@ namespace SoD
|
|||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket* inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
|
*p = nullptr;
|
||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
@@ -1709,65 +1713,98 @@ namespace SoD
|
|||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3338,34 +3375,44 @@ namespace SoD
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
|
||||||
IN(general.action);
|
IN(general.action);
|
||||||
IN(general.parameter);
|
IN(general.parameter);
|
||||||
FINISH_DIRECT_DECODE();
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(motd);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 36: { // raidPlayerNote unhandled
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
{
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
|
||||||
IN(action);
|
IN(action);
|
||||||
IN(parameter);
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3592,9 +3592,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
+118
-71
@@ -33,6 +33,7 @@
|
|||||||
#include "sof_structs.h"
|
#include "sof_structs.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -1357,19 +1358,22 @@ namespace SoF
|
|||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket* inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
|
*p = nullptr;
|
||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
@@ -1379,65 +1383,98 @@ namespace SoF
|
|||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2743,34 +2780,44 @@ namespace SoF
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
|
||||||
IN(general.action);
|
IN(general.action);
|
||||||
IN(general.parameter);
|
IN(general.parameter);
|
||||||
FINISH_DIRECT_DECODE();
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(motd);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 36: { // raidPlayerNote unhandled
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
{
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
|
||||||
IN(action);
|
IN(action);
|
||||||
IN(parameter);
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3517,9 +3517,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
@@ -128,6 +128,15 @@
|
|||||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||||
|
|
||||||
|
#define SETUP_VAR_DECODE(emu_struct, eq_struct, var_field) \
|
||||||
|
unsigned char *__eq_buffer = __packet->pBuffer; \
|
||||||
|
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
||||||
|
auto size = strlen(in->var_field); \
|
||||||
|
__packet->size = sizeof(emu_struct) + size + 1; \
|
||||||
|
__packet->pBuffer = new unsigned char[__packet->size]; \
|
||||||
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||||
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||||
|
|
||||||
#define MEMSET_IN(emu_struct) \
|
#define MEMSET_IN(emu_struct) \
|
||||||
memset(__packet->pBuffer, 0, sizeof(emu_struct));
|
memset(__packet->pBuffer, 0, sizeof(emu_struct));
|
||||||
|
|
||||||
@@ -146,6 +155,9 @@
|
|||||||
delete[] __eq_buffer; \
|
delete[] __eq_buffer; \
|
||||||
p->SetOpcode(OP_Unknown);
|
p->SetOpcode(OP_Unknown);
|
||||||
|
|
||||||
|
#define FINISH_VAR_DECODE() \
|
||||||
|
delete[] __eq_buffer;
|
||||||
|
|
||||||
//call to finish an encoder using SETUP_DIRECT_DECODE
|
//call to finish an encoder using SETUP_DIRECT_DECODE
|
||||||
#define FINISH_DIRECT_DECODE() \
|
#define FINISH_DIRECT_DECODE() \
|
||||||
delete[] __eq_buffer;
|
delete[] __eq_buffer;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "../item_instance.h"
|
#include "../item_instance.h"
|
||||||
#include "titanium_structs.h"
|
#include "titanium_structs.h"
|
||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@@ -1245,6 +1246,119 @@ namespace Titanium
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_MarkRaidNPC)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(MarkNPC_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(MarkNPC_Struct, MarkNPC_Struct);
|
||||||
|
|
||||||
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
|
||||||
|
MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer;
|
||||||
|
mnpcs->TargetID = emu->TargetID;
|
||||||
|
mnpcs->Number = emu->Number;
|
||||||
|
dest->QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_RaidUpdate)
|
||||||
|
{
|
||||||
|
EQApplicationPacket* inapp = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
switch (raid_gen->action)
|
||||||
|
{
|
||||||
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(raidGen.action);
|
||||||
|
OUT(raidGen.parameter);
|
||||||
|
OUT_str(raidGen.leader_name);
|
||||||
|
OUT_str(raidGen.player_name);
|
||||||
|
OUT(_class);
|
||||||
|
OUT(level);
|
||||||
|
OUT(isGroupLeader);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
case raidSetMotd:
|
||||||
|
{
|
||||||
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
|
{
|
||||||
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
safe_delete(inapp);
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_ReadBook)
|
ENCODE(OP_ReadBook)
|
||||||
{
|
{
|
||||||
// no apparent slot translation needed
|
// no apparent slot translation needed
|
||||||
@@ -2272,6 +2386,63 @@ namespace Titanium
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_RaidInvite)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
|
|
||||||
|
switch (rgs->action)
|
||||||
|
{
|
||||||
|
case raidSetMotd:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
|
||||||
|
auto len = 0;
|
||||||
|
if (__packet->size < sizeof(structs::RaidMOTD_Struct)) {
|
||||||
|
len = __packet->size - sizeof(structs::RaidGeneral_Struct);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len = sizeof(eq->motd);
|
||||||
|
}
|
||||||
|
|
||||||
|
strn0cpy(emu->motd, eq->motd, len > 1024 ? 1024 : len);
|
||||||
|
emu->motd[len - 1] = '\0';
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
|
IN(action);
|
||||||
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_ReadBook)
|
DECODE(OP_ReadBook)
|
||||||
{
|
{
|
||||||
// no apparent slot translation needed
|
// no apparent slot translation needed
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ E(OP_OnLevelMessage)
|
|||||||
E(OP_PetBuffWindow)
|
E(OP_PetBuffWindow)
|
||||||
E(OP_PlayerProfile)
|
E(OP_PlayerProfile)
|
||||||
E(OP_NewSpawn)
|
E(OP_NewSpawn)
|
||||||
|
E(OP_MarkRaidNPC)
|
||||||
|
E(OP_RaidUpdate)
|
||||||
E(OP_ReadBook)
|
E(OP_ReadBook)
|
||||||
E(OP_RespondAA)
|
E(OP_RespondAA)
|
||||||
E(OP_SendCharInfo)
|
E(OP_SendCharInfo)
|
||||||
@@ -106,6 +108,7 @@ D(OP_LoadSpellSet)
|
|||||||
D(OP_LootItem)
|
D(OP_LootItem)
|
||||||
D(OP_MoveItem)
|
D(OP_MoveItem)
|
||||||
D(OP_PetCommands)
|
D(OP_PetCommands)
|
||||||
|
D(OP_RaidInvite)
|
||||||
D(OP_ReadBook)
|
D(OP_ReadBook)
|
||||||
D(OP_SetServerFilter)
|
D(OP_SetServerFilter)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_ShopPlayerSell)
|
||||||
|
|||||||
@@ -3017,23 +3017,39 @@ struct leadExpUpdateStruct {
|
|||||||
/*0028*/ uint32 unknown0028;
|
/*0028*/ uint32 unknown0028;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct RaidGeneral_Struct {
|
struct RaidGeneral_Struct {
|
||||||
/*00*/ uint32 action; //=10
|
/*000*/ uint32 action; //=10
|
||||||
/*04*/ char player_name[64]; //should both be the player's name
|
/*004*/ char player_name[64]; //should both be the player's name
|
||||||
/*04*/ char leader_name[64];
|
/*068*/ char leader_name[64];
|
||||||
/*132*/ uint32 parameter;
|
/*132*/ uint32 parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidAdd_Struct {
|
struct RaidAddMember_Struct {
|
||||||
/*000*/ uint32 action; //=0
|
/*000*/ RaidGeneral_Struct raidGen;
|
||||||
/*004*/ char player_name[64]; //should both be the player's name
|
/*136*/ uint8 _class;
|
||||||
/*068*/ char leader_name[64];
|
/*137*/ uint8 level;
|
||||||
/*132*/ uint8 _class;
|
/*138*/ uint8 isGroupLeader;
|
||||||
/*133*/ uint8 level;
|
/*139*/ uint8 unknown139; //seems to be 0x42 or 0
|
||||||
/*134*/ uint8 has_group;
|
};
|
||||||
/*135*/ uint8 unknown135; //seems to be 0x42 or 0
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*136*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RaidMOTD_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
|
/*136*/ char motd[1024]; // max size is 1024, but reply is variable
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
/*000*/ uint32 action;
|
||||||
|
/*004*/ char player_name[64];
|
||||||
|
// /*068*/ uint32 Unknown068;
|
||||||
|
/*072*/ char leader_name[64];
|
||||||
|
/*136*/ GroupLeadershipAA_Struct group; //unneeded
|
||||||
|
/*200*/ RaidLeadershipAA_Struct raid;
|
||||||
|
/*264*/ char Unknown264[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidCreate_Struct {
|
struct RaidCreate_Struct {
|
||||||
|
|||||||
+121
-75
@@ -35,6 +35,7 @@
|
|||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../classes.h"
|
#include "../classes.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
|
#include "../raid.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -1932,19 +1933,22 @@ namespace UF
|
|||||||
ENCODE(OP_RaidJoin)
|
ENCODE(OP_RaidJoin)
|
||||||
{
|
{
|
||||||
EQApplicationPacket* inapp = *p;
|
EQApplicationPacket* inapp = *p;
|
||||||
|
*p = nullptr;
|
||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
|
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
|
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
general->action = 8;
|
general->action = raidCreate;
|
||||||
general->parameter = 1;
|
general->parameter = RaidCommandAcceptInvite;
|
||||||
strn0cpy(general->leader_name, raid_create->leader_name, 64);
|
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
strn0cpy(general->player_name, raid_create->leader_name, 64);
|
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp_create);
|
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_RaidUpdate)
|
ENCODE(OP_RaidUpdate)
|
||||||
@@ -1954,65 +1958,98 @@ namespace UF
|
|||||||
unsigned char* __emu_buffer = inapp->pBuffer;
|
unsigned char* __emu_buffer = inapp->pBuffer;
|
||||||
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
if (raid_gen->action == 0) // raid add has longer length than other raid updates
|
switch (raid_gen->action)
|
||||||
{
|
{
|
||||||
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
|
case raidAdd:
|
||||||
|
{
|
||||||
|
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
|
||||||
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
add_member->raidGen.action = in_add_member->raidGen.action;
|
OUT(raidGen.action);
|
||||||
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
|
OUT(raidGen.parameter);
|
||||||
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
|
OUT_str(raidGen.leader_name);
|
||||||
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
|
OUT_str(raidGen.player_name);
|
||||||
add_member->_class = in_add_member->_class;
|
OUT(_class);
|
||||||
add_member->level = in_add_member->level;
|
OUT(level);
|
||||||
add_member->isGroupLeader = in_add_member->isGroupLeader;
|
OUT(isGroupLeader);
|
||||||
add_member->flags[0] = in_add_member->flags[0];
|
OUT(flags[0]);
|
||||||
add_member->flags[1] = in_add_member->flags[1];
|
OUT(flags[1]);
|
||||||
add_member->flags[2] = in_add_member->flags[2];
|
OUT(flags[2]);
|
||||||
add_member->flags[3] = in_add_member->flags[3];
|
OUT(flags[3]);
|
||||||
add_member->flags[4] = in_add_member->flags[4];
|
OUT(flags[4]);
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
else if (raid_gen->action == 35)
|
|
||||||
{
|
|
||||||
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
|
|
||||||
strlen(inmotd->motd) + 1);
|
|
||||||
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
|
|
||||||
|
|
||||||
outmotd->general.action = inmotd->general.action;
|
|
||||||
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
|
|
||||||
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == 14 || raid_gen->action == 30)
|
case raidSetMotd:
|
||||||
{
|
{
|
||||||
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
|
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
|
||||||
auto outapp =
|
|
||||||
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
|
||||||
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
|
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(motd);
|
||||||
|
|
||||||
outlaa->action = inlaa->action;
|
|
||||||
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
|
|
||||||
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
|
|
||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case raidSetLeaderAbilities:
|
||||||
|
case raidMakeLeader:
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
|
||||||
|
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT_str(player_name);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
auto emu = (RaidNote_Struct*)__emu_buffer;
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
|
||||||
|
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
|
OUT(general.action);
|
||||||
|
OUT_str(general.leader_name);
|
||||||
|
OUT_str(general.player_name);
|
||||||
|
OUT_str(note);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case raidNoRaid:
|
||||||
|
{
|
||||||
|
dest->QueuePacket(inapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
|
||||||
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
|
||||||
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
|
|
||||||
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
|
|
||||||
raid_general->action = in_raid_general->action;
|
|
||||||
raid_general->parameter = in_raid_general->parameter;
|
|
||||||
dest->FastQueuePacket(&outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
OUT(action);
|
||||||
|
OUT(parameter);
|
||||||
|
OUT_str(leader_name);
|
||||||
|
OUT_str(player_name);
|
||||||
|
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
safe_delete(inapp);
|
safe_delete(inapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2721,7 +2758,7 @@ namespace UF
|
|||||||
if (strlen(emu->suffix))
|
if (strlen(emu->suffix))
|
||||||
PacketSize += strlen(emu->suffix) + 1;
|
PacketSize += strlen(emu->suffix) + 1;
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
if (emu->DestructibleObject)
|
if (emu->DestructibleObject)
|
||||||
PacketSize = PacketSize - 4; // No bodytype
|
PacketSize = PacketSize - 4; // No bodytype
|
||||||
@@ -2810,7 +2847,7 @@ namespace UF
|
|||||||
|
|
||||||
uint8 OtherData = 0;
|
uint8 OtherData = 0;
|
||||||
|
|
||||||
if (emu->class_ == LDON_TREASURE) //Ldon chest
|
if (emu->class_ == Class::LDoNTreasure) //Ldon chest
|
||||||
{
|
{
|
||||||
OtherData = OtherData | 0x01;
|
OtherData = OtherData | 0x01;
|
||||||
}
|
}
|
||||||
@@ -2836,7 +2873,7 @@ namespace UF
|
|||||||
}
|
}
|
||||||
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
VARSTRUCT_ENCODE_TYPE(float, Buffer, 0); // unknown4
|
||||||
|
|
||||||
if (emu->DestructibleObject || emu->class_ == LDON_TREASURE)
|
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleModel);
|
||||||
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
VARSTRUCT_ENCODE_STRING(Buffer, emu->DestructibleName2);
|
||||||
@@ -3637,39 +3674,48 @@ namespace UF
|
|||||||
{
|
{
|
||||||
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
|
||||||
|
|
||||||
// This is a switch on the RaidGeneral action
|
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
|
||||||
switch (*(uint32 *)__packet->pBuffer) {
|
|
||||||
case 35: { // raidMOTD
|
switch (rgs->action)
|
||||||
// we don't have a nice macro for this
|
{
|
||||||
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
|
case raidSetMotd:
|
||||||
__eq_buffer->motd[1023] = '\0';
|
{
|
||||||
size_t motd_size = strlen(__eq_buffer->motd) + 1;
|
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
|
||||||
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
|
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
|
||||||
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
|
|
||||||
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
|
|
||||||
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
|
|
||||||
strn0cpy(emu->motd, eq->motd, motd_size);
|
|
||||||
IN(general.action);
|
IN(general.action);
|
||||||
IN(general.parameter);
|
IN(general.parameter);
|
||||||
FINISH_DIRECT_DECODE();
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(motd);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 36: { // raidPlayerNote unhandled
|
case raidSetNote:
|
||||||
|
{
|
||||||
|
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
|
||||||
|
|
||||||
|
IN(general.action);
|
||||||
|
IN(general.parameter);
|
||||||
|
IN_str(general.leader_name);
|
||||||
|
IN_str(general.player_name);
|
||||||
|
IN_str(note);
|
||||||
|
|
||||||
|
FINISH_VAR_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
|
{
|
||||||
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
|
||||||
strn0cpy(emu->leader_name, eq->leader_name, 64);
|
|
||||||
strn0cpy(emu->player_name, eq->player_name, 64);
|
|
||||||
IN(action);
|
IN(action);
|
||||||
IN(parameter);
|
IN(parameter);
|
||||||
|
IN_str(leader_name);
|
||||||
|
IN_str(player_name);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DECODE(OP_ReadBook)
|
DECODE(OP_ReadBook)
|
||||||
|
|||||||
@@ -3647,9 +3647,14 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RaidNote_Struct {
|
||||||
|
/*000*/ RaidGeneral_Struct general;
|
||||||
|
/*140*/ char note[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
/*000*/ RaidGeneral_Struct general;
|
||||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
/*140*/ char motd[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// types
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
#include <cctype>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// containers
|
||||||
|
#include <iterator>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// utilities
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
|
#include <tuple>
|
||||||
|
#include <fstream>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
// fmt
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
// lua
|
||||||
|
#include "lua.hpp"
|
||||||
|
#include <luabind/luabind.hpp>
|
||||||
|
#include <luabind/object.hpp>
|
||||||
@@ -72,6 +72,8 @@ std::string GetPlatformName()
|
|||||||
return "HC";
|
return "HC";
|
||||||
case EQEmuExePlatform::ExePlatformTests:
|
case EQEmuExePlatform::ExePlatformTests:
|
||||||
return "Tests";
|
return "Tests";
|
||||||
|
case EQEmuExePlatform::ExePlatformZoneSidecar:
|
||||||
|
return "ZoneSidecar";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -37,7 +37,8 @@ enum EQEmuExePlatform
|
|||||||
ExePlatformClientImport,
|
ExePlatformClientImport,
|
||||||
ExePlatformClientExport,
|
ExePlatformClientExport,
|
||||||
ExePlatformHC,
|
ExePlatformHC,
|
||||||
ExePlatformTests
|
ExePlatformTests,
|
||||||
|
ExePlatformZoneSidecar
|
||||||
};
|
};
|
||||||
|
|
||||||
void RegisterExecutablePlatform(EQEmuExePlatform p);
|
void RegisterExecutablePlatform(EQEmuExePlatform p);
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
|
inline std::string random_string(size_t length)
|
||||||
|
{
|
||||||
|
auto randchar = []() -> char {
|
||||||
|
const char charset[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
const size_t max_index = (sizeof(charset) - 1);
|
||||||
|
return charset[static_cast<size_t>(std::rand()) % max_index];
|
||||||
|
};
|
||||||
|
std::string str(length, 0);
|
||||||
|
std::generate_n(str.begin(), length, randchar);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Process::execute(const std::string &cmd, bool return_result)
|
||||||
|
{
|
||||||
|
std::string random = "/tmp/" + random_string(25);
|
||||||
|
const char *file_name = random.c_str();
|
||||||
|
|
||||||
|
if (return_result) {
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||||
|
#else
|
||||||
|
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::system((cmd).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
if (return_result) {
|
||||||
|
std::ifstream file(file_name);
|
||||||
|
result = {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
|
||||||
|
std::remove(file_name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef EQEMU_PROCESS_H
|
||||||
|
#define EQEMU_PROCESS_H
|
||||||
|
|
||||||
|
class Process {
|
||||||
|
public:
|
||||||
|
static std::string execute(const std::string &cmd, bool return_result = true);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //EQEMU_PROCESS_H
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/* EQEMu: Everquest Server Emulator
|
||||||
|
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
are required to give you total support for your newly bought product;
|
||||||
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RAID_H
|
||||||
|
#define RAID_H
|
||||||
|
|
||||||
|
enum { //raid packet types:
|
||||||
|
raidAdd = 0,
|
||||||
|
raidRemove2 = 1, //parameter=0
|
||||||
|
raidMemberNameChange = 2,
|
||||||
|
raidRemove1 = 3, //parameter=0xFFFFFFFF
|
||||||
|
raidNoLongerLeader = 4,
|
||||||
|
raidDisband = 5,
|
||||||
|
raidMembers = 6, //len 395+, details + members list
|
||||||
|
raidNoAssignLeadership = 7,
|
||||||
|
raidCreate = 8, //len 72
|
||||||
|
raidUnknown = 9, // unused?
|
||||||
|
raidNoRaid = 10, //parameter=0
|
||||||
|
raidChangeLootType = 11,
|
||||||
|
raidStringID = 12,
|
||||||
|
raidChangeGroupLeader = 13, //136 raid leader, new group leader, group_id?
|
||||||
|
raidSetLeaderAbilities = 14, //472
|
||||||
|
raidSetLeaderData = 15, // 14,15 SoE names, not sure on difference, 14 packet has 0x100 bytes 15 0x214 in addition to raid general
|
||||||
|
raidChangeGroup = 16, //?? len 136 old leader, new leader, 0 (preceeded with a remove2)
|
||||||
|
raidLock = 17, //len 136 leader?, leader, 0
|
||||||
|
raidUnlock = 18, //len 136 leader?, leader, 0
|
||||||
|
raidRedStringID = 19,
|
||||||
|
raidSetLeader = 20, //len 388, contains 'details' struct without members; also used for "invite to raid"
|
||||||
|
raidMakeLeader = 30,
|
||||||
|
raidSetMotd = 35,
|
||||||
|
raidSetNote = 36,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum { //raid command types
|
||||||
|
RaidCommandInviteIntoExisting = 0, //in use
|
||||||
|
RaidCommandAcceptInvite = 1, //in use
|
||||||
|
RaidCommandInvite = 3, //in use
|
||||||
|
RaidCommandDisband = 5, //in use
|
||||||
|
RaidCommandMoveGroup = 6, //in use
|
||||||
|
RaidCommandRemoveGroupLeader = 7,
|
||||||
|
RaidCommandRaidLock = 8, //in use
|
||||||
|
RaidCommandRaidUnlock = 9, //in use
|
||||||
|
RaidCommandLootType = 20, //in use
|
||||||
|
RaidCommandAddLooter = 21, //in use
|
||||||
|
RaidCommandRemoveLooter = 22, //in use
|
||||||
|
RaidCommandMakeLeader = 30,
|
||||||
|
RaidCommandInviteFail = 31, //already in raid, waiting on invite from other raid, etc
|
||||||
|
RaidCommandLootType2 = 32, //in use
|
||||||
|
RaidCommandAddLooter2 = 33, //in use
|
||||||
|
RaidCommandRemoveLooter2 = 34, //in use
|
||||||
|
RaidCommandSetMotd = 35,
|
||||||
|
RaidCommandSetNote = 36,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseBlockedSpellsRepository {
|
class BaseBlockedSpellsRepository {
|
||||||
public:
|
public:
|
||||||
struct BlockedSpells {
|
struct BlockedSpells {
|
||||||
@@ -31,6 +32,10 @@ public:
|
|||||||
float z_diff;
|
float z_diff;
|
||||||
std::string message;
|
std::string message;
|
||||||
std::string description;
|
std::string description;
|
||||||
|
int8_t min_expansion;
|
||||||
|
int8_t max_expansion;
|
||||||
|
std::string content_flags;
|
||||||
|
std::string content_flags_disabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -53,6 +58,10 @@ public:
|
|||||||
"z_diff",
|
"z_diff",
|
||||||
"message",
|
"message",
|
||||||
"description",
|
"description",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +80,10 @@ public:
|
|||||||
"z_diff",
|
"z_diff",
|
||||||
"message",
|
"message",
|
||||||
"description",
|
"description",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +136,10 @@ public:
|
|||||||
e.z_diff = 0;
|
e.z_diff = 0;
|
||||||
e.message = "";
|
e.message = "";
|
||||||
e.description = "";
|
e.description = "";
|
||||||
|
e.min_expansion = -1;
|
||||||
|
e.max_expansion = -1;
|
||||||
|
e.content_flags = "";
|
||||||
|
e.content_flags_disabled = "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -148,8 +165,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
blocked_spells_id
|
blocked_spells_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -170,6 +188,10 @@ public:
|
|||||||
e.z_diff = strtof(row[9], nullptr);
|
e.z_diff = strtof(row[9], nullptr);
|
||||||
e.message = row[10] ? row[10] : "";
|
e.message = row[10] ? row[10] : "";
|
||||||
e.description = row[11] ? row[11] : "";
|
e.description = row[11] ? row[11] : "";
|
||||||
|
e.min_expansion = static_cast<int8_t>(atoi(row[12]));
|
||||||
|
e.max_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
|
e.content_flags = row[14] ? row[14] : "";
|
||||||
|
e.content_flags_disabled = row[15] ? row[15] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -214,6 +236,10 @@ public:
|
|||||||
v.push_back(columns[9] + " = " + std::to_string(e.z_diff));
|
v.push_back(columns[9] + " = " + std::to_string(e.z_diff));
|
||||||
v.push_back(columns[10] + " = '" + Strings::Escape(e.message) + "'");
|
v.push_back(columns[10] + " = '" + Strings::Escape(e.message) + "'");
|
||||||
v.push_back(columns[11] + " = '" + Strings::Escape(e.description) + "'");
|
v.push_back(columns[11] + " = '" + Strings::Escape(e.description) + "'");
|
||||||
|
v.push_back(columns[12] + " = " + std::to_string(e.min_expansion));
|
||||||
|
v.push_back(columns[13] + " = " + std::to_string(e.max_expansion));
|
||||||
|
v.push_back(columns[14] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back(columns[15] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -247,6 +273,10 @@ public:
|
|||||||
v.push_back(std::to_string(e.z_diff));
|
v.push_back(std::to_string(e.z_diff));
|
||||||
v.push_back("'" + Strings::Escape(e.message) + "'");
|
v.push_back("'" + Strings::Escape(e.message) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.description) + "'");
|
v.push_back("'" + Strings::Escape(e.description) + "'");
|
||||||
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -288,6 +318,10 @@ public:
|
|||||||
v.push_back(std::to_string(e.z_diff));
|
v.push_back(std::to_string(e.z_diff));
|
||||||
v.push_back("'" + Strings::Escape(e.message) + "'");
|
v.push_back("'" + Strings::Escape(e.message) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.description) + "'");
|
v.push_back("'" + Strings::Escape(e.description) + "'");
|
||||||
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -333,6 +367,10 @@ public:
|
|||||||
e.z_diff = strtof(row[9], nullptr);
|
e.z_diff = strtof(row[9], nullptr);
|
||||||
e.message = row[10] ? row[10] : "";
|
e.message = row[10] ? row[10] : "";
|
||||||
e.description = row[11] ? row[11] : "";
|
e.description = row[11] ? row[11] : "";
|
||||||
|
e.min_expansion = static_cast<int8_t>(atoi(row[12]));
|
||||||
|
e.max_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
|
e.content_flags = row[14] ? row[14] : "";
|
||||||
|
e.content_flags_disabled = row[15] ? row[15] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -369,6 +407,10 @@ public:
|
|||||||
e.z_diff = strtof(row[9], nullptr);
|
e.z_diff = strtof(row[9], nullptr);
|
||||||
e.message = row[10] ? row[10] : "";
|
e.message = row[10] ? row[10] : "";
|
||||||
e.description = row[11] ? row[11] : "";
|
e.description = row[11] ? row[11] : "";
|
||||||
|
e.min_expansion = static_cast<int8_t>(atoi(row[12]));
|
||||||
|
e.max_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||||
|
e.content_flags = row[14] ? row[14] : "";
|
||||||
|
e.content_flags_disabled = row[15] ? row[15] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,414 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
|
class BaseBotStartingItemsRepository {
|
||||||
|
public:
|
||||||
|
struct BotStartingItems {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t races;
|
||||||
|
uint32_t classes;
|
||||||
|
uint32_t item_id;
|
||||||
|
uint8_t item_charges;
|
||||||
|
int32_t slot_id;
|
||||||
|
int8_t min_expansion;
|
||||||
|
int8_t max_expansion;
|
||||||
|
std::string content_flags;
|
||||||
|
std::string content_flags_disabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"races",
|
||||||
|
"classes",
|
||||||
|
"item_id",
|
||||||
|
"item_charges",
|
||||||
|
"slot_id",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"races",
|
||||||
|
"classes",
|
||||||
|
"item_id",
|
||||||
|
"item_charges",
|
||||||
|
"slot_id",
|
||||||
|
"min_expansion",
|
||||||
|
"max_expansion",
|
||||||
|
"content_flags",
|
||||||
|
"content_flags_disabled",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("bot_starting_items");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotStartingItems NewEntity()
|
||||||
|
{
|
||||||
|
BotStartingItems e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.races = 0;
|
||||||
|
e.classes = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
e.item_charges = 1;
|
||||||
|
e.slot_id = -1;
|
||||||
|
e.min_expansion = -1;
|
||||||
|
e.max_expansion = -1;
|
||||||
|
e.content_flags = "";
|
||||||
|
e.content_flags_disabled = "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotStartingItems GetBotStartingItems(
|
||||||
|
const std::vector<BotStartingItems> &bot_starting_itemss,
|
||||||
|
int bot_starting_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &bot_starting_items : bot_starting_itemss) {
|
||||||
|
if (bot_starting_items.id == bot_starting_items_id) {
|
||||||
|
return bot_starting_items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotStartingItems FindOne(
|
||||||
|
Database& db,
|
||||||
|
int bot_starting_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
bot_starting_items_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
BotStartingItems e{};
|
||||||
|
|
||||||
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
|
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
|
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||||
|
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
|
e.slot_id = static_cast<int32_t>(atoi(row[5]));
|
||||||
|
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||||
|
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||||
|
e.content_flags = row[8] ? row[8] : "";
|
||||||
|
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int bot_starting_items_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
bot_starting_items_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const BotStartingItems &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.races));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.classes));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.item_charges));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.slot_id));
|
||||||
|
v.push_back(columns[6] + " = " + std::to_string(e.min_expansion));
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.max_expansion));
|
||||||
|
v.push_back(columns[8] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back(columns[9] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BotStartingItems InsertOne(
|
||||||
|
Database& db,
|
||||||
|
BotStartingItems e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.races));
|
||||||
|
v.push_back(std::to_string(e.classes));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_charges));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<BotStartingItems> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.races));
|
||||||
|
v.push_back(std::to_string(e.classes));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.item_charges));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BotStartingItems> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<BotStartingItems> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
BotStartingItems e{};
|
||||||
|
|
||||||
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
|
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
|
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||||
|
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
|
e.slot_id = static_cast<int32_t>(atoi(row[5]));
|
||||||
|
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||||
|
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||||
|
e.content_flags = row[8] ? row[8] : "";
|
||||||
|
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<BotStartingItems> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<BotStartingItems> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {}",
|
||||||
|
BaseSelect(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
BotStartingItems e{};
|
||||||
|
|
||||||
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
|
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
|
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||||
|
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
|
e.slot_id = static_cast<int32_t>(atoi(row[5]));
|
||||||
|
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||||
|
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||||
|
e.content_flags = row[8] ? row[8] : "";
|
||||||
|
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||||
@@ -16,12 +16,19 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseBotTimersRepository {
|
class BaseBotTimersRepository {
|
||||||
public:
|
public:
|
||||||
struct BotTimers {
|
struct BotTimers {
|
||||||
uint32_t bot_id;
|
uint32_t bot_id;
|
||||||
uint32_t timer_id;
|
uint32_t timer_id;
|
||||||
uint32_t timer_value;
|
uint32_t timer_value;
|
||||||
|
uint32_t recast_time;
|
||||||
|
uint8_t is_spell;
|
||||||
|
uint8_t is_disc;
|
||||||
|
uint32_t spell_id;
|
||||||
|
uint8_t is_item;
|
||||||
|
uint32_t item_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -35,6 +42,12 @@ public:
|
|||||||
"bot_id",
|
"bot_id",
|
||||||
"timer_id",
|
"timer_id",
|
||||||
"timer_value",
|
"timer_value",
|
||||||
|
"recast_time",
|
||||||
|
"is_spell",
|
||||||
|
"is_disc",
|
||||||
|
"spell_id",
|
||||||
|
"is_item",
|
||||||
|
"item_id",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +57,12 @@ public:
|
|||||||
"bot_id",
|
"bot_id",
|
||||||
"timer_id",
|
"timer_id",
|
||||||
"timer_value",
|
"timer_value",
|
||||||
|
"recast_time",
|
||||||
|
"is_spell",
|
||||||
|
"is_disc",
|
||||||
|
"spell_id",
|
||||||
|
"is_item",
|
||||||
|
"item_id",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +106,12 @@ public:
|
|||||||
e.bot_id = 0;
|
e.bot_id = 0;
|
||||||
e.timer_id = 0;
|
e.timer_id = 0;
|
||||||
e.timer_value = 0;
|
e.timer_value = 0;
|
||||||
|
e.recast_time = 0;
|
||||||
|
e.is_spell = 0;
|
||||||
|
e.is_disc = 0;
|
||||||
|
e.spell_id = 0;
|
||||||
|
e.is_item = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -112,8 +137,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
bot_timers_id
|
bot_timers_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -125,6 +151,12 @@ public:
|
|||||||
e.bot_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.bot_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.timer_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
e.timer_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
e.timer_value = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
e.timer_value = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
e.recast_time = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||||
|
e.is_spell = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
|
e.is_disc = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
|
e.spell_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||||
|
e.is_item = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
|
||||||
|
e.item_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -161,6 +193,12 @@ public:
|
|||||||
v.push_back(columns[0] + " = " + std::to_string(e.bot_id));
|
v.push_back(columns[0] + " = " + std::to_string(e.bot_id));
|
||||||
v.push_back(columns[1] + " = " + std::to_string(e.timer_id));
|
v.push_back(columns[1] + " = " + std::to_string(e.timer_id));
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.timer_value));
|
v.push_back(columns[2] + " = " + std::to_string(e.timer_value));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.recast_time));
|
||||||
|
v.push_back(columns[4] + " = " + std::to_string(e.is_spell));
|
||||||
|
v.push_back(columns[5] + " = " + std::to_string(e.is_disc));
|
||||||
|
v.push_back(columns[6] + " = " + std::to_string(e.spell_id));
|
||||||
|
v.push_back(columns[7] + " = " + std::to_string(e.is_item));
|
||||||
|
v.push_back(columns[8] + " = " + std::to_string(e.item_id));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -185,6 +223,12 @@ public:
|
|||||||
v.push_back(std::to_string(e.bot_id));
|
v.push_back(std::to_string(e.bot_id));
|
||||||
v.push_back(std::to_string(e.timer_id));
|
v.push_back(std::to_string(e.timer_id));
|
||||||
v.push_back(std::to_string(e.timer_value));
|
v.push_back(std::to_string(e.timer_value));
|
||||||
|
v.push_back(std::to_string(e.recast_time));
|
||||||
|
v.push_back(std::to_string(e.is_spell));
|
||||||
|
v.push_back(std::to_string(e.is_disc));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.is_item));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -217,6 +261,12 @@ public:
|
|||||||
v.push_back(std::to_string(e.bot_id));
|
v.push_back(std::to_string(e.bot_id));
|
||||||
v.push_back(std::to_string(e.timer_id));
|
v.push_back(std::to_string(e.timer_id));
|
||||||
v.push_back(std::to_string(e.timer_value));
|
v.push_back(std::to_string(e.timer_value));
|
||||||
|
v.push_back(std::to_string(e.recast_time));
|
||||||
|
v.push_back(std::to_string(e.is_spell));
|
||||||
|
v.push_back(std::to_string(e.is_disc));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.is_item));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -253,6 +303,12 @@ public:
|
|||||||
e.bot_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.bot_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.timer_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
e.timer_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
e.timer_value = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
e.timer_value = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
e.recast_time = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||||
|
e.is_spell = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
|
e.is_disc = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
|
e.spell_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||||
|
e.is_item = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
|
||||||
|
e.item_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -280,6 +336,12 @@ public:
|
|||||||
e.bot_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.bot_id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.timer_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
e.timer_id = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
e.timer_value = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
e.timer_value = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
e.recast_time = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||||
|
e.is_spell = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||||
|
e.is_disc = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||||
|
e.spell_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||||
|
e.is_item = static_cast<uint8_t>(strtoul(row[7], nullptr, 10));
|
||||||
|
e.item_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
int32_t damageshield;
|
int32_t damageshield;
|
||||||
int32_t deity;
|
int32_t deity;
|
||||||
int32_t delay;
|
int32_t delay;
|
||||||
int32_t augdistiller;
|
uint32_t augdistiller;
|
||||||
int32_t dotshielding;
|
int32_t dotshielding;
|
||||||
int32_t dr;
|
int32_t dr;
|
||||||
int32_t clicktype;
|
int32_t clicktype;
|
||||||
@@ -227,7 +227,7 @@ public:
|
|||||||
int32_t focusunk5;
|
int32_t focusunk5;
|
||||||
std::string focusunk6;
|
std::string focusunk6;
|
||||||
int32_t focusunk7;
|
int32_t focusunk7;
|
||||||
int32_t scrollunk1;
|
uint32_t scrollunk1;
|
||||||
int32_t scrollunk2;
|
int32_t scrollunk2;
|
||||||
int32_t scrollunk3;
|
int32_t scrollunk3;
|
||||||
int32_t scrollunk4;
|
int32_t scrollunk4;
|
||||||
@@ -266,10 +266,10 @@ public:
|
|||||||
std::string created;
|
std::string created;
|
||||||
int16_t elitematerial;
|
int16_t elitematerial;
|
||||||
int16_t ldonsellbackrate;
|
int16_t ldonsellbackrate;
|
||||||
int16_t scriptfileid;
|
int32_t scriptfileid;
|
||||||
int16_t expendablearrow;
|
int16_t expendablearrow;
|
||||||
int16_t powersourcecapacity;
|
int32_t powersourcecapacity;
|
||||||
int16_t bardeffect;
|
int32_t bardeffect;
|
||||||
int16_t bardeffecttype;
|
int16_t bardeffecttype;
|
||||||
int16_t bardlevel2;
|
int16_t bardlevel2;
|
||||||
int16_t bardlevel;
|
int16_t bardlevel;
|
||||||
@@ -1307,7 +1307,7 @@ public:
|
|||||||
e.damageshield = static_cast<int32_t>(atoi(row[52]));
|
e.damageshield = static_cast<int32_t>(atoi(row[52]));
|
||||||
e.deity = static_cast<int32_t>(atoi(row[53]));
|
e.deity = static_cast<int32_t>(atoi(row[53]));
|
||||||
e.delay = static_cast<int32_t>(atoi(row[54]));
|
e.delay = static_cast<int32_t>(atoi(row[54]));
|
||||||
e.augdistiller = static_cast<int32_t>(atoi(row[55]));
|
e.augdistiller = static_cast<uint32_t>(strtoul(row[55], nullptr, 10));
|
||||||
e.dotshielding = static_cast<int32_t>(atoi(row[56]));
|
e.dotshielding = static_cast<int32_t>(atoi(row[56]));
|
||||||
e.dr = static_cast<int32_t>(atoi(row[57]));
|
e.dr = static_cast<int32_t>(atoi(row[57]));
|
||||||
e.clicktype = static_cast<int32_t>(atoi(row[58]));
|
e.clicktype = static_cast<int32_t>(atoi(row[58]));
|
||||||
@@ -1459,7 +1459,7 @@ public:
|
|||||||
e.focusunk5 = static_cast<int32_t>(atoi(row[204]));
|
e.focusunk5 = static_cast<int32_t>(atoi(row[204]));
|
||||||
e.focusunk6 = row[205] ? row[205] : "";
|
e.focusunk6 = row[205] ? row[205] : "";
|
||||||
e.focusunk7 = static_cast<int32_t>(atoi(row[206]));
|
e.focusunk7 = static_cast<int32_t>(atoi(row[206]));
|
||||||
e.scrollunk1 = static_cast<int32_t>(atoi(row[207]));
|
e.scrollunk1 = static_cast<uint32_t>(strtoul(row[207], nullptr, 10));
|
||||||
e.scrollunk2 = static_cast<int32_t>(atoi(row[208]));
|
e.scrollunk2 = static_cast<int32_t>(atoi(row[208]));
|
||||||
e.scrollunk3 = static_cast<int32_t>(atoi(row[209]));
|
e.scrollunk3 = static_cast<int32_t>(atoi(row[209]));
|
||||||
e.scrollunk4 = static_cast<int32_t>(atoi(row[210]));
|
e.scrollunk4 = static_cast<int32_t>(atoi(row[210]));
|
||||||
@@ -1498,10 +1498,10 @@ public:
|
|||||||
e.created = row[243] ? row[243] : "";
|
e.created = row[243] ? row[243] : "";
|
||||||
e.elitematerial = static_cast<int16_t>(atoi(row[244]));
|
e.elitematerial = static_cast<int16_t>(atoi(row[244]));
|
||||||
e.ldonsellbackrate = static_cast<int16_t>(atoi(row[245]));
|
e.ldonsellbackrate = static_cast<int16_t>(atoi(row[245]));
|
||||||
e.scriptfileid = static_cast<int16_t>(atoi(row[246]));
|
e.scriptfileid = static_cast<int32_t>(atoi(row[246]));
|
||||||
e.expendablearrow = static_cast<int16_t>(atoi(row[247]));
|
e.expendablearrow = static_cast<int16_t>(atoi(row[247]));
|
||||||
e.powersourcecapacity = static_cast<int16_t>(atoi(row[248]));
|
e.powersourcecapacity = static_cast<int32_t>(atoi(row[248]));
|
||||||
e.bardeffect = static_cast<int16_t>(atoi(row[249]));
|
e.bardeffect = static_cast<int32_t>(atoi(row[249]));
|
||||||
e.bardeffecttype = static_cast<int16_t>(atoi(row[250]));
|
e.bardeffecttype = static_cast<int16_t>(atoi(row[250]));
|
||||||
e.bardlevel2 = static_cast<int16_t>(atoi(row[251]));
|
e.bardlevel2 = static_cast<int16_t>(atoi(row[251]));
|
||||||
e.bardlevel = static_cast<int16_t>(atoi(row[252]));
|
e.bardlevel = static_cast<int16_t>(atoi(row[252]));
|
||||||
@@ -2563,7 +2563,7 @@ public:
|
|||||||
e.damageshield = static_cast<int32_t>(atoi(row[52]));
|
e.damageshield = static_cast<int32_t>(atoi(row[52]));
|
||||||
e.deity = static_cast<int32_t>(atoi(row[53]));
|
e.deity = static_cast<int32_t>(atoi(row[53]));
|
||||||
e.delay = static_cast<int32_t>(atoi(row[54]));
|
e.delay = static_cast<int32_t>(atoi(row[54]));
|
||||||
e.augdistiller = static_cast<int32_t>(atoi(row[55]));
|
e.augdistiller = static_cast<uint32_t>(strtoul(row[55], nullptr, 10));
|
||||||
e.dotshielding = static_cast<int32_t>(atoi(row[56]));
|
e.dotshielding = static_cast<int32_t>(atoi(row[56]));
|
||||||
e.dr = static_cast<int32_t>(atoi(row[57]));
|
e.dr = static_cast<int32_t>(atoi(row[57]));
|
||||||
e.clicktype = static_cast<int32_t>(atoi(row[58]));
|
e.clicktype = static_cast<int32_t>(atoi(row[58]));
|
||||||
@@ -2715,7 +2715,7 @@ public:
|
|||||||
e.focusunk5 = static_cast<int32_t>(atoi(row[204]));
|
e.focusunk5 = static_cast<int32_t>(atoi(row[204]));
|
||||||
e.focusunk6 = row[205] ? row[205] : "";
|
e.focusunk6 = row[205] ? row[205] : "";
|
||||||
e.focusunk7 = static_cast<int32_t>(atoi(row[206]));
|
e.focusunk7 = static_cast<int32_t>(atoi(row[206]));
|
||||||
e.scrollunk1 = static_cast<int32_t>(atoi(row[207]));
|
e.scrollunk1 = static_cast<uint32_t>(strtoul(row[207], nullptr, 10));
|
||||||
e.scrollunk2 = static_cast<int32_t>(atoi(row[208]));
|
e.scrollunk2 = static_cast<int32_t>(atoi(row[208]));
|
||||||
e.scrollunk3 = static_cast<int32_t>(atoi(row[209]));
|
e.scrollunk3 = static_cast<int32_t>(atoi(row[209]));
|
||||||
e.scrollunk4 = static_cast<int32_t>(atoi(row[210]));
|
e.scrollunk4 = static_cast<int32_t>(atoi(row[210]));
|
||||||
@@ -2754,10 +2754,10 @@ public:
|
|||||||
e.created = row[243] ? row[243] : "";
|
e.created = row[243] ? row[243] : "";
|
||||||
e.elitematerial = static_cast<int16_t>(atoi(row[244]));
|
e.elitematerial = static_cast<int16_t>(atoi(row[244]));
|
||||||
e.ldonsellbackrate = static_cast<int16_t>(atoi(row[245]));
|
e.ldonsellbackrate = static_cast<int16_t>(atoi(row[245]));
|
||||||
e.scriptfileid = static_cast<int16_t>(atoi(row[246]));
|
e.scriptfileid = static_cast<int32_t>(atoi(row[246]));
|
||||||
e.expendablearrow = static_cast<int16_t>(atoi(row[247]));
|
e.expendablearrow = static_cast<int16_t>(atoi(row[247]));
|
||||||
e.powersourcecapacity = static_cast<int16_t>(atoi(row[248]));
|
e.powersourcecapacity = static_cast<int32_t>(atoi(row[248]));
|
||||||
e.bardeffect = static_cast<int16_t>(atoi(row[249]));
|
e.bardeffect = static_cast<int32_t>(atoi(row[249]));
|
||||||
e.bardeffecttype = static_cast<int16_t>(atoi(row[250]));
|
e.bardeffecttype = static_cast<int16_t>(atoi(row[250]));
|
||||||
e.bardlevel2 = static_cast<int16_t>(atoi(row[251]));
|
e.bardlevel2 = static_cast<int16_t>(atoi(row[251]));
|
||||||
e.bardlevel = static_cast<int16_t>(atoi(row[252]));
|
e.bardlevel = static_cast<int16_t>(atoi(row[252]));
|
||||||
@@ -2872,7 +2872,7 @@ public:
|
|||||||
e.damageshield = static_cast<int32_t>(atoi(row[52]));
|
e.damageshield = static_cast<int32_t>(atoi(row[52]));
|
||||||
e.deity = static_cast<int32_t>(atoi(row[53]));
|
e.deity = static_cast<int32_t>(atoi(row[53]));
|
||||||
e.delay = static_cast<int32_t>(atoi(row[54]));
|
e.delay = static_cast<int32_t>(atoi(row[54]));
|
||||||
e.augdistiller = static_cast<int32_t>(atoi(row[55]));
|
e.augdistiller = static_cast<uint32_t>(strtoul(row[55], nullptr, 10));
|
||||||
e.dotshielding = static_cast<int32_t>(atoi(row[56]));
|
e.dotshielding = static_cast<int32_t>(atoi(row[56]));
|
||||||
e.dr = static_cast<int32_t>(atoi(row[57]));
|
e.dr = static_cast<int32_t>(atoi(row[57]));
|
||||||
e.clicktype = static_cast<int32_t>(atoi(row[58]));
|
e.clicktype = static_cast<int32_t>(atoi(row[58]));
|
||||||
@@ -3024,7 +3024,7 @@ public:
|
|||||||
e.focusunk5 = static_cast<int32_t>(atoi(row[204]));
|
e.focusunk5 = static_cast<int32_t>(atoi(row[204]));
|
||||||
e.focusunk6 = row[205] ? row[205] : "";
|
e.focusunk6 = row[205] ? row[205] : "";
|
||||||
e.focusunk7 = static_cast<int32_t>(atoi(row[206]));
|
e.focusunk7 = static_cast<int32_t>(atoi(row[206]));
|
||||||
e.scrollunk1 = static_cast<int32_t>(atoi(row[207]));
|
e.scrollunk1 = static_cast<uint32_t>(strtoul(row[207], nullptr, 10));
|
||||||
e.scrollunk2 = static_cast<int32_t>(atoi(row[208]));
|
e.scrollunk2 = static_cast<int32_t>(atoi(row[208]));
|
||||||
e.scrollunk3 = static_cast<int32_t>(atoi(row[209]));
|
e.scrollunk3 = static_cast<int32_t>(atoi(row[209]));
|
||||||
e.scrollunk4 = static_cast<int32_t>(atoi(row[210]));
|
e.scrollunk4 = static_cast<int32_t>(atoi(row[210]));
|
||||||
@@ -3063,10 +3063,10 @@ public:
|
|||||||
e.created = row[243] ? row[243] : "";
|
e.created = row[243] ? row[243] : "";
|
||||||
e.elitematerial = static_cast<int16_t>(atoi(row[244]));
|
e.elitematerial = static_cast<int16_t>(atoi(row[244]));
|
||||||
e.ldonsellbackrate = static_cast<int16_t>(atoi(row[245]));
|
e.ldonsellbackrate = static_cast<int16_t>(atoi(row[245]));
|
||||||
e.scriptfileid = static_cast<int16_t>(atoi(row[246]));
|
e.scriptfileid = static_cast<int32_t>(atoi(row[246]));
|
||||||
e.expendablearrow = static_cast<int16_t>(atoi(row[247]));
|
e.expendablearrow = static_cast<int16_t>(atoi(row[247]));
|
||||||
e.powersourcecapacity = static_cast<int16_t>(atoi(row[248]));
|
e.powersourcecapacity = static_cast<int32_t>(atoi(row[248]));
|
||||||
e.bardeffect = static_cast<int16_t>(atoi(row[249]));
|
e.bardeffect = static_cast<int32_t>(atoi(row[249]));
|
||||||
e.bardeffecttype = static_cast<int16_t>(atoi(row[250]));
|
e.bardeffecttype = static_cast<int16_t>(atoi(row[250]));
|
||||||
e.bardlevel2 = static_cast<int16_t>(atoi(row[251]));
|
e.bardlevel2 = static_cast<int16_t>(atoi(row[251]));
|
||||||
e.bardlevel = static_cast<int16_t>(atoi(row[252]));
|
e.bardlevel = static_cast<int16_t>(atoi(row[252]));
|
||||||
|
|||||||
@@ -0,0 +1,344 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_KEYRING_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_KEYRING_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
|
class BaseKeyringRepository {
|
||||||
|
public:
|
||||||
|
struct Keyring {
|
||||||
|
uint32_t id;
|
||||||
|
int32_t char_id;
|
||||||
|
int32_t item_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"char_id",
|
||||||
|
"item_id",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"char_id",
|
||||||
|
"item_id",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("keyring");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Keyring NewEntity()
|
||||||
|
{
|
||||||
|
Keyring e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.char_id = 0;
|
||||||
|
e.item_id = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Keyring GetKeyring(
|
||||||
|
const std::vector<Keyring> &keyrings,
|
||||||
|
int keyring_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &keyring : keyrings) {
|
||||||
|
if (keyring.id == keyring_id) {
|
||||||
|
return keyring;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Keyring FindOne(
|
||||||
|
Database& db,
|
||||||
|
int keyring_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
keyring_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
Keyring e{};
|
||||||
|
|
||||||
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
|
e.char_id = static_cast<int32_t>(atoi(row[1]));
|
||||||
|
e.item_id = static_cast<int32_t>(atoi(row[2]));
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int keyring_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
keyring_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const Keyring &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.char_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Keyring InsertOne(
|
||||||
|
Database& db,
|
||||||
|
Keyring e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<Keyring> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<Keyring> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<Keyring> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
Keyring e{};
|
||||||
|
|
||||||
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
|
e.char_id = static_cast<int32_t>(atoi(row[1]));
|
||||||
|
e.item_id = static_cast<int32_t>(atoi(row[2]));
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<Keyring> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<Keyring> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {}",
|
||||||
|
BaseSelect(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
Keyring e{};
|
||||||
|
|
||||||
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
|
e.char_id = static_cast<int32_t>(atoi(row[1]));
|
||||||
|
e.item_id = static_cast<int32_t>(atoi(row[2]));
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_KEYRING_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseObjectRepository {
|
class BaseObjectRepository {
|
||||||
public:
|
public:
|
||||||
struct Object {
|
struct Object {
|
||||||
@@ -31,9 +32,9 @@ public:
|
|||||||
std::string objectname;
|
std::string objectname;
|
||||||
int32_t type;
|
int32_t type;
|
||||||
int32_t icon;
|
int32_t icon;
|
||||||
int32_t unknown08;
|
float size_percentage;
|
||||||
int32_t unknown10;
|
int32_t solid_type;
|
||||||
int32_t unknown20;
|
int32_t incline;
|
||||||
int32_t unknown24;
|
int32_t unknown24;
|
||||||
int32_t unknown60;
|
int32_t unknown60;
|
||||||
int32_t unknown64;
|
int32_t unknown64;
|
||||||
@@ -71,9 +72,9 @@ public:
|
|||||||
"objectname",
|
"objectname",
|
||||||
"type",
|
"type",
|
||||||
"icon",
|
"icon",
|
||||||
"unknown08",
|
"size_percentage",
|
||||||
"unknown10",
|
"solid_type",
|
||||||
"unknown20",
|
"incline",
|
||||||
"unknown24",
|
"unknown24",
|
||||||
"unknown60",
|
"unknown60",
|
||||||
"unknown64",
|
"unknown64",
|
||||||
@@ -107,9 +108,9 @@ public:
|
|||||||
"objectname",
|
"objectname",
|
||||||
"type",
|
"type",
|
||||||
"icon",
|
"icon",
|
||||||
"unknown08",
|
"size_percentage",
|
||||||
"unknown10",
|
"solid_type",
|
||||||
"unknown20",
|
"incline",
|
||||||
"unknown24",
|
"unknown24",
|
||||||
"unknown60",
|
"unknown60",
|
||||||
"unknown64",
|
"unknown64",
|
||||||
@@ -177,9 +178,9 @@ public:
|
|||||||
e.objectname = "";
|
e.objectname = "";
|
||||||
e.type = 0;
|
e.type = 0;
|
||||||
e.icon = 0;
|
e.icon = 0;
|
||||||
e.unknown08 = 0;
|
e.size_percentage = 0;
|
||||||
e.unknown10 = 0;
|
e.solid_type = 0;
|
||||||
e.unknown20 = 0;
|
e.incline = 0;
|
||||||
e.unknown24 = 0;
|
e.unknown24 = 0;
|
||||||
e.unknown60 = 0;
|
e.unknown60 = 0;
|
||||||
e.unknown64 = 0;
|
e.unknown64 = 0;
|
||||||
@@ -220,8 +221,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
object_id
|
object_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -242,9 +244,9 @@ public:
|
|||||||
e.objectname = row[9] ? row[9] : "";
|
e.objectname = row[9] ? row[9] : "";
|
||||||
e.type = static_cast<int32_t>(atoi(row[10]));
|
e.type = static_cast<int32_t>(atoi(row[10]));
|
||||||
e.icon = static_cast<int32_t>(atoi(row[11]));
|
e.icon = static_cast<int32_t>(atoi(row[11]));
|
||||||
e.unknown08 = static_cast<int32_t>(atoi(row[12]));
|
e.size_percentage = strtof(row[12], nullptr);
|
||||||
e.unknown10 = static_cast<int32_t>(atoi(row[13]));
|
e.solid_type = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.unknown20 = static_cast<int32_t>(atoi(row[14]));
|
e.incline = static_cast<int32_t>(atoi(row[14]));
|
||||||
e.unknown24 = static_cast<int32_t>(atoi(row[15]));
|
e.unknown24 = static_cast<int32_t>(atoi(row[15]));
|
||||||
e.unknown60 = static_cast<int32_t>(atoi(row[16]));
|
e.unknown60 = static_cast<int32_t>(atoi(row[16]));
|
||||||
e.unknown64 = static_cast<int32_t>(atoi(row[17]));
|
e.unknown64 = static_cast<int32_t>(atoi(row[17]));
|
||||||
@@ -304,9 +306,9 @@ public:
|
|||||||
v.push_back(columns[9] + " = '" + Strings::Escape(e.objectname) + "'");
|
v.push_back(columns[9] + " = '" + Strings::Escape(e.objectname) + "'");
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.type));
|
v.push_back(columns[10] + " = " + std::to_string(e.type));
|
||||||
v.push_back(columns[11] + " = " + std::to_string(e.icon));
|
v.push_back(columns[11] + " = " + std::to_string(e.icon));
|
||||||
v.push_back(columns[12] + " = " + std::to_string(e.unknown08));
|
v.push_back(columns[12] + " = " + std::to_string(e.size_percentage));
|
||||||
v.push_back(columns[13] + " = " + std::to_string(e.unknown10));
|
v.push_back(columns[13] + " = " + std::to_string(e.solid_type));
|
||||||
v.push_back(columns[14] + " = " + std::to_string(e.unknown20));
|
v.push_back(columns[14] + " = " + std::to_string(e.incline));
|
||||||
v.push_back(columns[15] + " = " + std::to_string(e.unknown24));
|
v.push_back(columns[15] + " = " + std::to_string(e.unknown24));
|
||||||
v.push_back(columns[16] + " = " + std::to_string(e.unknown60));
|
v.push_back(columns[16] + " = " + std::to_string(e.unknown60));
|
||||||
v.push_back(columns[17] + " = " + std::to_string(e.unknown64));
|
v.push_back(columns[17] + " = " + std::to_string(e.unknown64));
|
||||||
@@ -355,9 +357,9 @@ public:
|
|||||||
v.push_back("'" + Strings::Escape(e.objectname) + "'");
|
v.push_back("'" + Strings::Escape(e.objectname) + "'");
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.icon));
|
v.push_back(std::to_string(e.icon));
|
||||||
v.push_back(std::to_string(e.unknown08));
|
v.push_back(std::to_string(e.size_percentage));
|
||||||
v.push_back(std::to_string(e.unknown10));
|
v.push_back(std::to_string(e.solid_type));
|
||||||
v.push_back(std::to_string(e.unknown20));
|
v.push_back(std::to_string(e.incline));
|
||||||
v.push_back(std::to_string(e.unknown24));
|
v.push_back(std::to_string(e.unknown24));
|
||||||
v.push_back(std::to_string(e.unknown60));
|
v.push_back(std::to_string(e.unknown60));
|
||||||
v.push_back(std::to_string(e.unknown64));
|
v.push_back(std::to_string(e.unknown64));
|
||||||
@@ -414,9 +416,9 @@ public:
|
|||||||
v.push_back("'" + Strings::Escape(e.objectname) + "'");
|
v.push_back("'" + Strings::Escape(e.objectname) + "'");
|
||||||
v.push_back(std::to_string(e.type));
|
v.push_back(std::to_string(e.type));
|
||||||
v.push_back(std::to_string(e.icon));
|
v.push_back(std::to_string(e.icon));
|
||||||
v.push_back(std::to_string(e.unknown08));
|
v.push_back(std::to_string(e.size_percentage));
|
||||||
v.push_back(std::to_string(e.unknown10));
|
v.push_back(std::to_string(e.solid_type));
|
||||||
v.push_back(std::to_string(e.unknown20));
|
v.push_back(std::to_string(e.incline));
|
||||||
v.push_back(std::to_string(e.unknown24));
|
v.push_back(std::to_string(e.unknown24));
|
||||||
v.push_back(std::to_string(e.unknown60));
|
v.push_back(std::to_string(e.unknown60));
|
||||||
v.push_back(std::to_string(e.unknown64));
|
v.push_back(std::to_string(e.unknown64));
|
||||||
@@ -477,9 +479,9 @@ public:
|
|||||||
e.objectname = row[9] ? row[9] : "";
|
e.objectname = row[9] ? row[9] : "";
|
||||||
e.type = static_cast<int32_t>(atoi(row[10]));
|
e.type = static_cast<int32_t>(atoi(row[10]));
|
||||||
e.icon = static_cast<int32_t>(atoi(row[11]));
|
e.icon = static_cast<int32_t>(atoi(row[11]));
|
||||||
e.unknown08 = static_cast<int32_t>(atoi(row[12]));
|
e.size_percentage = strtof(row[12], nullptr);
|
||||||
e.unknown10 = static_cast<int32_t>(atoi(row[13]));
|
e.solid_type = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.unknown20 = static_cast<int32_t>(atoi(row[14]));
|
e.incline = static_cast<int32_t>(atoi(row[14]));
|
||||||
e.unknown24 = static_cast<int32_t>(atoi(row[15]));
|
e.unknown24 = static_cast<int32_t>(atoi(row[15]));
|
||||||
e.unknown60 = static_cast<int32_t>(atoi(row[16]));
|
e.unknown60 = static_cast<int32_t>(atoi(row[16]));
|
||||||
e.unknown64 = static_cast<int32_t>(atoi(row[17]));
|
e.unknown64 = static_cast<int32_t>(atoi(row[17]));
|
||||||
@@ -531,9 +533,9 @@ public:
|
|||||||
e.objectname = row[9] ? row[9] : "";
|
e.objectname = row[9] ? row[9] : "";
|
||||||
e.type = static_cast<int32_t>(atoi(row[10]));
|
e.type = static_cast<int32_t>(atoi(row[10]));
|
||||||
e.icon = static_cast<int32_t>(atoi(row[11]));
|
e.icon = static_cast<int32_t>(atoi(row[11]));
|
||||||
e.unknown08 = static_cast<int32_t>(atoi(row[12]));
|
e.size_percentage = strtof(row[12], nullptr);
|
||||||
e.unknown10 = static_cast<int32_t>(atoi(row[13]));
|
e.solid_type = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.unknown20 = static_cast<int32_t>(atoi(row[14]));
|
e.incline = static_cast<int32_t>(atoi(row[14]));
|
||||||
e.unknown24 = static_cast<int32_t>(atoi(row[15]));
|
e.unknown24 = static_cast<int32_t>(atoi(row[15]));
|
||||||
e.unknown60 = static_cast<int32_t>(atoi(row[16]));
|
e.unknown60 = static_cast<int32_t>(atoi(row[16]));
|
||||||
e.unknown64 = static_cast<int32_t>(atoi(row[17]));
|
e.unknown64 = static_cast<int32_t>(atoi(row[17]));
|
||||||
|
|||||||
@@ -0,0 +1,354 @@
|
|||||||
|
/**
|
||||||
|
* DO NOT MODIFY THIS FILE
|
||||||
|
*
|
||||||
|
* This repository was automatically generated and is NOT to be modified directly.
|
||||||
|
* Any repository modifications are meant to be made to the repository extending the base.
|
||||||
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
|
*
|
||||||
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
|
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EQEMU_BASE_SPAWN2_DISABLED_REPOSITORY_H
|
||||||
|
#define EQEMU_BASE_SPAWN2_DISABLED_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../../database.h"
|
||||||
|
#include "../../strings.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
|
class BaseSpawn2DisabledRepository {
|
||||||
|
public:
|
||||||
|
struct Spawn2Disabled {
|
||||||
|
int64_t id;
|
||||||
|
int32_t spawn2_id;
|
||||||
|
int32_t instance_id;
|
||||||
|
int16_t disabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string PrimaryKey()
|
||||||
|
{
|
||||||
|
return std::string("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Columns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"spawn2_id",
|
||||||
|
"instance_id",
|
||||||
|
"disabled",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> SelectColumns()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"id",
|
||||||
|
"spawn2_id",
|
||||||
|
"instance_id",
|
||||||
|
"disabled",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", Columns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SelectColumnsRaw()
|
||||||
|
{
|
||||||
|
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TableName()
|
||||||
|
{
|
||||||
|
return std::string("spawn2_disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseSelect()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"SELECT {} FROM {}",
|
||||||
|
SelectColumnsRaw(),
|
||||||
|
TableName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BaseInsert()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"INSERT INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Spawn2Disabled NewEntity()
|
||||||
|
{
|
||||||
|
Spawn2Disabled e{};
|
||||||
|
|
||||||
|
e.id = 0;
|
||||||
|
e.spawn2_id = 0;
|
||||||
|
e.instance_id = 0;
|
||||||
|
e.disabled = 0;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Spawn2Disabled GetSpawn2Disabled(
|
||||||
|
const std::vector<Spawn2Disabled> &spawn2_disableds,
|
||||||
|
int spawn2_disabled_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (auto &spawn2_disabled : spawn2_disableds) {
|
||||||
|
if (spawn2_disabled.id == spawn2_disabled_id) {
|
||||||
|
return spawn2_disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Spawn2Disabled FindOne(
|
||||||
|
Database& db,
|
||||||
|
int spawn2_disabled_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
|
spawn2_disabled_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
if (results.RowCount() == 1) {
|
||||||
|
Spawn2Disabled e{};
|
||||||
|
|
||||||
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
|
e.spawn2_id = static_cast<int32_t>(atoi(row[1]));
|
||||||
|
e.instance_id = static_cast<int32_t>(atoi(row[2]));
|
||||||
|
e.disabled = static_cast<int16_t>(atoi(row[3]));
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteOne(
|
||||||
|
Database& db,
|
||||||
|
int spawn2_disabled_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
PrimaryKey(),
|
||||||
|
spawn2_disabled_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UpdateOne(
|
||||||
|
Database& db,
|
||||||
|
const Spawn2Disabled &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto columns = Columns();
|
||||||
|
|
||||||
|
v.push_back(columns[1] + " = " + std::to_string(e.spawn2_id));
|
||||||
|
v.push_back(columns[2] + " = " + std::to_string(e.instance_id));
|
||||||
|
v.push_back(columns[3] + " = " + std::to_string(e.disabled));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"UPDATE {} SET {} WHERE {} = {}",
|
||||||
|
TableName(),
|
||||||
|
Strings::Implode(", ", v),
|
||||||
|
PrimaryKey(),
|
||||||
|
e.id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Spawn2Disabled InsertOne(
|
||||||
|
Database& db,
|
||||||
|
Spawn2Disabled e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.spawn2_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.disabled));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.Success()) {
|
||||||
|
e.id = results.LastInsertedID();
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = NewEntity();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int InsertMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<Spawn2Disabled> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.spawn2_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.disabled));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseInsert(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<Spawn2Disabled> All(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<Spawn2Disabled> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{}",
|
||||||
|
BaseSelect()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
Spawn2Disabled e{};
|
||||||
|
|
||||||
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
|
e.spawn2_id = static_cast<int32_t>(atoi(row[1]));
|
||||||
|
e.instance_id = static_cast<int32_t>(atoi(row[2]));
|
||||||
|
e.disabled = static_cast<int16_t>(atoi(row[3]));
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<Spawn2Disabled> GetWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
std::vector<Spawn2Disabled> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} WHERE {}",
|
||||||
|
BaseSelect(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
Spawn2Disabled e{};
|
||||||
|
|
||||||
|
e.id = strtoll(row[0], nullptr, 10);
|
||||||
|
e.spawn2_id = static_cast<int32_t>(atoi(row[1]));
|
||||||
|
e.instance_id = static_cast<int32_t>(atoi(row[2]));
|
||||||
|
e.disabled = static_cast<int16_t>(atoi(row[3]));
|
||||||
|
|
||||||
|
all_entries.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"DELETE FROM {} WHERE {}",
|
||||||
|
TableName(),
|
||||||
|
where_filter
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Truncate(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"TRUNCATE TABLE {}",
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 GetMaxId(Database& db)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||||
|
PrimaryKey(),
|
||||||
|
TableName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT COUNT(*) FROM {} {}",
|
||||||
|
TableName(),
|
||||||
|
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BASE_SPAWN2_DISABLED_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseSpawn2Repository {
|
class BaseSpawn2Repository {
|
||||||
public:
|
public:
|
||||||
struct Spawn2 {
|
struct Spawn2 {
|
||||||
@@ -33,7 +34,6 @@ public:
|
|||||||
int8_t path_when_zone_idle;
|
int8_t path_when_zone_idle;
|
||||||
uint32_t _condition;
|
uint32_t _condition;
|
||||||
int32_t cond_value;
|
int32_t cond_value;
|
||||||
uint8_t enabled;
|
|
||||||
uint8_t animation;
|
uint8_t animation;
|
||||||
int8_t min_expansion;
|
int8_t min_expansion;
|
||||||
int8_t max_expansion;
|
int8_t max_expansion;
|
||||||
@@ -63,7 +63,6 @@ public:
|
|||||||
"path_when_zone_idle",
|
"path_when_zone_idle",
|
||||||
"_condition",
|
"_condition",
|
||||||
"cond_value",
|
"cond_value",
|
||||||
"enabled",
|
|
||||||
"animation",
|
"animation",
|
||||||
"min_expansion",
|
"min_expansion",
|
||||||
"max_expansion",
|
"max_expansion",
|
||||||
@@ -89,7 +88,6 @@ public:
|
|||||||
"path_when_zone_idle",
|
"path_when_zone_idle",
|
||||||
"_condition",
|
"_condition",
|
||||||
"cond_value",
|
"cond_value",
|
||||||
"enabled",
|
|
||||||
"animation",
|
"animation",
|
||||||
"min_expansion",
|
"min_expansion",
|
||||||
"max_expansion",
|
"max_expansion",
|
||||||
@@ -149,7 +147,6 @@ public:
|
|||||||
e.path_when_zone_idle = 0;
|
e.path_when_zone_idle = 0;
|
||||||
e._condition = 0;
|
e._condition = 0;
|
||||||
e.cond_value = 1;
|
e.cond_value = 1;
|
||||||
e.enabled = 1;
|
|
||||||
e.animation = 0;
|
e.animation = 0;
|
||||||
e.min_expansion = -1;
|
e.min_expansion = -1;
|
||||||
e.max_expansion = -1;
|
e.max_expansion = -1;
|
||||||
@@ -180,8 +177,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
spawn2_id
|
spawn2_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -204,12 +202,11 @@ public:
|
|||||||
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
||||||
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.enabled = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
e.animation = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||||
e.animation = static_cast<uint8_t>(strtoul(row[15], nullptr, 10));
|
e.min_expansion = static_cast<int8_t>(atoi(row[15]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[16]));
|
e.max_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[17]));
|
e.content_flags = row[17] ? row[17] : "";
|
||||||
e.content_flags = row[18] ? row[18] : "";
|
e.content_flags_disabled = row[18] ? row[18] : "";
|
||||||
e.content_flags_disabled = row[19] ? row[19] : "";
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -256,12 +253,11 @@ public:
|
|||||||
v.push_back(columns[11] + " = " + std::to_string(e.path_when_zone_idle));
|
v.push_back(columns[11] + " = " + std::to_string(e.path_when_zone_idle));
|
||||||
v.push_back(columns[12] + " = " + std::to_string(e._condition));
|
v.push_back(columns[12] + " = " + std::to_string(e._condition));
|
||||||
v.push_back(columns[13] + " = " + std::to_string(e.cond_value));
|
v.push_back(columns[13] + " = " + std::to_string(e.cond_value));
|
||||||
v.push_back(columns[14] + " = " + std::to_string(e.enabled));
|
v.push_back(columns[14] + " = " + std::to_string(e.animation));
|
||||||
v.push_back(columns[15] + " = " + std::to_string(e.animation));
|
v.push_back(columns[15] + " = " + std::to_string(e.min_expansion));
|
||||||
v.push_back(columns[16] + " = " + std::to_string(e.min_expansion));
|
v.push_back(columns[16] + " = " + std::to_string(e.max_expansion));
|
||||||
v.push_back(columns[17] + " = " + std::to_string(e.max_expansion));
|
v.push_back(columns[17] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
v.push_back(columns[18] + " = '" + Strings::Escape(e.content_flags) + "'");
|
v.push_back(columns[18] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
v.push_back(columns[19] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -297,7 +293,6 @@ public:
|
|||||||
v.push_back(std::to_string(e.path_when_zone_idle));
|
v.push_back(std::to_string(e.path_when_zone_idle));
|
||||||
v.push_back(std::to_string(e._condition));
|
v.push_back(std::to_string(e._condition));
|
||||||
v.push_back(std::to_string(e.cond_value));
|
v.push_back(std::to_string(e.cond_value));
|
||||||
v.push_back(std::to_string(e.enabled));
|
|
||||||
v.push_back(std::to_string(e.animation));
|
v.push_back(std::to_string(e.animation));
|
||||||
v.push_back(std::to_string(e.min_expansion));
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
v.push_back(std::to_string(e.max_expansion));
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
@@ -346,7 +341,6 @@ public:
|
|||||||
v.push_back(std::to_string(e.path_when_zone_idle));
|
v.push_back(std::to_string(e.path_when_zone_idle));
|
||||||
v.push_back(std::to_string(e._condition));
|
v.push_back(std::to_string(e._condition));
|
||||||
v.push_back(std::to_string(e.cond_value));
|
v.push_back(std::to_string(e.cond_value));
|
||||||
v.push_back(std::to_string(e.enabled));
|
|
||||||
v.push_back(std::to_string(e.animation));
|
v.push_back(std::to_string(e.animation));
|
||||||
v.push_back(std::to_string(e.min_expansion));
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
v.push_back(std::to_string(e.max_expansion));
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
@@ -399,12 +393,11 @@ public:
|
|||||||
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
||||||
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.enabled = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
e.animation = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||||
e.animation = static_cast<uint8_t>(strtoul(row[15], nullptr, 10));
|
e.min_expansion = static_cast<int8_t>(atoi(row[15]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[16]));
|
e.max_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[17]));
|
e.content_flags = row[17] ? row[17] : "";
|
||||||
e.content_flags = row[18] ? row[18] : "";
|
e.content_flags_disabled = row[18] ? row[18] : "";
|
||||||
e.content_flags_disabled = row[19] ? row[19] : "";
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -443,12 +436,11 @@ public:
|
|||||||
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
e.path_when_zone_idle = static_cast<int8_t>(atoi(row[11]));
|
||||||
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
e._condition = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||||
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
e.cond_value = static_cast<int32_t>(atoi(row[13]));
|
||||||
e.enabled = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
e.animation = static_cast<uint8_t>(strtoul(row[14], nullptr, 10));
|
||||||
e.animation = static_cast<uint8_t>(strtoul(row[15], nullptr, 10));
|
e.min_expansion = static_cast<int8_t>(atoi(row[15]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[16]));
|
e.max_expansion = static_cast<int8_t>(atoi(row[16]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[17]));
|
e.content_flags = row[17] ? row[17] : "";
|
||||||
e.content_flags = row[18] ? row[18] : "";
|
e.content_flags_disabled = row[18] ? row[18] : "";
|
||||||
e.content_flags_disabled = row[19] ? row[19] : "";
|
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseSpawnentryRepository {
|
class BaseSpawnentryRepository {
|
||||||
public:
|
public:
|
||||||
struct Spawnentry {
|
struct Spawnentry {
|
||||||
@@ -23,6 +24,8 @@ public:
|
|||||||
int32_t npcID;
|
int32_t npcID;
|
||||||
int16_t chance;
|
int16_t chance;
|
||||||
int32_t condition_value_filter;
|
int32_t condition_value_filter;
|
||||||
|
int16_t min_time;
|
||||||
|
int16_t max_time;
|
||||||
int8_t min_expansion;
|
int8_t min_expansion;
|
||||||
int8_t max_expansion;
|
int8_t max_expansion;
|
||||||
std::string content_flags;
|
std::string content_flags;
|
||||||
@@ -41,6 +44,8 @@ public:
|
|||||||
"npcID",
|
"npcID",
|
||||||
"chance",
|
"chance",
|
||||||
"condition_value_filter",
|
"condition_value_filter",
|
||||||
|
"min_time",
|
||||||
|
"max_time",
|
||||||
"min_expansion",
|
"min_expansion",
|
||||||
"max_expansion",
|
"max_expansion",
|
||||||
"content_flags",
|
"content_flags",
|
||||||
@@ -55,6 +60,8 @@ public:
|
|||||||
"npcID",
|
"npcID",
|
||||||
"chance",
|
"chance",
|
||||||
"condition_value_filter",
|
"condition_value_filter",
|
||||||
|
"min_time",
|
||||||
|
"max_time",
|
||||||
"min_expansion",
|
"min_expansion",
|
||||||
"max_expansion",
|
"max_expansion",
|
||||||
"content_flags",
|
"content_flags",
|
||||||
@@ -103,6 +110,8 @@ public:
|
|||||||
e.npcID = 0;
|
e.npcID = 0;
|
||||||
e.chance = 0;
|
e.chance = 0;
|
||||||
e.condition_value_filter = 1;
|
e.condition_value_filter = 1;
|
||||||
|
e.min_time = 0;
|
||||||
|
e.max_time = 0;
|
||||||
e.min_expansion = -1;
|
e.min_expansion = -1;
|
||||||
e.max_expansion = -1;
|
e.max_expansion = -1;
|
||||||
e.content_flags = "";
|
e.content_flags = "";
|
||||||
@@ -132,8 +141,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
spawnentry_id
|
spawnentry_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -146,10 +156,12 @@ public:
|
|||||||
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
||||||
e.chance = static_cast<int16_t>(atoi(row[2]));
|
e.chance = static_cast<int16_t>(atoi(row[2]));
|
||||||
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[4]));
|
e.min_time = static_cast<int16_t>(atoi(row[4]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[5]));
|
e.max_time = static_cast<int16_t>(atoi(row[5]));
|
||||||
e.content_flags = row[6] ? row[6] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||||
e.content_flags_disabled = row[7] ? row[7] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||||
|
e.content_flags = row[8] ? row[8] : "";
|
||||||
|
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -187,10 +199,12 @@ public:
|
|||||||
v.push_back(columns[1] + " = " + std::to_string(e.npcID));
|
v.push_back(columns[1] + " = " + std::to_string(e.npcID));
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.chance));
|
v.push_back(columns[2] + " = " + std::to_string(e.chance));
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.condition_value_filter));
|
v.push_back(columns[3] + " = " + std::to_string(e.condition_value_filter));
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.min_expansion));
|
v.push_back(columns[4] + " = " + std::to_string(e.min_time));
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.max_expansion));
|
v.push_back(columns[5] + " = " + std::to_string(e.max_time));
|
||||||
v.push_back(columns[6] + " = '" + Strings::Escape(e.content_flags) + "'");
|
v.push_back(columns[6] + " = " + std::to_string(e.min_expansion));
|
||||||
v.push_back(columns[7] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
v.push_back(columns[7] + " = " + std::to_string(e.max_expansion));
|
||||||
|
v.push_back(columns[8] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
|
v.push_back(columns[9] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -216,6 +230,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.npcID));
|
v.push_back(std::to_string(e.npcID));
|
||||||
v.push_back(std::to_string(e.chance));
|
v.push_back(std::to_string(e.chance));
|
||||||
v.push_back(std::to_string(e.condition_value_filter));
|
v.push_back(std::to_string(e.condition_value_filter));
|
||||||
|
v.push_back(std::to_string(e.min_time));
|
||||||
|
v.push_back(std::to_string(e.max_time));
|
||||||
v.push_back(std::to_string(e.min_expansion));
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
v.push_back(std::to_string(e.max_expansion));
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
@@ -253,6 +269,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.npcID));
|
v.push_back(std::to_string(e.npcID));
|
||||||
v.push_back(std::to_string(e.chance));
|
v.push_back(std::to_string(e.chance));
|
||||||
v.push_back(std::to_string(e.condition_value_filter));
|
v.push_back(std::to_string(e.condition_value_filter));
|
||||||
|
v.push_back(std::to_string(e.min_time));
|
||||||
|
v.push_back(std::to_string(e.max_time));
|
||||||
v.push_back(std::to_string(e.min_expansion));
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
v.push_back(std::to_string(e.max_expansion));
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
@@ -294,10 +312,12 @@ public:
|
|||||||
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
||||||
e.chance = static_cast<int16_t>(atoi(row[2]));
|
e.chance = static_cast<int16_t>(atoi(row[2]));
|
||||||
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[4]));
|
e.min_time = static_cast<int16_t>(atoi(row[4]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[5]));
|
e.max_time = static_cast<int16_t>(atoi(row[5]));
|
||||||
e.content_flags = row[6] ? row[6] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||||
e.content_flags_disabled = row[7] ? row[7] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||||
|
e.content_flags = row[8] ? row[8] : "";
|
||||||
|
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -326,10 +346,12 @@ public:
|
|||||||
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
e.npcID = static_cast<int32_t>(atoi(row[1]));
|
||||||
e.chance = static_cast<int16_t>(atoi(row[2]));
|
e.chance = static_cast<int16_t>(atoi(row[2]));
|
||||||
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
e.condition_value_filter = static_cast<int32_t>(atoi(row[3]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[4]));
|
e.min_time = static_cast<int16_t>(atoi(row[4]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[5]));
|
e.max_time = static_cast<int16_t>(atoi(row[5]));
|
||||||
e.content_flags = row[6] ? row[6] : "";
|
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
|
||||||
e.content_flags_disabled = row[7] ? row[7] : "";
|
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
|
||||||
|
e.content_flags = row[8] ? row[8] : "";
|
||||||
|
e.content_flags_disabled = row[9] ? row[9] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,18 +16,19 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseStartingItemsRepository {
|
class BaseStartingItemsRepository {
|
||||||
public:
|
public:
|
||||||
struct StartingItems {
|
struct StartingItems {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
int32_t race;
|
std::string class_list;
|
||||||
int32_t class_;
|
std::string race_list;
|
||||||
int32_t deityid;
|
std::string deity_list;
|
||||||
int32_t zoneid;
|
std::string zone_id_list;
|
||||||
int32_t itemid;
|
uint32_t item_id;
|
||||||
uint8_t item_charges;
|
uint8_t item_charges;
|
||||||
int8_t gm;
|
int32_t status;
|
||||||
int32_t slot;
|
int32_t inventory_slot;
|
||||||
int8_t min_expansion;
|
int8_t min_expansion;
|
||||||
int8_t max_expansion;
|
int8_t max_expansion;
|
||||||
std::string content_flags;
|
std::string content_flags;
|
||||||
@@ -43,14 +44,14 @@ public:
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"id",
|
"id",
|
||||||
"race",
|
"class_list",
|
||||||
"`class`",
|
"race_list",
|
||||||
"deityid",
|
"deity_list",
|
||||||
"zoneid",
|
"zone_id_list",
|
||||||
"itemid",
|
"item_id",
|
||||||
"item_charges",
|
"item_charges",
|
||||||
"gm",
|
"status",
|
||||||
"slot",
|
"inventory_slot",
|
||||||
"min_expansion",
|
"min_expansion",
|
||||||
"max_expansion",
|
"max_expansion",
|
||||||
"content_flags",
|
"content_flags",
|
||||||
@@ -62,14 +63,14 @@ public:
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"id",
|
"id",
|
||||||
"race",
|
"class_list",
|
||||||
"`class`",
|
"race_list",
|
||||||
"deityid",
|
"deity_list",
|
||||||
"zoneid",
|
"zone_id_list",
|
||||||
"itemid",
|
"item_id",
|
||||||
"item_charges",
|
"item_charges",
|
||||||
"gm",
|
"status",
|
||||||
"slot",
|
"inventory_slot",
|
||||||
"min_expansion",
|
"min_expansion",
|
||||||
"max_expansion",
|
"max_expansion",
|
||||||
"content_flags",
|
"content_flags",
|
||||||
@@ -115,14 +116,14 @@ public:
|
|||||||
StartingItems e{};
|
StartingItems e{};
|
||||||
|
|
||||||
e.id = 0;
|
e.id = 0;
|
||||||
e.race = 0;
|
e.class_list = "";
|
||||||
e.class_ = 0;
|
e.race_list = "";
|
||||||
e.deityid = 0;
|
e.deity_list = "";
|
||||||
e.zoneid = 0;
|
e.zone_id_list = "";
|
||||||
e.itemid = 0;
|
e.item_id = 0;
|
||||||
e.item_charges = 1;
|
e.item_charges = 1;
|
||||||
e.gm = 0;
|
e.status = 0;
|
||||||
e.slot = -1;
|
e.inventory_slot = -1;
|
||||||
e.min_expansion = -1;
|
e.min_expansion = -1;
|
||||||
e.max_expansion = -1;
|
e.max_expansion = -1;
|
||||||
e.content_flags = "";
|
e.content_flags = "";
|
||||||
@@ -152,8 +153,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
starting_items_id
|
starting_items_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -163,14 +165,14 @@ public:
|
|||||||
StartingItems e{};
|
StartingItems e{};
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.race = static_cast<int32_t>(atoi(row[1]));
|
e.class_list = row[1] ? row[1] : "";
|
||||||
e.class_ = static_cast<int32_t>(atoi(row[2]));
|
e.race_list = row[2] ? row[2] : "";
|
||||||
e.deityid = static_cast<int32_t>(atoi(row[3]));
|
e.deity_list = row[3] ? row[3] : "";
|
||||||
e.zoneid = static_cast<int32_t>(atoi(row[4]));
|
e.zone_id_list = row[4] ? row[4] : "";
|
||||||
e.itemid = static_cast<int32_t>(atoi(row[5]));
|
e.item_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.gm = static_cast<int8_t>(atoi(row[7]));
|
e.status = static_cast<int32_t>(atoi(row[7]));
|
||||||
e.slot = static_cast<int32_t>(atoi(row[8]));
|
e.inventory_slot = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
|
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
|
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
|
||||||
e.content_flags = row[11] ? row[11] : "";
|
e.content_flags = row[11] ? row[11] : "";
|
||||||
@@ -208,14 +210,14 @@ public:
|
|||||||
|
|
||||||
auto columns = Columns();
|
auto columns = Columns();
|
||||||
|
|
||||||
v.push_back(columns[1] + " = " + std::to_string(e.race));
|
v.push_back(columns[1] + " = '" + Strings::Escape(e.class_list) + "'");
|
||||||
v.push_back(columns[2] + " = " + std::to_string(e.class_));
|
v.push_back(columns[2] + " = '" + Strings::Escape(e.race_list) + "'");
|
||||||
v.push_back(columns[3] + " = " + std::to_string(e.deityid));
|
v.push_back(columns[3] + " = '" + Strings::Escape(e.deity_list) + "'");
|
||||||
v.push_back(columns[4] + " = " + std::to_string(e.zoneid));
|
v.push_back(columns[4] + " = '" + Strings::Escape(e.zone_id_list) + "'");
|
||||||
v.push_back(columns[5] + " = " + std::to_string(e.itemid));
|
v.push_back(columns[5] + " = " + std::to_string(e.item_id));
|
||||||
v.push_back(columns[6] + " = " + std::to_string(e.item_charges));
|
v.push_back(columns[6] + " = " + std::to_string(e.item_charges));
|
||||||
v.push_back(columns[7] + " = " + std::to_string(e.gm));
|
v.push_back(columns[7] + " = " + std::to_string(e.status));
|
||||||
v.push_back(columns[8] + " = " + std::to_string(e.slot));
|
v.push_back(columns[8] + " = " + std::to_string(e.inventory_slot));
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.min_expansion));
|
v.push_back(columns[9] + " = " + std::to_string(e.min_expansion));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.max_expansion));
|
v.push_back(columns[10] + " = " + std::to_string(e.max_expansion));
|
||||||
v.push_back(columns[11] + " = '" + Strings::Escape(e.content_flags) + "'");
|
v.push_back(columns[11] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||||
@@ -242,14 +244,14 @@ public:
|
|||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.race));
|
v.push_back("'" + Strings::Escape(e.class_list) + "'");
|
||||||
v.push_back(std::to_string(e.class_));
|
v.push_back("'" + Strings::Escape(e.race_list) + "'");
|
||||||
v.push_back(std::to_string(e.deityid));
|
v.push_back("'" + Strings::Escape(e.deity_list) + "'");
|
||||||
v.push_back(std::to_string(e.zoneid));
|
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.item_id));
|
||||||
v.push_back(std::to_string(e.item_charges));
|
v.push_back(std::to_string(e.item_charges));
|
||||||
v.push_back(std::to_string(e.gm));
|
v.push_back(std::to_string(e.status));
|
||||||
v.push_back(std::to_string(e.slot));
|
v.push_back(std::to_string(e.inventory_slot));
|
||||||
v.push_back(std::to_string(e.min_expansion));
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
v.push_back(std::to_string(e.max_expansion));
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
@@ -284,14 +286,14 @@ public:
|
|||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
|
|
||||||
v.push_back(std::to_string(e.id));
|
v.push_back(std::to_string(e.id));
|
||||||
v.push_back(std::to_string(e.race));
|
v.push_back("'" + Strings::Escape(e.class_list) + "'");
|
||||||
v.push_back(std::to_string(e.class_));
|
v.push_back("'" + Strings::Escape(e.race_list) + "'");
|
||||||
v.push_back(std::to_string(e.deityid));
|
v.push_back("'" + Strings::Escape(e.deity_list) + "'");
|
||||||
v.push_back(std::to_string(e.zoneid));
|
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
|
||||||
v.push_back(std::to_string(e.itemid));
|
v.push_back(std::to_string(e.item_id));
|
||||||
v.push_back(std::to_string(e.item_charges));
|
v.push_back(std::to_string(e.item_charges));
|
||||||
v.push_back(std::to_string(e.gm));
|
v.push_back(std::to_string(e.status));
|
||||||
v.push_back(std::to_string(e.slot));
|
v.push_back(std::to_string(e.inventory_slot));
|
||||||
v.push_back(std::to_string(e.min_expansion));
|
v.push_back(std::to_string(e.min_expansion));
|
||||||
v.push_back(std::to_string(e.max_expansion));
|
v.push_back(std::to_string(e.max_expansion));
|
||||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||||
@@ -330,14 +332,14 @@ public:
|
|||||||
StartingItems e{};
|
StartingItems e{};
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.race = static_cast<int32_t>(atoi(row[1]));
|
e.class_list = row[1] ? row[1] : "";
|
||||||
e.class_ = static_cast<int32_t>(atoi(row[2]));
|
e.race_list = row[2] ? row[2] : "";
|
||||||
e.deityid = static_cast<int32_t>(atoi(row[3]));
|
e.deity_list = row[3] ? row[3] : "";
|
||||||
e.zoneid = static_cast<int32_t>(atoi(row[4]));
|
e.zone_id_list = row[4] ? row[4] : "";
|
||||||
e.itemid = static_cast<int32_t>(atoi(row[5]));
|
e.item_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.gm = static_cast<int8_t>(atoi(row[7]));
|
e.status = static_cast<int32_t>(atoi(row[7]));
|
||||||
e.slot = static_cast<int32_t>(atoi(row[8]));
|
e.inventory_slot = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
|
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
|
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
|
||||||
e.content_flags = row[11] ? row[11] : "";
|
e.content_flags = row[11] ? row[11] : "";
|
||||||
@@ -367,14 +369,14 @@ public:
|
|||||||
StartingItems e{};
|
StartingItems e{};
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.race = static_cast<int32_t>(atoi(row[1]));
|
e.class_list = row[1] ? row[1] : "";
|
||||||
e.class_ = static_cast<int32_t>(atoi(row[2]));
|
e.race_list = row[2] ? row[2] : "";
|
||||||
e.deityid = static_cast<int32_t>(atoi(row[3]));
|
e.deity_list = row[3] ? row[3] : "";
|
||||||
e.zoneid = static_cast<int32_t>(atoi(row[4]));
|
e.zone_id_list = row[4] ? row[4] : "";
|
||||||
e.itemid = static_cast<int32_t>(atoi(row[5]));
|
e.item_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||||
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
e.item_charges = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||||
e.gm = static_cast<int8_t>(atoi(row[7]));
|
e.status = static_cast<int32_t>(atoi(row[7]));
|
||||||
e.slot = static_cast<int32_t>(atoi(row[8]));
|
e.inventory_slot = static_cast<int32_t>(atoi(row[8]));
|
||||||
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
|
e.min_expansion = static_cast<int8_t>(atoi(row[9]));
|
||||||
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
|
e.max_expansion = static_cast<int8_t>(atoi(row[10]));
|
||||||
e.content_flags = row[11] ? row[11] : "";
|
e.content_flags = row[11] ? row[11] : "";
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||||
|
#define EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../database.h"
|
||||||
|
#include "../strings.h"
|
||||||
|
#include "base/base_bot_starting_items_repository.h"
|
||||||
|
|
||||||
|
class BotStartingItemsRepository: public BaseBotStartingItemsRepository {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file was auto generated and can be modified and extended upon
|
||||||
|
*
|
||||||
|
* Base repository methods are automatically
|
||||||
|
* generated in the "base" version of this repository. The base repository
|
||||||
|
* is immutable and to be left untouched, while methods in this class
|
||||||
|
* are used as extension methods for more specific persistence-layer
|
||||||
|
* accessors or mutators.
|
||||||
|
*
|
||||||
|
* Base Methods (Subject to be expanded upon in time)
|
||||||
|
*
|
||||||
|
* Note: Not all tables are designed appropriately to fit functionality with all base methods
|
||||||
|
*
|
||||||
|
* InsertOne
|
||||||
|
* UpdateOne
|
||||||
|
* DeleteOne
|
||||||
|
* FindOne
|
||||||
|
* GetWhere(std::string where_filter)
|
||||||
|
* DeleteWhere(std::string where_filter)
|
||||||
|
* InsertMany
|
||||||
|
* All
|
||||||
|
*
|
||||||
|
* Example custom methods in a repository
|
||||||
|
*
|
||||||
|
* BotStartingItemsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||||
|
* BotStartingItemsRepository::GetWhereNeverExpires()
|
||||||
|
* BotStartingItemsRepository::GetWhereXAndY()
|
||||||
|
* BotStartingItemsRepository::DeleteWhereXAndY()
|
||||||
|
*
|
||||||
|
* Most of the above could be covered by base methods, but if you as a developer
|
||||||
|
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||||
|
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||||
|
* method and encapsulate filters there
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Custom extended repository methods here
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
|
||||||
@@ -120,6 +120,8 @@ public:
|
|||||||
{.parent_command = "set", .sub_command = "title_suffix", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "titlesuffix"},
|
{.parent_command = "set", .sub_command = "title_suffix", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "titlesuffix"},
|
||||||
{.parent_command = "set", .sub_command = "weather", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "weather"},
|
{.parent_command = "set", .sub_command = "weather", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "weather"},
|
||||||
{.parent_command = "set", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zclip|zcolor|zheader|zonelock|zsafecoords|zsky|zunderworld"},
|
{.parent_command = "set", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zclip|zcolor|zheader|zonelock|zsafecoords|zsky|zunderworld"},
|
||||||
|
{.parent_command = "show", .sub_command = "aas", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showaas"},
|
||||||
|
{.parent_command = "show", .sub_command = "aa_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showaapoints|showaapts"},
|
||||||
{.parent_command = "show", .sub_command = "aggro", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "aggro"},
|
{.parent_command = "show", .sub_command = "aggro", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "aggro"},
|
||||||
{.parent_command = "show", .sub_command = "buffs", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showbuffs"},
|
{.parent_command = "show", .sub_command = "buffs", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showbuffs"},
|
||||||
{.parent_command = "show", .sub_command = "buried_corpse_count", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getplayerburiedcorpsecount"},
|
{.parent_command = "show", .sub_command = "buried_corpse_count", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getplayerburiedcorpsecount"},
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef EQEMU_KEYRING_REPOSITORY_H
|
||||||
|
#define EQEMU_KEYRING_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../database.h"
|
||||||
|
#include "../strings.h"
|
||||||
|
#include "base/base_keyring_repository.h"
|
||||||
|
|
||||||
|
class KeyringRepository: public BaseKeyringRepository {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file was auto generated and can be modified and extended upon
|
||||||
|
*
|
||||||
|
* Base repository methods are automatically
|
||||||
|
* generated in the "base" version of this repository. The base repository
|
||||||
|
* is immutable and to be left untouched, while methods in this class
|
||||||
|
* are used as extension methods for more specific persistence-layer
|
||||||
|
* accessors or mutators.
|
||||||
|
*
|
||||||
|
* Base Methods (Subject to be expanded upon in time)
|
||||||
|
*
|
||||||
|
* Note: Not all tables are designed appropriately to fit functionality with all base methods
|
||||||
|
*
|
||||||
|
* InsertOne
|
||||||
|
* UpdateOne
|
||||||
|
* DeleteOne
|
||||||
|
* FindOne
|
||||||
|
* GetWhere(std::string where_filter)
|
||||||
|
* DeleteWhere(std::string where_filter)
|
||||||
|
* InsertMany
|
||||||
|
* All
|
||||||
|
*
|
||||||
|
* Example custom methods in a repository
|
||||||
|
*
|
||||||
|
* KeyringRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||||
|
* KeyringRepository::GetWhereNeverExpires()
|
||||||
|
* KeyringRepository::GetWhereXAndY()
|
||||||
|
* KeyringRepository::DeleteWhereXAndY()
|
||||||
|
*
|
||||||
|
* Most of the above could be covered by base methods, but if you as a developer
|
||||||
|
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||||
|
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||||
|
* method and encapsulate filters there
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Custom extended repository methods here
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_KEYRING_REPOSITORY_H
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef EQEMU_SPAWN2_DISABLED_REPOSITORY_H
|
||||||
|
#define EQEMU_SPAWN2_DISABLED_REPOSITORY_H
|
||||||
|
|
||||||
|
#include "../database.h"
|
||||||
|
#include "../strings.h"
|
||||||
|
#include "base/base_spawn2_disabled_repository.h"
|
||||||
|
|
||||||
|
class Spawn2DisabledRepository: public BaseSpawn2DisabledRepository {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file was auto generated and can be modified and extended upon
|
||||||
|
*
|
||||||
|
* Base repository methods are automatically
|
||||||
|
* generated in the "base" version of this repository. The base repository
|
||||||
|
* is immutable and to be left untouched, while methods in this class
|
||||||
|
* are used as extension methods for more specific persistence-layer
|
||||||
|
* accessors or mutators.
|
||||||
|
*
|
||||||
|
* Base Methods (Subject to be expanded upon in time)
|
||||||
|
*
|
||||||
|
* Note: Not all tables are designed appropriately to fit functionality with all base methods
|
||||||
|
*
|
||||||
|
* InsertOne
|
||||||
|
* UpdateOne
|
||||||
|
* DeleteOne
|
||||||
|
* FindOne
|
||||||
|
* GetWhere(std::string where_filter)
|
||||||
|
* DeleteWhere(std::string where_filter)
|
||||||
|
* InsertMany
|
||||||
|
* All
|
||||||
|
*
|
||||||
|
* Example custom methods in a repository
|
||||||
|
*
|
||||||
|
* Spawn2DisabledRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||||
|
* Spawn2DisabledRepository::GetWhereNeverExpires()
|
||||||
|
* Spawn2DisabledRepository::GetWhereXAndY()
|
||||||
|
* Spawn2DisabledRepository::DeleteWhereXAndY()
|
||||||
|
*
|
||||||
|
* Most of the above could be covered by base methods, but if you as a developer
|
||||||
|
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||||
|
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||||
|
* method and encapsulate filters there
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Custom extended repository methods here
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //EQEMU_SPAWN2_DISABLED_REPOSITORY_H
|
||||||
@@ -303,6 +303,9 @@ RULE_BOOL(World, EnforceCharacterLimitAtLogin, false, "Enforce the limit for cha
|
|||||||
RULE_BOOL(World, EnableDevTools, true, "Enable or Disable the Developer Tools globally (Most of the time you want this enabled)")
|
RULE_BOOL(World, EnableDevTools, true, "Enable or Disable the Developer Tools globally (Most of the time you want this enabled)")
|
||||||
RULE_BOOL(World, EnableChecksumVerification, false, "Enable or Disable the Checksum Verification for eqgame.exe and spells_us.txt")
|
RULE_BOOL(World, EnableChecksumVerification, false, "Enable or Disable the Checksum Verification for eqgame.exe and spells_us.txt")
|
||||||
RULE_INT(World, MaximumQuestErrors, 30, "Changes the maximum number of quest errors that can be displayed in #questerrors, default is 30")
|
RULE_INT(World, MaximumQuestErrors, 30, "Changes the maximum number of quest errors that can be displayed in #questerrors, default is 30")
|
||||||
|
RULE_INT(World, BootHour, 0, "Sets the in-game hour world will set when it first boots. 0-24 are valid options, where 0 disables this rule")
|
||||||
|
RULE_BOOL(World, UseItemLinksForKeyRing, false, "Uses item links for Key Ring Listing instead of item name")
|
||||||
|
RULE_BOOL(World, UseOldShadowKnightClassExport, true, "Disable to have Shadowknight show as Shadow Knight (live-like)")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Zone)
|
RULE_CATEGORY(Zone)
|
||||||
@@ -456,6 +459,8 @@ RULE_INT(Spells, WizardCritMinimumRandomRatio, 20, "The minimum value for the ra
|
|||||||
RULE_INT(Spells, WizardCritMaximumRandomRatio, 70, "The maximum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 70 for vanilla values.")
|
RULE_INT(Spells, WizardCritMaximumRandomRatio, 70, "The maximum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 70 for vanilla values.")
|
||||||
RULE_INT(Spells, DefensiveProcPenaltyLevelGap, 6, "Defensive Proc Penalty Level Gap where procs start losing their proc rate at RuleR(Spells, DefensiveProcPenaltyModifier)% per level difference")
|
RULE_INT(Spells, DefensiveProcPenaltyLevelGap, 6, "Defensive Proc Penalty Level Gap where procs start losing their proc rate at RuleR(Spells, DefensiveProcPenaltyModifier)% per level difference")
|
||||||
RULE_REAL(Spells, DefensiveProcPenaltyLevelGapModifier, 10.0f, "Defensive Proc Penalty Level Gap Modifier where procs start losing their proc rate at defined % after RuleI(Spells, DefensiveProcLevelGap) level difference")
|
RULE_REAL(Spells, DefensiveProcPenaltyLevelGapModifier, 10.0f, "Defensive Proc Penalty Level Gap Modifier where procs start losing their proc rate at defined % after RuleI(Spells, DefensiveProcLevelGap) level difference")
|
||||||
|
RULE_BOOL(Spells, DOTBonusDamageSplitOverDuration, true, "Disable to have Damage Over Time total bonus damage added to each tick instead of divided across duration")
|
||||||
|
RULE_BOOL(Spells, HOTBonusHealingSplitOverDuration, true, "Disable to have Heal Over Time total bonus healing added to each tick instead of divided across duration")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Combat)
|
RULE_CATEGORY(Combat)
|
||||||
@@ -530,6 +535,8 @@ RULE_BOOL(Combat, BackstabIgnoresElemental, false, "Enable or disable Elemental
|
|||||||
RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.")
|
RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.")
|
||||||
RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.")
|
RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.")
|
||||||
RULE_BOOL(Combat, WaterMatchRequiredForAutoFireLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for AutoFire LoS to pass.")
|
RULE_BOOL(Combat, WaterMatchRequiredForAutoFireLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for AutoFire LoS to pass.")
|
||||||
|
RULE_INT(Combat, ExtraAllowedKickClassesBitmask, 0, "Bitmask for allowing extra classes beyond Warrior, Ranger, Beastlord, and Berserker to kick, No Extra Classes (0) by default")
|
||||||
|
RULE_INT(Combat, MaxProcs, 4, "Adjustable maximum number of procs per round, the hard cap is MAX_PROCS (11). Requires mob repop or client zone when changed")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(NPC)
|
RULE_CATEGORY(NPC)
|
||||||
@@ -646,6 +653,12 @@ RULE_BOOL(Bots, ResurrectionSickness, true, "Use Resurrection Sickness based on
|
|||||||
RULE_INT(Bots, OldResurrectionSicknessSpell, 757, "757 is Default Old Resurrection Sickness Spell")
|
RULE_INT(Bots, OldResurrectionSicknessSpell, 757, "757 is Default Old Resurrection Sickness Spell")
|
||||||
RULE_INT(Bots, ResurrectionSicknessSpell, 756, "756 is Default Resurrection Sickness Spell")
|
RULE_INT(Bots, ResurrectionSicknessSpell, 756, "756 is Default Resurrection Sickness Spell")
|
||||||
RULE_BOOL(Bots, AllowPickpocketCommand, true, "Allows the use of the bot command 'pickpocket'")
|
RULE_BOOL(Bots, AllowPickpocketCommand, true, "Allows the use of the bot command 'pickpocket'")
|
||||||
|
RULE_BOOL(Bots, BotHealOnLevel, false, "Setting whether a bot should heal completely when leveling. Default FALSE.")
|
||||||
|
RULE_INT(Bots, AutosaveIntervalSeconds, 300, "Number of seconds after which a timer is triggered which stores the bot data. The value 0 means no periodic automatic saving.")
|
||||||
|
RULE_BOOL(Bots, CazicTouchBotsOwner, true, "Default True. Cazic Touch/DT will hit bot owner rather than bot.")
|
||||||
|
RULE_INT(Bots, BotsClickItemsMinLvl, 1, "Minimum level for bots to be able to use ^clickitem. Default 1.")
|
||||||
|
RULE_BOOL(Bots, BotsCanClickItems, true, "Enabled the ability for bots to click items they have equipped. Default TRUE")
|
||||||
|
RULE_BOOL(Bots, CanClickMageEpicV1, true, "Whether or not bots are allowed to click Mage Epic 1.0. Default TRUE")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Chat)
|
RULE_CATEGORY(Chat)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct eq_cpu_info_s {
|
typedef struct eq_cpu_info_s {
|
||||||
std::string model;
|
std::string model;
|
||||||
|
|||||||
+9
-9
@@ -461,12 +461,12 @@ struct SPackSendQueue {
|
|||||||
uchar buffer[0];
|
uchar buffer[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerZoneStateChange_struct {
|
struct ServerZoneStateChange_Struct {
|
||||||
uint32 ZoneServerID;
|
uint32 zone_server_id;
|
||||||
char adminname[64];
|
uint32 zone_id;
|
||||||
uint32 zoneid;
|
uint16 instance_id;
|
||||||
uint16 instanceid;
|
bool is_static;
|
||||||
bool makestatic;
|
char admin_name[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerZoneIncomingClient_Struct {
|
struct ServerZoneIncomingClient_Struct {
|
||||||
@@ -1077,7 +1077,7 @@ struct ServerRaidMessage_Struct {
|
|||||||
|
|
||||||
struct ServerRaidMOTD_Struct {
|
struct ServerRaidMOTD_Struct {
|
||||||
uint32 rid;
|
uint32 rid;
|
||||||
char motd[0];
|
char motd[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerRaidNote_Struct {
|
struct ServerRaidNote_Struct {
|
||||||
@@ -1142,10 +1142,10 @@ struct ServerInstanceUpdateTime_Struct
|
|||||||
uint32 new_duration;
|
uint32 new_duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerSpawnStatusChange_Struct
|
struct ServerSpawnStatusChange_Struct {
|
||||||
{
|
|
||||||
uint32 id;
|
uint32 id;
|
||||||
bool new_status;
|
bool new_status;
|
||||||
|
uint32 instance_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerQGlobalUpdate_Struct
|
struct ServerQGlobalUpdate_Struct
|
||||||
|
|||||||
+78
-35
@@ -41,6 +41,7 @@
|
|||||||
#include "repositories/criteria/content_filter_criteria.h"
|
#include "repositories/criteria/content_filter_criteria.h"
|
||||||
#include "repositories/account_repository.h"
|
#include "repositories/account_repository.h"
|
||||||
#include "repositories/faction_association_repository.h"
|
#include "repositories/faction_association_repository.h"
|
||||||
|
#include "repositories/starting_items_repository.h"
|
||||||
#include "path_manager.h"
|
#include "path_manager.h"
|
||||||
#include "repositories/loottable_repository.h"
|
#include "repositories/loottable_repository.h"
|
||||||
|
|
||||||
@@ -51,7 +52,9 @@ namespace ItemField
|
|||||||
#define F(x) x,
|
#define F(x) x,
|
||||||
#include "item_fieldlist.h"
|
#include "item_fieldlist.h"
|
||||||
#undef F
|
#undef F
|
||||||
updated
|
updated,
|
||||||
|
minstatus,
|
||||||
|
comment,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,45 +447,81 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQ::InventoryProfile* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
|
bool SharedDatabase::SetStartingItems(
|
||||||
|
PlayerProfile_Struct *pp,
|
||||||
|
EQ::InventoryProfile *inv,
|
||||||
|
uint32 si_race,
|
||||||
|
uint32 si_class,
|
||||||
|
uint32 si_deity,
|
||||||
|
uint32 si_current_zone,
|
||||||
|
char *si_name,
|
||||||
|
int admin_level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const EQ::ItemData *item_data;
|
||||||
|
|
||||||
const EQ::ItemData *myitem;
|
const auto &l = StartingItemsRepository::All(*this);
|
||||||
|
|
||||||
const std::string query = StringFormat(
|
if (l.empty()) {
|
||||||
"SELECT itemid, item_charges, slot FROM starting_items "
|
|
||||||
"WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND "
|
|
||||||
"(deityid = %i or deityid = 0) AND (zoneid = %i or zoneid = 0) AND "
|
|
||||||
"gm <= %i %s ORDER BY id",
|
|
||||||
si_race,
|
|
||||||
si_class,
|
|
||||||
si_deity,
|
|
||||||
si_current_zone,
|
|
||||||
admin_level,
|
|
||||||
ContentFilterCriteria::apply().c_str()
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<StartingItemsRepository::StartingItems> v;
|
||||||
|
|
||||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
for (const auto &e : l) {
|
||||||
const int32 itemid = Strings::ToInt(row[0]);
|
const auto &classes = Strings::Split(e.class_list, "|");
|
||||||
const int32 charges = Strings::ToInt(row[1]);
|
const auto &deities = Strings::Split(e.deity_list, "|");
|
||||||
int32 slot = Strings::ToInt(row[2]);
|
const auto &races = Strings::Split(e.race_list, "|");
|
||||||
myitem = GetItem(itemid);
|
const auto &zones = Strings::Split(e.zone_id_list, "|");
|
||||||
|
|
||||||
if(!myitem)
|
const std::string &all = std::to_string(0);
|
||||||
|
|
||||||
|
if (classes[0] != all) {
|
||||||
|
if (!Strings::Contains(classes, std::to_string(si_class))) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const EQ::ItemInstance* myinst = CreateBaseItem(myitem, charges);
|
if (deities[0] != all) {
|
||||||
|
if (!Strings::Contains(deities, std::to_string(si_deity))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(slot < 0)
|
if (races[0] != all) {
|
||||||
slot = inv->FindFreeSlot(0, 0);
|
if (!Strings::Contains(races, std::to_string(si_race))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inv->PutItem(slot, *myinst);
|
if (zones[0] != all) {
|
||||||
safe_delete(myinst);
|
if (!Strings::Contains(zones, std::to_string(si_current_zone))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v.emplace_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &e : v) {
|
||||||
|
const uint32 item_id = e.item_id;
|
||||||
|
const uint8 item_charges = e.item_charges;
|
||||||
|
int32 slot = e.inventory_slot;
|
||||||
|
|
||||||
|
item_data = GetItem(item_id);
|
||||||
|
|
||||||
|
if (!item_data) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto *inst = CreateBaseItem(item_data, item_charges);
|
||||||
|
|
||||||
|
if (slot < EQ::invslot::slotCharm) {
|
||||||
|
slot = inv->FindFreeSlot(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
inv->PutItem(slot, *inst);
|
||||||
|
safe_delete(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -965,7 +1004,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
#define F(x) "`"#x"`,"
|
#define F(x) "`"#x"`,"
|
||||||
#include "item_fieldlist.h"
|
#include "item_fieldlist.h"
|
||||||
#undef F
|
#undef F
|
||||||
"updated FROM items ORDER BY id";
|
"updated, minstatus, comment FROM items ORDER BY id";
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return;
|
return;
|
||||||
@@ -977,9 +1016,13 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
|||||||
// Unique Identifier
|
// Unique Identifier
|
||||||
item.ID = Strings::ToUnsignedInt(row[ItemField::id]);
|
item.ID = Strings::ToUnsignedInt(row[ItemField::id]);
|
||||||
|
|
||||||
// Name and Lore
|
// Minimum Status
|
||||||
|
item.MinStatus = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::minstatus]));
|
||||||
|
|
||||||
|
// Name, Lore, and Comment
|
||||||
strn0cpy(item.Name, row[ItemField::name], sizeof(item.Name));
|
strn0cpy(item.Name, row[ItemField::name], sizeof(item.Name));
|
||||||
strn0cpy(item.Lore, row[ItemField::lore], sizeof(item.Lore));
|
strn0cpy(item.Lore, row[ItemField::lore], sizeof(item.Lore));
|
||||||
|
strn0cpy(item.Comment, row[ItemField::comment], sizeof(item.Comment));
|
||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
item.ArtifactFlag = Strings::ToBool(row[ItemField::artifactflag]);
|
item.ArtifactFlag = Strings::ToBool(row[ItemField::artifactflag]);
|
||||||
@@ -1765,7 +1808,7 @@ bool SharedDatabase::LoadSkillCaps(const std::string &prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SharedDatabase::LoadSkillCaps(void *data) {
|
void SharedDatabase::LoadSkillCaps(void *data) {
|
||||||
const uint32 class_count = PLAYER_CLASS_COUNT;
|
const uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||||
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||||
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||||
uint16 *skill_caps_table = static_cast<uint16*>(data);
|
uint16 *skill_caps_table = static_cast<uint16*>(data);
|
||||||
@@ -1805,7 +1848,7 @@ uint16 SharedDatabase::GetSkillCap(uint8 Class_, EQ::skills::SkillType Skill, ui
|
|||||||
SkillMaxLevel = RuleI(Character, MaxLevel);
|
SkillMaxLevel = RuleI(Character, MaxLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32 class_count = PLAYER_CLASS_COUNT;
|
const uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||||
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||||
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||||
if(Class_ > class_count || static_cast<uint32>(Skill) > skill_count || Level > level_count) {
|
if(Class_ > class_count || static_cast<uint32>(Skill) > skill_count || Level > level_count) {
|
||||||
@@ -1835,7 +1878,7 @@ uint8 SharedDatabase::GetTrainLevel(uint8 Class_, EQ::skills::SkillType Skill, u
|
|||||||
SkillMaxLevel = RuleI(Character, MaxLevel);
|
SkillMaxLevel = RuleI(Character, MaxLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32 class_count = PLAYER_CLASS_COUNT;
|
const uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||||
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
const uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||||
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
const uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||||
if(Class_ > class_count || static_cast<uint32>(Skill) > skill_count || Level > level_count) {
|
if(Class_ > class_count || static_cast<uint32>(Skill) > skill_count || Level > level_count) {
|
||||||
@@ -2018,7 +2061,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
|||||||
sp[tempid].environment_type=Strings::ToInt(row[102]);
|
sp[tempid].environment_type=Strings::ToInt(row[102]);
|
||||||
sp[tempid].time_of_day=Strings::ToInt(row[103]);
|
sp[tempid].time_of_day=Strings::ToInt(row[103]);
|
||||||
|
|
||||||
for(y=0; y < PLAYER_CLASS_COUNT;y++)
|
for(y=0; y < Class::PLAYER_CLASS_COUNT;y++)
|
||||||
sp[tempid].classes[y]=Strings::ToInt(row[104+y]);
|
sp[tempid].classes[y]=Strings::ToInt(row[104+y]);
|
||||||
|
|
||||||
sp[tempid].casting_animation=Strings::ToInt(row[120]);
|
sp[tempid].casting_animation=Strings::ToInt(row[120]);
|
||||||
|
|||||||
+3
-3
@@ -666,7 +666,7 @@ bool IsBardSong(uint16 spell_id)
|
|||||||
const auto& spell = spells[spell_id];
|
const auto& spell = spells[spell_id];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
spell.classes[BARD - 1] < UINT8_MAX &&
|
spell.classes[Class::Bard - 1] < UINT8_MAX &&
|
||||||
!spell.is_discipline
|
!spell.is_discipline
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
@@ -780,7 +780,7 @@ uint8 GetSpellMinimumLevel(uint16 spell_id)
|
|||||||
|
|
||||||
const auto& spell = spells[spell_id];
|
const auto& spell = spells[spell_id];
|
||||||
|
|
||||||
for (int i = 0; i < PLAYER_CLASS_COUNT; i++) {
|
for (int i = 0; i < Class::PLAYER_CLASS_COUNT; i++) {
|
||||||
if (spell.classes[i] < minimum_level) {
|
if (spell.classes[i] < minimum_level) {
|
||||||
minimum_level = spell.classes[i];
|
minimum_level = spell.classes[i];
|
||||||
}
|
}
|
||||||
@@ -798,7 +798,7 @@ uint8 GetSpellLevel(uint16 spell_id, uint8 class_id)
|
|||||||
return UINT8_MAX;
|
return UINT8_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class_id >= PLAYER_CLASS_COUNT) {
|
if (class_id >= Class::PLAYER_CLASS_COUNT) {
|
||||||
return UINT8_MAX;
|
return UINT8_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1369,7 +1369,7 @@ struct SPDat_Spell_Struct
|
|||||||
/* 101 */ int8 zone_type; // 01=Outdoors, 02=dungeons, ff=Any -- ZONETYPE
|
/* 101 */ int8 zone_type; // 01=Outdoors, 02=dungeons, ff=Any -- ZONETYPE
|
||||||
/* 102 */ int8 environment_type; // -- ENVIRONMENTTYPE
|
/* 102 */ int8 environment_type; // -- ENVIRONMENTTYPE
|
||||||
/* 103 */ int8 time_of_day; // -- TIMEOFDAY
|
/* 103 */ int8 time_of_day; // -- TIMEOFDAY
|
||||||
/* 104 */ uint8 classes[PLAYER_CLASS_COUNT]; // Classes, and their min levels -- WARRIORMIN ... BERSERKERMIN
|
/* 104 */ uint8 classes[Class::PLAYER_CLASS_COUNT]; // Classes, and their min levels -- WARRIORMIN ... BERSERKERMIN
|
||||||
/* 120 */ uint8 casting_animation; // -- CASTINGANIM
|
/* 120 */ uint8 casting_animation; // -- CASTINGANIM
|
||||||
/* 121 */ //uint8 TargetAnim; // -- TARGETANIM
|
/* 121 */ //uint8 TargetAnim; // -- TARGETANIM
|
||||||
/* 122 */ //uint32 TravelType; // -- TRAVELTYPE
|
/* 122 */ //uint32 TravelType; // -- TRAVELTYPE
|
||||||
|
|||||||
+22
-15
@@ -42,10 +42,32 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//Const char based
|
//Const char based
|
||||||
#include "strings_legacy.cpp" // legacy c functions
|
#include "strings_legacy.cpp" // legacy c functions
|
||||||
#include "strings_misc.cpp" // anything non "Strings" scoped
|
#include "strings_misc.cpp" // anything non "Strings" scoped
|
||||||
|
|
||||||
|
std::string Strings::Random(size_t length)
|
||||||
|
{
|
||||||
|
static auto &chrs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
thread_local static std::mt19937 rg{std::random_device{}()};
|
||||||
|
|
||||||
|
thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
|
||||||
|
s.reserve(length);
|
||||||
|
|
||||||
|
while (length--) {
|
||||||
|
s += chrs[pick(rg)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> Strings::Split(const std::string &str, const char delim)
|
std::vector<std::string> Strings::Split(const std::string &str, const char delim)
|
||||||
{
|
{
|
||||||
std::vector<std::string> ret;
|
std::vector<std::string> ret;
|
||||||
@@ -783,21 +805,6 @@ bool Strings::ToBool(const std::string& bool_string)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a random string of specified length
|
|
||||||
std::string Strings::Random(size_t length)
|
|
||||||
{
|
|
||||||
auto randchar = []() -> char {
|
|
||||||
const char charset[] = "0123456789"
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
"abcdefghijklmnopqrstuvwxyz";
|
|
||||||
const size_t max_index = (sizeof(charset) - 1);
|
|
||||||
return charset[static_cast<size_t>(std::rand()) % max_index];
|
|
||||||
};
|
|
||||||
std::string str(length, 0);
|
|
||||||
std::generate_n(str.begin(), length, randchar);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// a wrapper for stoi which will return a fallback if the string
|
// a wrapper for stoi which will return a fallback if the string
|
||||||
// fails to cast to a number
|
// fails to cast to a number
|
||||||
int Strings::ToInt(const std::string &s, int fallback)
|
int Strings::ToInt(const std::string &s, int fallback)
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ public:
|
|||||||
value = strtod(tmp_str.data(), nullptr);
|
value = strtod(tmp_str.data(), nullptr);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string StringFormat(const char *format, ...);
|
const std::string StringFormat(const char *format, ...);
|
||||||
|
|||||||
+3
-3
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Build variables
|
// Build variables
|
||||||
// these get injected during the build pipeline
|
// these get injected during the build pipeline
|
||||||
#define CURRENT_VERSION "22.26.0-dev" // always append -dev to the current version for custom-builds
|
#define CURRENT_VERSION "22.37.0-dev" // always append -dev to the current version for custom-builds
|
||||||
#define LOGIN_VERSION "0.8.0"
|
#define LOGIN_VERSION "0.8.0"
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
@@ -42,9 +42,9 @@
|
|||||||
* 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 9235
|
#define CURRENT_BINARY_DATABASE_VERSION 9247
|
||||||
|
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9041
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -121,43 +121,25 @@ bool Database::GetLoginTokenDataFromToken(
|
|||||||
std::string &user
|
std::string &user
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto query = fmt::format(
|
auto query = fmt::format("SELECT login_server, username, account_id FROM login_tickets WHERE expires > NOW()"
|
||||||
"SELECT tbllogintokens.Id, tbllogintokens.IpAddress, tbllogintokenclaims.Name, tbllogintokenclaims.Value FROM tbllogintokens "
|
" AND id='{0}' AND ip_address='{1}' LIMIT 1",
|
||||||
"JOIN tbllogintokenclaims ON tbllogintokens.Id = tbllogintokenclaims.TokenId WHERE tbllogintokens.Expires > NOW() "
|
|
||||||
"AND tbllogintokens.Id='{0}' AND tbllogintokens.IpAddress='{1}'",
|
|
||||||
Strings::Escape(token),
|
Strings::Escape(token),
|
||||||
Strings::Escape(ip)
|
Strings::Escape(ip));
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (results.RowCount() == 0 || !results.Success()) {
|
if (results.RowCount() == 0 || !results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found_username = false;
|
|
||||||
bool found_login_id = false;
|
|
||||||
bool found_login_server_name = false;
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
if (strcmp(row[2], "username") == 0) {
|
db_loginserver = row[0];
|
||||||
user = row[3];
|
user = row[1];
|
||||||
found_username = true;
|
db_account_id = Strings::ToUnsignedInt(row[2]);
|
||||||
continue;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(row[2], "login_server_id") == 0) {
|
return false;
|
||||||
db_account_id = Strings::ToUnsignedInt(row[3]);
|
|
||||||
found_login_id = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(row[2], "login_server_name") == 0) {
|
|
||||||
db_loginserver = row[3];
|
|
||||||
found_login_server_name = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found_username && found_login_id && found_login_server_name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
DROP TABLE IF EXISTS `login_tickets`;
|
||||||
|
CREATE TABLE `login_tickets` (
|
||||||
|
`id` VARCHAR(128) NOT NULL,
|
||||||
|
`login_server` TEXT NOT NULL,
|
||||||
|
`username` TEXT NOT NULL,
|
||||||
|
`account_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`ip_address` VARCHAR(45) NOT NULL,
|
||||||
|
`expires` DATETIME NOT NULL,
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
)
|
||||||
|
ENGINE=InnoDB;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eqemu-server",
|
"name": "eqemu-server",
|
||||||
"version": "22.26.0",
|
"version": "22.37.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EQEmu/Server.git"
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ void LoadSkillCaps(SharedDatabase *database, const std::string &prefix) {
|
|||||||
EQ::IPCMutex mutex("skill_caps");
|
EQ::IPCMutex mutex("skill_caps");
|
||||||
mutex.Lock();
|
mutex.Lock();
|
||||||
|
|
||||||
uint32 class_count = PLAYER_CLASS_COUNT;
|
uint32 class_count = Class::PLAYER_CLASS_COUNT;
|
||||||
uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
uint32 skill_count = EQ::skills::HIGHEST_SKILL + 1;
|
||||||
uint32 level_count = HARD_LEVEL_CAP + 1;
|
uint32 level_count = HARD_LEVEL_CAP + 1;
|
||||||
uint32 size = (class_count * skill_count * level_count * sizeof(uint16));
|
uint32 size = (class_count * skill_count * level_count * sizeof(uint16));
|
||||||
|
|||||||
@@ -156,6 +156,11 @@ bool UCSDatabase::VerifyMailKey(const std::string& characterName, int IPAddress,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
|
LogInfo("No mailkeys found for [{}].", characterName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
// The key is the client's IP address (expressed as 8 hex digits) and an 8 hex digit random string generated
|
// The key is the client's IP address (expressed as 8 hex digits) and an 8 hex digit random string generated
|
||||||
|
|||||||
@@ -423,6 +423,8 @@ OP_CancelInvite=0x0000
|
|||||||
OP_RaidJoin=0x1f21 # ShowEQ 10/27/05
|
OP_RaidJoin=0x1f21 # ShowEQ 10/27/05
|
||||||
OP_RaidInvite=0x5891 # ShowEQ 10/27/05
|
OP_RaidInvite=0x5891 # ShowEQ 10/27/05
|
||||||
OP_RaidUpdate=0x1f21 # EQEmu 06/29/05
|
OP_RaidUpdate=0x1f21 # EQEmu 06/29/05
|
||||||
|
OP_RaidDelegateAbility=0x56eb
|
||||||
|
OP_RaidClearNPCMarks=0x1794
|
||||||
|
|
||||||
OP_InspectBuffs=0x4FB6
|
OP_InspectBuffs=0x4FB6
|
||||||
|
|
||||||
|
|||||||
@@ -534,6 +534,8 @@ OP_LFGResponse=0x0000 #
|
|||||||
OP_RaidInvite=0x60b5 # C
|
OP_RaidInvite=0x60b5 # C
|
||||||
OP_RaidUpdate=0x4d8b # C
|
OP_RaidUpdate=0x4d8b # C
|
||||||
OP_RaidJoin=0x0000 #
|
OP_RaidJoin=0x0000 #
|
||||||
|
OP_RaidDelegateAbility=0x0297
|
||||||
|
OP_RaidClearNPCMarks=0x2af4
|
||||||
|
|
||||||
# Button-push commands
|
# Button-push commands
|
||||||
OP_Taunt=0x30e2 # C
|
OP_Taunt=0x30e2 # C
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -x
|
set -ex
|
||||||
|
|
||||||
sudo chown eqemu:eqemu /drone/src/ * -R
|
sudo chown eqemu:eqemu /drone/src/ * -R
|
||||||
sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
|
sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
|
||||||
@@ -9,7 +9,17 @@ git submodule init && git submodule update
|
|||||||
|
|
||||||
perl utils/scripts/build/tag-version.pl
|
perl utils/scripts/build/tag-version.pl
|
||||||
|
|
||||||
mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_STATIC=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))
|
mkdir -p build && cd build && \
|
||||||
|
cmake -DEQEMU_BUILD_TESTS=ON \
|
||||||
|
-DEQEMU_BUILD_STATIC=ON \
|
||||||
|
-DEQEMU_BUILD_LOGIN=ON \
|
||||||
|
-DEQEMU_BUILD_LUA=ON \
|
||||||
|
-DEQEMU_BUILD_PERL=ON \
|
||||||
|
-DCMAKE_CXX_FLAGS:STRING="-O1 -g -Wno-everything" \
|
||||||
|
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-O1 -g -Wno-everything" \
|
||||||
|
-DCMAKE_CXX_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
|
curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
|
||||||
./bin/tests
|
./bin/tests
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ require (
|
|||||||
require (
|
require (
|
||||||
github.com/golang/protobuf v1.3.2 // indirect
|
github.com/golang/protobuf v1.3.2 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
golang.org/x/crypto v0.1.0 // indirect
|
golang.org/x/crypto v0.14.0 // indirect
|
||||||
golang.org/x/net v0.7.0 // indirect
|
golang.org/x/net v0.17.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
|
|||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|||||||
@@ -2,42 +2,56 @@
|
|||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
#::: 13th floor import script
|
#::: 13th floor import script
|
||||||
#::: Current Source: http://items.sodeq.org/download.php
|
#::: Items Source: http://items.sodeq.org/download.php
|
||||||
#::: Authors: (Natedog, Akkadius)
|
#::: How To:
|
||||||
|
#::: 1. Place this script with your server eqemu_config.json
|
||||||
|
#::: 2. Download the items.txt file and place with this script
|
||||||
|
#::: 3. Run this script with Perl
|
||||||
|
#::: 4. Review new and updated items in the items_new table
|
||||||
|
#::: 5. Make any desired changes and replace the items table contents
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
use DBI;
|
use DBI;
|
||||||
use DBD::mysql;
|
use DBD::mysql;
|
||||||
|
|
||||||
my $database_name = "";
|
my $db_host = "";
|
||||||
|
my $db_port = "";
|
||||||
|
my $db_name = "";
|
||||||
|
my $db_user = "";
|
||||||
|
my $db_pass = "";
|
||||||
my $total_items = 0;
|
my $total_items = 0;
|
||||||
my $read_items_file = "items.txt"; #default
|
my $read_items_file = "items.txt"; #default
|
||||||
my $dbh = LoadMysql();
|
my $keep_temp_items_table = 0; #keeps the imported items table
|
||||||
|
|
||||||
|
read_eqemu_config_json();
|
||||||
|
|
||||||
|
my $dbh = DBI->connect("DBI:mysql:database=$db_name;host=$db_host;port=$db_port", $db_user, $db_pass) or die "Cannot connect to MySql.";
|
||||||
|
|
||||||
read_items_file_from_13th_floor_text();
|
read_items_file_from_13th_floor_text();
|
||||||
update_items_table();
|
update_items_table();
|
||||||
|
|
||||||
sub LoadMysql{
|
print "\n\nImport complete! Review items_new table before replacing into items table.\n\n";
|
||||||
#::: Config Variables
|
|
||||||
my $confile = "eqemu_config.xml";
|
sub read_eqemu_config_json {
|
||||||
open(F, "<$confile") or die "Unable to open config: $confile\n";
|
use JSON;
|
||||||
my $indb = 0;
|
my $json = new JSON();
|
||||||
while(<F>) {
|
my $config;
|
||||||
s/\r//g;
|
my $config_file = "eqemu_config.json";
|
||||||
if(/<database>/i) { $indb = 1; }
|
|
||||||
next unless($indb == 1);
|
my $content;
|
||||||
if(/<\/database>/i) { $indb = 0; last; }
|
open(my $fh, '<', $config_file) or die "cannot open file $config_file"; {
|
||||||
if(/<host>(.*)<\/host>/i) { $host = $1; }
|
local $/;
|
||||||
elsif(/<username>(.*)<\/username>/i) { $user = $1; }
|
$content = <$fh>;
|
||||||
elsif(/<password>(.*)<\/password>/i) { $pass = $1; }
|
|
||||||
elsif(/<db>(.*)<\/db>/i) { $db = $1; }
|
|
||||||
}
|
}
|
||||||
$database_name = $db;
|
close($fh);
|
||||||
#::: DATA SOURCE NAME
|
|
||||||
$dsn = "dbi:mysql:$db:localhost:3306";
|
$config = $json->decode($content);
|
||||||
#::: PERL DBI CONNECT
|
|
||||||
$connect = DBI->connect($dsn, $user, $pass);
|
$db_host = $config->{"server"}{"database"}{"host"};
|
||||||
return $connect;
|
$db_port = $config->{"server"}{"database"}{"port"};
|
||||||
|
$db_name = $config->{"server"}{"database"}{"db"};
|
||||||
|
$db_user = $config->{"server"}{"database"}{"username"};
|
||||||
|
$db_pass = $config->{"server"}{"database"}{"password"};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub read_items_file_from_13th_floor_text {
|
sub read_items_file_from_13th_floor_text {
|
||||||
@@ -56,7 +70,7 @@ sub read_items_file_from_13th_floor_text {
|
|||||||
$sth->execute();
|
$sth->execute();
|
||||||
my $has_items_floor = $sth->fetchrow_array();
|
my $has_items_floor = $sth->fetchrow_array();
|
||||||
|
|
||||||
#::: If we have items_floor
|
#::: If we don't have items_floor table
|
||||||
if ($has_items_floor eq '') {
|
if ($has_items_floor eq '') {
|
||||||
$dbh->do("CREATE TABLE `items_floor` (`" . join("` VARCHAR(64) NOT NULL DEFAULT '', `", @fields). "` VARCHAR(64) NOT NULL DEFAULT '', UNIQUE INDEX `ID` (`id`)) COLLATE='latin1_swedish_ci' ENGINE=MyISAM");
|
$dbh->do("CREATE TABLE `items_floor` (`" . join("` VARCHAR(64) NOT NULL DEFAULT '', `", @fields). "` VARCHAR(64) NOT NULL DEFAULT '', UNIQUE INDEX `ID` (`id`)) COLLATE='latin1_swedish_ci' ENGINE=MyISAM");
|
||||||
$dbh->do("ALTER TABLE `items_floor` CHANGE `id` `id` INT(11) NOT NULL DEFAULT '0'");
|
$dbh->do("ALTER TABLE `items_floor` CHANGE `id` `id` INT(11) NOT NULL DEFAULT '0'");
|
||||||
@@ -110,32 +124,41 @@ sub read_items_file_from_13th_floor_text {
|
|||||||
#::: One last processing print
|
#::: One last processing print
|
||||||
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
|
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
|
||||||
|
|
||||||
printf "\n" . $total_items . " items added to database... Took " . (time() - $start_time) . " second(s)... \n";
|
printf "\n" . $total_items . " items imported... Took " . (time() - $start_time) . " second(s)... \n";
|
||||||
|
|
||||||
|
#::: Process slots 21, 22
|
||||||
print "Flipping slots 21 and 22...";
|
print "Flipping slots 21 and 22...";
|
||||||
$rows_affected = $dbh->prepare("
|
$rows_affected = $dbh->prepare("
|
||||||
UPDATE `items_floor`
|
UPDATE `items_floor`
|
||||||
SET `slots` = (`slots` ^ 6291456)
|
SET `slots` = (`slots` ^ 6291456)
|
||||||
WHERE (`slots` & 6291456)
|
WHERE (`slots` & 6291456)
|
||||||
IN (2097152, 4194304)")->execute();
|
IN (2097152, 4194304)")->execute();
|
||||||
print " Rows affected (" . $rows_affected . ")\n";
|
print " :: Rows affected (" . $rows_affected . ")\n";
|
||||||
|
|
||||||
|
#::: Update idfile entries
|
||||||
|
print "Updating idfile entries...";
|
||||||
|
$rows_affected = $dbh->prepare("
|
||||||
|
UPDATE `items_floor`
|
||||||
|
SET `idfile` = CONCAT('IT', `idfile`)")->execute();
|
||||||
|
print " :: Rows affected(" . $rows_affected . ")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub update_items_table {
|
sub update_items_table {
|
||||||
|
|
||||||
#::: Keep Items table sane
|
#::: Establish items_new table
|
||||||
$query_handle = $dbh->prepare("
|
print "Setting up new items table...\n";
|
||||||
ALTER TABLE `items`
|
$dbh->do("DROP TABLE IF EXISTS items_new");
|
||||||
MODIFY COLUMN `UNK132` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL;
|
$dbh->do("CREATE TABLE items_new AS SELECT * FROM items");
|
||||||
");
|
|
||||||
$query_handle->execute();
|
print "Updating new items table...\n";
|
||||||
|
|
||||||
my @matching_table;
|
my @matching_table;
|
||||||
my @missing_items_table;
|
my @missing_items_table;
|
||||||
my @missing_items_floor_table;
|
my @missing_items_floor_table;
|
||||||
|
|
||||||
|
print "Comparing table structure...\n";
|
||||||
#::: Get columns from `items`
|
#::: Get columns from `items`
|
||||||
my $sth = $dbh->prepare("SHOW COLUMNS FROM `items`;");
|
my $sth = $dbh->prepare("SHOW COLUMNS FROM `items_new`;");
|
||||||
$sth->execute();
|
$sth->execute();
|
||||||
my @items_table;
|
my @items_table;
|
||||||
while (my @row = $sth->fetchrow_array()) {
|
while (my @row = $sth->fetchrow_array()) {
|
||||||
@@ -195,15 +218,16 @@ sub update_items_table {
|
|||||||
my @items_add = (
|
my @items_add = (
|
||||||
"casttime_", "endur", "range", "attuneable", "evolvinglevel", "herosforgemodel", "scrolltype",
|
"casttime_", "endur", "range", "attuneable", "evolvinglevel", "herosforgemodel", "scrolltype",
|
||||||
"scriptfileid", "powersourcecapacity", "augslot1unk2", "augslot2unk2", "augslot3unk2", "augslot4unk2",
|
"scriptfileid", "powersourcecapacity", "augslot1unk2", "augslot2unk2", "augslot3unk2", "augslot4unk2",
|
||||||
"augslot5unk2", "augslot6unk2", "recskill", "book"
|
"augslot5unk2", "augslot6unk2", "recskill", "book", "procunk1"
|
||||||
);
|
);
|
||||||
my @items_floor_add = (
|
my @items_floor_add = (
|
||||||
"foodduration", "endurance", "therange", "attunable", "evolvl", "heroforge1", "scrolleffecttype",
|
"foodduration", "endurance", "therange", "attunable", "evolvl", "heroforge1", "scrolleffecttype",
|
||||||
"rightclickscriptid", "powersourcecap", "augslot1unk", "augslot2unk", "augslot3unk", "augslot4unk",
|
"rightclickscriptid", "powersourcecap", "augslot1unk", "augslot2unk", "augslot3unk", "augslot4unk",
|
||||||
"augslot5unk", "augslot6unk", "reqskill", "booktype"
|
"augslot5unk", "augslot6unk", "reqskill", "booktype", "prockunk1"
|
||||||
);
|
);
|
||||||
|
|
||||||
#::: Match the mis-matched fields...
|
#::: Match the mis-matched fields...
|
||||||
|
print "Matching fields...\n";
|
||||||
my $spot = 0;
|
my $spot = 0;
|
||||||
foreach $value (@items_add) {
|
foreach $value (@items_add) {
|
||||||
$items_field_list .= ", `" . $value . "`";
|
$items_field_list .= ", `" . $value . "`";
|
||||||
@@ -217,21 +241,22 @@ sub update_items_table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $update_query = "
|
my $update_query = "
|
||||||
INSERT INTO items (" . $items_field_list . ")
|
INSERT INTO items_new (" . $items_field_list . ")
|
||||||
SELECT " . $items_floor_field_list . "
|
SELECT " . $items_floor_field_list . "
|
||||||
FROM items_floor fi
|
FROM items_floor fi
|
||||||
ON DUPLICATE KEY UPDATE " . $update_fields;
|
ON DUPLICATE KEY UPDATE " . $update_fields;
|
||||||
|
|
||||||
#::: Print missing fields to file
|
#::: Print missing fields to file
|
||||||
|
print "Writing query and discrepencies to file...\n";
|
||||||
my $write_file = "missing_item_fields.txt";
|
my $write_file = "missing_item_fields.txt";
|
||||||
|
|
||||||
open(F, ">$write_file") or die "Unable to open questfile: $write_file\n";
|
open(F, ">$write_file") or die "Unable to open file: $write_file\n";
|
||||||
print F "$update_query \n\n";
|
print F "$update_query \n\n";
|
||||||
print F "EQEMU items Table missing fields\n";
|
print F "EQEMU items table extra fields:\n";
|
||||||
foreach $value (@missing_items_table) {
|
foreach $value (@missing_items_table) {
|
||||||
print F "$value\n";
|
print F "$value\n";
|
||||||
}
|
}
|
||||||
print F "\n\n13thFloor items Table missing fields\n";
|
print F "\n\n13thFloor items table extra fields:\n";
|
||||||
foreach $value (@missing_items_floor_table) {
|
foreach $value (@missing_items_floor_table) {
|
||||||
print F "$value\n";
|
print F "$value\n";
|
||||||
}
|
}
|
||||||
@@ -239,12 +264,24 @@ sub update_items_table {
|
|||||||
|
|
||||||
#::: Number of rows affected by query
|
#::: Number of rows affected by query
|
||||||
$rows = $dbh->do($update_query);
|
$rows = $dbh->do($update_query);
|
||||||
|
print "Added or updated " . $rows . " entries.\n";
|
||||||
|
|
||||||
#::: Update stackables
|
#::: Update stackables
|
||||||
$dbh->do("UPDATE items i SET i.stackable = 1 WHERE i.stacksize > 1");
|
print "Updating stackable field...\n";
|
||||||
|
$dbh->do("UPDATE items_new i SET i.stackable = 1 WHERE i.stacksize > 1");
|
||||||
|
|
||||||
print "Added all new items to Items table (" . $rows . ")!\n";
|
#::: Update legacy research tome bagtypes
|
||||||
|
print "Updating legacy research tomes...\n";
|
||||||
|
$dbh->do("UPDATE items_new i SET i.bagtype = 24 WHERE i.id IN (17655, 17903)"); #RESEARCHWIZ
|
||||||
|
$dbh->do("UPDATE items_new i SET i.bagtype = 25 WHERE i.id IN (17502, 17653)"); #RESEARCHMAG
|
||||||
|
$dbh->do("UPDATE items_new i SET i.bagtype = 26 WHERE i.id IN (17501, 17654)"); #RESEARCHNEC
|
||||||
|
$dbh->do("UPDATE items_new i SET i.bagtype = 27 WHERE i.id IN (17500, 17652)"); #RESEARCHENC
|
||||||
|
|
||||||
|
#::: Remove temp table
|
||||||
|
if (!$keep_temp_items_table) {
|
||||||
|
print "Cleaning up temp items table...\n";
|
||||||
|
$dbh->do("DROP TABLE items_floor");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub trim($) {
|
sub trim($) {
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ ADD_EXECUTABLE(world ${world_sources} ${world_headers})
|
|||||||
|
|
||||||
INSTALL(TARGETS world RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
INSTALL(TARGETS world RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||||
|
|
||||||
|
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||||
|
TARGET_PRECOMPILE_HEADERS(world PRIVATE ../common/pch/pch.h)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DWORLD)
|
ADD_DEFINITIONS(-DWORLD)
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(world ${SERVER_LIBS})
|
TARGET_LINK_LIBRARIES(world ${SERVER_LIBS})
|
||||||
|
|||||||
+5
-5
@@ -1966,7 +1966,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
|||||||
{ /*Drakkin*/ 70, 80, 85, 75, 80, 85, 75}
|
{ /*Drakkin*/ 70, 80, 85, 75, 80, 85, 75}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int BaseClass[PLAYER_CLASS_COUNT][8] =
|
static const int BaseClass[Class::PLAYER_CLASS_COUNT][8] =
|
||||||
{ /* STR STA AGI DEX WIS INT CHR ADD*/
|
{ /* STR STA AGI DEX WIS INT CHR ADD*/
|
||||||
{ /*Warrior*/ 10, 10, 5, 0, 0, 0, 0, 25},
|
{ /*Warrior*/ 10, 10, 5, 0, 0, 0, 0, 25},
|
||||||
{ /*Cleric*/ 5, 5, 0, 0, 10, 0, 0, 30},
|
{ /*Cleric*/ 5, 5, 0, 0, 10, 0, 0, 30},
|
||||||
@@ -1986,7 +1986,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
|||||||
{ /*Berserker*/ 10, 5, 0, 10, 0, 0, 0, 25}
|
{ /*Berserker*/ 10, 5, 0, 10, 0, 0, 0, 25}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const bool ClassRaceLookupTable[PLAYER_CLASS_COUNT][_TABLE_RACES]=
|
static const bool ClassRaceLookupTable[Class::PLAYER_CLASS_COUNT][_TABLE_RACES]=
|
||||||
{ /*Human Barbarian Erudite Woodelf Highelf Darkelf Halfelf Dwarf Troll Ogre Halfling Gnome Iksar Vahshir Froglok Drakkin*/
|
{ /*Human Barbarian Erudite Woodelf Highelf Darkelf Halfelf Dwarf Troll Ogre Halfling Gnome Iksar Vahshir Froglok Drakkin*/
|
||||||
{ /*Warrior*/ true, true, false, true, false, true, true, true, true, true, true, true, true, true, true, true},
|
{ /*Warrior*/ true, true, false, true, false, true, true, true, true, true, true, true, true, true, true, true},
|
||||||
{ /*Cleric*/ true, false, true, false, true, true, true, true, false, false, true, true, false, false, true, true},
|
{ /*Cleric*/ true, false, true, false, true, true, true, true, false, false, true, true, false, false, true, true},
|
||||||
@@ -2021,7 +2021,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
|||||||
|
|
||||||
// if out of range looking it up in the table would crash stuff
|
// if out of range looking it up in the table would crash stuff
|
||||||
// so we return from these
|
// so we return from these
|
||||||
if (classtemp >= PLAYER_CLASS_COUNT) {
|
if (classtemp >= Class::PLAYER_CLASS_COUNT) {
|
||||||
LogInfo(" class is out of range");
|
LogInfo(" class is out of range");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2114,7 +2114,7 @@ void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cle->GetClientVersion() < static_cast<uint8>(EQ::versions::ClientVersion::RoF2) && pp->class_ == BERSERKER) {
|
if (cle->GetClientVersion() < static_cast<uint8>(EQ::versions::ClientVersion::RoF2) && pp->class_ == Class::Berserker) {
|
||||||
pp->skills[EQ::skills::Skill1HPiercing] = pp->skills[EQ::skills::Skill2HPiercing];
|
pp->skills[EQ::skills::Skill1HPiercing] = pp->skills[EQ::skills::Skill2HPiercing];
|
||||||
pp->skills[EQ::skills::Skill2HPiercing] = 0;
|
pp->skills[EQ::skills::Skill2HPiercing] = 0;
|
||||||
}
|
}
|
||||||
@@ -2299,7 +2299,7 @@ void Client::SetClassLanguages(PlayerProfile_Struct *pp)
|
|||||||
{
|
{
|
||||||
// we only need to handle one class, but custom server might want to do more
|
// we only need to handle one class, but custom server might want to do more
|
||||||
switch(pp->class_) {
|
switch(pp->class_) {
|
||||||
case ROGUE:
|
case Class::Rogue:
|
||||||
pp->languages[LANG_THIEVES_CANT] = 100;
|
pp->languages[LANG_THIEVES_CANT] = 100;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+10
-10
@@ -578,25 +578,25 @@ void ConsoleZoneShutdown(
|
|||||||
strcpy(&tmpname[1], connection->UserName().c_str());
|
strcpy(&tmpname[1], connection->UserName().c_str());
|
||||||
|
|
||||||
auto pack = new ServerPacket;
|
auto pack = new ServerPacket;
|
||||||
pack->size = sizeof(ServerZoneStateChange_struct);
|
pack->size = sizeof(ServerZoneStateChange_Struct);
|
||||||
pack->pBuffer = new uchar[pack->size];
|
pack->pBuffer = new uchar[pack->size];
|
||||||
memset(pack->pBuffer, 0, sizeof(ServerZoneStateChange_struct));
|
memset(pack->pBuffer, 0, sizeof(ServerZoneStateChange_Struct));
|
||||||
ServerZoneStateChange_struct *s = (ServerZoneStateChange_struct *) pack->pBuffer;
|
auto *s = (ServerZoneStateChange_Struct *) pack->pBuffer;
|
||||||
pack->opcode = ServerOP_ZoneShutdown;
|
pack->opcode = ServerOP_ZoneShutdown;
|
||||||
strcpy(s->adminname, tmpname);
|
strcpy(s->admin_name, tmpname);
|
||||||
if (Strings::IsNumber(args[0])) {
|
if (Strings::IsNumber(args[0])) {
|
||||||
s->ZoneServerID = Strings::ToInt(args[0]);
|
s->zone_server_id = Strings::ToInt(args[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
s->zoneid = ZoneID(args[0].c_str());
|
s->zone_id = ZoneID(args[0].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneServer *zs = 0;
|
ZoneServer *zs = 0;
|
||||||
if (s->ZoneServerID != 0) {
|
if (s->zone_server_id != 0) {
|
||||||
zs = zoneserver_list.FindByID(s->ZoneServerID);
|
zs = zoneserver_list.FindByID(s->zone_server_id);
|
||||||
}
|
}
|
||||||
else if (s->zoneid != 0) {
|
else if (s->zone_id != 0) {
|
||||||
zs = zoneserver_list.FindByName(ZoneName(s->zoneid));
|
zs = zoneserver_list.FindByName(ZoneName(s->zone_id));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
connection->SendLine("Error: ZoneShutdown: neither ID nor name specified");
|
connection->SendLine("Error: ZoneShutdown: neither ID nor name specified");
|
||||||
|
|||||||
+2
-2
@@ -33,7 +33,7 @@ GroupLFP::GroupLFP(uint32 inLeaderID) {
|
|||||||
LeaderID = inLeaderID;
|
LeaderID = inLeaderID;
|
||||||
for (auto &member : Members) {
|
for (auto &member : Members) {
|
||||||
member.Name[0] = '\0';
|
member.Name[0] = '\0';
|
||||||
member.Class = NO_CLASS;
|
member.Class = Class::None;
|
||||||
member.Level = 0;
|
member.Level = 0;
|
||||||
member.Zone = 0;
|
member.Zone = 0;
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ void GroupLFP::SetDetails(ServerLFPUpdate_Struct *Update) {
|
|||||||
Members[i].GuildID = CLE->GuildID();
|
Members[i].GuildID = CLE->GuildID();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Members[i].Class = NO_CLASS;
|
Members[i].Class = Class::None;
|
||||||
Members[i].Level = 0;
|
Members[i].Level = 0;
|
||||||
Members[i].Zone = 0;
|
Members[i].Zone = 0;
|
||||||
Members[i].GuildID = 0xFFFF;
|
Members[i].GuildID = 0xFFFF;
|
||||||
|
|||||||
+14
-6
@@ -424,12 +424,20 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (EQTimeTimer.Check()) {
|
if (EQTimeTimer.Check()) {
|
||||||
TimeOfDay_Struct tod;
|
TimeOfDay_Struct tod{};
|
||||||
zoneserver_list.worldclock.GetCurrentEQTimeOfDay(time(0), &tod);
|
zoneserver_list.worldclock.GetCurrentEQTimeOfDay(time(nullptr), &tod);
|
||||||
if (!database.SaveTime(tod.minute, tod.hour, tod.day, tod.month, tod.year))
|
if (!database.SaveTime(tod.minute, tod.hour, tod.day, tod.month, tod.year)) {
|
||||||
LogError("Failed to save eqtime");
|
LogEqTime("Failed to save eqtime");
|
||||||
else
|
}
|
||||||
LogDebug("EQTime successfully saved");
|
else {
|
||||||
|
LogEqTimeDetail("EQTime successfully saved - time is now year [{}] month [{}] day [{}] hour [{}] minute [{}]",
|
||||||
|
tod.year,
|
||||||
|
tod.month,
|
||||||
|
tod.day,
|
||||||
|
tod.hour - 1,
|
||||||
|
tod.minute
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zoneserver_list.Process();
|
zoneserver_list.Process();
|
||||||
|
|||||||
+19
-16
@@ -720,15 +720,15 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_ZoneShutdown: {
|
case ServerOP_ZoneShutdown: {
|
||||||
auto s = (ServerZoneStateChange_struct*) pack->pBuffer;
|
auto *s = (ServerZoneStateChange_Struct*) pack->pBuffer;
|
||||||
ZoneServer* zs = 0;
|
ZoneServer* zs = 0;
|
||||||
if (s->ZoneServerID) {
|
if (s->zone_server_id) {
|
||||||
zs = zoneserver_list.FindByID(s->ZoneServerID);
|
zs = zoneserver_list.FindByID(s->zone_server_id);
|
||||||
} else if (s->zoneid) {
|
} else if (s->zone_id) {
|
||||||
zs = zoneserver_list.FindByName(ZoneName(s->zoneid));
|
zs = zoneserver_list.FindByName(ZoneName(s->zone_id));
|
||||||
} else {
|
} else {
|
||||||
zoneserver_list.SendEmoteMessage(
|
zoneserver_list.SendEmoteMessage(
|
||||||
s->adminname,
|
s->admin_name,
|
||||||
0,
|
0,
|
||||||
AccountStatus::Player,
|
AccountStatus::Player,
|
||||||
Chat::White,
|
Chat::White,
|
||||||
@@ -738,7 +738,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
|
|
||||||
if (!zs) {
|
if (!zs) {
|
||||||
zoneserver_list.SendEmoteMessage(
|
zoneserver_list.SendEmoteMessage(
|
||||||
s->adminname,
|
s->admin_name,
|
||||||
0,
|
0,
|
||||||
AccountStatus::Player,
|
AccountStatus::Player,
|
||||||
Chat::White,
|
Chat::White,
|
||||||
@@ -751,8 +751,8 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_ZoneBootup: {
|
case ServerOP_ZoneBootup: {
|
||||||
auto s = (ServerZoneStateChange_struct*) pack->pBuffer;
|
auto *s = (ServerZoneStateChange_Struct*) pack->pBuffer;
|
||||||
zoneserver_list.SOPZoneBootup(s->adminname, s->ZoneServerID, ZoneName(s->zoneid), s->makestatic);
|
zoneserver_list.SOPZoneBootup(s->admin_name, s->zone_server_id, ZoneName(s->zone_id), s->is_static);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_ZoneStatus: {
|
case ServerOP_ZoneStatus: {
|
||||||
@@ -1610,16 +1610,19 @@ void ZoneServer::TriggerBootup(uint32 in_zone_id, uint32 in_instance_id, const c
|
|||||||
zone_server_zone_id = in_zone_id;
|
zone_server_zone_id = in_zone_id;
|
||||||
instance_id = in_instance_id;
|
instance_id = in_instance_id;
|
||||||
|
|
||||||
auto pack = new ServerPacket(ServerOP_ZoneBootup, sizeof(ServerZoneStateChange_struct));
|
auto pack = new ServerPacket(ServerOP_ZoneBootup, sizeof(ServerZoneStateChange_Struct));
|
||||||
auto s = (ServerZoneStateChange_struct*) pack->pBuffer;
|
auto *s = (ServerZoneStateChange_Struct*) pack->pBuffer;
|
||||||
s->ZoneServerID = zone_server_id;
|
|
||||||
|
s->zone_server_id = zone_server_id;
|
||||||
|
|
||||||
|
s->zone_id = in_zone_id ? in_zone_id : GetZoneID();
|
||||||
|
s->instance_id = in_instance_id;
|
||||||
|
s->is_static = is_static_zone;
|
||||||
|
|
||||||
if (admin_name) {
|
if (admin_name) {
|
||||||
strn0cpy(s->adminname, admin_name, sizeof(s->adminname));
|
strn0cpy(s->admin_name, admin_name, sizeof(s->admin_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
s->zoneid = in_zone_id ? in_zone_id : GetZoneID();
|
|
||||||
s->instanceid = in_instance_id;
|
|
||||||
s->makestatic = is_static_zone;
|
|
||||||
SendPacket(pack);
|
SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
LSBootUpdate(in_zone_id, in_instance_id);
|
LSBootUpdate(in_zone_id, in_instance_id);
|
||||||
|
|||||||
+11
-1
@@ -133,6 +133,8 @@ SET(zone_sources
|
|||||||
quest_parser_collection.cpp
|
quest_parser_collection.cpp
|
||||||
raids.cpp
|
raids.cpp
|
||||||
raycast_mesh.cpp
|
raycast_mesh.cpp
|
||||||
|
sidecar_api/sidecar_api.cpp
|
||||||
|
sidecar_api/loot_simulator_controller.cpp
|
||||||
shared_task_zone_messaging.cpp
|
shared_task_zone_messaging.cpp
|
||||||
spawn2.cpp
|
spawn2.cpp
|
||||||
spawn2.h
|
spawn2.h
|
||||||
@@ -253,6 +255,7 @@ SET(zone_headers
|
|||||||
quest_parser_collection.h
|
quest_parser_collection.h
|
||||||
raids.h
|
raids.h
|
||||||
raycast_mesh.h
|
raycast_mesh.h
|
||||||
|
sidecar_api/sidecar_api.h
|
||||||
shared_task_zone_messaging.h
|
shared_task_zone_messaging.h
|
||||||
spawn2.cpp
|
spawn2.cpp
|
||||||
spawn2.h
|
spawn2.h
|
||||||
@@ -273,13 +276,20 @@ SET(zone_headers
|
|||||||
zone_config.h
|
zone_config.h
|
||||||
zonedb.h
|
zonedb.h
|
||||||
zonedump.h
|
zonedump.h
|
||||||
|
zone_cli.h
|
||||||
zone_reload.h
|
zone_reload.h
|
||||||
)
|
zone_cli.cpp)
|
||||||
|
|
||||||
ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers})
|
ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers})
|
||||||
|
|
||||||
INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||||
|
|
||||||
|
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||||
|
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch.h)
|
||||||
|
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/types.h ../common/eqemu_logsys.h ../common/eqemu_logsys_log_aliases.h ../common/features.h ../common/global_define.h)
|
||||||
|
TARGET_PRECOMPILE_HEADERS(zone PRIVATE mob.h npc.h corpse.h doors.h bot.h entity.h client.h zone.h)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DZONE)
|
ADD_DEFINITIONS(-DZONE)
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(zone ${ZONE_LIBS})
|
TARGET_LINK_LIBRARIES(zone ${ZONE_LIBS})
|
||||||
|
|||||||
+134
-38
@@ -373,72 +373,72 @@ void Mob::WakeTheDead(uint16 spell_id, Corpse *corpse_to_use, Mob *tar, uint32 d
|
|||||||
//some basic combat mods here too since it's convienent
|
//some basic combat mods here too since it's convienent
|
||||||
switch (corpse_to_use->class_)
|
switch (corpse_to_use->class_)
|
||||||
{
|
{
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
made_npc->npc_spells_id = 1;
|
made_npc->npc_spells_id = 1;
|
||||||
break;
|
break;
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
made_npc->npc_spells_id = 2;
|
made_npc->npc_spells_id = 2;
|
||||||
break;
|
break;
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
made_npc->npc_spells_id = 3;
|
made_npc->npc_spells_id = 3;
|
||||||
break;
|
break;
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
made_npc->npc_spells_id = 4;
|
made_npc->npc_spells_id = 4;
|
||||||
break;
|
break;
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
made_npc->npc_spells_id = 5;
|
made_npc->npc_spells_id = 5;
|
||||||
break;
|
break;
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
made_npc->npc_spells_id = 6;
|
made_npc->npc_spells_id = 6;
|
||||||
break;
|
break;
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
made_npc->npc_spells_id = 7;
|
made_npc->npc_spells_id = 7;
|
||||||
break;
|
break;
|
||||||
case PALADIN:
|
case Class::Paladin:
|
||||||
//SPECATK_TRIPLE
|
//SPECATK_TRIPLE
|
||||||
strcpy(made_npc->special_abilities, "6,1");
|
strcpy(made_npc->special_abilities, "6,1");
|
||||||
made_npc->current_hp = made_npc->current_hp * 150 / 100;
|
made_npc->current_hp = made_npc->current_hp * 150 / 100;
|
||||||
made_npc->max_hp = made_npc->max_hp * 150 / 100;
|
made_npc->max_hp = made_npc->max_hp * 150 / 100;
|
||||||
made_npc->npc_spells_id = 8;
|
made_npc->npc_spells_id = 8;
|
||||||
break;
|
break;
|
||||||
case SHADOWKNIGHT:
|
case Class::ShadowKnight:
|
||||||
strcpy(made_npc->special_abilities, "6,1");
|
strcpy(made_npc->special_abilities, "6,1");
|
||||||
made_npc->current_hp = made_npc->current_hp * 150 / 100;
|
made_npc->current_hp = made_npc->current_hp * 150 / 100;
|
||||||
made_npc->max_hp = made_npc->max_hp * 150 / 100;
|
made_npc->max_hp = made_npc->max_hp * 150 / 100;
|
||||||
made_npc->npc_spells_id = 9;
|
made_npc->npc_spells_id = 9;
|
||||||
break;
|
break;
|
||||||
case RANGER:
|
case Class::Ranger:
|
||||||
strcpy(made_npc->special_abilities, "7,1");
|
strcpy(made_npc->special_abilities, "7,1");
|
||||||
made_npc->current_hp = made_npc->current_hp * 135 / 100;
|
made_npc->current_hp = made_npc->current_hp * 135 / 100;
|
||||||
made_npc->max_hp = made_npc->max_hp * 135 / 100;
|
made_npc->max_hp = made_npc->max_hp * 135 / 100;
|
||||||
made_npc->npc_spells_id = 10;
|
made_npc->npc_spells_id = 10;
|
||||||
break;
|
break;
|
||||||
case BARD:
|
case Class::Bard:
|
||||||
strcpy(made_npc->special_abilities, "6,1");
|
strcpy(made_npc->special_abilities, "6,1");
|
||||||
made_npc->current_hp = made_npc->current_hp * 110 / 100;
|
made_npc->current_hp = made_npc->current_hp * 110 / 100;
|
||||||
made_npc->max_hp = made_npc->max_hp * 110 / 100;
|
made_npc->max_hp = made_npc->max_hp * 110 / 100;
|
||||||
made_npc->npc_spells_id = 11;
|
made_npc->npc_spells_id = 11;
|
||||||
break;
|
break;
|
||||||
case BEASTLORD:
|
case Class::Beastlord:
|
||||||
strcpy(made_npc->special_abilities, "7,1");
|
strcpy(made_npc->special_abilities, "7,1");
|
||||||
made_npc->current_hp = made_npc->current_hp * 110 / 100;
|
made_npc->current_hp = made_npc->current_hp * 110 / 100;
|
||||||
made_npc->max_hp = made_npc->max_hp * 110 / 100;
|
made_npc->max_hp = made_npc->max_hp * 110 / 100;
|
||||||
made_npc->npc_spells_id = 12;
|
made_npc->npc_spells_id = 12;
|
||||||
break;
|
break;
|
||||||
case ROGUE:
|
case Class::Rogue:
|
||||||
strcpy(made_npc->special_abilities, "7,1");
|
strcpy(made_npc->special_abilities, "7,1");
|
||||||
made_npc->max_dmg = made_npc->max_dmg * 150 / 100;
|
made_npc->max_dmg = made_npc->max_dmg * 150 / 100;
|
||||||
made_npc->current_hp = made_npc->current_hp * 110 / 100;
|
made_npc->current_hp = made_npc->current_hp * 110 / 100;
|
||||||
made_npc->max_hp = made_npc->max_hp * 110 / 100;
|
made_npc->max_hp = made_npc->max_hp * 110 / 100;
|
||||||
break;
|
break;
|
||||||
case MONK:
|
case Class::Monk:
|
||||||
strcpy(made_npc->special_abilities, "7,1");
|
strcpy(made_npc->special_abilities, "7,1");
|
||||||
made_npc->max_dmg = made_npc->max_dmg * 150 / 100;
|
made_npc->max_dmg = made_npc->max_dmg * 150 / 100;
|
||||||
made_npc->current_hp = made_npc->current_hp * 135 / 100;
|
made_npc->current_hp = made_npc->current_hp * 135 / 100;
|
||||||
made_npc->max_hp = made_npc->max_hp * 135 / 100;
|
made_npc->max_hp = made_npc->max_hp * 135 / 100;
|
||||||
break;
|
break;
|
||||||
case WARRIOR:
|
case Class::Warrior:
|
||||||
case BERSERKER:
|
case Class::Berserker:
|
||||||
strcpy(made_npc->special_abilities, "7,1");
|
strcpy(made_npc->special_abilities, "7,1");
|
||||||
made_npc->max_dmg = made_npc->max_dmg * 150 / 100;
|
made_npc->max_dmg = made_npc->max_dmg * 150 / 100;
|
||||||
made_npc->current_hp = made_npc->current_hp * 175 / 100;
|
made_npc->current_hp = made_npc->current_hp * 175 / 100;
|
||||||
@@ -1354,7 +1354,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Bards can cast instant cast AAs while they are casting or channeling item cast.
|
// Bards can cast instant cast AAs while they are casting or channeling item cast.
|
||||||
if (GetClass() == BARD && IsCasting() && spells[rank->spell].cast_time == 0) {
|
if (GetClass() == Class::Bard && IsCasting() && spells[rank->spell].cast_time == 0) {
|
||||||
if (!DoCastingChecksOnCaster(rank->spell, EQ::spells::CastingSlot::AltAbility)) {
|
if (!DoCastingChecksOnCaster(rank->spell, EQ::spells::CastingSlot::AltAbility)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1576,6 +1576,10 @@ bool Mob::SetAA(uint32 rank_id, uint32 new_value, uint32 charges) {
|
|||||||
|
|
||||||
|
|
||||||
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
||||||
|
if (!rank) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
AA::Ability *ability = rank->base_ability;
|
AA::Ability *ability = rank->base_ability;
|
||||||
|
|
||||||
if(!ability)
|
if(!ability)
|
||||||
@@ -2149,30 +2153,28 @@ void Client::AutoGrantAAPoints() {
|
|||||||
SendAlternateAdvancementStats();
|
SendAlternateAdvancementStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::GrantAllAAPoints()
|
void Client::GrantAllAAPoints(uint8 unlock_level)
|
||||||
{
|
{
|
||||||
//iterate through every AA
|
//iterate through every AA
|
||||||
for (auto& iter : zone->aa_abilities) {
|
for (auto& aa : zone->aa_abilities) {
|
||||||
auto ability = iter.second.get();
|
AA::Ability* ability = aa.second.get();
|
||||||
|
|
||||||
if (ability->charges > 0) {
|
if (ability->charges > 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto level = GetLevel();
|
const uint8 level = unlock_level ? unlock_level : GetLevel();
|
||||||
auto p = 1;
|
|
||||||
auto rank = ability->first;
|
AA::Rank* rank = ability->first;
|
||||||
while (rank != nullptr) {
|
while (rank) {
|
||||||
if (CanUseAlternateAdvancementRank(rank)) {
|
if (!CanUseAlternateAdvancementRank(rank)) {
|
||||||
if (rank->level_req <= level && !HasAlreadyPurchasedRank(rank)) {
|
|
||||||
FinishAlternateAdvancementPurchase(rank, true, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
p++;
|
if (rank->level_req <= level && !HasAlreadyPurchasedRank(rank)) {
|
||||||
|
FinishAlternateAdvancementPurchase(rank, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
rank = rank->next;
|
rank = rank->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2185,17 +2187,17 @@ void Client::GrantAllAAPoints()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Client::HasAlreadyPurchasedRank(AA::Rank* rank) {
|
bool Client::HasAlreadyPurchasedRank(AA::Rank* rank) {
|
||||||
auto iter = aa_ranks.find(rank->base_ability->id);
|
const auto& aa = aa_ranks.find(rank->base_ability->id);
|
||||||
|
if (aa == aa_ranks.end()) {
|
||||||
if (iter == aa_ranks.end()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(iter->first, iter->second.first);
|
const auto& ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa->first, aa->second.first);
|
||||||
auto ability = ability_rank.first;
|
|
||||||
auto current = ability_rank.second;
|
|
||||||
|
|
||||||
while (current != nullptr) {
|
AA::Ability* ability = ability_rank.first;
|
||||||
|
AA::Rank* current = ability_rank.second;
|
||||||
|
|
||||||
|
while (current) {
|
||||||
if (current == rank) {
|
if (current == rank) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2205,3 +2207,97 @@ bool Client::HasAlreadyPurchasedRank(AA::Rank *rank) {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::ListPurchasedAAs(Client *to, std::string search_criteria)
|
||||||
|
{
|
||||||
|
if (!to) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, uint8> client_aa_ranks;
|
||||||
|
|
||||||
|
for (auto &aa : zone->aa_abilities) {
|
||||||
|
AA::Ability *ability = aa.second.get();
|
||||||
|
|
||||||
|
AA::Rank *rank = ability->first;
|
||||||
|
while (rank) {
|
||||||
|
if (!CanUseAlternateAdvancementRank(rank)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasAlreadyPurchasedRank(rank)) {
|
||||||
|
const std::string aa_name = zone->GetAAName(rank->id);
|
||||||
|
if (
|
||||||
|
search_criteria.empty() ||
|
||||||
|
Strings::Contains(
|
||||||
|
Strings::ToLower(aa_name),
|
||||||
|
Strings::ToLower(search_criteria)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (client_aa_ranks.find(aa_name) == client_aa_ranks.end()) {
|
||||||
|
client_aa_ranks[aa_name] = 1;
|
||||||
|
} else {
|
||||||
|
client_aa_ranks[aa_name]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rank = rank->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_aa_ranks.empty()) {
|
||||||
|
to->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} {} no purchased AAs{}.",
|
||||||
|
to->GetTargetDescription(this, TargetDescriptionType::UCYou),
|
||||||
|
this == to ? "have" : "has",
|
||||||
|
(
|
||||||
|
!search_criteria.empty() ?
|
||||||
|
fmt::format(
|
||||||
|
" matching '{}'",
|
||||||
|
search_criteria
|
||||||
|
) :
|
||||||
|
""
|
||||||
|
)
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aa_number = 1;
|
||||||
|
|
||||||
|
for (const auto &aa : client_aa_ranks) {
|
||||||
|
to->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{}. {} (Rank {})",
|
||||||
|
aa_number,
|
||||||
|
aa.first,
|
||||||
|
aa.second
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
aa_number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
to->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} {} {} purchased AA{}{}.",
|
||||||
|
to->GetTargetDescription(this, TargetDescriptionType::UCYou),
|
||||||
|
this == to ? "have" : "has",
|
||||||
|
client_aa_ranks.size(),
|
||||||
|
client_aa_ranks.size() > 1 ? "s" : "",
|
||||||
|
(
|
||||||
|
!search_criteria.empty() ?
|
||||||
|
fmt::format(
|
||||||
|
" matching '{}'",
|
||||||
|
search_criteria
|
||||||
|
) :
|
||||||
|
""
|
||||||
|
)
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
+2
-2
@@ -46,7 +46,7 @@ void EntityList::DescribeAggro(Client *to_who, NPC *from_who, float d, bool verb
|
|||||||
);
|
);
|
||||||
|
|
||||||
bool is_engaged = from_who->IsEngaged();
|
bool is_engaged = from_who->IsEngaged();
|
||||||
bool will_aggro_npcs = from_who->WillAggroNPCs();
|
bool will_aggro_npcs = from_who->GetNPCAggro();
|
||||||
if (is_engaged) {
|
if (is_engaged) {
|
||||||
Mob *top = from_who->GetHateTop();
|
Mob *top = from_who->GetHateTop();
|
||||||
to_who->Message(
|
to_who->Message(
|
||||||
@@ -678,7 +678,7 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack)
|
|||||||
|
|
||||||
if(!isSpellAttack)
|
if(!isSpellAttack)
|
||||||
{
|
{
|
||||||
if(GetClass() == LDON_TREASURE)
|
if(GetClass() == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ Json::Value ApiGetNpcListDetail(EQ::Net::WebsocketServerConnection *connection,
|
|||||||
row["swarm_owner"] = npc->GetSwarmOwner();
|
row["swarm_owner"] = npc->GetSwarmOwner();
|
||||||
row["swarm_target"] = npc->GetSwarmTarget();
|
row["swarm_target"] = npc->GetSwarmTarget();
|
||||||
row["waypoint_max"] = npc->GetWaypointMax();
|
row["waypoint_max"] = npc->GetWaypointMax();
|
||||||
row["will_aggro_npcs"] = npc->WillAggroNPCs();
|
row["npc_aggro"] = npc->GetNPCAggro();
|
||||||
|
|
||||||
response.append(row);
|
response.append(row);
|
||||||
}
|
}
|
||||||
|
|||||||
+174
-175
@@ -558,7 +558,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dodge
|
// dodge
|
||||||
if (CanThisClassDodge() && (InFront || GetClass() == MONK)) {
|
if (CanThisClassDodge() && (InFront || GetClass() == Class::Monk)) {
|
||||||
if (IsClient())
|
if (IsClient())
|
||||||
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillDodge, other, -10);
|
CastToClient()->CheckIncreaseSkill(EQ::skills::SkillDodge, other, -10);
|
||||||
// check auto discs ... I guess aa/items too :P
|
// check auto discs ... I guess aa/items too :P
|
||||||
@@ -674,28 +674,28 @@ int Mob::GetACSoftcap()
|
|||||||
int level = std::min(105, static_cast<int>(GetLevel())) - 1;
|
int level = std::min(105, static_cast<int>(GetLevel())) - 1;
|
||||||
|
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case WARRIOR:
|
case Class::Warrior:
|
||||||
return war_softcaps[level];
|
return war_softcaps[level];
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
case BARD:
|
case Class::Bard:
|
||||||
case MONK:
|
case Class::Monk:
|
||||||
return clrbrdmnk_softcaps[level];
|
return clrbrdmnk_softcaps[level];
|
||||||
case PALADIN:
|
case Class::Paladin:
|
||||||
case SHADOWKNIGHT:
|
case Class::ShadowKnight:
|
||||||
return palshd_softcaps[level];
|
return palshd_softcaps[level];
|
||||||
case RANGER:
|
case Class::Ranger:
|
||||||
return rng_softcaps[level];
|
return rng_softcaps[level];
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
return dru_softcaps[level];
|
return dru_softcaps[level];
|
||||||
case ROGUE:
|
case Class::Rogue:
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
case BEASTLORD:
|
case Class::Beastlord:
|
||||||
case BERSERKER:
|
case Class::Berserker:
|
||||||
return rogshmbstber_softcaps[level];
|
return rogshmbstber_softcaps[level];
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
return necwizmagenc_softcaps[level];
|
return necwizmagenc_softcaps[level];
|
||||||
default:
|
default:
|
||||||
return 350;
|
return 350;
|
||||||
@@ -707,28 +707,28 @@ double Mob::GetSoftcapReturns()
|
|||||||
// These are based on the dev post, they seem to be correct for every level
|
// These are based on the dev post, they seem to be correct for every level
|
||||||
// AKA no more hard caps
|
// AKA no more hard caps
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case WARRIOR:
|
case Class::Warrior:
|
||||||
return 0.35;
|
return 0.35;
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
case BARD:
|
case Class::Bard:
|
||||||
case MONK:
|
case Class::Monk:
|
||||||
return 0.3;
|
return 0.3;
|
||||||
case PALADIN:
|
case Class::Paladin:
|
||||||
case SHADOWKNIGHT:
|
case Class::ShadowKnight:
|
||||||
return 0.33;
|
return 0.33;
|
||||||
case RANGER:
|
case Class::Ranger:
|
||||||
return 0.315;
|
return 0.315;
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
return 0.265;
|
return 0.265;
|
||||||
case ROGUE:
|
case Class::Rogue:
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
case BEASTLORD:
|
case Class::Beastlord:
|
||||||
case BERSERKER:
|
case Class::Berserker:
|
||||||
return 0.28;
|
return 0.28;
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
return 0.25;
|
return 0.25;
|
||||||
default:
|
default:
|
||||||
return 0.3;
|
return 0.3;
|
||||||
@@ -739,7 +739,7 @@ int Mob::GetClassRaceACBonus()
|
|||||||
{
|
{
|
||||||
int ac_bonus = 0;
|
int ac_bonus = 0;
|
||||||
auto level = GetLevel();
|
auto level = GetLevel();
|
||||||
if (GetClass() == MONK) {
|
if (GetClass() == Class::Monk) {
|
||||||
int hardcap = 30;
|
int hardcap = 30;
|
||||||
int softcap = 14;
|
int softcap = 14;
|
||||||
if (level > 99) {
|
if (level > 99) {
|
||||||
@@ -824,7 +824,7 @@ int Mob::GetClassRaceACBonus()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetClass() == ROGUE) {
|
if (GetClass() == Class::Rogue) {
|
||||||
int level_scaler = level - 26;
|
int level_scaler = level - 26;
|
||||||
if (GetAGI() < 80)
|
if (GetAGI() < 80)
|
||||||
ac_bonus = level_scaler / 4;
|
ac_bonus = level_scaler / 4;
|
||||||
@@ -840,7 +840,7 @@ int Mob::GetClassRaceACBonus()
|
|||||||
ac_bonus = 12;
|
ac_bonus = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetClass() == BEASTLORD) {
|
if (GetClass() == Class::Beastlord) {
|
||||||
int level_scaler = level - 6;
|
int level_scaler = level - 6;
|
||||||
if (GetAGI() < 80)
|
if (GetAGI() < 80)
|
||||||
ac_bonus = level_scaler / 5;
|
ac_bonus = level_scaler / 5;
|
||||||
@@ -894,14 +894,14 @@ int Mob::ACSum(bool skip_caps)
|
|||||||
ac += GetPetACBonusFromOwner();
|
ac += GetPetACBonusFromOwner();
|
||||||
auto spell_aa_ac = aabonuses.AC + spellbonuses.AC;
|
auto spell_aa_ac = aabonuses.AC + spellbonuses.AC;
|
||||||
ac += GetSkill(EQ::skills::SkillDefense) / 5;
|
ac += GetSkill(EQ::skills::SkillDefense) / 5;
|
||||||
if (EQ::ValueWithin(static_cast<int>(GetClass()), NECROMANCER, ENCHANTER))
|
if (EQ::ValueWithin(static_cast<int>(GetClass()), Class::Necromancer, Class::Enchanter))
|
||||||
ac += spell_aa_ac / 3;
|
ac += spell_aa_ac / 3;
|
||||||
else
|
else
|
||||||
ac += spell_aa_ac / 4;
|
ac += spell_aa_ac / 4;
|
||||||
}
|
}
|
||||||
else { // TODO: so we can't set NPC skills ... so the skill bonus ends up being HUGE so lets nerf them a bit
|
else { // TODO: so we can't set NPC skills ... so the skill bonus ends up being HUGE so lets nerf them a bit
|
||||||
auto spell_aa_ac = aabonuses.AC + spellbonuses.AC;
|
auto spell_aa_ac = aabonuses.AC + spellbonuses.AC;
|
||||||
if (EQ::ValueWithin(static_cast<int>(GetClass()), NECROMANCER, ENCHANTER))
|
if (EQ::ValueWithin(static_cast<int>(GetClass()), Class::Necromancer, Class::Enchanter))
|
||||||
ac += GetSkill(EQ::skills::SkillDefense) / 2 + spell_aa_ac / 3;
|
ac += GetSkill(EQ::skills::SkillDefense) / 2 + spell_aa_ac / 3;
|
||||||
else
|
else
|
||||||
ac += GetSkill(EQ::skills::SkillDefense) / 3 + spell_aa_ac / 4;
|
ac += GetSkill(EQ::skills::SkillDefense) / 3 + spell_aa_ac / 4;
|
||||||
@@ -1085,7 +1085,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemData *weapon_item) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((GetClass() == MONK || GetClass() == BEASTLORD) && GetLevel() >= 30) {
|
else if ((GetClass() == Class::Monk || GetClass() == Class::Beastlord) && GetLevel() >= 30) {
|
||||||
dmg = GetHandToHandDamage();
|
dmg = GetHandToHandDamage();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1199,7 +1199,7 @@ int64 Mob::GetWeaponDamage(Mob *against, const EQ::ItemInstance *weapon_item, in
|
|||||||
MagicGloves = gloves->GetItemMagical(true);
|
MagicGloves = gloves->GetItemMagical(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetClass() == MONK || GetClass() == BEASTLORD) {
|
if (GetClass() == Class::Monk || GetClass() == Class::Beastlord) {
|
||||||
if (MagicGloves || GetLevel() >= 30) {
|
if (MagicGloves || GetLevel() >= 30) {
|
||||||
dmg = GetHandToHandDamage();
|
dmg = GetHandToHandDamage();
|
||||||
if (hate)
|
if (hate)
|
||||||
@@ -1295,15 +1295,15 @@ int64 Mob::DoDamageCaps(int64 base_damage)
|
|||||||
}
|
}
|
||||||
else if (level >= 40) {
|
else if (level >= 40) {
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
cap = 80;
|
cap = 80;
|
||||||
break;
|
break;
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
cap = 40;
|
cap = 40;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1313,15 +1313,15 @@ int64 Mob::DoDamageCaps(int64 base_damage)
|
|||||||
}
|
}
|
||||||
else if (level >= 30) {
|
else if (level >= 30) {
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
cap = 26;
|
cap = 26;
|
||||||
break;
|
break;
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
cap = 18;
|
cap = 18;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1331,15 +1331,15 @@ int64 Mob::DoDamageCaps(int64 base_damage)
|
|||||||
}
|
}
|
||||||
else if (level >= 20) {
|
else if (level >= 20) {
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
cap = 20;
|
cap = 20;
|
||||||
break;
|
break;
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
cap = 12;
|
cap = 12;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1349,15 +1349,15 @@ int64 Mob::DoDamageCaps(int64 base_damage)
|
|||||||
}
|
}
|
||||||
else if (level >= 10) {
|
else if (level >= 10) {
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
cap = 12;
|
cap = 12;
|
||||||
break;
|
break;
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
cap = 10;
|
cap = 10;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1367,15 +1367,15 @@ int64 Mob::DoDamageCaps(int64 base_damage)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (GetClass()) {
|
switch (GetClass()) {
|
||||||
case CLERIC:
|
case Class::Cleric:
|
||||||
case DRUID:
|
case Class::Druid:
|
||||||
case SHAMAN:
|
case Class::Shaman:
|
||||||
cap = 9;
|
cap = 9;
|
||||||
break;
|
break;
|
||||||
case NECROMANCER:
|
case Class::Necromancer:
|
||||||
case WIZARD:
|
case Class::Wizard:
|
||||||
case MAGICIAN:
|
case Class::Magician:
|
||||||
case ENCHANTER:
|
case Class::Enchanter:
|
||||||
cap = 6;
|
cap = 6;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1476,7 +1476,7 @@ bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
LogCombatDetail("Attacking [{}] with hand [{}] [{}]", other->GetName(), Hand, bRiposte ? "this is a riposte" : "");
|
LogCombatDetail("Attacking [{}] with hand [{}] [{}]", other->GetName(), Hand, bRiposte ? "this is a riposte" : "");
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(IsCasting() && GetClass() != BARD && !IsFromSpell)
|
(IsCasting() && GetClass() != Class::Bard && !IsFromSpell)
|
||||||
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
|| ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
||||||
|| (GetHP() < 0)
|
|| (GetHP() < 0)
|
||||||
|| (!IsAttackAllowed(other))
|
|| (!IsAttackAllowed(other))
|
||||||
@@ -1741,8 +1741,7 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
static_cast<int>(attack_skill)
|
static_cast<int>(attack_skill)
|
||||||
);
|
);
|
||||||
|
|
||||||
std::vector<std::any> args = { CastToMob() };
|
if (parse->EventPlayer(EVENT_DEATH, this, export_string, 0) != 0) {
|
||||||
if (parse->EventPlayer(EVENT_DEATH, this, export_string, 0, &args) != 0) {
|
|
||||||
if (GetHP() < 0) {
|
if (GetHP() < 0) {
|
||||||
SetHP(0);
|
SetHP(0);
|
||||||
}
|
}
|
||||||
@@ -2020,7 +2019,7 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
/*
|
/*
|
||||||
Reset reuse timer for classic skill based Lay on Hands (For tit I guess)
|
Reset reuse timer for classic skill based Lay on Hands (For tit I guess)
|
||||||
*/
|
*/
|
||||||
if (GetClass() == PALADIN) { // we could check if it's not expired I guess, but should be fine not to
|
if (GetClass() == Class::Paladin) { // we could check if it's not expired I guess, but should be fine not to
|
||||||
p_timers.Clear(&database, pTimerLayHands);
|
p_timers.Clear(&database, pTimerLayHands);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2344,7 +2343,7 @@ void NPC::Damage(Mob* other, int64 damage, uint16 spell_id, EQ::skills::SkillTyp
|
|||||||
if (!IsEngaged())
|
if (!IsEngaged())
|
||||||
zone->AddAggroMob();
|
zone->AddAggroMob();
|
||||||
|
|
||||||
if (GetClass() == LDON_TREASURE)
|
if (GetClass() == Class::LDoNTreasure)
|
||||||
{
|
{
|
||||||
if (IsLDoNLocked() && GetLDoNLockedSkill() != LDoNTypeMechanical)
|
if (IsLDoNLocked() && GetLDoNLockedSkill() != LDoNTypeMechanical)
|
||||||
{
|
{
|
||||||
@@ -2389,8 +2388,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
static_cast<int>(attack_skill)
|
static_cast<int>(attack_skill)
|
||||||
);
|
);
|
||||||
|
|
||||||
std::vector<std::any> args = { CastToMob() };
|
if (parse->EventNPC(EVENT_DEATH, this, oos, export_string, 0) != 0) {
|
||||||
if (parse->EventNPC(EVENT_DEATH, this, oos, export_string, 0, &args) != 0) {
|
|
||||||
if (GetHP() < 0) {
|
if (GetHP() < 0) {
|
||||||
SetHP(0);
|
SetHP(0);
|
||||||
}
|
}
|
||||||
@@ -2407,9 +2405,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
spell,
|
spell,
|
||||||
static_cast<int>(attack_skill)
|
static_cast<int>(attack_skill)
|
||||||
);
|
);
|
||||||
|
if (parse->EventBot(EVENT_DEATH, CastToBot(), oos, export_string, 0) != 0) {
|
||||||
std::vector<std::any> args = { CastToMob() };
|
|
||||||
if (parse->EventBot(EVENT_DEATH, CastToBot(), oos, export_string, 0, &args) != 0) {
|
|
||||||
if (GetHP() < 0) {
|
if (GetHP() < 0) {
|
||||||
SetHP(0);
|
SetHP(0);
|
||||||
}
|
}
|
||||||
@@ -2465,7 +2461,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
BuffFadeAll();
|
BuffFadeAll();
|
||||||
const auto killed_level = GetLevel();
|
const auto killed_level = GetLevel();
|
||||||
|
|
||||||
if (GetClass() == LDON_TREASURE) { // open chest
|
if (GetClass() == Class::LDoNTreasure) { // open chest
|
||||||
auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct));
|
auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct));
|
||||||
Animation_Struct* anim = (Animation_Struct*)outapp->pBuffer;
|
Animation_Struct* anim = (Animation_Struct*)outapp->pBuffer;
|
||||||
anim->spawnid = GetID();
|
anim->spawnid = GetID();
|
||||||
@@ -2492,7 +2488,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
respawn2->DeathReset(1);
|
respawn2->DeathReset(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killer_mob && GetClass() != LDON_TREASURE) {
|
if (killer_mob && GetClass() != Class::LDoNTreasure) {
|
||||||
hate_list.AddEntToHateList(killer_mob, damage);
|
hate_list.AddEntToHateList(killer_mob, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2539,7 +2535,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
hate_list.DoFactionHits(GetNPCFactionID(), GetPrimaryFaction(), GetFactionAmount());
|
hate_list.DoFactionHits(GetNPCFactionID(), GetPrimaryFaction(), GetFactionAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLdonTreasure = (GetClass() == LDON_TREASURE);
|
bool IsLdonTreasure = (GetClass() == Class::LDoNTreasure);
|
||||||
|
|
||||||
if (give_exp_client && !IsCorpse()) {
|
if (give_exp_client && !IsCorpse()) {
|
||||||
Group *kg = entity_list.GetGroupByClient(give_exp_client);
|
Group *kg = entity_list.GetGroupByClient(give_exp_client);
|
||||||
@@ -2705,10 +2701,73 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool allow_merchant_corpse = RuleB(Merchant, AllowCorpse);
|
bool allow_merchant_corpse = RuleB(Merchant, AllowCorpse);
|
||||||
bool is_merchant = (class_ == MERCHANT || class_ == ADVENTURE_MERCHANT || MerchantType != 0);
|
bool is_merchant = (class_ == Class::Merchant || class_ == Class::AdventureMerchant || MerchantType != 0);
|
||||||
|
|
||||||
Corpse* corpse = nullptr;
|
Corpse* corpse = nullptr;
|
||||||
|
|
||||||
|
// Parse quests even if we're killed by an NPC
|
||||||
|
if (oos) {
|
||||||
|
if (IsNPC()) {
|
||||||
|
auto emote_id = GetEmoteID();
|
||||||
|
if (emote_id) {
|
||||||
|
DoNPCEmote(EQ::constants::EmoteEventTypes::OnDeath, emoteid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oos->IsNPC()) {
|
||||||
|
if (parse->HasQuestSub(oos->GetNPCTypeID(), EVENT_NPC_SLAY)) {
|
||||||
|
parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto emote_id = oos->GetEmoteID();
|
||||||
|
if (emote_id) {
|
||||||
|
oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id);
|
||||||
|
}
|
||||||
|
if (killer_mob) {
|
||||||
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (killer_mob && killer_mob->IsBot()) {
|
||||||
|
if (parse->BotHasQuestSub(EVENT_NPC_SLAY)) {
|
||||||
|
parse->EventBot(EVENT_NPC_SLAY, killer_mob->CastToBot(), this, "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_combat_record.Stop();
|
||||||
|
if (parse->HasQuestSub(GetNPCTypeID(), EVENT_DEATH_COMPLETE)) {
|
||||||
|
const auto& export_string = fmt::format(
|
||||||
|
"{} {} {} {}",
|
||||||
|
killer_mob ? killer_mob->GetID() : 0,
|
||||||
|
damage,
|
||||||
|
spell,
|
||||||
|
static_cast<int>(attack_skill)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<std::any> args = { corpse };
|
||||||
|
|
||||||
|
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
||||||
|
|
||||||
|
if (parse->HasQuestSub(ZONE_CONTROLLER_NPC_ID, EVENT_DEATH_ZONE)) {
|
||||||
|
const auto& export_string = fmt::format(
|
||||||
|
"{} {} {} {}",
|
||||||
|
killer_mob ? killer_mob->GetID() : 0,
|
||||||
|
damage,
|
||||||
|
spell,
|
||||||
|
static_cast<int>(attack_skill)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<std::any> args = { corpse, this };
|
||||||
|
|
||||||
|
DispatchZoneControllerEvent(EVENT_DEATH_ZONE, oos, export_string, 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
if (!HasOwner() && !IsMerc() && !GetSwarmInfo() && (!is_merchant || allow_merchant_corpse) &&
|
if (!HasOwner() && !IsMerc() && !GetSwarmInfo() && (!is_merchant || allow_merchant_corpse) &&
|
||||||
((killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) ||
|
((killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) ||
|
||||||
(killer->IsNPC() && killer->CastToNPC()->GetSwarmInfo() && killer->CastToNPC()->GetSwarmInfo()->GetOwner() && killer->CastToNPC()->GetSwarmInfo()->GetOwner()->IsClient())))
|
(killer->IsNPC() && killer->CastToNPC()->GetSwarmInfo() && killer->CastToNPC()->GetSwarmInfo()->GetOwner() && killer->CastToNPC()->GetSwarmInfo()->GetOwner()->IsClient())))
|
||||||
@@ -2818,38 +2877,6 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
entity_list.RemoveFromXTargets(this);
|
entity_list.RemoveFromXTargets(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse quests even if we're killed by an NPC
|
|
||||||
if (oos) {
|
|
||||||
if (IsNPC()) {
|
|
||||||
auto emote_id = GetEmoteID();
|
|
||||||
if (emote_id) {
|
|
||||||
DoNPCEmote(EQ::constants::EmoteEventTypes::OnDeath, emoteid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oos->IsNPC()) {
|
|
||||||
if (parse->HasQuestSub(oos->GetNPCTypeID(), EVENT_NPC_SLAY)) {
|
|
||||||
parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto emote_id = oos->GetEmoteID();
|
|
||||||
if (emote_id) {
|
|
||||||
oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id);
|
|
||||||
}
|
|
||||||
if (killer_mob) {
|
|
||||||
killer_mob->TrySpellOnKill(killed_level, spell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (killer_mob && killer_mob->IsBot()) {
|
|
||||||
if (parse->BotHasQuestSub(EVENT_NPC_SLAY)) {
|
|
||||||
parse->EventBot(EVENT_NPC_SLAY, killer_mob->CastToBot(), this, "", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
killer_mob->TrySpellOnKill(killed_level, spell);
|
|
||||||
}
|
|
||||||
|
|
||||||
WipeHateList();
|
WipeHateList();
|
||||||
p_depop = true;
|
p_depop = true;
|
||||||
|
|
||||||
@@ -2858,37 +2885,6 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
|
|
||||||
entity_list.UpdateFindableNPCState(this, true);
|
entity_list.UpdateFindableNPCState(this, true);
|
||||||
|
|
||||||
m_combat_record.Stop();
|
|
||||||
if (parse->HasQuestSub(GetNPCTypeID(), EVENT_DEATH_COMPLETE)) {
|
|
||||||
const auto& export_string = fmt::format(
|
|
||||||
"{} {} {} {}",
|
|
||||||
killer_mob ? killer_mob->GetID() : 0,
|
|
||||||
damage,
|
|
||||||
spell,
|
|
||||||
static_cast<int>(attack_skill)
|
|
||||||
);
|
|
||||||
|
|
||||||
std::vector<std::any> args = { corpse };
|
|
||||||
|
|
||||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, export_string, 0, &args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
|
||||||
|
|
||||||
if (parse->HasQuestSub(ZONE_CONTROLLER_NPC_ID, EVENT_DEATH_ZONE)) {
|
|
||||||
const auto& export_string = fmt::format(
|
|
||||||
"{} {} {} {}",
|
|
||||||
killer_mob ? killer_mob->GetID() : 0,
|
|
||||||
damage,
|
|
||||||
spell,
|
|
||||||
static_cast<int>(attack_skill)
|
|
||||||
);
|
|
||||||
|
|
||||||
std::vector<std::any> args = { corpse, this };
|
|
||||||
|
|
||||||
DispatchZoneControllerEvent(EVENT_DEATH_ZONE, oos, export_string, 0, &args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3299,14 +3295,14 @@ int Mob::GetHandToHandDamage(void)
|
|||||||
7, 7, 7, 8, 8, 8, 8, 8, 8, 9, // 21-30
|
7, 7, 7, 8, 8, 8, 8, 8, 8, 9, // 21-30
|
||||||
9, 9, 9, 9, 9, 10, 10, 10, 10, 10, // 31-40
|
9, 9, 9, 9, 9, 10, 10, 10, 10, 10, // 31-40
|
||||||
10, 11, 11, 11, 11, 11, 11, 12, 12 }; // 41-49
|
10, 11, 11, 11, 11, 11, 11, 12, 12 }; // 41-49
|
||||||
if (GetClass() == MONK) {
|
if (GetClass() == Class::Monk) {
|
||||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 50)
|
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 50)
|
||||||
return 9;
|
return 9;
|
||||||
if (level > 62)
|
if (level > 62)
|
||||||
return 15;
|
return 15;
|
||||||
return mnk_dmg[level];
|
return mnk_dmg[level];
|
||||||
}
|
}
|
||||||
else if (GetClass() == BEASTLORD) {
|
else if (GetClass() == Class::Beastlord) {
|
||||||
if (level > 49)
|
if (level > 49)
|
||||||
return 13;
|
return 13;
|
||||||
return bst_dmg[level];
|
return bst_dmg[level];
|
||||||
@@ -3358,7 +3354,7 @@ int Mob::GetHandToHandDelay(void)
|
|||||||
28, 28, 28, 27, 27, 27, 27, 27, 26, 26, // 61-70
|
28, 28, 28, 27, 27, 27, 27, 27, 26, 26, // 61-70
|
||||||
26, 26, 26 }; // 71-73
|
26, 26, 26 }; // 71-73
|
||||||
|
|
||||||
if (GetClass() == MONK) {
|
if (GetClass() == Class::Monk) {
|
||||||
// Have a look to see if we have epic fists on
|
// Have a look to see if we have epic fists on
|
||||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 50)
|
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 50)
|
||||||
return 16;
|
return 16;
|
||||||
@@ -3367,7 +3363,7 @@ int Mob::GetHandToHandDelay(void)
|
|||||||
return GetRace() == IKSAR ? 21 : 20;
|
return GetRace() == IKSAR ? 21 : 20;
|
||||||
return GetRace() == IKSAR ? mnk_iks_delay[level] : mnk_hum_delay[level];
|
return GetRace() == IKSAR ? mnk_iks_delay[level] : mnk_hum_delay[level];
|
||||||
}
|
}
|
||||||
else if (GetClass() == BEASTLORD) {
|
else if (GetClass() == Class::Beastlord) {
|
||||||
int level = GetLevel();
|
int level = GetLevel();
|
||||||
if (level > 73)
|
if (level > 73)
|
||||||
return 25;
|
return 25;
|
||||||
@@ -3628,7 +3624,7 @@ int64 Mob::ReduceAllDamage(int64 damage)
|
|||||||
|
|
||||||
bool Mob::HasProcs() const
|
bool Mob::HasProcs() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_PROCS; i++) {
|
for (int i = 0; i < m_max_procs; i++) {
|
||||||
if (IsValidSpell(PermaProcs[i].spellID) || IsValidSpell(SpellProcs[i].spellID)) {
|
if (IsValidSpell(PermaProcs[i].spellID) || IsValidSpell(SpellProcs[i].spellID)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3646,7 +3642,7 @@ bool Mob::HasProcs() const
|
|||||||
|
|
||||||
bool Mob::HasDefensiveProcs() const
|
bool Mob::HasDefensiveProcs() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_PROCS; i++) {
|
for (int i = 0; i < m_max_procs; i++) {
|
||||||
if (IsValidSpell(DefensiveProcs[i].spellID)) {
|
if (IsValidSpell(DefensiveProcs[i].spellID)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3682,7 +3678,7 @@ bool Mob::HasSkillProcSuccess() const
|
|||||||
|
|
||||||
bool Mob::HasRangedProcs() const
|
bool Mob::HasRangedProcs() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_PROCS; i++){
|
for (int i = 0; i < m_max_procs; i++){
|
||||||
if (IsValidSpell(RangedProcs[i].spellID)) {
|
if (IsValidSpell(RangedProcs[i].spellID)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4071,7 +4067,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (skill_used == EQ::skills::SkillKick &&
|
else if (skill_used == EQ::skills::SkillKick &&
|
||||||
(attacker->GetLevel() > 55 || attacker->IsNPC()) && GetClass() == WARRIOR) {
|
(attacker->GetLevel() > 55 || attacker->IsNPC()) && GetClass() == Class::Warrior) {
|
||||||
can_stun = true;
|
can_stun = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4580,7 +4576,7 @@ void Mob::TryDefensiveProc(Mob *on, uint16 hand)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Spell Procs and Quest added procs
|
//Spell Procs and Quest added procs
|
||||||
for (int i = 0; i < MAX_PROCS; i++) {
|
for (int i = 0; i < m_max_procs; i++) {
|
||||||
if (IsValidSpell(DefensiveProcs[i].spellID)) {
|
if (IsValidSpell(DefensiveProcs[i].spellID)) {
|
||||||
if (!IsProcLimitTimerActive(DefensiveProcs[i].base_spellID, DefensiveProcs[i].proc_reuse_time, ProcType::DEFENSIVE_PROC)) {
|
if (!IsProcLimitTimerActive(DefensiveProcs[i].base_spellID, DefensiveProcs[i].proc_reuse_time, ProcType::DEFENSIVE_PROC)) {
|
||||||
float chance = proc_chance * (static_cast<float>(DefensiveProcs[i].chance) / 100.0f);
|
float chance = proc_chance * (static_cast<float>(DefensiveProcs[i].chance) / 100.0f);
|
||||||
@@ -4783,7 +4779,7 @@ void Mob::TrySpellProc(const EQ::ItemInstance *inst, const EQ::ItemData *weapon,
|
|||||||
|
|
||||||
int16 poison_slot=-1;
|
int16 poison_slot=-1;
|
||||||
|
|
||||||
for (uint32 i = 0; i < MAX_PROCS; i++) {
|
for (uint32 i = 0; i < m_max_procs; i++) {
|
||||||
if (IsPet() && hand != EQ::invslot::slotPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets)
|
if (IsPet() && hand != EQ::invslot::slotPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets)
|
||||||
continue; // If pets ever can proc from off hand, this will need to change
|
continue; // If pets ever can proc from off hand, this will need to change
|
||||||
|
|
||||||
@@ -5057,11 +5053,11 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
|||||||
// We either require an innate crit chance or some SPA 169 to crit
|
// We either require an innate crit chance or some SPA 169 to crit
|
||||||
bool innate_crit = false;
|
bool innate_crit = false;
|
||||||
int crit_chance = GetCriticalChanceBonus(hit.skill);
|
int crit_chance = GetCriticalChanceBonus(hit.skill);
|
||||||
if ((GetClass() == WARRIOR || GetClass() == BERSERKER) && GetLevel() >= 12)
|
if ((GetClass() == Class::Warrior || GetClass() == Class::Berserker) && GetLevel() >= 12)
|
||||||
innate_crit = true;
|
innate_crit = true;
|
||||||
else if (GetClass() == RANGER && GetLevel() >= 12 && hit.skill == EQ::skills::SkillArchery)
|
else if (GetClass() == Class::Ranger && GetLevel() >= 12 && hit.skill == EQ::skills::SkillArchery)
|
||||||
innate_crit = true;
|
innate_crit = true;
|
||||||
else if (GetClass() == ROGUE && GetLevel() >= 12 && hit.skill == EQ::skills::SkillThrowing)
|
else if (GetClass() == Class::Rogue && GetLevel() >= 12 && hit.skill == EQ::skills::SkillThrowing)
|
||||||
innate_crit = true;
|
innate_crit = true;
|
||||||
|
|
||||||
// we have a chance to crit!
|
// we have a chance to crit!
|
||||||
@@ -5081,7 +5077,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
|||||||
dex_bonus += 45; // chances did not match live without a small boost
|
dex_bonus += 45; // chances did not match live without a small boost
|
||||||
|
|
||||||
// so if we have an innate crit we have a better chance, except for ber throwing
|
// so if we have an innate crit we have a better chance, except for ber throwing
|
||||||
if (!innate_crit || (GetClass() == BERSERKER && hit.skill == EQ::skills::SkillThrowing))
|
if (!innate_crit || (GetClass() == Class::Berserker && hit.skill == EQ::skills::SkillThrowing))
|
||||||
dex_bonus = dex_bonus * 3 / 5;
|
dex_bonus = dex_bonus * 3 / 5;
|
||||||
|
|
||||||
if (crit_chance)
|
if (crit_chance)
|
||||||
@@ -5105,7 +5101,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
|||||||
LogCombat("Crit success roll [{}] dex chance [{}] og dmg [{}] crit_mod [{}] new dmg [{}]", roll, dex_bonus, og_damage, crit_mod, hit.damage_done);
|
LogCombat("Crit success roll [{}] dex chance [{}] og dmg [{}] crit_mod [{}] new dmg [{}]", roll, dex_bonus, og_damage, crit_mod, hit.damage_done);
|
||||||
|
|
||||||
// step 3: check deadly strike
|
// step 3: check deadly strike
|
||||||
if (GetClass() == ROGUE && hit.skill == EQ::skills::SkillThrowing) {
|
if (GetClass() == Class::Rogue && hit.skill == EQ::skills::SkillThrowing) {
|
||||||
if (BehindMob(defender, GetX(), GetY())) {
|
if (BehindMob(defender, GetX(), GetY())) {
|
||||||
int chance = GetLevel() * 12;
|
int chance = GetLevel() * 12;
|
||||||
if (zone->random.Int(1, 1000) < chance) {
|
if (zone->random.Int(1, 1000) < chance) {
|
||||||
@@ -5212,8 +5208,11 @@ bool Mob::TryFinishingBlow(Mob *defender, int64 &damage)
|
|||||||
FB_Level = itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
|
FB_Level = itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
|
||||||
|
|
||||||
// modern AA description says rank 1 (500) is 50% chance
|
// modern AA description says rank 1 (500) is 50% chance
|
||||||
int ProcChance =
|
int ProcChance = (
|
||||||
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE];
|
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
|
||||||
|
itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
|
||||||
|
spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE]
|
||||||
|
);
|
||||||
|
|
||||||
if (FB_Level && FB_Dmg && (defender->GetLevel() <= FB_Level) &&
|
if (FB_Level && FB_Dmg && (defender->GetLevel() <= FB_Level) &&
|
||||||
(ProcChance >= zone->random.Int(1, 1000))) {
|
(ProcChance >= zone->random.Int(1, 1000))) {
|
||||||
@@ -5285,7 +5284,7 @@ void Mob::DoRiposte(Mob *defender)
|
|||||||
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
|
||||||
LogCombat("Preforming a return SPECIAL ATTACK ([{}] percent chance)", DoubleRipChance);
|
LogCombat("Preforming a return SPECIAL ATTACK ([{}] percent chance)", DoubleRipChance);
|
||||||
|
|
||||||
if (defender->GetClass() == MONK)
|
if (defender->GetClass() == Class::Monk)
|
||||||
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_SKILL]);
|
defender->MonkSpecialAttack(this, defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_SKILL]);
|
||||||
else if (defender->IsClient()) // so yeah, even if you don't have the skill you can still do the attack :P (and we don't crash anymore)
|
else if (defender->IsClient()) // so yeah, even if you don't have the skill you can still do the attack :P (and we don't crash anymore)
|
||||||
defender->CastToClient()->DoClassAttacks(this, defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_SKILL], true);
|
defender->CastToClient()->DoClassAttacks(this, defender->aabonuses.GiveDoubleRiposte[SBIndex::DOUBLE_RIPOSTE_SKILL], true);
|
||||||
@@ -5302,7 +5301,7 @@ void Mob::ApplyMeleeDamageMods(uint16 skill, int64 &damage, Mob *defender, Extra
|
|||||||
dmgbonusmod += opts->melee_damage_bonus_flat;
|
dmgbonusmod += opts->melee_damage_bonus_flat;
|
||||||
|
|
||||||
if (defender) {
|
if (defender) {
|
||||||
if (defender->IsOfClientBotMerc() && defender->GetClass() == WARRIOR) {
|
if (defender->IsOfClientBotMerc() && defender->GetClass() == Class::Warrior) {
|
||||||
dmgbonusmod -= 5;
|
dmgbonusmod -= 5;
|
||||||
}
|
}
|
||||||
// 168 defensive
|
// 168 defensive
|
||||||
@@ -5446,7 +5445,7 @@ const DamageTable &Mob::GetDamageTable() const
|
|||||||
{ 415, 15, 40 }, // 105
|
{ 415, 15, 40 }, // 105
|
||||||
};
|
};
|
||||||
|
|
||||||
bool monk = GetClass() == MONK;
|
bool monk = GetClass() == Class::Monk;
|
||||||
bool melee = IsWarriorClass();
|
bool melee = IsWarriorClass();
|
||||||
// tables caped at 105 for now -- future proofed for a while at least :P
|
// tables caped at 105 for now -- future proofed for a while at least :P
|
||||||
int level = std::min(static_cast<int>(GetLevel()), 105);
|
int level = std::min(static_cast<int>(GetLevel()), 105);
|
||||||
@@ -5894,7 +5893,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
|||||||
|
|
||||||
// BER weren't parsing the halving
|
// BER weren't parsing the halving
|
||||||
if (hit.skill == EQ::skills::SkillArchery ||
|
if (hit.skill == EQ::skills::SkillArchery ||
|
||||||
(hit.skill == EQ::skills::SkillThrowing && GetClass() != BERSERKER))
|
(hit.skill == EQ::skills::SkillThrowing && GetClass() != Class::Berserker))
|
||||||
hit.damage_done /= 2;
|
hit.damage_done /= 2;
|
||||||
|
|
||||||
if (hit.damage_done < 1)
|
if (hit.damage_done < 1)
|
||||||
@@ -5907,7 +5906,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
|||||||
if (headshot > 0) {
|
if (headshot > 0) {
|
||||||
hit.damage_done = headshot;
|
hit.damage_done = headshot;
|
||||||
}
|
}
|
||||||
else if (GetClass() == RANGER && GetLevel() > 50) { // no double dmg on headshot
|
else if (GetClass() == Class::Ranger && GetLevel() > 50) { // no double dmg on headshot
|
||||||
if ((defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) || !RuleB(Combat, ArcheryBonusRequiresStationary)) {
|
if ((defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) || !RuleB(Combat, ArcheryBonusRequiresStationary)) {
|
||||||
hit.damage_done *= 2;
|
hit.damage_done *= 2;
|
||||||
MessageString(Chat::MeleeCrit, BOW_DOUBLE_DAMAGE);
|
MessageString(Chat::MeleeCrit, BOW_DOUBLE_DAMAGE);
|
||||||
@@ -5932,7 +5931,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
|
|||||||
hit.damage_done = ass;
|
hit.damage_done = ass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (hit.skill == EQ::skills::SkillFrenzy && GetClass() == BERSERKER && GetLevel() > 50) {
|
else if (hit.skill == EQ::skills::SkillFrenzy && GetClass() == Class::Berserker && GetLevel() > 50) {
|
||||||
extra_mincap = 4 * GetLevel() / 5;
|
extra_mincap = 4 * GetLevel() / 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -117,7 +117,7 @@ void Client::CalcBonuses()
|
|||||||
|
|
||||||
// hmm maybe a better way to do this
|
// hmm maybe a better way to do this
|
||||||
int metabolism = spellbonuses.Metabolism + itembonuses.Metabolism + aabonuses.Metabolism;
|
int metabolism = spellbonuses.Metabolism + itembonuses.Metabolism + aabonuses.Metabolism;
|
||||||
int timer = GetClass() == MONK ? CONSUMPTION_MNK_TIMER : CONSUMPTION_TIMER;
|
int timer = GetClass() == Class::Monk ? CONSUMPTION_MNK_TIMER : CONSUMPTION_TIMER;
|
||||||
timer = timer * (100 + metabolism) / 100;
|
timer = timer * (100 + metabolism) / 100;
|
||||||
if (timer != consume_food_timer.GetTimerTime())
|
if (timer != consume_food_timer.GetTimerTime())
|
||||||
consume_food_timer.SetTimer(timer);
|
consume_food_timer.SetTimer(timer);
|
||||||
@@ -2053,7 +2053,7 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetClass() == BARD)
|
if (GetClass() == Class::Bard)
|
||||||
newbon->ManaRegen = 0; // Bards do not get mana regen from spells.
|
newbon->ManaRegen = 0; // Bards do not get mana regen from spells.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+901
-199
File diff suppressed because it is too large
Load Diff
+37
-18
@@ -39,17 +39,15 @@
|
|||||||
|
|
||||||
constexpr uint32 BOT_FOLLOW_DISTANCE_DEFAULT = 184; // as DSq value (~13.565 units)
|
constexpr uint32 BOT_FOLLOW_DISTANCE_DEFAULT = 184; // as DSq value (~13.565 units)
|
||||||
constexpr uint32 BOT_FOLLOW_DISTANCE_DEFAULT_MAX = 2500; // as DSq value (50 units)
|
constexpr uint32 BOT_FOLLOW_DISTANCE_DEFAULT_MAX = 2500; // as DSq value (50 units)
|
||||||
constexpr uint32 BOT_FOLLOW_DISTANCE_WALK = 1000; // as DSq value (~31.623 units)
|
|
||||||
|
|
||||||
constexpr uint32 BOT_KEEP_ALIVE_INTERVAL = 5000; // 5 seconds
|
constexpr uint32 BOT_KEEP_ALIVE_INTERVAL = 5000; // 5 seconds
|
||||||
|
|
||||||
|
constexpr uint32 MAG_EPIC_1_0 = 28034;
|
||||||
|
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
|
|
||||||
constexpr int BotAISpellRange = 100; // TODO: Write a method that calcs what the bot's spell range is based on spell, equipment, AA, whatever and replace this
|
constexpr int BotAISpellRange = 100; // TODO: Write a method that calcs what the bot's spell range is based on spell, equipment, AA, whatever and replace this
|
||||||
constexpr int MaxSpellTimer = 15;
|
constexpr int NegativeItemReuse = -1; // Unlinked timer for items
|
||||||
constexpr int MaxDisciplineTimer = 10;
|
|
||||||
constexpr int DisciplineReuseStart = MaxSpellTimer + 1;
|
|
||||||
constexpr int MaxTimer = MaxSpellTimer + MaxDisciplineTimer;
|
|
||||||
|
|
||||||
// nHSND negative Healer/Slower/Nuker/Doter
|
// nHSND negative Healer/Slower/Nuker/Doter
|
||||||
// pH positive Healer
|
// pH positive Healer
|
||||||
@@ -223,6 +221,8 @@ public:
|
|||||||
void SetPullFlag(bool flag = true) { m_pull_flag = flag; }
|
void SetPullFlag(bool flag = true) { m_pull_flag = flag; }
|
||||||
bool GetPullingFlag() const { return m_pulling_flag; }
|
bool GetPullingFlag() const { return m_pulling_flag; }
|
||||||
bool GetReturningFlag() const { return m_returning_flag; }
|
bool GetReturningFlag() const { return m_returning_flag; }
|
||||||
|
bool GetIsUsingItemClick() { return is_using_item_click; }
|
||||||
|
void SetIsUsingItemClick(bool flag = true) { is_using_item_click = flag; }
|
||||||
bool UseDiscipline(uint32 spell_id, uint32 target);
|
bool UseDiscipline(uint32 spell_id, uint32 target);
|
||||||
uint8 GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets, Raid* raid);
|
uint8 GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets, Raid* raid);
|
||||||
uint8 GetNumberNeedingHealedInRaidGroup(uint8& need_healed, uint8 hpr, bool includePets, Raid* raid);
|
uint8 GetNumberNeedingHealedInRaidGroup(uint8& need_healed, uint8 hpr, bool includePets, Raid* raid);
|
||||||
@@ -287,6 +287,10 @@ public:
|
|||||||
void SetEndurance(int32 newEnd) override;
|
void SetEndurance(int32 newEnd) override;
|
||||||
void DoEnduranceUpkeep();
|
void DoEnduranceUpkeep();
|
||||||
|
|
||||||
|
void TryItemClick(uint16 slot_id);
|
||||||
|
EQ::ItemInstance* GetClickItem(uint16 slot_id);
|
||||||
|
void DoItemClick(const EQ::ItemData* inst, uint16 slot_id);
|
||||||
|
|
||||||
bool AI_AddBotSpells(uint32 bot_spell_id);
|
bool AI_AddBotSpells(uint32 bot_spell_id);
|
||||||
void AddSpellToBotList(
|
void AddSpellToBotList(
|
||||||
int16 iPriority,
|
int16 iPriority,
|
||||||
@@ -395,25 +399,20 @@ public:
|
|||||||
|
|
||||||
// Static Class Methods
|
// Static Class Methods
|
||||||
static Bot* LoadBot(uint32 botID);
|
static Bot* LoadBot(uint32 botID);
|
||||||
static uint32 SpawnedBotCount(const uint32 owner_id, uint8 class_id = NO_CLASS);
|
static uint32 SpawnedBotCount(const uint32 owner_id, uint8 class_id = Class::None);
|
||||||
static void LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp);
|
static void LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp);
|
||||||
|
|
||||||
static bool IsBotAttackAllowed(Mob* attacker, Mob* target, bool& hasRuleDefined);
|
static bool IsBotAttackAllowed(Mob* attacker, Mob* target, bool& hasRuleDefined);
|
||||||
static Bot* GetBotByBotClientOwnerAndBotName(Client* c, const std::string& botName);
|
static Bot* GetBotByBotClientOwnerAndBotName(Client* c, const std::string& botName);
|
||||||
static void ProcessBotGroupInvite(Client* c, std::string const& botName);
|
static void ProcessBotGroupInvite(Client* c, std::string const& botName);
|
||||||
static void ProcessBotGroupDisband(Client* c, const std::string& botName);
|
static void ProcessBotGroupDisband(Client* c, const std::string& botName);
|
||||||
static void BotOrderCampAll(Client* c, uint8 class_id = NO_CLASS);
|
static void BotOrderCampAll(Client* c, uint8 class_id = Class::None);
|
||||||
static void ProcessBotInspectionRequest(Bot* inspectedBot, Client* client);
|
static void ProcessBotInspectionRequest(Bot* inspectedBot, Client* client);
|
||||||
static void LoadAndSpawnAllZonedBots(Client* bot_owner);
|
static void LoadAndSpawnAllZonedBots(Client* bot_owner);
|
||||||
static bool GroupHasBot(Group* group);
|
static bool GroupHasBot(Group* group);
|
||||||
static Bot* GetFirstBotInGroup(Group* group);
|
static Bot* GetFirstBotInGroup(Group* group);
|
||||||
static void ProcessClientZoneChange(Client* botOwner);
|
static void ProcessClientZoneChange(Client* botOwner);
|
||||||
static void ProcessBotOwnerRefDelete(Mob* botOwner); // Removes a Client* reference when the Client object is destroyed
|
static void ProcessBotOwnerRefDelete(Mob* botOwner); // Removes a Client* reference when the Client object is destroyed
|
||||||
static int32 GetSpellRecastTimer(Bot *caster, int timer_index);
|
|
||||||
static bool CheckSpellRecastTimers(Bot *caster, int SpellIndex);
|
|
||||||
static int32 GetDisciplineRecastTimer(Bot *caster, int timer_index);
|
|
||||||
static bool CheckDisciplineRecastTimers(Bot *caster, int timer_index);
|
|
||||||
static uint32 GetDisciplineRemainingTime(Bot *caster, int timer_index);
|
|
||||||
|
|
||||||
//Raid methods
|
//Raid methods
|
||||||
static void ProcessRaidInvite(Mob* invitee, Client* invitor, bool group_invite = false);
|
static void ProcessRaidInvite(Mob* invitee, Client* invitor, bool group_invite = false);
|
||||||
@@ -461,6 +460,8 @@ public:
|
|||||||
uint8 gender
|
uint8 gender
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void AddBotStartingItems(uint16 race_id, uint8 class_id);
|
||||||
|
|
||||||
// Static Bot Group Methods
|
// Static Bot Group Methods
|
||||||
static bool AddBotToGroup(Bot* bot, Group* group);
|
static bool AddBotToGroup(Bot* bot, Group* group);
|
||||||
static bool RemoveBotFromGroup(Bot* bot, Group* group);
|
static bool RemoveBotFromGroup(Bot* bot, Group* group);
|
||||||
@@ -603,7 +604,7 @@ public:
|
|||||||
void SetBotCharmer(bool c) { _botCharmer = c; }
|
void SetBotCharmer(bool c) { _botCharmer = c; }
|
||||||
void SetPetChooser(bool p) { _petChooser = p; }
|
void SetPetChooser(bool p) { _petChooser = p; }
|
||||||
void SetBotOwner(Mob* botOwner) { this->_botOwner = botOwner; }
|
void SetBotOwner(Mob* botOwner) { this->_botOwner = botOwner; }
|
||||||
void SetRangerAutoWeaponSelect(bool enable) { GetClass() == RANGER ? _rangerAutoWeaponSelect = enable : _rangerAutoWeaponSelect = false; }
|
void SetRangerAutoWeaponSelect(bool enable) { GetClass() == Class::Ranger ? _rangerAutoWeaponSelect = enable : _rangerAutoWeaponSelect = false; }
|
||||||
void SetBotStance(EQ::constants::StanceType botStance) {
|
void SetBotStance(EQ::constants::StanceType botStance) {
|
||||||
if (botStance >= EQ::constants::stancePassive && botStance <= EQ::constants::stanceBurnAE)
|
if (botStance >= EQ::constants::stancePassive && botStance <= EQ::constants::stanceBurnAE)
|
||||||
_botStance = botStance;
|
_botStance = botStance;
|
||||||
@@ -611,8 +612,23 @@ public:
|
|||||||
_botStance = EQ::constants::stancePassive;
|
_botStance = EQ::constants::stancePassive;
|
||||||
}
|
}
|
||||||
void SetBotCasterRange(uint32 bot_caster_range) { m_bot_caster_range = bot_caster_range; }
|
void SetBotCasterRange(uint32 bot_caster_range) { m_bot_caster_range = bot_caster_range; }
|
||||||
void SetSpellRecastTimer(int timer_index, int32 recast_delay);
|
uint32 GetSpellRecastTimer(uint16 spell_id = 0);
|
||||||
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
|
bool CheckSpellRecastTimer(uint16 spell_id = 0);
|
||||||
|
uint32 GetSpellRecastRemainingTime(uint16 spell_id = 0);
|
||||||
|
void SetSpellRecastTimer(uint16 spell_id, int32 recast_delay = 0);
|
||||||
|
uint32 CalcSpellRecastTimer(uint16 spell_id);
|
||||||
|
uint32 GetDisciplineReuseTimer(uint16 spell_id = 0);
|
||||||
|
bool CheckDisciplineReuseTimer(uint16 spell_id = 0);
|
||||||
|
uint32 GetDisciplineReuseRemainingTime(uint16 spell_id = 0);
|
||||||
|
void SetDisciplineReuseTimer(uint16 spell_id, int32 reuse_timer = 0);
|
||||||
|
uint32 GetItemReuseTimer(uint32 item_id = 0);
|
||||||
|
bool CheckItemReuseTimer(uint32 item_id = 0);
|
||||||
|
void SetItemReuseTimer(uint32 item_id, uint32 reuse_timer = 0);
|
||||||
|
void ClearDisciplineReuseTimer(uint16 spell_id = 0);
|
||||||
|
void ClearItemReuseTimer(uint32 item_id = 0);
|
||||||
|
void ClearSpellRecastTimer(uint16 spell_id = 0);
|
||||||
|
uint32 GetItemReuseRemainingTime(uint32 item_id = 0);
|
||||||
|
void ClearExpiredTimers();
|
||||||
void SetAltOutOfCombatBehavior(bool behavior_flag) { _altoutofcombatbehavior = behavior_flag;}
|
void SetAltOutOfCombatBehavior(bool behavior_flag) { _altoutofcombatbehavior = behavior_flag;}
|
||||||
void SetShowHelm(bool showhelm) { _showhelm = showhelm; }
|
void SetShowHelm(bool showhelm) { _showhelm = showhelm; }
|
||||||
void SetBeardColor(uint8 value) { beardcolor = value; }
|
void SetBeardColor(uint8 value) { beardcolor = value; }
|
||||||
@@ -712,7 +728,8 @@ public:
|
|||||||
|
|
||||||
// New accessors for BotDatabase access
|
// New accessors for BotDatabase access
|
||||||
bool DeleteBot();
|
bool DeleteBot();
|
||||||
uint32* GetTimers() { return timers; }
|
std::vector<BotTimer_Struct> GetBotTimers() { return bot_timers; }
|
||||||
|
void SetBotTimers(std::vector<BotTimer_Struct> timers) { bot_timers = timers; }
|
||||||
uint32 GetLastZoneID() const { return _lastZoneId; }
|
uint32 GetLastZoneID() const { return _lastZoneId; }
|
||||||
int32 GetBaseAC() const { return _baseAC; }
|
int32 GetBaseAC() const { return _baseAC; }
|
||||||
int32 GetBaseATK() const { return _baseATK; }
|
int32 GetBaseATK() const { return _baseATK; }
|
||||||
@@ -737,7 +754,7 @@ public:
|
|||||||
//Raid additions
|
//Raid additions
|
||||||
Raid* p_raid_instance;
|
Raid* p_raid_instance;
|
||||||
|
|
||||||
static uint8 spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND];
|
static uint8 spell_casting_chances[SPELL_TYPE_COUNT][Class::PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND];
|
||||||
|
|
||||||
bool BotCastMez(Mob* tar, uint8 botLevel, bool checked_los, BotSpell& botSpell, Raid* raid);
|
bool BotCastMez(Mob* tar, uint8 botLevel, bool checked_los, BotSpell& botSpell, Raid* raid);
|
||||||
bool BotCastHeal(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpell, Raid* raid);
|
bool BotCastHeal(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpell, Raid* raid);
|
||||||
@@ -827,6 +844,7 @@ protected:
|
|||||||
|
|
||||||
std::vector<BotSpells_Struct> AIBot_spells;
|
std::vector<BotSpells_Struct> AIBot_spells;
|
||||||
std::vector<BotSpells_Struct> AIBot_spells_enforced;
|
std::vector<BotSpells_Struct> AIBot_spells_enforced;
|
||||||
|
std::vector<BotTimer_Struct> bot_timers;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Class Members
|
// Class Members
|
||||||
@@ -860,11 +878,11 @@ private:
|
|||||||
int32 cur_end;
|
int32 cur_end;
|
||||||
int32 max_end;
|
int32 max_end;
|
||||||
int32 end_regen;
|
int32 end_regen;
|
||||||
uint32 timers[MaxTimer];
|
|
||||||
|
|
||||||
Timer m_evade_timer; // can be moved to pTimers at some point
|
Timer m_evade_timer; // can be moved to pTimers at some point
|
||||||
Timer m_alt_combat_hate_timer;
|
Timer m_alt_combat_hate_timer;
|
||||||
Timer m_auto_defend_timer;
|
Timer m_auto_defend_timer;
|
||||||
|
Timer auto_save_timer;
|
||||||
bool m_dirtyautohaters;
|
bool m_dirtyautohaters;
|
||||||
bool m_guard_flag;
|
bool m_guard_flag;
|
||||||
bool m_hold_flag;
|
bool m_hold_flag;
|
||||||
@@ -873,6 +891,7 @@ private:
|
|||||||
bool m_pull_flag;
|
bool m_pull_flag;
|
||||||
bool m_pulling_flag;
|
bool m_pulling_flag;
|
||||||
bool m_returning_flag;
|
bool m_returning_flag;
|
||||||
|
bool is_using_item_click;
|
||||||
eStandingPetOrder m_previous_pet_order;
|
eStandingPetOrder m_previous_pet_order;
|
||||||
uint32 m_bot_caster_range;
|
uint32 m_bot_caster_range;
|
||||||
BotCastingRoles m_CastingRoles;
|
BotCastingRoles m_CastingRoles;
|
||||||
|
|||||||
+1031
-254
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -554,6 +554,7 @@ void bot_command_bind_affinity(Client *c, const Seperator *sep);
|
|||||||
void bot_command_bot(Client *c, const Seperator *sep);
|
void bot_command_bot(Client *c, const Seperator *sep);
|
||||||
void bot_command_caster_range(Client* c, const Seperator* sep);
|
void bot_command_caster_range(Client* c, const Seperator* sep);
|
||||||
void bot_command_charm(Client *c, const Seperator *sep);
|
void bot_command_charm(Client *c, const Seperator *sep);
|
||||||
|
void bot_command_click_item(Client* c, const Seperator* sep);
|
||||||
void bot_command_cure(Client *c, const Seperator *sep);
|
void bot_command_cure(Client *c, const Seperator *sep);
|
||||||
void bot_command_defensive(Client *c, const Seperator *sep);
|
void bot_command_defensive(Client *c, const Seperator *sep);
|
||||||
void bot_command_depart(Client *c, const Seperator *sep);
|
void bot_command_depart(Client *c, const Seperator *sep);
|
||||||
@@ -595,6 +596,7 @@ void bot_command_enforce_spell_list(Client* c, const Seperator* sep);
|
|||||||
void bot_command_summon_corpse(Client *c, const Seperator *sep);
|
void bot_command_summon_corpse(Client *c, const Seperator *sep);
|
||||||
void bot_command_suspend(Client *c, const Seperator *sep);
|
void bot_command_suspend(Client *c, const Seperator *sep);
|
||||||
void bot_command_taunt(Client *c, const Seperator *sep);
|
void bot_command_taunt(Client *c, const Seperator *sep);
|
||||||
|
void bot_command_timer(Client* c, const Seperator* sep);
|
||||||
void bot_command_track(Client *c, const Seperator *sep);
|
void bot_command_track(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);
|
||||||
void bot_command_water_breathing(Client *c, const Seperator *sep);
|
void bot_command_water_breathing(Client *c, const Seperator *sep);
|
||||||
@@ -677,7 +679,7 @@ void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_b
|
|||||||
bool helper_is_help_or_usage(const char* arg);
|
bool helper_is_help_or_usage(const char* arg);
|
||||||
bool helper_no_available_bots(Client *bot_owner, Bot *my_bot = nullptr);
|
bool helper_no_available_bots(Client *bot_owner, Bot *my_bot = nullptr);
|
||||||
void helper_send_available_subcommands(Client *bot_owner, const char* command_simile, const std::list<const char*>& subcommand_list);
|
void helper_send_available_subcommands(Client *bot_owner, const char* command_simile, const std::list<const char*>& subcommand_list);
|
||||||
void helper_send_usage_required_bots(Client *bot_owner, BCEnum::SpType spell_type, uint8 bot_class = NO_CLASS);
|
void helper_send_usage_required_bots(Client *bot_owner, BCEnum::SpType spell_type, uint8 bot_class = Class::None);
|
||||||
bool helper_spell_check_fail(STBaseEntry* local_entry);
|
bool helper_spell_check_fail(STBaseEntry* local_entry);
|
||||||
bool helper_spell_list_fail(Client *bot_owner, bcst_list* spell_list, BCEnum::SpType spell_type);
|
bool helper_spell_list_fail(Client *bot_owner, bcst_list* spell_list, BCEnum::SpType spell_type);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+78
-55
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "../common/repositories/bot_data_repository.h"
|
#include "../common/repositories/bot_data_repository.h"
|
||||||
#include "../common/repositories/bot_inventories_repository.h"
|
#include "../common/repositories/bot_inventories_repository.h"
|
||||||
|
#include "../common/repositories/bot_timers_repository.h"
|
||||||
|
|
||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
@@ -141,7 +142,7 @@ bool BotDatabase::LoadBotSpellCastingChances()
|
|||||||
if (spell_type_index >= Bot::SPELL_TYPE_COUNT)
|
if (spell_type_index >= Bot::SPELL_TYPE_COUNT)
|
||||||
continue;
|
continue;
|
||||||
uint8 class_index = Strings::ToInt(row[1]);
|
uint8 class_index = Strings::ToInt(row[1]);
|
||||||
if (class_index < WARRIOR || class_index > BERSERKER)
|
if (class_index < Class::Warrior || class_index > Class::Berserker)
|
||||||
continue;
|
continue;
|
||||||
--class_index;
|
--class_index;
|
||||||
uint8 stance_index = Strings::ToInt(row[2]);
|
uint8 stance_index = Strings::ToInt(row[2]);
|
||||||
@@ -224,7 +225,7 @@ bool BotDatabase::QueryBotCount(const uint32 owner_id, int class_id, uint32& bot
|
|||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
bot_count = Strings::ToUnsignedInt(row[0]);
|
bot_count = Strings::ToUnsignedInt(row[0]);
|
||||||
|
|
||||||
if (EQ::ValueWithin(class_id, WARRIOR, BERSERKER)) {
|
if (EQ::ValueWithin(class_id, Class::Warrior, Class::Berserker)) {
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"SELECT COUNT(`bot_id`) FROM `bot_data` WHERE `owner_id` = {} AND `class` = {}",
|
"SELECT COUNT(`bot_id`) FROM `bot_data` WHERE `owner_id` = {} AND `class` = {}",
|
||||||
owner_id,
|
owner_id,
|
||||||
@@ -917,45 +918,39 @@ bool BotDatabase::LoadTimers(Bot* bot_inst)
|
|||||||
if (!bot_inst)
|
if (!bot_inst)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
query = StringFormat(
|
auto timers = BotTimersRepository::GetWhere(
|
||||||
"SELECT"
|
database,
|
||||||
" IfNull(bt.`timer_id`, '0') As timer_id,"
|
fmt::format("bot_id = {}", bot_inst->GetBotID())
|
||||||
" IfNull(bt.`timer_value`, '0') As timer_value,"
|
|
||||||
" IfNull(MAX(sn.`recast_time`), '0') AS MaxTimer"
|
|
||||||
" FROM `bot_timers` bt, `spells_new` sn"
|
|
||||||
" WHERE bt.`bot_id` = '%u' AND sn.`EndurTimerIndex` = ("
|
|
||||||
"SELECT case"
|
|
||||||
" WHEN timer_id > '%i' THEN timer_id - '%i'"
|
|
||||||
" ELSE timer_id END AS timer_id"
|
|
||||||
" FROM `bot_timers` WHERE `timer_id` = bt.`timer_id` AND `bot_id` = bt.`bot_id`" // double-check validity
|
|
||||||
")"
|
|
||||||
" AND sn.`classes%i` <= '%i'",
|
|
||||||
bot_inst->GetBotID(),
|
|
||||||
(DisciplineReuseStart - 1),
|
|
||||||
(DisciplineReuseStart - 1),
|
|
||||||
bot_inst->GetClass(),
|
|
||||||
bot_inst->GetLevel()
|
|
||||||
);
|
);
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success())
|
|
||||||
return false;
|
|
||||||
if (!results.RowCount())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
uint32* bot_timers = bot_inst->GetTimers();
|
std::vector<BotTimer_Struct> bot_timers;
|
||||||
if (!bot_timers)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int timer_id = 0;
|
BotTimer_Struct t{};
|
||||||
uint32 timer_value = 0;
|
t.timer_id = 0;
|
||||||
uint32 max_value = 0;
|
t.timer_value = 0;
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
t.recast_time = 0;
|
||||||
timer_id = Strings::ToInt(row[0]) - 1;
|
t.is_spell = false;
|
||||||
timer_value = Strings::ToInt(row[1]);
|
t.is_disc = false;
|
||||||
max_value = Strings::ToInt(row[2]);
|
t.spell_id = 0;
|
||||||
|
t.is_item = false;
|
||||||
|
t.item_id = 0;
|
||||||
|
|
||||||
if (timer_id >= 0 && timer_id < MaxTimer && timer_value < (Timer::GetCurrentTime() + max_value))
|
for (auto& timer : timers) {
|
||||||
bot_timers[timer_id] = timer_value;
|
if (t.timer_value < (Timer::GetCurrentTime() + t.recast_time)) {
|
||||||
|
t.timer_id = timer.timer_id;
|
||||||
|
t.timer_value = timer.timer_value;
|
||||||
|
t.recast_time = timer.recast_time;
|
||||||
|
t.is_spell = timer.is_spell ? true : false;
|
||||||
|
t.is_disc = timer.is_disc ? true : false;
|
||||||
|
t.spell_id = timer.spell_id;
|
||||||
|
t.is_item = timer.is_item ? true : false;
|
||||||
|
t.item_id = timer.item_id;
|
||||||
|
bot_timers.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bot_timers.empty()) {
|
||||||
|
bot_inst->SetBotTimers(bot_timers);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -963,26 +958,56 @@ bool BotDatabase::LoadTimers(Bot* bot_inst)
|
|||||||
|
|
||||||
bool BotDatabase::SaveTimers(Bot* bot_inst)
|
bool BotDatabase::SaveTimers(Bot* bot_inst)
|
||||||
{
|
{
|
||||||
if (!bot_inst)
|
if (!bot_inst) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!DeleteTimers(bot_inst->GetBotID()))
|
if (!DeleteTimers(bot_inst->GetBotID())) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint32* bot_timers = bot_inst->GetTimers();
|
std::vector<BotTimer_Struct> bot_timers = bot_inst->GetBotTimers();
|
||||||
if (!bot_timers)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int timer_index = 0; timer_index < MaxTimer; ++timer_index) {
|
if (bot_timers.empty()) {
|
||||||
if (bot_timers[timer_index] <= Timer::GetCurrentTime())
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<BotTimersRepository::BotTimers> timers;
|
||||||
|
|
||||||
|
if (!bot_timers.empty()) {
|
||||||
|
for (auto & bot_timer : bot_timers) {
|
||||||
|
if (bot_timer.timer_value <= Timer::GetCurrentTime()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
auto t = BotTimersRepository::BotTimers{
|
||||||
"REPLACE INTO `bot_timers` (`bot_id`, `timer_id`, `timer_value`) VALUES ('{}', '{}', '{}')",
|
.bot_id = bot_inst->GetBotID(),
|
||||||
bot_inst->GetBotID(), (timer_index + 1), bot_timers[timer_index]
|
.timer_id = bot_timer.timer_id,
|
||||||
|
.timer_value = bot_timer.timer_value,
|
||||||
|
.recast_time = bot_timer.recast_time,
|
||||||
|
.is_spell = bot_timer.is_spell ? true : false,
|
||||||
|
.is_disc = bot_timer.is_disc ? true : false,
|
||||||
|
.spell_id = bot_timer.spell_id,
|
||||||
|
.is_item = bot_timer.is_item ? true : false,
|
||||||
|
.item_id = bot_timer.item_id
|
||||||
|
};
|
||||||
|
|
||||||
|
timers.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timers.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete existing
|
||||||
|
BotTimersRepository::DeleteWhere(
|
||||||
|
database,
|
||||||
|
fmt::format("bot_id = {}", bot_inst->GetBotID())
|
||||||
);
|
);
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
// bulk insert current
|
||||||
|
auto success = BotTimersRepository::InsertMany(database, timers);
|
||||||
|
if (!success) {
|
||||||
DeleteTimers(bot_inst->GetBotID());
|
DeleteTimers(bot_inst->GetBotID());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -993,13 +1018,11 @@ bool BotDatabase::SaveTimers(Bot* bot_inst)
|
|||||||
|
|
||||||
bool BotDatabase::DeleteTimers(const uint32 bot_id)
|
bool BotDatabase::DeleteTimers(const uint32 bot_id)
|
||||||
{
|
{
|
||||||
if (!bot_id)
|
if (!bot_id) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
query = StringFormat("DELETE FROM `bot_timers` WHERE `bot_id` = '%u'", bot_id);
|
BotTimersRepository::DeleteWhere(database, fmt::format("bot_id = {}", bot_id));
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2517,7 +2540,7 @@ uint8 BotDatabase::GetSpellCastingChance(uint8 spell_type_index, uint8 class_ind
|
|||||||
{
|
{
|
||||||
if (spell_type_index >= Bot::SPELL_TYPE_COUNT)
|
if (spell_type_index >= Bot::SPELL_TYPE_COUNT)
|
||||||
return 0;
|
return 0;
|
||||||
if (class_index >= PLAYER_CLASS_COUNT)
|
if (class_index >= Class::PLAYER_CLASS_COUNT)
|
||||||
return 0;
|
return 0;
|
||||||
if (stance_index >= EQ::constants::STANCE_TYPE_COUNT)
|
if (stance_index >= EQ::constants::STANCE_TYPE_COUNT)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -81,4 +81,15 @@ struct BotSpells_Struct {
|
|||||||
uint8 bucket_comparison;
|
uint8 bucket_comparison;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BotTimer_Struct {
|
||||||
|
uint32 timer_id;
|
||||||
|
uint32 timer_value;
|
||||||
|
uint32 recast_time;
|
||||||
|
bool is_spell;
|
||||||
|
bool is_disc;
|
||||||
|
uint16 spell_id;
|
||||||
|
bool is_item;
|
||||||
|
uint32 item_id;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // BOT_STRUCTS
|
#endif // BOT_STRUCTS
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user